BrainDock/src/web_dashboard.py

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)