Full-stack trading bot with: - FastAPI backend with ICT strategy (Order Block + Liquidity Sweep detection) - Backtester engine with rolling window, spread simulation, and performance metrics - Hybrid market data service (yfinance + TwelveData with rate limiting + SQLite cache) - Simulated exchange for paper trading - React/TypeScript frontend with TradingView lightweight-charts v5 - Live dashboard with candlestick chart, OHLC legend, trade markers - Backtest page with configurable parameters, equity curve, and trade table - WebSocket support for real-time updates - Bot runner with asyncio loop for automated trading Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
47 lines
1.2 KiB
Python
47 lines
1.2 KiB
Python
from fastapi import APIRouter, HTTPException
|
|
from pydantic import BaseModel
|
|
|
|
from app.core.config import settings
|
|
|
|
router = APIRouter(prefix="/bot", tags=["bot"])
|
|
|
|
# Instance globale du bot (initialisée dans main.py)
|
|
_bot_runner = None
|
|
|
|
|
|
def set_bot_runner(runner) -> None:
|
|
global _bot_runner
|
|
_bot_runner = runner
|
|
|
|
|
|
class BotStartRequest(BaseModel):
|
|
instrument: str = ""
|
|
granularity: str = ""
|
|
|
|
|
|
@router.get("/status")
|
|
async def bot_status():
|
|
if _bot_runner is None:
|
|
return {"running": False, "message": "Bot non initialisé"}
|
|
return _bot_runner.get_status()
|
|
|
|
|
|
@router.post("/start")
|
|
async def start_bot(req: BotStartRequest):
|
|
if _bot_runner is None:
|
|
raise HTTPException(503, "Bot non initialisé")
|
|
if req.instrument:
|
|
_bot_runner.instrument = req.instrument
|
|
if req.granularity:
|
|
_bot_runner.granularity = req.granularity
|
|
await _bot_runner.start()
|
|
return {"message": "Bot démarré", "status": _bot_runner.get_status()}
|
|
|
|
|
|
@router.post("/stop")
|
|
async def stop_bot():
|
|
if _bot_runner is None:
|
|
raise HTTPException(503, "Bot non initialisé")
|
|
await _bot_runner.stop()
|
|
return {"message": "Bot arrêté"}
|