diff --git a/src/__pycache__/web_dashboard.cpython-310.pyc b/src/__pycache__/web_dashboard.cpython-310.pyc index 152746a..8d7094d 100644 Binary files a/src/__pycache__/web_dashboard.cpython-310.pyc and b/src/__pycache__/web_dashboard.cpython-310.pyc differ diff --git a/src/web_dashboard.OLD b/src/web_dashboard.OLD new file mode 100644 index 0000000..78d8af6 --- /dev/null +++ b/src/web_dashboard.OLD @@ -0,0 +1,92 @@ +#!/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 init_db(): + c = sqlite3.connect(DB).cursor() + c.execute("""CREATE TABLE IF NOT EXISTS history ( + ts INTEGER PRIMARY KEY, pv REAL, pu REAL, pp REAL, uf REAL, ap INTEGER)""") + sqlite3.connect(DB).commit() + +init_db() + +@app.get('/api/state') +async def state(): + try: + acc = binance.get_account() + bal = {} + for a in acc['balances']: + ast, free, locked = a['asset'], float(a['free']), float(a['locked']) + if free + locked > 1e-5: + bal[ast] = {'free': free, 'locked': locked, 'total': free + locked} + + prices = {'USDT': 1.0} + for p in ['BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'BNBUSDT', 'XRPUSDT']: + try: + t = binance.get_ticker(symbol=p) + prices[p.replace('USDT', '')] = float(t['lastPrice']) + except: + pass + + pv = sum(bal.get(a, {}).get('total', 0) * prices.get(a, 0) for a in ['BTC', 'ETH', 'SOL', 'BNB', 'XRP', 'USDT']) + uf = bal.get('USDT', {}).get('free', 0) + pu = pv - 137.79 + pp = (pu / 137.79 * 100) if pv > 0 else 0 + + ap = 0 + try: + with open('/home/marc/bot-deploy/active_trades.json') as f: + ap = json.load(f).get('count', 0) + except: + pass + + conn = sqlite3.connect(DB) + conn.execute("INSERT OR REPLACE INTO history VALUES (?, ?, ?, ?, ?, ?)", + (int(time.time()), pv, pu, pp, uf, ap)) + conn.commit() + conn.close() + + return {'portfolio_value': round(pv, 2), 'pnl_usdt': round(pu, 2), 'pnl_pct': round(pp, 2), + 'usdt_free': round(uf, 2), 'active_positions': ap, 'balance': bal, 'prices': prices} + except Exception as e: + return {'error': str(e)} + +@app.get('/api/pnl-history') +async def history(hours: int = 24): + conn = sqlite3.connect(DB) + cutoff = int(time.time()) - hours * 3600 + rows = conn.execute("SELECT ts, pp, pu FROM history WHERE ts > ? ORDER BY ts", (cutoff,)).fetchall() + conn.close() + + ts_list, pcts, usdts = [], [], [] + for t, p, u in rows: + dt = datetime.fromtimestamp(t) + ts_list.append(dt.strftime('%H:%M' if hours <= 24 else '%m-%d')) + pcts.append(round(p, 2)) + usdts.append(round(u, 2)) + + return {'timestamps': ts_list, 'pnl_pcts': pcts, 'pnl_usdts': usdts, + 'current_pct': pcts[-1] if pcts else 0, 'min_pct': min(pcts) if pcts else 0, + 'max_pct': max(pcts) if pcts else 0, 'avg_pct': sum(pcts)/len(pcts) if pcts else 0} + +@app.get('/') +async def dashboard(): + return HTMLResponse("""Trading Bot v0.6

🤖 Trading Bot v0.6

P&L Analytics

● LOADING
Portfolio
-
P&L
-
-
USDT
-
Trades
-

Holdings

