Skip to content

Commit f8d128b

Browse files
authored
Create dashboard.py
minor change
1 parent 471072c commit f8d128b

1 file changed

Lines changed: 119 additions & 0 deletions

File tree

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
from __future__ import annotations
2+
3+
from flask import Flask, jsonify, render_template_string
4+
5+
from copybot import CopyBot
6+
7+
HTML = """
8+
<!doctype html>
9+
<html>
10+
<head>
11+
<meta charset="utf-8" />
12+
<title>Polymarket Copy Bot</title>
13+
<style>
14+
body { font-family: Arial, sans-serif; margin: 24px; background: #0b1020; color: #e4e8f3; }
15+
.grid { display: grid; grid-template-columns: repeat(4, minmax(130px, 1fr)); gap: 12px; }
16+
.card { background: #151d36; border-radius: 10px; padding: 12px; }
17+
button { padding: 10px 16px; border-radius: 8px; border: none; cursor: pointer; }
18+
.ok { background: #1f9d55; color: white; }
19+
.warn { background: #d64545; color: white; }
20+
table { width: 100%; border-collapse: collapse; margin-top: 12px; }
21+
th, td { text-align: left; border-bottom: 1px solid #2a355d; padding: 8px; font-size: 13px; }
22+
</style>
23+
</head>
24+
<body>
25+
<h1>Polymarket Copy Bot Dashboard</h1>
26+
<p>Status: <strong id="status">stopped</strong></p>
27+
<button class="ok" onclick="startBot()">Start Live</button>
28+
<button class="warn" onclick="stopBot()">Stop</button>
29+
30+
<h2>Stats</h2>
31+
<div class="grid">
32+
<div class="card">PnL: <span id="pnl">0</span></div>
33+
<div class="card">Win rate: <span id="winRate">0</span>%</div>
34+
<div class="card">Executed: <span id="executed">0</span></div>
35+
<div class="card">Winners: <span id="winners">0</span></div>
36+
<div class="card">Losers: <span id="losers">0</span></div>
37+
<div class="card">Failed: <span id="failed">0</span></div>
38+
<div class="card">Skipped: <span id="skipped">0</span></div>
39+
</div>
40+
41+
<h2>Trade Log</h2>
42+
<table>
43+
<thead><tr><th>Time</th><th>Trader</th><th>Market</th><th>Outcome</th><th>Action</th><th>Amount</th><th>Status</th><th>PnL</th></tr></thead>
44+
<tbody id="trades"></tbody>
45+
</table>
46+
47+
<script>
48+
async function loadStats() {
49+
const r = await fetch('/api/stats');
50+
const data = await r.json();
51+
document.getElementById('status').innerText = data.running ? 'running' : 'stopped';
52+
document.getElementById('pnl').innerText = data.total_pnl_usd;
53+
document.getElementById('winRate').innerText = data.win_rate;
54+
document.getElementById('executed').innerText = data.trades_executed;
55+
document.getElementById('winners').innerText = data.winners;
56+
document.getElementById('losers').innerText = data.losers;
57+
document.getElementById('failed').innerText = data.failed;
58+
document.getElementById('skipped').innerText = data.skipped;
59+
60+
const rows = data.recent_trades.map(t => `
61+
<tr>
62+
<td>${t.timestamp}</td>
63+
<td>${t.source_trader}</td>
64+
<td>${t.market_slug}</td>
65+
<td>${t.outcome}</td>
66+
<td>${t.action}</td>
67+
<td>${t.copied_amount_usd}</td>
68+
<td>${t.status}</td>
69+
<td>${t.pnl_usd}</td>
70+
</tr>
71+
`).join('');
72+
document.getElementById('trades').innerHTML = rows;
73+
}
74+
75+
async function startBot() {
76+
await fetch('/api/start', { method: 'POST' });
77+
await loadStats();
78+
}
79+
80+
async function stopBot() {
81+
await fetch('/api/stop', { method: 'POST' });
82+
await loadStats();
83+
}
84+
85+
setInterval(loadStats, 5000);
86+
loadStats();
87+
</script>
88+
</body>
89+
</html>
90+
"""
91+
92+
93+
def create_app() -> Flask:
94+
bot = CopyBot()
95+
app = Flask(__name__)
96+
97+
@app.get("/")
98+
def home() -> str:
99+
return render_template_string(HTML)
100+
101+
@app.get("/api/stats")
102+
def stats():
103+
return jsonify(bot.stats())
104+
105+
@app.post("/api/start")
106+
def start():
107+
started = bot.start()
108+
return jsonify({"started": started, "running": True})
109+
110+
@app.post("/api/stop")
111+
def stop():
112+
stopped = bot.stop()
113+
return jsonify({"stopped": stopped, "running": False})
114+
115+
return app
116+
117+
118+
if __name__ == "__main__":
119+
create_app().run(host="127.0.0.1", port=5055, debug=False)

0 commit comments

Comments
 (0)