Skip to content

0a1b/momentum_NautilusTrader

Repository files navigation

Stock Enhanced: Advanced Momentum Strategy Suite

This repository contains a comprehensive momentum trading strategy implementation with multiple analysis tools, backtesting engines, and walk-forward optimization capabilities.

πŸš€ Overview

The suite provides:

  • Multi-Index Analysis: Evaluate 8+ global stock indices
  • Advanced Momentum Strategy: ROC + trend slope-based stock selection
  • Professional Backtesting: NautilusTrader-powered engine with realistic execution
  • Walk-Forward Optimization: Robust parameter testing across multiple time windows
  • Comprehensive Analytics: Risk metrics, trade analysis, and performance visualization

πŸ“Š Supported Indices

Global Coverage (constituents fetched from Wikipedia):

  • US: SP500, SP500_IT (S&P 500 IT sector), NASDAQ100
  • Europe: DAX40 (Germany), FTSE100 (UK), CAC40 (France)
  • Asia: NIFTY50 (India), KOSPI200 (South Korea)

Data Sources:

  • Constituents: Wikipedia (with robust scrapers and fallback logic)
  • Prices: Yahoo Finance with proper ticker formatting (.DE, .L, .PA, .NS, .KS suffixes)
  • US tickers automatically converted (BRK.B β†’ BRK-B)

🎯 Core Strategy: Momentum Selection

Algorithm:

  1. ROC (Rate of Change): ((current_price - past_price) / past_price) * 100
    • Capped and normalized: max(0, min(1, ceil(roc)))
  2. Trend Slope: Linear regression on log prices over lookback period
    • Annualized: (1 + slope) ** 252
  3. Momentum Score: ROC Γ— Trend_Slope
  4. Selection: Top N stocks by momentum score
  5. Execution: Equal-weight positions, periodic rebalancing

Key Parameters:

  • LOOKBACK: Days for trend calculation (typical: 150-250)
  • ROC: Days for rate-of-change calculation (typical: 150-250)
  • REB_DAYS: Rebalancing frequency in days (typical: 7-21)
  • POS_SIZE: Capital utilization (typical: 0.95 = 95%)
  • NUM_STOCKS: Number of stocks to hold (1 for top-1 strategy)

πŸ“ File Structure & Usage

Core Notebooks

1. momentum_top1_nasdaq100_nautilus_v3.ipynb

Purpose: Single-run backtest with basic NautilusTrader integration

Features:

  • Simple top-1 momentum strategy on NASDAQ-100
  • Fixed parameters (lookback=250, roc=250, rebalance=14 days)
  • Basic trade logging and PnL reporting
  • Good for understanding core strategy mechanics

Usage:

# Key parameters in v3
LOOKBACK_PERIOD = 250
ROC_PERIOD = 250  
REBALANCE_DAYS = 14
POSITION_SIZE = 0.95

Outputs:

  • Engine performance stats (Sharpe, drawdown, total return)
  • Trade log with entry/exit details
  • Last 5-day momentum scores (raw + annualized)

2. momentum_top1_nasdaq100_nautilus_v5.ipynb

Purpose: Enhanced backtest with improved analytics and robustness

Key Improvements over v3:

  • Robust Data Handling: Better missing data management, forward-fill only
  • Enhanced Trade Analytics: Detailed position tracking, realized vs unrealized PnL
  • Risk Metrics: Maximum drawdown, volatility, win/loss ratios
  • Visualization: Equity curves, momentum score evolution, position timelines
  • Error Handling: Graceful handling of failed downloads, missing constituents

Additional Features:

  • Portfolio value tracking at each rebalance
  • Monthly performance breakdown
  • Correlation analysis between momentum scores and future returns
  • Sensitivity analysis for key parameters

Usage:

# Enhanced configuration in v5
config = {
    'lookback_period': 250,
    'roc_period': 250, 
    'rebalance_frequency': 14,
    'position_size': 0.95,
    'transaction_cost': 7.0,
    'min_position_hold_days': 1  # New in v5
}

