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