quant-lit進階課程 ▸ Lesson 5

進階課程 · Lesson 5

Lesson 5:建立第一個完整策略

來源:Codex 製作

學習目標

1. 先做最小策略,不先優化

第一版的任務是確認研究管線,不是追求高 Sharpe。建議用少量規則:

商品:單一流動性資產
頻率:日線
訊號:收盤高於 20 日 SMA
決策:日 t 收盤後
成交:日 t+1 開盤(簡化範例若無 open,使用 position shift)
出場:訊號反轉
部位:0% 或 100%,不加槓桿
成本:每次 position change 扣固定 bps

先驗證對齊,再加入 stop、分批、short、volatility sizing。

2. 正確對齊訊號與報酬

signal_t 使用 close_t,則不能乘上同一期由 close_(t-1)close_t 的報酬。最小寫法:

signal = close > close.rolling(20).mean()
position = signal.shift(1).fillna(False).astype(float)
asset_return = close.pct_change().fillna(0.0)
gross_return = position * asset_return

這仍是一個 close-to-close approximation(近似)。若規格要求 next-open execution,就必須有 open data 並分開 overnight 與 intraday return。

3. 計算 turnover 與成本

turnover = position.diff().abs().fillna(position.abs())
net_return = gross_return - turnover * cost_rate

從 0 到 1 是一次買進;1 到 0 是一次賣出;從 -1 到 1 則是 2 單位 turnover。cost_rate 必須說清楚是單邊還是 round-trip。

4. Benchmark 不可缺席

至少建立:

如果策略只在多頭市場工作,可能只是降低或增加 beta。可進一步估計 market exposure、up/down capture 與 regime performance。

5. 回測輸出要能追溯

不要只輸出 summary。至少保存:

timestamp, raw_signal, position, entry/exit flag,
fill price, quantity, fee, slippage, gross pnl, net pnl,
equity, drawdown, parameter version, data version

任何一筆異常績效都應能追到原始 bar 與計算步驟。

6. 三個必要單元測試

  1. 無未來資料:把資料在日期 T 截斷,T 以前訊號不得改變。
  2. 成交延遲:已知訊號日,position 必須在規格指定的下一期才改變。
  3. 成本方向:提高成本後,net equity 不得改善。

Python 實作

執行 python .\code\simple_backtest.py。範例用合成資料,不下載市場資料,因此結果可重現。請依序修改:

  1. window=20 改為 10;
  2. cost_bps=5 改為 50;
  3. 移除 shift(1),觀察不當時間對齊如何改變結果。

第三步只用來理解 bias,不得保留為正式版本。

通關判準

你應能從任一 equity 點反查:當日使用哪個訊號、前一日持有什麼部位、扣了多少成本,以及為何該報酬屬於策略。

上一課Lesson 4