148 lines
4.6 KiB
Python
148 lines
4.6 KiB
Python
|
|
"""
|
||
|
|
FULL NAUTILUS BACKTEST EXECUTION
|
||
|
|
================================
|
||
|
|
|
||
|
|
Runs complete Nautilus-Dolphin backtest with itest_v7 tight_3_3 configuration.
|
||
|
|
Generates actual trades for trade-by-trade comparison.
|
||
|
|
|
||
|
|
Usage:
|
||
|
|
python run_nd_backtest_full.py [--timeout TIMEOUT_MINUTES]
|
||
|
|
"""
|
||
|
|
|
||
|
|
import argparse
|
||
|
|
import sys
|
||
|
|
import json
|
||
|
|
from pathlib import Path
|
||
|
|
from datetime import datetime
|
||
|
|
|
||
|
|
# Maximum timeout for critical backtest
|
||
|
|
DEFAULT_TIMEOUT_MINUTES = 60 # 1 hour default
|
||
|
|
|
||
|
|
|
||
|
|
def main():
|
||
|
|
"""Main entry point."""
|
||
|
|
parser = argparse.ArgumentParser(
|
||
|
|
description='Run full Nautilus-Dolphin backtest'
|
||
|
|
)
|
||
|
|
parser.add_argument(
|
||
|
|
'--timeout', '-t',
|
||
|
|
type=int,
|
||
|
|
default=DEFAULT_TIMEOUT_MINUTES,
|
||
|
|
help=f'Timeout in minutes (default: {DEFAULT_TIMEOUT_MINUTES})'
|
||
|
|
)
|
||
|
|
parser.add_argument(
|
||
|
|
'--output', '-o',
|
||
|
|
default='backtest_results',
|
||
|
|
help='Output directory (default: backtest_results)'
|
||
|
|
)
|
||
|
|
|
||
|
|
args = parser.parse_args()
|
||
|
|
|
||
|
|
print("=" * 80)
|
||
|
|
print("NAUTILUS-DOLPHIN FULL BACKTEST EXECUTION")
|
||
|
|
print("=" * 80)
|
||
|
|
print(f"Start Time: {datetime.now().isoformat()}")
|
||
|
|
print(f"Timeout: {args.timeout} minutes")
|
||
|
|
print(f"Output: {args.output}")
|
||
|
|
print()
|
||
|
|
|
||
|
|
# Import backtest engine
|
||
|
|
try:
|
||
|
|
from nautilus_dolphin.nautilus.backtest_engine import (
|
||
|
|
NDBacktestEngine,
|
||
|
|
run_nd_backtest
|
||
|
|
)
|
||
|
|
print("[OK] Backtest engine imported")
|
||
|
|
except ImportError as e:
|
||
|
|
print(f"[FAIL] Failed to import backtest engine: {e}")
|
||
|
|
sys.exit(1)
|
||
|
|
|
||
|
|
# Configuration matching itest_v7 tight_3_3
|
||
|
|
config = {
|
||
|
|
'venue': 'BINANCE_FUTURES',
|
||
|
|
'environment': 'BACKTEST',
|
||
|
|
'trader_id': 'DOLPHIN-BACKTEST-001',
|
||
|
|
'strategy': {
|
||
|
|
'venue': 'BINANCE_FUTURES',
|
||
|
|
'max_leverage': 2.5,
|
||
|
|
'min_leverage': 0.5,
|
||
|
|
'leverage_convexity': 3.0,
|
||
|
|
'capital_fraction': 0.15,
|
||
|
|
'max_hold_bars': 120,
|
||
|
|
'tp_bps': 99,
|
||
|
|
'irp_alignment_min': 0.45,
|
||
|
|
'momentum_magnitude_min': 0.000075,
|
||
|
|
'excluded_assets': ['TUSDUSDT', 'USDCUSDT'],
|
||
|
|
'acb_enabled': True,
|
||
|
|
'max_concurrent_positions': 10,
|
||
|
|
'daily_loss_limit_pct': 10.0,
|
||
|
|
},
|
||
|
|
'data_catalog': {
|
||
|
|
'eigenvalues_dir': '../eigenvalues',
|
||
|
|
'catalog_path': 'nautilus_dolphin/catalog',
|
||
|
|
'start_date': '2025-12-31',
|
||
|
|
'end_date': '2026-02-14',
|
||
|
|
'assets': [
|
||
|
|
'BTCUSDT', 'ETHUSDT', 'ADAUSDT', 'SOLUSDT', 'DOTUSDT',
|
||
|
|
'AVAXUSDT', 'MATICUSDT', 'LINKUSDT', 'UNIUSDT', 'ATOMUSDT'
|
||
|
|
],
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
print("Configuration:")
|
||
|
|
print(f" Strategy: tight_3_3 (from itest_v7)")
|
||
|
|
print(f" Max Leverage: {config['strategy']['max_leverage']}x")
|
||
|
|
print(f" Capital Fraction: {config['strategy']['capital_fraction']}")
|
||
|
|
print(f" Max Hold Bars: {config['strategy']['max_hold_bars']}")
|
||
|
|
print(f" Date Range: {config['data_catalog']['start_date']} to {config['data_catalog']['end_date']}")
|
||
|
|
print()
|
||
|
|
|
||
|
|
# Run backtest
|
||
|
|
try:
|
||
|
|
print("Initializing backtest engine...")
|
||
|
|
engine = NDBacktestEngine(config, args.output)
|
||
|
|
|
||
|
|
print("Running backtest (this may take several minutes)...")
|
||
|
|
print("Processing ~255,000 scans from eigenvalue data...")
|
||
|
|
print()
|
||
|
|
|
||
|
|
results = engine.run_backtest()
|
||
|
|
|
||
|
|
print()
|
||
|
|
print("=" * 80)
|
||
|
|
print("BACKTEST COMPLETE")
|
||
|
|
print("=" * 80)
|
||
|
|
print(f"End Time: {datetime.now().isoformat()}")
|
||
|
|
print()
|
||
|
|
print(f"Status: {results.get('status', 'unknown')}")
|
||
|
|
print(f"Trades Generated: {len(results.get('trades', []))}")
|
||
|
|
print()
|
||
|
|
|
||
|
|
# Save results
|
||
|
|
output_path = Path(args.output)
|
||
|
|
results_file = output_path / 'nd_backtest_full.json'
|
||
|
|
with open(results_file, 'w') as f:
|
||
|
|
json.dump(results, f, indent=2, default=str)
|
||
|
|
|
||
|
|
print(f"Results saved: {results_file}")
|
||
|
|
print()
|
||
|
|
print("Next Steps:")
|
||
|
|
print(" 1. Run trade comparison: pytest tests/test_trade_by_trade_validation.py -v")
|
||
|
|
print(" 2. View detailed results:", results_file)
|
||
|
|
|
||
|
|
return 0
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
print()
|
||
|
|
print("=" * 80)
|
||
|
|
print("BACKTEST FAILED")
|
||
|
|
print("=" * 80)
|
||
|
|
print(f"Error: {e}")
|
||
|
|
import traceback
|
||
|
|
traceback.print_exc()
|
||
|
|
return 1
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == '__main__':
|
||
|
|
sys.exit(main())
|