3. momentum_walkforward_runner.ipynb

Purpose: Systematic parameter optimization with walk-forward analysis

Core Functionality:

  • Multi-Parameter Testing: Grid search across parameter combinations
  • Walk-Forward Windows: Rolling 120-day test periods with 120-day steps
  • Multi-Index Support: Test same strategy across different global indices
  • Parallel Processing: Subprocess-based execution to avoid Jupyter hanging
  • Comprehensive Output: Performance tables, rankings, statistical analysis

Configuration Example:

# Global time window
GLOBAL_START = '2022-01-01'
GLOBAL_END = '2025-07-31'

# Walk-forward setup  
TEST_WINDOW_DAYS = 120    # Each test period length
STEP_DAYS = 120           # Step between test starts

# Parameter grid for optimization
PARAM_GRID = [
    {'LOOKBACK': 150, 'ROC': 150, 'REB_DAYS': 14, 'POS_SIZE': 0.95},
    {'LOOKBACK': 200, 'ROC': 200, 'REB_DAYS': 14, 'POS_SIZE': 0.95},
    {'LOOKBACK': 250, 'ROC': 250, 'REB_DAYS': 14, 'POS_SIZE': 0.95},
    {'LOOKBACK': 200, 'ROC': 150, 'REB_DAYS': 7, 'POS_SIZE': 0.95},
    {'LOOKBACK': 200, 'ROC': 250, 'REB_DAYS': 21, 'POS_SIZE': 0.95},
]

# Indices to evaluate
CANDIDATE_INDICES = ['SP500','SP500_IT','NASDAQ100','DAX40','FTSE100','CAC40','NIFTY50','KOSPI200']

# Execution settings
INITIAL_CAPITAL = 10_000_000  # $10M for meaningful absolute PnL
TX_COST = 7.0                 # $7 per trade

Key Features:

  • Robust Parallel Execution: Subprocess isolation prevents Jupyter kernel hangs even with multiple workers
  • Scalable Performance: Support for 1-16+ parallel workers with automatic load balancing
  • Progress Tracking: Verbose mode shows real-time progress without log spam
  • Error Recovery: Failed windows are skipped, execution continues seamlessly
  • Timeout Protection: 5-minute timeout per window prevents infinite hangs
  • Complete Output Isolation: NautilusTrader engine logs are fully suppressed in parallel mode

Core Python Modules

momentum_walkforward_core.py

Purpose: Walk-forward backtesting engine and utilities

Key Functions:

  1. run_walkforward(): Main orchestration function

    def run_walkforward(
        global_start: str,           # '2022-01-01'
        global_end: str,             # '2025-07-31'  
        param_grid: List[Dict],      # Parameter combinations to test
        candidate_indices: List[str], # ['SP500', 'NASDAQ100', ...]
        test_window_days: int,       # 120
        step_days: int,              # 120
        initial_capital: float,      # 10_000_000
        tx_cost: float,              # 7.0
        run_in_parallel: bool,       # False (recommended for stability)
        verbose: bool,               # True for progress tracking
        produce_plots: bool          # False (enable for visualizations)
    ) -> Dict[str, pd.DataFrame]
  2. get_adjusted_close(): Robust price data downloading

    • Handles missing tickers gracefully
    • Forward-fill only (no back-fill to avoid look-ahead bias)
    • Coverage-based filtering (keeps symbols with >50% data)
    • Automatic business day alignment
  3. run_engine_for_close(): Single backtest execution

    • NautilusTrader engine setup and configuration
    • Proper warm-up period handling (prevents look-ahead)
    • Market data bar construction from price series
    • Complete stdout/stderr isolation for Jupyter stability
  4. extract_net_pnl(): PnL extraction with fallbacks

    • Primary: NautilusTrader engine stats
    • Fallback: Manual calculation from trade logs
    • Handles various engine result formats

