from __future__ import annotations from app.broker.base import Broker, Fill from app.broker.binance import TESTNET_URL, BinanceBroker from app.broker.coinbase import CoinbaseBroker from app.broker.paper import PaperBroker from app.config import Settings from app.market.binance import BASE_URL # Exchanges with a live execution adapter. Others fall back to paper and the # engine surfaces a clear error at start. _LIVE_BROKERS: dict[str, type[Broker]] = { "binance": BinanceBroker, "binanceus": BinanceBroker, "coinbase": CoinbaseBroker, } def build_broker(settings: Settings) -> Broker: if settings.mode != "live": return PaperBroker(fee_bps=settings.fee_bps, slippage_bps=settings.slippage_bps) exchange = settings.exchange.lower() if exchange not in _LIVE_BROKERS: raise ValueError( f"live trading is not supported on '{settings.exchange}' yet; " f"use MODE=paper or one of {sorted(_LIVE_BROKERS)}" ) if exchange in {"binance", "binanceus"}: return BinanceBroker( api_key=settings.exchange_api_key, api_secret=settings.exchange_api_secret, base_url=TESTNET_URL if settings.exchange_sandbox else BASE_URL, ) return CoinbaseBroker( api_key=settings.exchange_api_key, api_secret=settings.exchange_api_secret, ) __all__ = ["Broker", "Fill", "PaperBroker", "build_broker"]