基于Python的策略开发与回测:传统机器学习 - 随机森林分类策略

基于Python的策略开发与回测:传统机器学习 - 随机森林分类策略


1. 策略原理深度解析

核心逻辑
使用历史价格、技术指标和基本面数据构建特征矩阵,通过随机森林模型预测次日股价涨跌方向(分类问题),根据预测概率生成交易信号:

  • 预测上涨概率 > 60%:买入
  • 预测下跌概率 > 60%:卖出
  • 其他情况:持有现金

关键技术点

  1. 特征工程

    • 时间序列特征:N日收益率、波动率、量价背离
    • 技术指标:MACD直方图、RSI超卖/超买状态、布林带宽度
    • 市场环境:行业指数相对强弱、市场宽幅指标
  2. 标签构造

    # 次日收益率二值化(涨=1,跌=0)  
    data['Target'] = (data['Close'].shift(-1) > data['Close']).astype(int)  
    
  3. 模型优势

    • 自动处理非线性关系与特征交互
    • 内置特征重要性评估防止过拟合

2. 完整策略实现代码

步骤1:生成带噪声的模拟数据

import numpy as np  
import pandas as pd  

# 生成基准价格序列(带趋势和波动聚集)  
np.random.seed(42)  
days = 1000  
trend = np.linspace(100, 200, days)  
noise = np.concatenate([  
    np.random.normal(0, 2, 300),  
    np.random.normal(0, 5, 400),  
    np.random.normal(0, 3, 300)  
])  
price = trend + np.cumsum(noise)  

# 构建DataFrame  
data = pd.DataFrame({'Close': price},  
                   index=pd.date_range('2020-01-01', periods=days))  

步骤2:特征工程

# 技术指标计算  
data['Return_1D'] = data['Close'].pct_change()  
data['MA10'] = data['Close'].rolling(10).mean()  
data['MA50'] = data['Close'].rolling(50).mean()  
data['Volatility_20D'] = data['Return_1D'].rolling(20).std() * np.sqrt(252)  

# 构造滞后特征  
for lag in [1, 2, 3, 5]:  
    data[f'Return_Lag{lag}'] = data['Return_1D'].shift(lag)  

# 目标变量(次日涨跌)  
data['Target'] = (data['Close'].shift(-1) > data['Close']).astype(int)  

# 清理缺失值  
data.dropna(inplace=True)  

步骤3:模型训练与预测

from sklearn.ensemble import RandomForestClassifier  
from sklearn.model_selection import train_test_split  

# 特征/标签拆分  
features = data.columns.drop(['Close', 'Target'])  
X = data[features]  
y = data['Target']  

# 时间序列分割(避免前瞻偏差)  
train_size = int(len(data)*0.7)  
X_train, X_test = X.iloc[:train_size], X.iloc[train_size:]  
y_train, y_test = y.iloc[:train_size], y.iloc[train_size:]  

# 模型训练  
model = RandomForestClassifier(n_estimators=100, max_depth=5, random_state=42)  
model.fit(X_train, y_train)  

# 生成预测概率  
data['Pred_Prob'] = model.predict_proba(X)[:, 1]  

3. 可视化代码与解析

可视化1:特征重要性分析
import matplotlib.pyplot as plt  

# 提取特征重要性  
importance = pd.Series(model.feature_importances_, index=features)  
importance = importance.sort_values(ascending=True)  

# 绘制水平条形图  
plt.figure(figsize=(10,6))  
importance.plot(kind='barh', color='#1f77b4')  
plt.title('Random Forest Feature Importance', pad=15)  
plt.xlabel('Importance Score')  
plt.grid(alpha=0.3, axis='x')  
plt.tight_layout()  
plt.show()  

在这里插入图片描述
图表说明

  • 横轴为特征重要性得分(Gini重要性)
  • 纵轴显示特征名称,重要性越高表明对预测贡献越大

可视化2:预测概率分布

