返回目錄
A
數據驅動的投資決策:金融分析與機器學習實務 - 第 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 策略升級為可交易、風險可控的全自動投資系統的基礎。接下來的章節將進一步探討更高階的機器學習模型、非線性特徵選取與深度學習在金融市場中的應用。