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

  1. Backtest with conservative costs → filter bad ideas early
  2. Backtest again, verify performance on out-of-sample data
  3. Paper trade the real-time pipeline → rehearse execution
  4. 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.

댓글

이 블로그의 인기 게시물

한국투자증권 KIS API로 실시간 시세 받기 (WebSocket 실전)

파이썬으로 업비트 API 연동하기 — 시세 조회부터 주문까지 기초

Go로 자동매매 신호봇 프레임워크 설계하기