Backtesting and Paper Trading: Gatekeepers Before Live Capital
When a strategy idea strikes, you want to trade it immediately. Two gatekeepers stop that impulse: backtesting and paper trading. I skipped these, lost time and money, and learned. Here's what I wish I'd done first.
⚠️ This is educational material, not investment advice. Investment losses are your responsibility.
Two Gates, Two Different Questions
- Backtesting asks: "Did this strategy work on past data?"
- Paper trading asks: "Does it work now, in real-time, with actual order flow?"
Passing backtest doesn't guarantee live success. Real-time brings data delays, order rejections, partial fills, and vanishing liquidity—none of which replay faithfully from historical data. Both stages are sequential, both essential.
Trap 1: Overfitting
Most common failure. Tune parameters endlessly against historical data, backtest returns skyrocket. But you've just memorized historical accidents; the future won't replay them.
Defense:
- Reduce parameter count. A two-parameter strategy (entry/exit thresholds) beats a ten-knob tuning nightmare.
- In-sample / out-of-sample split. Optimize on one date range, verify performance holds on untouched data.
- Suspiciously perfect results are red flags. 95% win rate usually means a bug or overfit.
For my gap strategy, I started with arbitrary thresholds (e.g., 0.50% gap) without historical data to justify them. I admitted ignorance, ran small live, and observed real distributions before adjusting. That's more honest than force-fitting parameters to absent data.
Trap 2: Slippage and Fees Set to Zero
Backtests where every order "fills instantly at desired price" magically show huge returns. Reality:
Backtest P&L = (exit price − entry price) × quantity
Live P&L = (exit price − entry price) × quantity
− entry slippage − exit slippage
− buy fee − sell fee − tax
Thin-liquidity stocks (new-list ETFs especially) move on a market order. Gap strategies profit 0.1–0.5% per round—fees and slippage alone can wipe that out.
Use conservative cost assumptions in backtest. When in doubt, worse is safer.
Trap 3: Look-Ahead Bias
Subtle bug: using data not yet known at that moment. Example: signal on "today's open," but backtest code accidentally references today's close first. Results look magical; live, it fails.
Defense: force code to know only what a real bot knew at execution time. Feed data chronologically, mask future bars, and compute only on visible history.
Paper Trading: Stub Orders, Real Everything Else
After backtest passes, run live data with orders blocked (dry-run). Production bots should have a stub mode:
// Paper trading mode: log only, no real order
logCh <- fmt.Sprintf("[DRY-RUN] BUY %s x%d @ %.0f", code, qty, price)
// orderExecutor doesn't send actual REST order
Check: Does WebSocket hold all day without dropping? Do signals fire at expected frequency? Does forced liquidation execute on time? Does restart recover state? Does the system survive a full market day? This is rehearsal.
The Sequence
- Backtest with conservative costs → filter bad ideas early
- Backtest again, verify performance on out-of-sample data
- Paper trade the real-time pipeline → rehearse execution
- Go live with tiny capital → months of observation before scaling
Skip stages, lose fast. Respect the gates; they're the shortest path despite seeming slow.
Summary
Order matters: backtest → validate → paper-trade → micro-live → scale. Every stage answers a different failure mode. No shortcut bypasses them; only luck does, and luck runs out.
This is educational material, not investment advice. Investment losses are your responsibility.
댓글
댓글 쓰기