Files
XauBot/web-dashboard/api/main.py
T

96 lines
2.6 KiB
Python
Raw Normal View History

"""
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)