feat: trading bot MVP — ICT Order Block + Liquidity Sweep strategy
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>
This commit is contained in:
46
backend/app/api/routes/bot.py
Normal file
46
backend/app/api/routes/bot.py
Normal file
@@ -0,0 +1,46 @@
|
||||
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é"}
|
||||
Reference in New Issue
Block a user