MidasBot: bot trading crypto IA + stratégies Ichimoku validées
- Infra: Freqtrade (futures dry-run) + Redis + dashboard + Docker Compose - Couche IA: ai_analyzer (Claude via abonnement, MCP TradingView, backfill biais) - Stratégies: SampleStrategy, AiBiasStrategy, IchimokuLS (long/short, validée train/test + données vierges + walk-forward), MTFIchimoku, variantes hyperopt - Arbitrage CEX (dry-run), backtesting, walk-forward, volatility targeting - IchimokuLS en dry-run live (config_live.json) Claude-Session: https://claude.ai/code/session_01VHETcFacdnDhQzthLpdYFR
This commit is contained in:
113
dashboard/app.py
Normal file
113
dashboard/app.py
Normal file
@@ -0,0 +1,113 @@
|
||||
"""Dashboard MidasBot — panneau « Insights IA ».
|
||||
|
||||
Affiche les derniers biais de marché produits par Claude (lus depuis Redis) et
|
||||
un lien vers FreqUI (positions / P&L / trades). Volontairement minimal et autonome
|
||||
(pas de dépendance au package ai_analyzer).
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
from datetime import datetime, timezone
|
||||
|
||||
import redis
|
||||
from fastapi import FastAPI
|
||||
from fastapi.responses import HTMLResponse, JSONResponse
|
||||
|
||||
REDIS_URL = os.environ.get("REDIS_URL", "redis://localhost:6379/0")
|
||||
FREQUI_URL = os.environ.get("FREQUI_URL", "http://127.0.0.1:8080")
|
||||
|
||||
app = FastAPI(title="MidasBot Dashboard")
|
||||
|
||||
|
||||
def _redis() -> redis.Redis:
|
||||
return redis.Redis.from_url(REDIS_URL, decode_responses=True)
|
||||
|
||||
|
||||
def _read_biases() -> list[dict]:
|
||||
r = _redis()
|
||||
out: list[dict] = []
|
||||
try:
|
||||
for key in r.scan_iter("bias:*"):
|
||||
raw = r.get(key)
|
||||
if not raw:
|
||||
continue
|
||||
try:
|
||||
out.append(json.loads(raw))
|
||||
except json.JSONDecodeError:
|
||||
continue
|
||||
except redis.RedisError:
|
||||
return []
|
||||
out.sort(key=lambda b: b.get("pair", ""))
|
||||
return out
|
||||
|
||||
|
||||
@app.get("/api/biases")
|
||||
def api_biases() -> JSONResponse:
|
||||
return JSONResponse({"biases": _read_biases(), "generated_at": _now()})
|
||||
|
||||
|
||||
@app.get("/api/health")
|
||||
def health() -> dict:
|
||||
try:
|
||||
_redis().ping()
|
||||
redis_ok = True
|
||||
except redis.RedisError:
|
||||
redis_ok = False
|
||||
return {"status": "ok", "redis": redis_ok}
|
||||
|
||||
|
||||
def _now() -> str:
|
||||
return datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S UTC")
|
||||
|
||||
|
||||
_COLORS = {"bullish": "#16a34a", "bearish": "#dc2626", "neutral": "#6b7280"}
|
||||
|
||||
|
||||
@app.get("/", response_class=HTMLResponse)
|
||||
def index() -> str:
|
||||
biases = _read_biases()
|
||||
if biases:
|
||||
rows = "\n".join(
|
||||
f"""<tr>
|
||||
<td class="pair">{b.get('pair','?')}</td>
|
||||
<td><span class="badge" style="background:{_COLORS.get(b.get('direction'),'#6b7280')}">{b.get('direction','?')}</span></td>
|
||||
<td>{float(b.get('confidence',0)):.0%}</td>
|
||||
<td class="rat">{b.get('rationale','')}</td>
|
||||
<td>{b.get('key_support','—')}</td>
|
||||
<td>{b.get('key_resistance','—')}</td>
|
||||
</tr>"""
|
||||
for b in biases
|
||||
)
|
||||
else:
|
||||
rows = '<tr><td colspan="6" class="empty">Aucun biais en cache. Lance l\'analyzer (ai-analyzer).</td></tr>'
|
||||
|
||||
return f"""<!doctype html>
|
||||
<html lang="fr"><head>
|
||||
<meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta http-equiv="refresh" content="30">
|
||||
<title>MidasBot — Insights IA</title>
|
||||
<style>
|
||||
:root {{ color-scheme: dark; }}
|
||||
body {{ font-family: system-ui, sans-serif; background:#0b0e14; color:#e6e6e6; margin:0; padding:2rem; }}
|
||||
h1 {{ margin:0 0 .25rem; font-size:1.5rem; }}
|
||||
.sub {{ color:#8b95a7; margin-bottom:1.5rem; font-size:.9rem; }}
|
||||
a {{ color:#60a5fa; }}
|
||||
table {{ width:100%; border-collapse:collapse; background:#111722; border-radius:10px; overflow:hidden; }}
|
||||
th, td {{ padding:.7rem .9rem; text-align:left; border-bottom:1px solid #1f2937; vertical-align:top; }}
|
||||
th {{ background:#0f1521; color:#94a3b8; font-weight:600; font-size:.8rem; text-transform:uppercase; letter-spacing:.04em; }}
|
||||
.pair {{ font-weight:700; }}
|
||||
.rat {{ color:#cbd5e1; font-size:.9rem; max-width:520px; }}
|
||||
.badge {{ color:#fff; padding:.15rem .55rem; border-radius:999px; font-size:.8rem; text-transform:capitalize; }}
|
||||
.empty {{ color:#8b95a7; text-align:center; padding:2rem; }}
|
||||
.links {{ margin-top:1.5rem; }}
|
||||
</style></head>
|
||||
<body>
|
||||
<h1>🪙 MidasBot — Insights IA</h1>
|
||||
<div class="sub">Biais de marché produits par Claude · {_now()} · rafraîchissement auto 30 s · <strong>DRY-RUN</strong></div>
|
||||
<table>
|
||||
<thead><tr><th>Paire</th><th>Biais</th><th>Confiance</th><th>Justification</th><th>Support</th><th>Résistance</th></tr></thead>
|
||||
<tbody>{rows}</tbody>
|
||||
</table>
|
||||
<div class="links">📊 <a href="{FREQUI_URL}" target="_blank">Ouvrir FreqUI</a> (positions, P&L, trades) · <a href="/api/biases">API JSON</a></div>
|
||||
</body></html>"""
|
||||
Reference in New Issue
Block a user