Skip to content

on_strategy_start

Called once when the backtest begins. Use this function to initialize variables, set up state, and perform any one-time setup logic.

Signature

python
def on_strategy_start(portfolio, state):
    # Initialization logic here
    pass

Parameters

  • portfolio (PortfolioContext) - Portfolio with initial capital and empty positions
  • state (dict) - Strategy state dictionary for storing custom data

Usage

This function is optional but recommended for strategies that need initialization.

Common Use Cases

  • Initialize state variables
  • Set up tracking dictionaries
  • Log strategy start information
  • Calculate initial parameters

Strategy Global Variables

New in v2.0: You can now define strategy-specific global variables that are automatically accessible in on_strategy_start and all other lifecycle functions:

python
# Define globals at the top of your strategy
g_sma_fast = 20
g_sma_slow = 50 
g_position_size = 100
DEFAULT_SYMBOLS = ["AAPL", "GOOGL"]

def on_strategy_start(portfolio, state):
    """Global variables are automatically available"""
    
    print(f"Strategy configured for SMA {g_sma_fast}/{g_sma_slow}")
    print(f"Position size: {g_position_size}")
    print(f"Trading symbols: {DEFAULT_SYMBOLS}")
    
    # Optional: store globals in state for API parameter overrides
    state['fast_period'] = state.get('fast_period', g_sma_fast)
    state['slow_period'] = state.get('slow_period', g_sma_slow)

Examples

Basic Initialization

python
def on_strategy_start(portfolio, state):
    """Initialize strategy state"""
    state['position_tracker'] = {}
    state['daily_targets'] = {}
    state['trades_today'] = 0
    
    print(f"Starting backtest with ${portfolio.initial_capital:,.2f}")

Using Global Variables

python
# Strategy configuration at the top
g_max_risk_per_trade = 0.02
g_stop_loss_percent = 0.05
g_symbols = ["AAPL", "GOOGL", "MSFT"]

def on_strategy_start(portfolio, state):
    """Initialize with global configuration"""
    
    # Access global variables directly
    max_risk = portfolio.initial_capital * g_max_risk_per_trade
    
    print(f"=== Strategy Configuration ===")
    print(f"Max risk per trade: ${max_risk:,.2f} ({g_max_risk_per_trade:.1%})")
    print(f"Stop loss: {g_stop_loss_percent:.1%}")
    print(f"Trading symbols: {g_symbols}")
    
    # Initialize tracking
    state['position_tracker'] = {}
    state['max_risk_per_trade'] = max_risk
    
    for symbol in g_symbols:
        state['position_tracker'][symbol] = {
            'entry_price': None,
            'stop_loss': None,
            'position_size': 0
        }

Advanced Setup with Hybrid Configuration

python
# Strategy defaults
g_default_symbols = ["AAPL"]
g_sma_periods = {"fast": 20, "slow": 50}
g_risk_management = {
    "max_position_pct": 0.10,
    "stop_loss_pct": 0.05,
    "daily_loss_limit_pct": 0.02
}

def on_strategy_start(portfolio, state):
    """Advanced initialization with global + API parameter support"""
    
    # Allow API parameters to override globals
    symbols = state.get('symbols', g_default_symbols)
    fast_period = state.get('fast_period', g_sma_periods['fast'])
    slow_period = state.get('slow_period', g_sma_periods['slow'])
    
    # Calculate risk management parameters
    max_position_size = portfolio.initial_capital * g_risk_management['max_position_pct']
    daily_loss_limit = portfolio.initial_capital * g_risk_management['daily_loss_limit_pct']
    
    print(f"=== Strategy Started ===")
    print(f"Symbols: {symbols}")
    print(f"SMA Periods: {fast_period}/{slow_period}")
    print(f"Max position size: ${max_position_size:,.2f}")
    print(f"Daily loss limit: ${daily_loss_limit:,.2f}")
    
    # Store final configuration in state
    state.update({
        'symbols': symbols,
        'fast_period': fast_period, 
        'slow_period': slow_period,
        'max_position_size': max_position_size,
        'daily_loss_limit': daily_loss_limit,
        'daily_pnl': 0,
        'trades_today': 0,
        'signals': {}
    })

Notes

  • This function runs exactly once at the beginning of the backtest
  • The portfolio parameter starts with initial_capital in cash and no positions
  • Use the state dictionary to store any variables you need throughout the strategy
  • This is the best place to set up logging or debugging information

Test your trading strategies risk-free with professional backtesting.