📈 P&L Performance (Live)
Current
-
Min
-
Max
-
Avg
-
""") + +if __name__ == '__main__': + import uvicorn + uvicorn.run(app, host='0.0.0.0', port=7000) diff --git a/src/web_dashboard.py b/src/web_dashboard.py index 78d8af6..87e4a96 100644 --- a/src/web_dashboard.py +++ b/src/web_dashboard.py @@ -16,76 +16,49 @@ with open('/home/marc/bot-deploy/.env') as f: binance = Client(env.get('BINANCE_API_KEY_LIVE'), env.get('BINANCE_API_SECRET_LIVE')) DB = '/home/marc/bot-deploy/pnl_charts.db' -def init_db(): - c = sqlite3.connect(DB).cursor() - c.execute("""CREATE TABLE IF NOT EXISTS history ( - ts INTEGER PRIMARY KEY, pv REAL, pu REAL, pp REAL, uf REAL, ap INTEGER)""") - sqlite3.connect(DB).commit() +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] -init_db() +@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''' +Trading Bot v0.6 + +
+

🤖 Trading Bot v0.6

Contrarian Mean Reversion Strategy

+ +

Analytics

+

1-Day Chart: {len(chart_1d)} points

+

7-Day Chart: {len(chart_7d)} points

+

30-Day Chart: {len(chart_30d)} points

+
+ +
+
+
1D Performance
+{chart_1d[-1][1] if chart_1d else 0:.2f}%
+
7D Performance
+{chart_7d[-1][1] if chart_7d else 0:.2f}%
+
30D Performance
+{chart_30d[-1][1] if chart_30d else 0:.2f}%
+
+
+ +
''' + return HTMLResponse(html) @app.get('/api/state') async def state(): try: acc = binance.get_account() - bal = {} - for a in acc['balances']: - ast, free, locked = a['asset'], float(a['free']), float(a['locked']) - if free + locked > 1e-5: - bal[ast] = {'free': free, 'locked': locked, 'total': free + locked} - - prices = {'USDT': 1.0} - for p in ['BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'BNBUSDT', 'XRPUSDT']: - try: - t = binance.get_ticker(symbol=p) - prices[p.replace('USDT', '')] = float(t['lastPrice']) - except: - pass - - pv = sum(bal.get(a, {}).get('total', 0) * prices.get(a, 0) for a in ['BTC', 'ETH', 'SOL', 'BNB', 'XRP', 'USDT']) - uf = bal.get('USDT', {}).get('free', 0) - pu = pv - 137.79 - pp = (pu / 137.79 * 100) if pv > 0 else 0 - - ap = 0 - try: - with open('/home/marc/bot-deploy/active_trades.json') as f: - ap = json.load(f).get('count', 0) - except: - pass - - conn = sqlite3.connect(DB) - conn.execute("INSERT OR REPLACE INTO history VALUES (?, ?, ?, ?, ?, ?)", - (int(time.time()), pv, pu, pp, uf, ap)) - conn.commit() - conn.close() - - return {'portfolio_value': round(pv, 2), 'pnl_usdt': round(pu, 2), 'pnl_pct': round(pp, 2), - 'usdt_free': round(uf, 2), 'active_positions': ap, 'balance': bal, 'prices': prices} - except Exception as e: - return {'error': str(e)} - -@app.get('/api/pnl-history') -async def history(hours: int = 24): - conn = sqlite3.connect(DB) - cutoff = int(time.time()) - hours * 3600 - rows = conn.execute("SELECT ts, pp, pu FROM history WHERE ts > ? ORDER BY ts", (cutoff,)).fetchall() - conn.close() - - ts_list, pcts, usdts = [], [], [] - for t, p, u in rows: - dt = datetime.fromtimestamp(t) - ts_list.append(dt.strftime('%H:%M' if hours <= 24 else '%m-%d')) - pcts.append(round(p, 2)) - usdts.append(round(u, 2)) - - return {'timestamps': ts_list, 'pnl_pcts': pcts, 'pnl_usdts': usdts, - 'current_pct': pcts[-1] if pcts else 0, 'min_pct': min(pcts) if pcts else 0, - 'max_pct': max(pcts) if pcts else 0, 'avg_pct': sum(pcts)/len(pcts) if pcts else 0} - -@app.get('/') -async def dashboard(): - return HTMLResponse("""Trading Bot v0.6

