"""Binance REST API helpers for fetching historical candle data.""" from datetime import datetime, timezone from decimal import Decimal from shared.models import Candle def _normalize_symbol(symbol: str) -> str: """Convert 'BTC/USDT' to 'BTCUSDT'.""" return symbol.replace("/", "") async def fetch_historical_candles( exchange, symbol: str, timeframe: str, since: int, limit: int = 500, ) -> list[Candle]: """Fetch historical OHLCV candles from the exchange and return Candle models. Args: exchange: An async ccxt exchange instance. symbol: Market symbol, e.g. 'BTC/USDT'. timeframe: Candle timeframe, e.g. '1m'. since: Start timestamp in milliseconds. limit: Maximum number of candles to fetch. Returns: A list of Candle model instances. """ rows = await exchange.fetch_ohlcv(symbol, timeframe, since=since, limit=limit) normalized = _normalize_symbol(symbol) candles: list[Candle] = [] for row in rows: ts_ms, o, h, low, c, v = row open_time = datetime.fromtimestamp(ts_ms / 1000, tz=timezone.utc) candles.append( Candle( symbol=normalized, timeframe=timeframe, open_time=open_time, open=Decimal(str(o)), high=Decimal(str(h)), low=Decimal(str(low)), close=Decimal(str(c)), volume=Decimal(str(v)), ) ) return candles