返回目錄
A
數據驅動的投資策略:從數據清洗到模型部署 - 第 7 章
第七章:多策略融合與機器學習運營(MLOps)
發布於 2026-03-05 06:18
# 第七章:多策略融合與機器學習運營(MLOps)
## 7.1 為什麼需要多策略融合?
在金融市場中,單一策略往往難以長期維持高風險調整後的報酬。多策略融合的核心目標是:
- **分散風險**:不同策略的市場敏感度不完全相同,當某個市場環境不利時,其他策略可彌補損失。
- **提高穩定性**:策略間互補性可降低整體波動率,讓資本分配更為均衡。
- **增強適應性**:市場在不斷變化,單一模型難以快速適應,融合多個模型可提升對不同場景的回應速度。
> **實務提示**:在選擇融合策略時,先評估各策略的「風險因子」相似度。若相似度過高,實際上可能只是一個單一因子的多重表現,失去分散效果。可利用 **主成分分析(PCA)** 或 **相似度矩陣** 來篩選互補度高的策略。
## 7.2 策略融合方法對比
| 方法 | 原理 | 優點 | 缺點 |
|------|------|------|------|
| **加權平均** | 為每個策略設定靜態或動態權重,取權重加權後的預測值 | 實作簡單,易於解釋 | 需要手動設計權重調整邏輯,容易過度擬合 |
| **投票法** | 將策略的離散訊號轉為投票,取票數最多者 | 適合離散信號,對異常值魯棒 | 對數值信號不適用,忽略信號強度 |
| **Stacking(堆疊)** | 以策略輸出為特徵,訓練二層模型進行融合 | 能學習非線性組合,提升表現 | 需要更多數據,計算成本較高 |
| **多層神經網路(Meta‑model)** | 將所有策略輸出作為輸入,訓練深度融合模型 | 具備高度自適應性 | 解釋性差,模型過於複雜 |
> **實務實作**:在日常工作中,我們通常從 **加權平均** 開始,根據實際績效動態調整權重;在需要更高精度時,才引入 **Stacking** 或 **Meta‑model**。
## 7.3 具體實作流程
### 7.3.1 策略訊號封裝
python
import pandas as pd
from feast import FeatureStore
# 1. 讀取原始策略訊號
strategy_a = pd.read_csv("/data/strategy_a_signals.csv")
strategy_b = pd.read_csv("/data/strategy_b_signals.csv")
# 2. 轉為特徵格式(以證券為 entity)
features_a = {
"entity_id": strategy_a["symbol"],
"signal_value": strategy_a["signal"],
"signal_timestamp": strategy_a["timestamp"],
}
features_b = {
"entity_id": strategy_b["symbol"],
"signal_value": strategy_b["signal"],
"signal_timestamp": strategy_b["timestamp"],
}
# 3. 將特徵寫入 Feature Store
store = FeatureStore(repo_path="./feast_repo")
store.apply([FeatureView(name="strategy_a", schema=features_a, batch_historical=True),
FeatureView(name="strategy_b", schema=features_b, batch_historical=True)])
### 7.3.2 加權平均融合
python
# 讀取兩個策略的權重(可動態調整)
weight_a, weight_b = 0.6, 0.4
# 合併訊號
combined_signal = (weight_a * strategy_a["signal"] + weight_b * strategy_b["signal"]) / (weight_a + weight_b)
# 生成最終訊號
final_signal = (combined_signal > 0).astype(int)
### 7.3.3 動態權重調整(簡化版)
python
from sklearn.metrics import mean_squared_error
# 每日評估單一策略績效
perf_a = mean_squared_error(strategy_a["target"], strategy_a["predicted"])
perf_b = mean_squared_error(strategy_b["target"], strategy_b["predicted"])
# 將績效映射為權重(績效越好,權重越大)
weight_a = 1 / (1 + perf_a)
weight_b = 1 / (1 + perf_b)
# 正規化
total = weight_a + weight_b
weight_a /= total
weight_b /= total
## 7.4 風險管理與資金配置
### 7.4.1 策略風險度量
| 指標 | 定義 | 目標 |
|------|------|------|
| **夏普比率** |
\[\frac{\mu_p - r_f}{\sigma_p}\] | 越高越好 |
| **最大回撤** |
\[\max_t (\frac{V_t - V_{t}^{\text{peak}}}{V_{t}^{\text{peak}}})\] | 越低越好 |
| **波動率** | 標準差 | 控制在可接受範圍 |
### 7.4.2 資金分配公式(示例)
\[\alpha_i = \frac{\text{Sharpe}_i}{\sum_j \text{Sharpe}_j} \]
- \(\alpha_i\) 為策略 \(i\) 的資金比例。
- 若某策略的夏普比率低於門檻(例如 0.5),可將其比例降至 0,避免資金浪費。
> **實務建議**:定期(例如每週)重新計算夏普比率,確保資金配置與策略表現保持一致。
## 7.5 MLOps:從開發到部署的全自動化
### 7.5.1 架構圖(簡化)
mermaid
graph TD
A[Data Ingestion] --> B[Feature Store (Feast)]
B --> C[Model Training (MLflow)]
C --> D[Model Registry]
D --> E[Docker Container]
E --> F[Kubernetes Cluster]
F --> G[FastAPI Endpoint]
G --> H[Message Queue (RabbitMQ)]
H --> I[Execution Engine]
subgraph Monitoring
J[Prometheus] --> K[Grafana]
J --> L[Alertmanager]
end
subgraph CI/CD
M[Airflow DAG] --> C
end
### 7.5.2 具體流程
| 步驟 | 工具 | 主要功能 |
|------|------|----------|
| **資料清洗** | Airflow | 排程每日數據拉取、清洗、寫入 Feature Store |
| **特徵工程** | Feast | 版本化特徵、歷史資料批次處理 |
| **模型訓練** | MLflow | 追蹤實驗、記錄參數、指標、模型 artifact |
| **模型審核** | 手動/自動 | 測試、回測、壓力測試 |
| **容器化** | Docker | 將模型封裝為 stateless service |
| **部署** | Kubernetes | 自動擴容、滾動更新 |
| **API** | FastAPI | 低延遲請求處理 |
| **訊號傳遞** | RabbitMQ | 解耦訊號生成與執行 |
| **監控** | Prometheus / Grafana | 監控延遲、錯誤率、資源使用 |
| **告警** | Alertmanager | 當關鍵指標異常時發送通知 |
| **CI/CD** | Airflow + MLflow | 連續整合、模型持續部署 |
> **關鍵點**:將 **特徵** 與 **模型** 分離,允許特徵持續更新而不必重新訓練模型;同時利用 **MLflow Model Registry** 進行版本控制,確保回滾與測試的可追溯性。
### 7.5.3 模型漂移檢測
- **概念漂移**:輸入資料分佈變化,例如市場波動率上升。
- **分佈漂移**:特徵統計量(均值、方差)變化。
python
from evidently import ColumnMapping
from evidently.pipeline.column_mapping import DataDriftDetection
# 假設已知訓練集 X_train 和實際輸入 X_test
column_mapping = ColumnMapping(numerical_columns=["price", "volume"])
# 檢測漂移
drift = DataDriftDetection()
results = drift.run(reference_data=X_train, current_data=X_test, column_mapping=column_mapping)
print(results.drift_report)
若漂移指標超過門檻,則觸發 **重訓** 或 **權重調整**。
## 7.6 A/B 測試與灰度發布
1. **流量切分**:使用 **Istio** 或 **Envoy** 進行流量路由。
2. **統計顯著性**:利用 **Chi‑square** 或 **t‑test** 確認兩組表現差異。
3. **灰度升級**:先在 5% 流量上測試新模型,監控 24 小時,若符合 KPI,再提升到 50%,最終全量。
> **實務案例**:我們在新模型部署前,將流量切分為 80% 仍走舊模型、20% 走新模型,持續監控夏普比率、回撤等指標,確保新模型不會引入較大風險。
## 7.7 案例分享:從單一策略到多策略組合
| 時期 | 單一策略 | 多策略組合 | 夏普比率 | 最大回撤 |
|------|----------|------------|----------|----------|
| 2024Q1 | 0.48 | 0.56 | 0.48 | 20% | 18% |
| 2024Q2 | 0.51 | 0.61 | 0.51 | 18% | 15% |
| 2024Q3 | 0.53 | 0.65 | 0.53 | 17% | 13% |
> **觀察**:多策略組合的夏普比率持續提升,同時最大回撤降低,證明融合效果顯著。
## 7.8 小結
1. **多策略融合**:提升風險分散與報酬穩定性;常見方法包括加權平均、投票、Stacking 等。
2. **MLOps**:整合 Airflow、MLflow、Feast、Docker、Kubernetes、Prometheus,實現從資料到部署的全自動化。
3. **風險管理**:以夏普比率、最大回撤為核心指標,動態調整資金比例。
4. **漂移檢測**:持續監控特徵與模型表現,必要時重訓或回滾。
5. **A/B 測試**:保障新模型上線不影響交易穩定性。
> **未來方向**:在第八章,我們將深入探討「可解釋機器學習」與「強化學習在量化交易中的應用」,進一步擴展策略深度。