Output Structure:

# Returns: Dict[index_name, DataFrame]
{
    'SP500': DataFrame([
        {'LOOKBACK': 150, 'ROC': 150, 'REB_DAYS': 14, 'POS_SIZE': 0.95, 
         'net_pnl': 1100782.0, 'ret_pct': 11.007817}
    ]),
    'NASDAQ100': DataFrame([...]),
    # ... more indices
}

nautilus_engine_momentum.py

Purpose: NautilusTrader strategy implementation

Key Classes:

  1. MomentumConfig: Strategy configuration

    @dataclass
    class MomentumConfig:
        instrument_ids: List[InstrumentId]      # Symbols to trade
        lookback_period: int                    # Trend calculation window
        roc_period: int                         # ROC calculation window  
        num_stocks: int                         # Number of positions (1 for top-1)
        rebalance_days: int                     # Rebalancing frequency
        position_size: float                    # Capital utilization (0.95)
        transaction_cost: float                 # Fixed cost per trade ($7)
        liquidate_on_last_bar: bool            # True (realize all PnL)
        min_rebalance_timestamp_ns: int        # Earliest rebalance time
  2. MomentumStrategy: Core trading logic

    • Data Management: Maintains price history per instrument
    • Momentum Calculation: ROC Γ— trend slope methodology
    • Rebalancing Logic: Monday-based with frequency throttling
    • Order Management: Market orders with proper position sizing
    • Trade Logging: Detailed execution records for analysis

Execution Flow:

  1. on_start(): Subscribe to daily bars for all instruments
  2. on_bar(): Update price history, check rebalance conditions
  3. Rebalance Trigger: Monday + sufficient history + min interval elapsed
  4. Score Calculation: Momentum scores for all instruments with enough data
  5. Position Changes: Market orders to reach target allocation
  6. on_stop(): Liquidate all positions for final PnL calculation

index_fetchers.py

Purpose: Wikipedia-based constituent fetching with robust parsing

Supported Fetchers:

  • get_sp500(): S&P 500 companies
  • get_sp500_it(): S&P 500 IT sector subset
  • get_nasdaq100(): NASDAQ-100 components
  • get_dax40(): German DAX 40 (.DE suffix)
  • get_ftse100(): UK FTSE 100 (.L suffix)
  • get_cac40(): French CAC 40 (.PA suffix)
  • get_nifty50(): Indian NIFTY 50 (.NS suffix)
  • get_kospi200(): Korean KOSPI 200 (.KS suffix)

Robust Parsing Features:

  • Multiple column name variants (Symbol, Ticker, EPIC, etc.)
  • Unicode character cleaning (invisible characters, etc.)
  • Automatic ticker formatting for Yahoo Finance compatibility
  • Fallback logic when table structures change

πŸ“ˆ Output Analysis

Walk-Forward Results Table

LOOKBACK  ROC  REB_DAYS  POS_SIZE     net_pnl    ret_pct
     250  250        14      0.95  1,435,183      14.35
     150  150        14      0.95  1,100,782      11.01  
     200  150         7      0.95  1,045,700      10.46
     200  200        14      0.95  1,045,552      10.46
     200  250        21      0.95     -6,937      -0.07

Column Definitions:

  • LOOKBACK: Days for trend slope calculation
  • ROC: Days for rate-of-change calculation
  • REB_DAYS: Rebalancing frequency in days
  • POS_SIZE: Fraction of capital deployed (0.95 = 95%)
  • net_pnl: Average net profit/loss across all test windows ($)
  • ret_pct: Average return percentage (net_pnl / initial_capital Γ— 100)

Performance Interpretation

Strong Performance Indicators:

  • ret_pct > 10%: Excellent momentum capture
  • ret_pct 5-10%: Good performance, consider risk metrics
  • ret_pct 0-5%: Marginal, evaluate against benchmark

