Skip to content

Paper Trading

Difficulty expert

Overview

Paper trading simulates live trading with real-time data but without real money. It's the critical bridge between backtesting and live trading.

Why Paper Trade

Reason Description
Validate Backtest Confirm backtest results in live conditions
Test Infrastructure Verify systems work in real-time
Build Confidence Practice without financial risk
Refine Process Improve execution and decision-making
Test Edge Verify strategy works in current market regime

Paper Trading Setup

class PaperTradingEngine:
    """Simulate live trading with real-time data."""

    def __init__(self, strategy, initial_capital=100000):
        self.strategy = strategy
        self.capital = initial_capital
        self.positions = {}
        self.orders = []
        self.fills = []
        self.equity_curve = [initial_capital]
        self.market_data = None

    def on_market_data(self, data):
        """Process incoming market data."""
        self.market_data = data

        # Generate signals
        signal = self.strategy.generate_signal(data)

        if signal:
            order = self.create_order(signal, data)
            self.execute_order(order)

    def create_order(self, signal, data):
        """Create order from signal."""
        return {
            'symbol': signal.symbol,
            'side': signal.side,
            'quantity': signal.quantity,
            'price': data.current_price,
            'timestamp': data.timestamp,
            'type': 'paper'
        }

    def execute_order(self, order):
        """Simulate order execution."""
        # Simulate slippage and commission
        slippage = self.estimate_slippage(order)
        commission = order.quantity * 0.005  # $0.005 per share

        fill_price = order.price + slippage * (1 if order.side == 'BUY' else -1)

        fill = {
            **order,
            'fill_price': fill_price,
            'commission': commission,
            'slippage': slippage
        }

        self.update_position(fill)
        self.fills.append(fill)

    def update_position(self, fill):
        """Update portfolio based on fill."""
        cost = fill.quantity * fill.fill_price + fill.commission
        if fill.side == 'BUY':
            self.capital -= cost
            self.positions[fill.symbol] = self.positions.get(fill.symbol, 0) + fill.quantity
        else:
            self.capital += cost
            self.positions[fill.symbol] = self.positions.get(fill.symbol, 0) - fill.quantity

        # Track equity
        total_value = self.capital + self.calculate_position_value()
        self.equity_curve.append(total_value)

Slippage Simulation

def simulate_slippage(order, market_data):
    """Realistic slippage simulation."""
    base_slippage = 0.001  # 0.1% base

    # Size impact
    participation = order.quantity / market_data.avg_volume
    size_impact = 0.5 * participation

    # Volatility impact
    vol_impact = market_data.volatility * 0.1

    # Spread cost
    spread_cost = market_data.spread / 2

    total_slippage = base_slippage + size_impact + vol_impact + spread_cost
    return total_slippage

Paper Trading Checklist

Before Going Live:
☐ Paper traded for minimum 3 months
☐ Results match backtest within 10-20%
☐ Infrastructure tested and stable
☐ Risk management verified
☐ Execution quality acceptable
☐ Emotional readiness confirmed
☐ Capital allocated and ready

Common Issues

Issue Cause Solution
Overfilling Assuming all orders fill Use realistic fill rates
No slippage Perfect execution assumed Add slippage model
Perfect timing Look-ahead in execution Add realistic delay
Ignoring fees No cost modeling Include all costs
Short bias Easy to short in simulation Only short tradeable securities

Transitioning to Live

Phase 1: Paper trade (3+ months)
Phase 2: Small live capital (10% of target)
Phase 3: Scale up gradually (25%, 50%, 100%)
Phase 4: Full deployment

Practical Guidelines

  1. Be Realistic — Simulate real conditions as closely as possible
  2. Track Everything — Paper trades should be logged like real trades
  3. Don't Over-Optimize — Paper trading is validation, not optimization
  4. Set Clear Criteria — Define what "good enough" means before going live
  5. Psychological Gap — Paper trading doesn't capture emotional pressure
  6. Time-Bounded — Don't paper trade forever; transition to live
  7. Compare to Backtest — Results should be similar but not identical

Next Steps