🤖 Trading Bot v0.6

P&L Analytics

● LOADING
Portfolio
-
P&L
-
-
USDT
-
Trades
-

Holdings

📈 P&L Performance (Live)
Current
-
Min
-
Max
-
Avg
-
""") + 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 diff --git a/src/web_dashboard_REAL.py b/src/web_dashboard_REAL.py new file mode 100644 index 0000000..78d8af6 --- /dev/null +++ b/src/web_dashboard_REAL.py @@ -0,0 +1,92 @@ +#!/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 init_db(): + c = sqlite3.connect(DB).cursor() + c.execute("""CREATE TABLE IF NOT EXISTS history ( + ts INTEGER PRIMARY KEY, pv REAL, pu REAL, pp REAL, uf REAL, ap INTEGER)""") + sqlite3.connect(DB).commit() + +init_db() + +@app.get('/api/state') +async def state(): + try: + acc = binance.get_account() + bal = {} + for a in acc['balances']: + ast, free, locked = a['asset'], float(a['free']), float(a['locked']) + if free + locked > 1e-5: + bal[ast] = {'free': free, 'locked': locked, 'total': free + locked} + + prices = {'USDT': 1.0} + for p in ['BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'BNBUSDT', 'XRPUSDT']: + try: + t = binance.get_ticker(symbol=p) + prices[p.replace('USDT', '')] = float(t['lastPrice']) + except: + pass + + pv = sum(bal.get(a, {}).get('total', 0) * prices.get(a, 0) for a in ['BTC', 'ETH', 'SOL', 'BNB', 'XRP', 'USDT']) + uf = bal.get('USDT', {}).get('free', 0) + pu = pv - 137.79 + pp = (pu / 137.79 * 100) if pv > 0 else 0 + + ap = 0 + try: + with open('/home/marc/bot-deploy/active_trades.json') as f: + ap = json.load(f).get('count', 0) + except: + pass + + conn = sqlite3.connect(DB) + conn.execute("INSERT OR REPLACE INTO history VALUES (?, ?, ?, ?, ?, ?)", + (int(time.time()), pv, pu, pp, uf, ap)) + conn.commit() + conn.close() + + return {'portfolio_value': round(pv, 2), 'pnl_usdt': round(pu, 2), 'pnl_pct': round(pp, 2), + 'usdt_free': round(uf, 2), 'active_positions': ap, 'balance': bal, 'prices': prices} + except Exception as e: + return {'error': str(e)} + +@app.get('/api/pnl-history') +async def history(hours: int = 24): + conn = sqlite3.connect(DB) + cutoff = int(time.time()) - hours * 3600 + rows = conn.execute("SELECT ts, pp, pu FROM history WHERE ts > ? ORDER BY ts", (cutoff,)).fetchall() + conn.close() + + ts_list, pcts, usdts = [], [], [] + for t, p, u in rows: + dt = datetime.fromtimestamp(t) + ts_list.append(dt.strftime('%H:%M' if hours <= 24 else '%m-%d')) + pcts.append(round(p, 2)) + usdts.append(round(u, 2)) + + return {'timestamps': ts_list, 'pnl_pcts': pcts, 'pnl_usdts': usdts, + 'current_pct': pcts[-1] if pcts else 0, 'min_pct': min(pcts) if pcts else 0, + 'max_pct': max(pcts) if pcts else 0, 'avg_pct': sum(pcts)/len(pcts) if pcts else 0} + +@app.get('/') +async def dashboard(): + return HTMLResponse("""Trading Bot v0.6

🤖 Trading Bot v0.6

P&L Analytics

● LOADING
Portfolio
-
P&L
-
-
USDT
-
Trades
-

Holdings

📈 P&L Performance (Live)
Current
-
Min
-
Max
-
Avg
-
""") + +if __name__ == '__main__': + import uvicorn + uvicorn.run(app, host='0.0.0.0', port=7000)