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:
88
backend/app/core/exchange/base.py
Normal file
88
backend/app/core/exchange/base.py
Normal file
@@ -0,0 +1,88 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
import pandas as pd
|
||||
|
||||
|
||||
@dataclass
|
||||
class OrderResult:
|
||||
trade_id: str
|
||||
instrument: str
|
||||
direction: str # "buy" | "sell"
|
||||
units: float
|
||||
entry_price: float
|
||||
stop_loss: float
|
||||
take_profit: float
|
||||
opened_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class OpenTrade:
|
||||
trade_id: str
|
||||
instrument: str
|
||||
direction: str
|
||||
units: float
|
||||
entry_price: float
|
||||
stop_loss: float
|
||||
take_profit: float
|
||||
unrealized_pnl: float
|
||||
opened_at: datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class AccountInfo:
|
||||
balance: float
|
||||
nav: float # Net Asset Value
|
||||
unrealized_pnl: float
|
||||
currency: str
|
||||
|
||||
|
||||
class AbstractExchange(ABC):
|
||||
"""Interface commune pour tous les exchanges/brokers."""
|
||||
|
||||
@abstractmethod
|
||||
async def get_candles(
|
||||
self,
|
||||
instrument: str,
|
||||
granularity: str,
|
||||
count: int = 200,
|
||||
from_time: Optional[datetime] = None,
|
||||
to_time: Optional[datetime] = None,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
Retourne un DataFrame avec colonnes : time, open, high, low, close, volume.
|
||||
"""
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
async def place_order(
|
||||
self,
|
||||
instrument: str,
|
||||
units: float, # positif = buy, négatif = sell
|
||||
stop_loss: float,
|
||||
take_profit: float,
|
||||
) -> OrderResult:
|
||||
"""Place un ordre au marché avec SL et TP."""
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
async def close_trade(self, trade_id: str) -> float:
|
||||
"""Ferme un trade par son ID. Retourne le PnL réalisé."""
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
async def get_open_trades(self) -> list[OpenTrade]:
|
||||
"""Retourne la liste des positions ouvertes."""
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
async def get_account_info(self) -> AccountInfo:
|
||||
"""Retourne les infos du compte (solde, PnL, etc.)."""
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
async def get_price(self, instrument: str) -> float:
|
||||
"""Retourne le prix mid actuel."""
|
||||
...
|
||||
Reference in New Issue
Block a user