Files
XauBot/web-dashboard/api/main.py
T
GifariKemal 214b64945d feat: apply #28B smart breakeven + #31B H1 EMA20 filter, add backtests #26-#32
Live trading optimizations (cumulative: $2,807 net, 81.8% WR, Sharpe 3.97):
- #28B: Smart breakeven locks profit at entry + 0.5x ATR instead of fixed $2
- #31B: H1 Price vs EMA20 filter — BUY only when H1 bullish, SELL only when bearish

Backtests #26-#32 (7 scripts testing sell improvement, regime-aware entry,
confluence scoring, dynamic RR, multi-TF H1, and ML exit optimizer).
Winners: #28B (+$229), #31B (+$343). Failed: #26, #27, #29, #30, #32.

Also includes: web dashboard redesign, Docker setup, startup scripts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 10:33:24 +07:00

96 lines
2.6 KiB
Python

"""
FastAPI Backend for Web Dashboard (Docker-compatible)
=====================================================
Serves trading bot status data to the web frontend.
Reads from data/bot_status.json which is written by main_live.py.
This allows the API to run in Docker without needing MT5 (Windows-only).
"""
import json
from pathlib import Path
from datetime import datetime
from zoneinfo import ZoneInfo
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI(title="Trading Bot API", version="2.0.0")
# CORS for frontend
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Status file path (mounted as volume in Docker)
STATUS_FILE = Path("/app/data/bot_status.json")
# Default empty response
DEFAULT_STATUS = {
"timestamp": "00:00:00",
"connected": False,
"price": 0.0,
"spread": 0.0,
"priceChange": 0.0,
"priceHistory": [],
"balance": 0.0,
"equity": 0.0,
"profit": 0.0,
"equityHistory": [],
"balanceHistory": [],
"session": "Unknown",
"isGoldenTime": False,
"canTrade": False,
"dailyLoss": 0.0,
"dailyProfit": 0.0,
"consecutiveLosses": 0,
"riskPercent": 0.0,
"smc": {"signal": "", "confidence": 0.0, "reason": ""},
"ml": {"signal": "", "confidence": 0.0, "buyProb": 0.0, "sellProb": 0.0},
"regime": {"name": "", "volatility": 0.0, "confidence": 0.0},
"positions": [],
"logs": [],
}
@app.get("/api/status")
async def get_status():
"""Get current trading status from bot's status file."""
# Try local path first (non-Docker), then Docker path
for path in [STATUS_FILE, Path("data/bot_status.json")]:
if path.exists():
try:
data = json.loads(path.read_text())
return data
except (json.JSONDecodeError, OSError):
continue
# No status file — bot not running
now = datetime.now(ZoneInfo("Asia/Jakarta"))
result = DEFAULT_STATUS.copy()
result["timestamp"] = now.strftime("%H:%M:%S")
result["logs"] = [
{
"time": now.strftime("%H:%M:%S"),
"level": "warning",
"message": "Bot is not running — waiting for bot_status.json",
}
]
return result
@app.get("/api/health")
async def health():
"""Health check endpoint."""
bot_running = STATUS_FILE.exists() or Path("data/bot_status.json").exists()
return {"status": "ok", "bot_running": bot_running}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)