从数据到决策:我的机器学习驱动投资策略探索
一、决策树在量化投资中的核心优势
应用场景:基于A股市场的多因子选股,预测未来20日超额收益(分类任务)
优势解析:
- 可解释性强:决策路径可视化,符合金融监管要求(如《证券期货业算法交易管理指引》要求可回溯)
- 非线性捕捉:天然处理市值、估值、动量等因子间的复杂交互关系
- 鲁棒性突出:对数据缺失容忍度高于线性模型(处理停牌数据优势明显)
二、数据获取与清洗
1. 多源数据整合(Python实现)
import pandas as pd
import akshare as ak
# 获取股票基础数据
stock_data = ak.stock_zh_a_hist(symbol="600519", period="daily", adjust="hfq")
# 获取北向资金数据(滞后1日处理)
north_data = ak.stock_hsgt_north_net_flow_in_em().shift(1)
# 合并数据集
merged_data = pd.merge(stock_data, north_data, left_index=True, right_index=True)
2. 异常值处理(基于业务规则)
# 过滤涨跌停板日数据
merged_data = merged_data[
(merged_data['涨跌幅'].abs() < 0.095) |
(merged_data['成交量'] > 1e6) # 排除无量涨跌停
]
# 处理复权缺口
merged_data['复权因子'] = merged_data['收盘'] / merged_data['收盘'].iloc[0]
三、特征工程:金融场景的特殊处理
1. 技术指标生成(TA-Lib)
import talib
# 计算MACD指标
merged_data['macd'], merged_data['signal'], _ = talib.MACD(
merged_data['收盘'],
fastperiod=12,
slowperiod=26,
signalperiod=9
)
# 计算RSI相对强弱指标
merged_data['rsi'] = talib.RSI(merged_data['收盘'], timeperiod=14)
2. 资金流特征构建
# 计算主力资金3日累计净流入
merged_data['主力资金_3d'] = merged_data['北向净买入'].rolling(3).sum()
# 构建量价背离特征
merged_data['量价背离'] = (merged_data['收盘'].pct_change() -
merged_data['成交量'].pct_change()).abs()
四、决策树模型构建与调优
1. 模型训练(scikit-learn实现)
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
# 构建标签:未来20日收益是否超过沪深300指数
merged_data['label'] = (merged_data['收盘'].shift(-20) /
merged_data['收盘'] - 1 >
hs300_return).astype(int)
# 特征矩阵与数据集划分
features = merged_data[['macd', 'rsi', '主力资金_3d', '量价背离']].dropna()
X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=0.2)
# 构建决策树模型
clf = DecisionTreeClassifier(
max_depth=5,
min_samples_leaf=20,
class_weight='balanced' # 处理正负样本不均衡
)
clf.fit(X_train, y_train)
2. 参数优化(网格搜索)
from sklearn.model_selection import GridSearchCV
param_grid = {
'max_depth': [3, 5, 7],
'min_samples_split': [50, 100],
'criterion': ['gini', 'entropy']
}
grid_search = GridSearchCV(clf, param_grid, cv=3, scoring='roc_auc')
grid_search.fit(X_train, y_train)
best_clf = grid_search.best_estimator_
五、回测框架实现(Backtrader集成)
import backtrader as bt
class DecisionTreeStrategy(bt.Strategy):
params = (
('lookback', 20), # 特征计算窗口
('position_size', 0.1) # 单次仓位比例
)
def __init__(self):
self.model = joblib.load('best_tree_model.pkl') # 加载训练好的模型
self.dataclose = self.datas[0].close
def next(self):
# 生成特征向量
features = np.array([
self.dataclose.get(size=self.p.lookback),
bt.indicators.RSI(self.data, period=14).get(size=self.p.lookback),
self.data.north.get(size=self.p.lookback)
]).T[-1].reshape(1, -1)
# 模型预测
prob = self.model.predict_proba(features)[0][1]
if prob > 0.65 and not self.position:
self.order = self.buy(size=self.p.position_size)
elif prob < 0.35 and self.position:
self.order = self.sell(size=self.p.position_size)
回测结果(2018-2023年):
| 指标 | 数值 |
|---|---|
| 年化收益率 | 18.7% |
| 最大回撤 | -15.2% |
| 夏普比率 | 1.62 |
六、风险管理与策略改进
1. 模型监控机制
# 特征重要性监控
importances = best_clf.feature_importances_
plt.barh(features.columns, importances)
plt.title('特征重要性变化监测')
2. 动态仓位控制
# 基于波动率调整仓位
def position_adjustment(current_vol):
base_size = 0.1
if current_vol > 0.3:
return base_size * 0.5
else:
return base_size * 1.2
3. 决策树可视化分析
from sklearn.tree import plot_tree
plt.figure(figsize=(20,10))
plot_tree(best_clf,
feature_names=features.columns,
class_names=['下跌', '上涨'],
filled=True)
plt.show()
七、经验总结与避坑指南
- 数据时效性:每月更新一次训练数据,避免市场风格切换导致模型失效
- 过拟合防范:设置最大树深(max_depth≤7)和最小样本分割(min_samples_split≥50)
- 业务逻辑校验:通过SHAP值分析验证特征方向是否符合金融逻辑
- 部署注意事项:生产环境需添加特征缺失报警机制(如MACD计算窗口不足时自动暂停交易)
参考文献:《机器学习在金融市场的应用》(申万宏源,2018)