""" Quick backtest runner for strategy validation. Runs any strategy against historical bar data to check basic logic before deploying live. Uses NautilusTrader's BacktestEngine. Usage: python backtests/run_backtest.py --strategy ofi --bars data/BTC-1h.parquet """ import argparse import asyncio from pathlib import Path from nautilus_trader.config import BacktestEngineConfig from nautilus_trader.config import BacktestDataConfig from nautilus_trader.config import BacktestVenueConfig from nautilus_trader.model.data import BarType from nautilus_trader.model.identifiers import InstrumentId, Venue from nautilus_trader.backtest.node import BacktestNode STRATEGIES = { "ofi": "strategies.orderbook_imbalance:OrderBookImbalanceConfig", "iceberg": "strategies.iceberg_detection:IcebergDetectorConfig", "funding_arb": "strategies.funding_rate_arb:FundingRateArbConfig", "pairs": "strategies.pairs_trading:PairsTradingConfig", "avellaneda": "strategies.avellaneda_stoikov:AvellanedaStoikovConfig", } async def run_backtest(strategy_name: str, data_path: str) -> None: """Run a single strategy backtest.""" if strategy_name not in STRATEGIES: print(f"Unknown strategy: {strategy_name}") print(f"Options: {list(STRATEGIES.keys())}") return config_path = STRATEGIES[strategy_name] # Basic backtest config — swap these for real data engine_config = BacktestEngineConfig() venue_config = BacktestVenueConfig( name="HYPERLIQUID", oms_type="NETTING", account_type="MARGIN", starting_balances=["100000 USDC"], ) data_config = BacktestDataConfig( catalog_path=str(Path(data_path).parent), data_cls="nautilus_trader.model.data.Bar", catalog_fs_protocol="file", bar_type=BarType.from_str("BTC-USD-PERP-1-HOUR-LAST-INTERNAL"), instrument_id=InstrumentId.from_str("BTC-USD-PERP.HYPERLIQUID"), start_time=None, end_time=None, ) node = BacktestNode( config=engine_config, venue_configs=[venue_config], data_configs=[data_config], ) node.add_strategy(config_path=config_path) await node.run() node.dispose() def main(): parser = argparse.ArgumentParser(description="FTDT Quant Lab - Backtest Runner") parser.add_argument( "--strategy", "-s", choices=list(STRATEGIES.keys()), required=True, help="Strategy to backtest", ) parser.add_argument( "--data", "-d", default="data/BTC-1h.parquet", help="Path to bar data (parquet format)", ) args = parser.parse_args() asyncio.run(run_backtest(args.strategy, args.data)) if __name__ == "__main__": main()