Skip to content

on_market_open

Called at 9:30 AM ET each trading day when the market opens. Use this for daily initialization, gap analysis, or pre-market setup.

Signature

python
def on_market_open(portfolio, state, market_data):
    # Daily market open logic
    pass

Parameters

  • portfolio (PortfolioContext) - Current portfolio state
  • state (dict) - Strategy state dictionary
  • market_data (dict) - Market session information containing:
    • date - Trading date
    • timestamp - Market open timestamp
    • is_market_open - Always True for this function
    • trading_day - Current trading day
    • session_time - Time of day (9:30 AM ET)

Usage

This function is optional but useful for strategies that need daily setup or gap analysis.

Common Use Cases

  • Reset daily counters and flags
  • Analyze overnight gaps
  • Set daily profit/loss targets
  • Log daily market open information
  • Perform daily portfolio rebalancing

Examples

Basic Daily Reset

python
def on_market_open(portfolio, state, market_data):
    """Reset daily tracking variables"""
    trading_date = market_data['date']
    
    # Reset daily counters
    state['trades_today'] = 0
    state['daily_pnl_start'] = portfolio.equity
    state['daily_high'] = portfolio.equity
    state['daily_low'] = portfolio.equity
    
    print(f"Market open - {trading_date}")
    print(f"Starting equity: ${portfolio.equity:,.2f}")

Gap Analysis

python
def on_market_open(portfolio, state, market_data):
    """Analyze overnight gaps and adjust strategy"""
    trading_date = market_data['date']
    
    # Store previous close prices if available
    if 'previous_closes' in state:
        for symbol in state['previous_closes']:
            if symbol in data_contexts:
                current_open = data_contexts[symbol].open
                previous_close = state['previous_closes'][symbol]
                gap_pct = (current_open - previous_close) / previous_close
                
                # Large gap detection
                if abs(gap_pct) > 0.02:  # 2% gap
                    print(f"{symbol} gapped {gap_pct*100:.1f}%")
                    state[f'{symbol}_gap'] = gap_pct
    
    # Set daily targets based on portfolio size
    state['daily_target'] = portfolio.equity * 0.01  # 1% daily target
    state['daily_stop'] = portfolio.equity * 0.02    # 2% daily stop

Daily Rebalancing

python
def on_market_open(portfolio, state, market_data):
    """Perform daily portfolio rebalancing"""
    trading_date = market_data['date']
    
    # Calculate current allocation
    total_equity = portfolio.equity
    positions = portfolio.positions()
    
    state['daily_rebalance_needed'] = False
    
    for symbol, shares in positions.items():
        current_value = portfolio.market_value(symbol)
        current_weight = current_value / total_equity
        target_weight = state.get(f'{symbol}_target_weight', 0.25)  # 25% default
        
        # Check if rebalancing needed (>5% deviation)
        if abs(current_weight - target_weight) > 0.05:
            state['daily_rebalance_needed'] = True
            state[f'{symbol}_rebalance_target'] = target_weight
            
    if state['daily_rebalance_needed']:
        print(f"Daily rebalancing needed on {trading_date}")

Performance Tracking

python
def on_market_open(portfolio, state, market_data):
    """Track daily and cumulative performance"""
    trading_date = market_data['date']
    
    # Calculate yesterday's performance
    if 'previous_close_equity' in state:
        yesterday_return = (portfolio.equity - state['previous_close_equity']) / state['previous_close_equity']
        state['yesterday_return'] = yesterday_return
        
        # Update performance history
        if 'daily_returns' not in state:
            state['daily_returns'] = []
        state['daily_returns'].append(yesterday_return)
        
        print(f"Yesterday's return: {yesterday_return*100:.2f}%")
    
    # Set today's starting equity
    state['today_start_equity'] = portfolio.equity
    
    # Calculate running metrics
    total_return = (portfolio.equity - portfolio.initial_capital) / portfolio.initial_capital
    print(f"Total return: {total_return*100:.2f}%")

Integration with on_bar_close

You can use flags set in on_market_open to control behavior in on_bar_close:

python
def on_market_open(portfolio, state, market_data):
    """Set daily trading flags"""
    # Enable trading only on certain days
    weekday = market_data['timestamp'].weekday()  # 0=Monday, 4=Friday
    state['trading_enabled'] = weekday in [1, 2, 3]  # Trade Tue-Thu only
    
    # Set daily volatility flag
    state['high_vol_day'] = check_volatility_forecast()

def on_bar_close(data_contexts, portfolio, state):
    """Use daily flags in trading logic"""
    # Skip trading if disabled
    if not state.get('trading_enabled', True):
        return None
    
    # Adjust position size based on volatility
    base_quantity = 100
    if state.get('high_vol_day', False):
        base_quantity = 50  # Reduce size on high volatility days
    
    # Your trading logic...

Notes

  • This function runs once per trading day at market open (9:30 AM ET)
  • Use this for daily setup tasks that don't need to run every minute
  • The market_data parameter provides context about the current trading session
  • Consider time zones - all timestamps are in Eastern Time (NYSE timezone)
  • This is not called on weekends or holidays (no market open)

Test your trading strategies risk-free with professional backtesting.