c1da0cbe65
Replaced the placeholder live node with a proper NautilusTrader TradingNode that connects to Hyperliquid Testnet using the official adapter. Added: - common/hyperliquid_api.py: direct REST calls to Hyperliquid's info endpoint for funding rates, predicted fundings, and asset contexts - backtests/run_backtest.py: CLI runner for strategy backtests - Updated funding_rate_arb.py to fetch real funding rates instead of using a hardcoded placeholder - Added requests to requirements.txt
91 lines
2.7 KiB
Python
91 lines
2.7 KiB
Python
"""
|
|
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()
|