plt.figure(figsize=(12,5))  

# 正负样本概率分布  
plt.hist(data[data['Target']==1]['Pred_Prob'],   
         bins=30, alpha=0.7, color='green', label='Up Days')  
plt.hist(data[data['Target']==0]['Pred_Prob'],  
         bins=30, alpha=0.7, color='red', label='Down Days')  

# 标注交易阈值  
plt.axvline(0.6, color='black', linestyle='--', label='Buy Threshold')  
plt.axvline(0.4, color='gray', linestyle='--', label='Sell Threshold')  

# 图表装饰  
plt.title('Prediction Probability Distribution', pad=15)  
plt.xlabel('Predicted Probability of Rising')  
plt.ylabel('Frequency')  
plt.legend()  
plt.grid(alpha=0.3)  
plt.show()  

在这里插入图片描述

图表说明

  • 绿色直方图显示实际上涨日的预测概率分布
  • 红色直方图显示实际下跌日的预测概率分布
  • 黑色虚线为买入阈值(>60%),灰色虚线为卖出阈值(<40%)

4. 策略回测实现

信号生成与收益计算
# 生成交易信号  
data['Signal'] = 0  
data.loc[data['Pred_Prob'] > 0.6, 'Signal'] = 1    # 做多  
data.loc[data['Pred_Prob'] < 0.4, 'Signal'] = -1   # 做空  

# 计算策略收益  
data['Strategy_Return'] = data['Signal'].shift(1) * data['Return_1D']  

# 累计收益  
data['Cumulative_Market'] = (1 + data['Return_1D']).cumprod()  
data['Cumulative_Strategy'] = (1 + data['Strategy_Return']).cumprod()  

可视化3:策略与基准对比

plt.figure(figsize=(12,6))  

# 绘制净值曲线  
plt.plot(data['Cumulative_Market'], label='Buy & Hold', color='#1f77b4', alpha=0.8)  
plt.plot(data['Cumulative_Strategy'], label='RF Strategy', color='#ff7f0e', linewidth=2)  

# 标注信号点  
buy_dates = data[data['Signal'] == 1].index  
sell_dates = data[data['Signal'] == -1].index  
plt.scatter(buy_dates, data.loc[buy_dates, 'Cumulative_Strategy'],  
           marker='^', color='lime', s=50, edgecolors='black', label='Long')  
plt.scatter(sell_dates, data.loc[sell_dates, 'Cumulative_Strategy'],  
           marker='v', color='red', s=50, edgecolors='black', label='Short')  

# 图表装饰  
plt.title('Strategy vs Buy & Hold Performance', pad=15)  
plt.xlabel('Date')  
plt.ylabel('Cumulative Return')  
plt.legend()  
plt.grid(alpha=0.3)  
plt.yscale('log')  # 对数坐标更好展示长期收益  
plt.tight_layout()  
plt.show()  

在这里插入图片描述

图表说明

  • 蓝色曲线为买入持有策略净值
  • 橙色曲线为随机森林策略净值
  • 绿色▲标记做多信号,红色▼标记做空信号

5. 关键风险控制

  1. 过拟合防范
    # 使用Walk-Forward验证  
    for i in range(train_size, len(data), 30):  
        model.fit(X.iloc[i-180:i], y.iloc[i-180:i])  # 滚动180天训练窗口  
        data.loc[i:i+30, 'Pred_Prob'] = model.predict_proba(X.iloc[i:i+30])[:,1]  
    
  2. 交易成本模型
    transaction_cost = 0.001  # 单边千分之一手续费  
    data['Strategy_Return'] = data['Strategy_Return'] - \
                             abs(data['Signal'].diff()) * transaction_cost  
    
  3. 杠杆控制
    max_leverage = 2  # 最大杠杆倍数  
    data['Signal'] = np.clip(data['Signal'], -max_leverage, max_leverage)  
    
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

灏瀚星空

你的鼓励是我前进和创作的源泉!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值