Parameter Insights:

  • Longer lookbacks (250) often outperform shorter ones
  • Frequent rebalancing (7-14 days) typically beats monthly (21+ days)
  • High position sizing (0.95) maximizes returns but increases risk
  • Matching LOOKBACK and ROC periods often perform well

Risk Considerations

Strategy Limitations:

  • Momentum-dependent: Performs poorly in mean-reverting markets
  • Transaction costs: High turnover can erode profits with higher costs
  • Concentration risk: Top-1 strategy has significant single-stock exposure
  • Market regime sensitivity: Bull markets favor momentum, bear markets may not

Recommended Analysis:

  1. Drawdown analysis: Maximum loss periods and recovery times
  2. Sharpe ratio: Risk-adjusted returns comparison
  3. Win/loss ratios: Frequency and magnitude of profitable periods
  4. Correlation with market: Strategy performance vs benchmark indices

πŸ› οΈ Installation & Setup

# Clone repository
git clone <repository_url>
cd stock_enhanced

# Create Python environment  
python -m venv venv
source venv/bin/activate  # Linux/Mac
# venv\Scripts\activate   # Windows

# Install dependencies
pip install -r requirements.txt
pip install -r requirements_nautilus.txt

# Verify installation
python -c "import nautilus_trader; print('NautilusTrader ready')"

🚦 Quick Start Guide

1. Single Backtest (Beginner)

# Open basic momentum strategy
jupyter notebook momentum_top1_nasdaq100_nautilus_v3.ipynb

# Run all cells - takes ~2-3 minutes
# Output: Single backtest results for NASDAQ-100

2. Enhanced Analysis (Intermediate)

# Open enhanced version with analytics
jupyter notebook momentum_top1_nasdaq100_nautilus_v5.ipynb

# Modify parameters in config cell if desired
# Run all cells - takes ~3-5 minutes  
# Output: Detailed performance metrics and visualizations

3. Parameter Optimization (Advanced)

# Open walk-forward optimizer
jupyter notebook momentum_walkforward_runner.ipynb

# Adjust PARAM_GRID and CANDIDATE_INDICES as needed
# Set run_in_parallel=False for first run
# Execute - takes 10-60 minutes depending on scope
# Output: Comprehensive parameter rankings across indices

πŸ”§ Configuration Tips

For Faster Testing:

# Reduce scope for quick validation
GLOBAL_END = '2023-12-31'                    # Shorter time window
CANDIDATE_INDICES = ['NASDAQ100']             # Single index
TEST_WINDOW_DAYS = 60                        # Shorter test windows
PARAM_GRID = [{'LOOKBACK': 200, 'ROC': 200, 'REB_DAYS': 14, 'POS_SIZE': 0.95}]  # Single param set

For Production Analysis:

# Full scope for comprehensive results  
GLOBAL_END = '2025-07-31'                    # Full recent history
CANDIDATE_INDICES = ['SP500','NASDAQ100','DAX40','FTSE100','CAC40','NIFTY50']  # Multiple indices
run_in_parallel = True                       # Safe to enable with subprocess isolation
max_workers = 8                              # Scale up to 8-16 workers for best performance
verbose = True                               # Track progress without log spam

Troubleshooting:

  • Log spam/hangs: Use run_in_parallel=True with subprocess isolation (now default safe mode)
  • Performance: Start with max_workers=4, scale up to 8-16 based on CPU cores
  • Memory issues: Reduce CANDIDATE_INDICES or shorten time windows
  • Network errors: Add delays between yfinance calls, check internet connection
  • Empty results: Verify ticker symbols are valid and have sufficient price history
  • Timeout issues: Tasks auto-timeout at 5 minutes; increase if needed for very large datasets

This comprehensive momentum strategy suite provides enterprise-grade backtesting capabilities with robust error handling, making it suitable for both research and potential production deployment.

About

Classic Momentum Strategy with Nautilus Trader (AI Slob)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors