聊天視窗

數據驅動的投資決策:金融分析與機器學習實務 - 第 6 章

第六章:回測、風險控管與實盤部署

發布於 2026-02-24 02:55

# 第六章:回測、風險控管與實盤部署 > **提醒**:以下示例聚焦於理論回測,實務部署時仍須自行補充滑點、手續費、風險控管與多資產同步執行的完整邏輯。 ## 1. 回測框架概覽 在上一章的程式碼中,我們使用 **Backtrader** 建立了一個簡單的 SMA‑Cross 策略。為了讓此策略在實際投資中可落地,以下幾個環節必須完整搭建: 1. **資料來源** – 讀取歷史 OHLCV,並確保資料完整性。 2. **交易成本** – 加入手續費、滑點模型。 3. **風險控管** – 位置 sizing、停損停利、最大連續虧損限制。 4. **多資產同步** – 同時管理多支證券,避免單一資產集中風險。 5. **回測品質** – 期間分割、參數穩健性檢驗。 ## 2. 完整程式碼示例 以下示例在原先的 SMA‑Cross 基礎上,加入了上述關鍵功能,並提供簡易的 `RiskControl` 子類,演示如何在回測中同時控制多項風險指標。 python import backtrader as bt import pandas as pd # ---------- 資料載入 ---------- data = pd.read_csv('historical_data.csv', index_col='Date', parse_dates=True) # ---------- SMA‑Cross 策略 ---------- class SMAcrossStrategy(bt.Strategy): params = dict( short_sma=15, long_sma=50, atr_len=14, atr_mult=1.5, risk=0.02, # 每筆交易佔資金比例 ) def __init__(self): self.short_sma = bt.indicators.SimpleMovingAverage(self.data.close, period=self.params.short_sma) self.long_sma = bt.indicators.SimpleMovingAverage(self.data.close, period=self.params.long_sma) self.crossover = bt.indicators.CrossOver(self.short_sma, self.long_sma) self.atr = bt.indicators.ATR(self.data, period=self.params.atr_len) self.position_size = 0 def next(self): # 無持倉時進場 if not self.position: if self.crossover > 0: # 黃金交叉 size = self.broker.getcash() * self.params.risk / self.data.close[0] self.buy(size=size) self.position_size = size else: # 出場條件:死叉或價格突破 ATR 指標 if self.crossover < 0 or self.data.close[0] > self.position.price + self.params.atr_mult * self.atr[0]: self.close() self.position_size = 0 # ---------- 風險控管 ---------- class RiskControl(bt.Strategy): def __init__(self): self.dataclose = self.datas[0].close self.order = None self.buyprice = None self.buycomm = None self.max_drawdown = 0.2 # 20% 最大允許虧損 self.prev_value = self.broker.getvalue() def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: return if order.status in [order.Completed]: if order.isbuy(): self.buyprice = order.executed.price self.buycomm = order.executed.comm self.bar_executed = len(self) elif order.status in [order.Canceled, order.Margin, order.Rejected]: self.bar_executed = None self.order = None def next(self): # 最大回撤檢測 current_value = self.broker.getvalue() if current_value < self.prev_value: self.max_drawdown = min(self.max_drawdown, current_value / self.prev_value) self.prev_value = current_value # 若回撤已超過限制,平倉全部持倉 if self.max_drawdown < 1 - self.max_drawdown: if self.position: self.close() # ---------- 回測引擎設定 ---------- cerebro = bt.Cerebro() # 1. 加入 SMA‑Cross 策略 cerebro.addstrategy(SMAcrossStrategy) # 2. 加入風險控管策略(可選) # cerebro.addstrategy(RiskControl) # 3. 資料源 class PandasData(bt.feeds.PandasData): cols = (bt.feeds.PandasData._lines + (('atr', -1),)) cerebro.adddata(PandasData(dataname=data)) # 4. 交易成本設定 cerebro.broker.setcash(100000.0) cerebro.broker.setcommission(commission=0.001) # 0.1% 手續費 cerebro.broker.set_slippage_fixed(0.05) # 固定 0.05 美元滑點 # 5. 回測執行 results = cerebro.run() # 6. 結果輸出 print(f'Final Portfolio Value: {cerebro.broker.getvalue():.2f}') > **說明**: > - `RiskControl` 內部使用簡單的 **最大回撤** 機制,實務可替換為更複雜的風險模型(如 Value‑at‑Risk、Conditional VaR)。 > - 多資產同時交易時,只需在 `cerebro.adddata` 中添加多個 `PandasData` 即可;策略內的邏輯需自行針對每個資料源做處理。 ## 3. 參數穩健性測試 在正式跑前,務必執行 **參數掃描**(Walk‑Forward、Out‑of‑Sample)來驗證策略在不同時段、不同市場環境下的穩健度。可採用 `backtrader` 的 `bt.brokers.BackBroker` 來進行交叉驗證,或使用外部套件如 `pyfolio`、`zipline` 進行更完整的風險度量。 ## 4. 從回測到實盤 ### 4.1 連接券商 API * **Interactive Brokers**:可透過 `ib_insync` 或 `backtrader` 自帶的 IB API。 * **TradeStation / Oanda**:亦有 Python SDK。 ### 4.2 交易指令封裝 python from ib_insync import IB, Stock ib = IB() ib.connect('127.0.0.1', 7497, clientId=1) def send_order(symbol, qty, order_type='MKT'): contract = Stock(symbol, 'SMART', 'USD') if order_type == 'MKT': ib.placeOrder(contract, ib.MarketOrder('BUY', qty)) else: ib.placeOrder(contract, ib.LimitOrder('BUY', qty, price)) ### 4.3 風險與資金管理 1. **Position Sizing**:使用 Kelly、Fixed‑Fraction、ATR‑Based 等方法。 2. **Stop‑Loss / Take‑Profit**:根據 ATR 或固定比例設置。 3. **多元化**:同時持有不同行業、不同市場的資產,以降低非系統性風險。 ## 5. 常見陷阱與調試技巧 | 障礙 | 可能原因 | 解決方案 | |------|----------|----------| | 回測結果過於理想 | 缺乏滑點、手續費 | 加入真實成本、使用真實行情回測 | | 策略失效於實盤 | 參數過度擬合 | 進行多期驗證、使用更寬鬆的參數區間 | | 連接失敗 | API 速率限制 | 加入重試機制、調整請求頻率 | ## 6. 總結 本章落腳於將數據驅動的策略從 **理論** 轉移至 **實務** 的關鍵環節:完整回測、風險控管與實盤部署。透過範例程式碼與實務建議,讀者已具備將簡易 SMA‑Cross 策略升級為可交易、風險可控的全自動投資系統的基礎。接下來的章節將進一步探討更高階的機器學習模型、非線性特徵選取與深度學習在金融市場中的應用。