Skip to main content

Live Trading

Moving from backtest to live trading is a significant step. This guide covers the process and best practices.

The Transition

Backtest → Paper Trading → Live Trading
↓ ↓ ↓
Theoretical Simulated Real

Why Paper Trade First?

Before risking real capital:

  1. Verify behavior - Does the strategy trade as expected?
  2. Test infrastructure - Are systems reliable?
  3. Build confidence - Gain experience without risk
  4. Compare metrics - Validate backtest assumptions

Pre-Launch Checklist

Strategy Ready

  • Backtest Sharpe > 1.0 over 3+ years
  • Max drawdown < 20%
  • Passed walk-forward analysis
  • Paper traded for 2-4 weeks
  • Performance tracks backtest within 20%

Infrastructure Ready

  • API keys configured and tested
  • Error notifications set up
  • Kill switch accessible
  • Monitoring dashboard ready
  • Emergency contact list prepared

Risk Management Set

  • Maximum position size defined
  • Maximum drawdown limit set
  • Daily loss limit configured
  • Correlation limits in place

Paper Trading

Setup

from vecalpha import PaperTrading

paper = PaperTrading(
strategy=MyStrategy,
symbols=['AAPL', 'MSFT', 'GOOGL'],
initial_capital=100000,
commission=0.001
)

paper.start()

Monitoring

Track key metrics daily:

MetricCheck
Number of tradesExpected range?
Win rateSimilar to backtest?
SlippageWithin assumptions?
LatencyAcceptable delays?

Comparison Framework

# Compare paper vs backtest
comparison = paper.compare_to_backtest(backtest_results)

print(f"Return difference: {comparison.return_diff:.2%}")
print(f"Trade count ratio: {comparison.trade_ratio:.2f}")
print(f"Win rate difference: {comparison.win_rate_diff:.2%}")

if comparison.return_diff > 0.20:
print("WARNING: Significant divergence from backtest")

Going Live

Gradual Scaling

Don't deploy full capital immediately:

Week 1-2: 25% of target capital
Week 3-4: 50% of target capital
Week 5+: 100% of target capital

Risk Limits

risk_config = {
'max_position_pct': 0.10, # Max 10% in single position
'max_sector_pct': 0.30, # Max 30% in single sector
'max_daily_loss': 0.02, # Stop if down 2% in a day
'max_drawdown': 0.10, # Stop if drawdown hits 10%
'max_trades_per_day': 20, # Limit trading frequency
}

strategy.set_risk_config(risk_config)

Kill Switch

Emergency stop capability:

# Immediate halt
strategy.emergency_stop()

# Scheduled pause
strategy.pause(duration='24h')

# Reduce positions
strategy.reduce_positions(target_pct=0.50)

Live Monitoring

Daily Checks

CheckWhat to Look For
PositionsExpected sizes and directions
P&LWithin normal variance
OrdersFilled correctly, no rejects
ErrorsSystem errors, API issues

Performance Tracking

# Real-time metrics
dashboard = LiveDashboard(strategy)
dashboard.show_metrics()

# Periodic reports
report = strategy.generate_report(period='weekly')
report.email_to('[email protected]')

Alert Configuration

alerts = {
'drawdown_alert': {'threshold': 0.05, 'action': 'notify'},
'loss_alert': {'threshold': 0.02, 'action': 'notify'},
'error_alert': {'threshold': 1, 'action': 'notify + pause'},
'position_alert': {'threshold': 0.15, 'action': 'notify'},
}

strategy.configure_alerts(alerts)

Live vs Backtest Divergence

Common Causes

DivergenceLikely Cause
Fewer tradesStricter fill conditions
Lower returnsSlippage, missed opportunities
Higher varianceMarket regime change
Different signalsData feed differences

How to Handle

  1. Document differences - Track when and where divergence occurs
  2. Investigate root cause - Is it infrastructure, market, or strategy?
  3. Adjust expectations - Live performance is usually 10-30% lower
  4. Consider re-optimization - If divergence is systematic
# Track divergence over time
divergence_log = []

def track_divergence(live_result, backtest_result):
div = {
'date': datetime.now(),
'live_return': live_result.return,
'backtest_return': backtest_result.return,
'divergence': live_result.return - backtest_result.return
}
divergence_log.append(div)

# Alert if significant
if abs(div['divergence']) > 0.10:
send_alert(f"Large divergence detected: {div['divergence']:.2%}")

Operational Best Practices

Regular Reviews

FrequencyReview Content
DailyPositions, P&L, errors
WeeklyPerformance metrics, risk exposure
MonthlyStrategy effectiveness, market regime
QuarterlyFull strategy review, optimization

Documentation

Maintain a trading log:

## [Date] Trading Log

### Market Conditions
- Trend: Bullish/Bearish/Sideways
- Volatility: High/Normal/Low
- Key Events: [Earnings, Fed, etc.]

### Strategy Performance
- Trades: X
- P&L: X%
- Issues: [Any problems]

### Notes
- [Observations, adjustments needed]

Contingency Plans

ScenarioAction
API failureSwitch to backup, manual review
Unexpected loss > 5%Pause, investigate
Market circuit breakerHalt all strategies
Strategy bugImmediate stop, fix, paper test

When to Stop

Red Lines

Stop trading if:

  • Max drawdown exceeded
  • Live Sharpe < 0 for extended period
  • Systematic divergence from backtest
  • Market regime fundamentally changed
  • Strategy logic proven flawed

Post-Mortem

After stopping, analyze:

  1. What went wrong? - Strategy, execution, or market?
  2. What assumptions failed? - Backtest missed something?
  3. What can be improved? - For next iteration

Scaling Up

When Ready to Increase Capital

Criteria for scaling:

  • 3+ months of profitable live trading
  • Risk metrics within targets
  • Consistent execution
  • Comfortable with drawdowns
  • Adequate capital reserves

Multi-Strategy Portfolio

portfolio = Portfolio([
{'strategy': TrendStrategy, 'allocation': 0.40},
{'strategy': MeanReversionStrategy, 'allocation': 0.30},
{'strategy': MomentumStrategy, 'allocation': 0.30},
])

portfolio.set_correlation_limit(0.6) # Max correlation
portfolio.set_max_drawdown(0.15) # Portfolio-level limit

Summary

PhaseDurationKey Actions
Paper Trading2-4 weeksValidate behavior
Initial Live1-2 monthsScale up gradually
Full DeploymentOngoingMonitor and iterate

Next Steps