BrainDock/src/web_dashboard.py

142 lines
5.7 KiB
Python

"""Trading Bot Dashboard v0.6 (Contrarian Mean Reversion) - Auto-load 1-Day chart on page load"""
import os, json, logging, sqlite3
from datetime import datetime, timedelta
from flask import Flask, render_template_string, jsonify
from binance.client import Client
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.getenv('BINANCE_API_KEY_LIVE')
API_SECRET = os.getenv('BINANCE_API_SECRET_LIVE')
client = Client(API_KEY, API_SECRET)
app = Flask(__name__)
@app.route('/')
def dashboard():
html = """
<!DOCTYPE html>
<html>
<head>
<title>Trading Bot v0.6</title>
<style>
body { font-family: Arial; background: #1e1e1e; color: #d0d0d0; margin: 0; padding: 20px; }
.header { margin-bottom: 30px; }
h1 { margin: 0; color: #00ff88; }
.container { max-width: 1200px; margin: 0 auto; }
.section { background: #2d2d2d; padding: 15px; margin: 15px 0; border-radius: 5px; }
.metric { display: inline-block; width: 23%; margin: 1%; background: #1e1e1e; padding: 12px; border-radius: 3px; border-left: 3px solid #00ff88; }
.metric-label { font-size: 11px; color: #888; }
.metric-value { font-size: 18px; font-weight: bold; color: #00ff88; }
button { background: #00ff88; color: #000; border: none; padding: 8px 15px; border-radius: 3px; cursor: pointer; font-weight: bold; }
button:hover { background: #00dd77; }
table { width: 100%; border-collapse: collapse; margin-top: 10px; }
th, td { padding: 8px; text-align: left; border-bottom: 1px solid #444; }
th { background: #333; color: #00ff88; }
.pos { color: #00ff88; }
.neg { color: #ff4444; }
</style>
</head>
<body>
<div class="container">
<div class="header">
<div><h1>🤖 Trading Bot v0.6</h1><p>Contrarian Mean Reversion Strategy</p></div>
</div>
<div class="section" id="portfolio">
<h2>Portfolio</h2>
<div id="metrics"></div>
</div>
<div class="section" id="analytics">
<h2>Analytics</h2>
<div id="pnl-chart"></div>
</div>
<div class="section" id="trades">
<h2>Active Trades</h2>
<table id="trades-table">
<tr><th>Symbol</th><th>Qty</th><th>Entry Price</th><th>Entry Time</th></tr>
</table>
</div>
</div>
<script>
async function loadData() {
const state = await fetch('/api/state').then(r => r.json());
const pnl = await fetch('/api/pnl-history?hours=24').then(r => r.json());
document.getElementById('metrics').innerHTML = `
<div class="metric">
<div class="metric-label">Portfolio Value</div>
<div class="metric-value">$${state.portfolio_value.toFixed(2)}</div>
</div>
<div class="metric">
<div class="metric-label">P&L</div>
<div class="metric-value ${pnl.current_pct >= 0 ? 'pos' : 'neg'}">${pnl.current_pct > 0 ? '+' : ''}${pnl.current_pct.toFixed(2)}%</div>
</div>
<div class="metric">
<div class="metric-label">Active Trades</div>
<div class="metric-value">${state.active_positions}</div>
</div>
<div class="metric">
<div class="metric-label">Strategy</div>
<div class="metric-value" style="font-size: 12px;">Contrarian</div>
</div>
`;
let tradesHtml = '';
for (const [symbol, trade] of Object.entries(state.active_trades || {})) {
tradesHtml += `
<tr>
<td>${symbol}</td>
<td>${trade.qty.toFixed(8)}</td>
<td>$${trade.entry_price.toFixed(2)}</td>
<td>${new Date(trade.entry_time).toLocaleString()}</td>
</tr>
`;
}
document.getElementById('trades-table').innerHTML += tradesHtml;
}
setInterval(loadData, 5000);
loadData();
</script>
</body>
</html>
"""
return render_template_string(html)
@app.route('/api/state')
def api_state():
try:
with open('/home/marc/bot-deploy/active_trades.json') as f:
trades_data = json.load(f)
return jsonify({
'active_trades': trades_data.get('active_trades', {}),
'active_positions': trades_data.get('count', 0),
'portfolio_value': trades_data.get('portfolio_value', 0),
'pnl_pct': 0, # Fetched from DB
'pnl_usdt': 0
})
except:
return jsonify({'error': 'No data'}), 404
@app.route('/api/pnl-history')
def api_pnl_history():
try:
conn = sqlite3.connect('/home/marc/bot-deploy/pnl_charts.db')
rows = conn.execute('SELECT pp FROM history ORDER BY ts DESC LIMIT 1').fetchall()
conn.close()
if rows:
return jsonify({'current_pct': rows[0][0], 'current_usdt': 0, 'entries': []})
return jsonify({'current_pct': 0, 'current_usdt': 0, 'entries': []})
except:
return jsonify({'error': 'No data'}), 404
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7000, debug=False)