Upgrade mission-control UI with charts and live metrics API without impacting trading loop
This commit is contained in:
64
app.py
64
app.py
@@ -33,6 +33,70 @@ def curate_now():
|
||||
def api_account():
|
||||
return JSONResponse(account_snapshot())
|
||||
|
||||
@app.get("/api/metrics")
|
||||
def api_metrics(hours: int = 72):
|
||||
db = SessionLocal()
|
||||
try:
|
||||
since = datetime.utcnow() - timedelta(hours=hours)
|
||||
decs = db.query(BotDecision).filter(BotDecision.ts >= since).order_by(BotDecision.ts.asc()).all()
|
||||
trades = db.query(TradeExecution).filter(TradeExecution.ts >= since).order_by(TradeExecution.ts.asc()).all()
|
||||
|
||||
# hour buckets
|
||||
buckets = {}
|
||||
for d in decs:
|
||||
k = d.ts.strftime("%m-%d %H:00")
|
||||
buckets.setdefault(k, {"buy": 0, "sell": 0, "hold": 0, "executed": 0, "failed": 0})
|
||||
if d.action in ("buy", "sell", "hold"):
|
||||
buckets[k][d.action] += 1
|
||||
if d.status == "executed":
|
||||
buckets[k]["executed"] += 1
|
||||
if d.status == "failed":
|
||||
buckets[k]["failed"] += 1
|
||||
|
||||
labels = list(buckets.keys())
|
||||
buy = [buckets[k]["buy"] for k in labels]
|
||||
sell = [buckets[k]["sell"] for k in labels]
|
||||
hold = [buckets[k]["hold"] for k in labels]
|
||||
executed = [buckets[k]["executed"] for k in labels]
|
||||
failed = [buckets[k]["failed"] for k in labels]
|
||||
|
||||
# cumulative notional (proxy activity curve)
|
||||
t_labels, t_values = [], []
|
||||
c = 0.0
|
||||
for t in trades:
|
||||
c += float(t.notional or 0)
|
||||
t_labels.append(t.ts.strftime("%m-%d %H:%M"))
|
||||
t_values.append(round(c, 2))
|
||||
|
||||
# symbol leaderboard
|
||||
lb = {}
|
||||
for d in decs:
|
||||
row = lb.setdefault(d.symbol, {"symbol": d.symbol, "decisions": 0, "executed": 0})
|
||||
row["decisions"] += 1
|
||||
if d.status == "executed":
|
||||
row["executed"] += 1
|
||||
leaderboard = sorted(lb.values(), key=lambda x: x["executed"], reverse=True)
|
||||
|
||||
return {
|
||||
"ok": True,
|
||||
"hours": hours,
|
||||
"decisionSeries": {
|
||||
"labels": labels,
|
||||
"buy": buy,
|
||||
"sell": sell,
|
||||
"hold": hold,
|
||||
"executed": executed,
|
||||
"failed": failed,
|
||||
},
|
||||
"activitySeries": {
|
||||
"labels": t_labels,
|
||||
"cumulativeNotional": t_values,
|
||||
},
|
||||
"leaderboard": leaderboard,
|
||||
}
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
@app.get("/")
|
||||
def home(request: Request):
|
||||
db = SessionLocal()
|
||||
|
||||
Reference in New Issue
Block a user