Files
ramseshk c1da0cbe65 Wire up real Hyperliquid integration and funding rate API
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
2026-08-03 11:37:47 +00:00

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()