66 lines
2.7 KiB
Python
66 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
from fastapi import FastAPI
|
|
from fastapi.responses import HTMLResponse
|
|
from binance.client import Client
|
|
from datetime import datetime
|
|
import json, os, time, sqlite3
|
|
|
|
app = FastAPI()
|
|
|
|
env = {}
|
|
with open('/home/marc/bot-deploy/.env') as f:
|
|
for line in f:
|
|
k, _, v = line.partition('=')
|
|
env[k.strip()] = v.strip()
|
|
|
|
binance = Client(env.get('BINANCE_API_KEY_LIVE'), env.get('BINANCE_API_SECRET_LIVE'))
|
|
DB = '/home/marc/bot-deploy/pnl_charts.db'
|
|
|
|
def get_chart_data(days=1):
|
|
conn = sqlite3.connect(DB)
|
|
rows = conn.execute(f"""SELECT ts, pv, pp FROM history WHERE ts > {int(time.time()) - days*86400} ORDER BY ts""").fetchall()
|
|
conn.close()
|
|
return [(datetime.fromtimestamp(r[0]).strftime('%H:%M'), r[2]) for r in rows]
|
|
|
|
@app.get('/')
|
|
async def root():
|
|
chart_1d = get_chart_data(1)
|
|
chart_7d = get_chart_data(7)
|
|
chart_30d = get_chart_data(30)
|
|
|
|
html = f'''<!DOCTYPE html>
|
|
<html><head><title>Trading Bot v0.6</title>
|
|
<style>body{{font-family:Arial;background:#1e1e1e;color:#d0d0d0;margin:0;padding:20px}}.container{{max-width:1200px;margin:auto}}.header{{margin-bottom:30px}}.header h1{{margin:0;color:#00ff88}}.section{{background:#2d2d2d;padding:15px;margin:15px 0;border-radius:5px}}.metrics{{display:flex;gap:15px}}.metric{{flex:1;background:#1e1e1e;padding:15px;border-left:3px solid #00ff88;border-radius:3px}}.metric-label{{font-size:12px;color:#888}}.metric-value{{font-size:20px;font-weight:bold;color:#00ff88;margin-top:5px}}</style>
|
|
</head><body><div class="container">
|
|
<div class="header"><h1>🤖 Trading Bot v0.6</h1><p>Contrarian Mean Reversion Strategy</p></div>
|
|
|
|
<div class="section"><h2>Analytics</h2>
|
|
<p>1-Day Chart: {len(chart_1d)} points</p>
|
|
<p>7-Day Chart: {len(chart_7d)} points</p>
|
|
<p>30-Day Chart: {len(chart_30d)} points</p>
|
|
</div>
|
|
|
|
<div class="section">
|
|
<div class="metrics">
|
|
<div class="metric"><div class="metric-label">1D Performance</div><div class="metric-value">+{chart_1d[-1][1] if chart_1d else 0:.2f}%</div></div>
|
|
<div class="metric"><div class="metric-label">7D Performance</div><div class="metric-value">+{chart_7d[-1][1] if chart_7d else 0:.2f}%</div></div>
|
|
<div class="metric"><div class="metric-label">30D Performance</div><div class="metric-value">+{chart_30d[-1][1] if chart_30d else 0:.2f}%</div></div>
|
|
</div>
|
|
</div>
|
|
|
|
</div></body></html>'''
|
|
return HTMLResponse(html)
|
|
|
|
@app.get('/api/state')
|
|
async def state():
|
|
try:
|
|
acc = binance.get_account()
|
|
portfolio = sum(float(b['free']) * (1.0 if b['asset']=='USDT' else 0) for b in acc['balances'])
|
|
return {'portfolio': portfolio, 'status': 'ok'}
|
|
except:
|
|
return {'error': 'failed'}
|
|
|
|
if __name__ == '__main__':
|
|
import uvicorn
|
|
uvicorn.run(app, host='0.0.0.0', port=7000)
|