Appearance
Buy and Hold Strategy
The simplest investment strategy - buy a stock and hold it for the entire period.
Strategy Overview
Concept: Buy once at the beginning and hold until the end
Complexity: Beginner
Time Frame: Long-term (months to years)
Best For: Learning backtesting basics, benchmark comparison
Code Example
python
def on_strategy_start(portfolio, state):
"""Initialize - called once at backtest start"""
print("=== Buy and Hold Strategy Started ===")
print(f"Initial Capital: ${portfolio.initial_capital:,.2f}")
# Track if we've made our initial purchase
state['purchased'] = False
def on_bar_close(data_contexts, portfolio, state):
"""Buy once at the very beginning and hold"""
# Only buy once at the start
if not state['purchased'] and portfolio.position('AAPL') == 0:
# Calculate how many shares we can buy with all our cash
current_price = data_contexts['AAPL'].close
max_shares = int(portfolio.cash / current_price)
print(f"Making initial purchase: {max_shares} shares at ${current_price:.2f}")
state['purchased'] = True
return {
'symbol': 'AAPL',
'action': 'buy',
'quantity': max_shares
}
# After initial purchase, just hold (do nothing)
return None
Expected Results
Typical Performance (varies by time period):
- Total Return: Matches market performance
- Sharpe Ratio: 0.8 - 1.2 (depends on period)
- Max Drawdown: Follows market drawdowns
- Win Rate: N/A (single trade)
Key Learnings
1. Benchmark Performance
Buy-and-hold provides a baseline to compare other strategies against.
2. Market Risk
Your performance directly tracks the underlying stock's movement.
3. Simplicity Works
Sometimes the simplest strategies are hard to beat.
Variations
Multi-Asset Buy and Hold
python
SYMBOLS = ['AAPL', 'GOOGL', 'MSFT']
def on_bar_close(data_contexts, portfolio, state):
if not state.get('purchased', False):
orders = []
cash_per_stock = portfolio.cash / len(SYMBOLS)
for symbol in SYMBOLS:
price = data_contexts[symbol].close
shares = int(cash_per_stock / price)
orders.append({
'symbol': symbol,
'action': 'buy',
'quantity': shares
})
state['purchased'] = True
return orders
return None
Dollar-Cost Averaging
python
def on_bar_close(data_contexts, portfolio, state):
"""Buy fixed dollar amount every month"""
# Initialize purchase tracking
if 'last_purchase_day' not in state:
state['last_purchase_day'] = 0
state['monthly_investment'] = 1000 # $1000 per month
# Get current day (assuming daily data)
current_day = state.get('current_day', 0)
state['current_day'] = current_day + 1
# Buy every 30 days (monthly)
if current_day - state['last_purchase_day'] >= 30:
price = data_contexts['AAPL'].close
shares = int(state['monthly_investment'] / price)
if portfolio.cash >= (shares * price):
state['last_purchase_day'] = current_day
return {
'symbol': 'AAPL',
'action': 'buy',
'quantity': shares
}
return None
When to Use
Good For:
- Learning backtesting basics
- Long-term investing simulation
- Benchmark comparison
- Testing market timing strategies
Not Good For:
- Active trading strategies
- Short-term performance
- Risk management learning
Next Steps
- SMA Crossover - Add technical analysis
- RSI Strategy - Learn momentum indicators
- Portfolio Strategies - Multi-asset allocation
This strategy teaches the fundamentals of backtesting without complex logic.