华泰证券:量化股票投资(第一到六周)
Week 1: 数据收集与探索性分析(NVDA)
任务目标
我们将围绕英伟达(NVIDIA, 股票代码:NVDA)开展量化研究。第一周的目标是掌握如何通过公开数据源获取金融数据,并对这些数据进行基础处理和可视化分析。
一、数据来源
通过 yfinance
与 pandas-datareader
获取以下数据:
- 股票基本信息(名称、行业、市值等)
- 日线行情数据(近5年)
- 年度与季度财报
- 资产负债表
- 现金流量表
二、数据预处理步骤
- 将所有日期列转换为标准时间格式。
- 清洗缺失数据:如部分列数据缺失严重则删除;少量缺失则使用均值填补。
- 检查重复行,确保数据唯一性。
- 类型统一(数值列转为float/int)。
三、探索性数据分析(EDA)
1. 历史收盘价趋势(近5年)
展示了NVDA的日线收盘价格走势:
2. 年度与季度财务表现
分析 季度营收、营业利润 与 毛利润:
4. 资产负债表分析(年度 + 季度)
展示了资产总额、流动资产与现金的变化:
- 季度趋势:
5. 现金流分析
- 季度现金流:
Week 2: 数据预处理与可视化
一、空值处理
在金融数据分析中,填充空值可能引入偏差,故此处采用删除缺失值行的方式处理关键财务数据字段,以保障模型训练数据的准确性。
二、数据合并与时间对齐
由于历史价格(日频)、财务数据(季频或年频)时间精度不一致,我们采用以下策略:
- 对日线数据保持原频率
- 使用广播填充(forward fill)将季度数据扩展到月度或日度
- 最终将所有数据合并到统一的时间索引
三、辅助数据广播与特征融合
季度报表字段(如:营收、现金流、资产等)经过扩展后,合并进历史行情数据中,为后续建模构造完整特征向量。
四、历史波动率分析
我们利用对数收益率的标准差计算历史波动率:
- 采用1天精度,回看期为2年
- 与价格的boxplot联合展示,辅助判断异常波动
插图:历史波动率与价格箱线图(boxplot):
面对时间分布不均的数据,特别是在数据量随时间远去而减少的情况下,进行特征工程和窗口采样时需要谨慎处理。
五、预测建模与评估
使用'totalAssets', 'operatingIncome', 'totalLiabilities'预测2024Q1-4的totalRevenue
VDA 所属行业: SEMICONDUCTORS & RELATED DEVICES
2023年行业平均总收入: 112416709000.0
2023年nvda总收入: 26974000000.0
2023年nvda总收入高于行业平均总收入是: 否
Week 3: 量化交易策略与回测分析
一、任务目标
本周核心任务包括:
- 批量爬取并更新上证/深证市场全部股票数据通过ak.stock_zh_a_spot()(sqlalchemy的.to_sql保存至本地MySQL数据库)
- 实现基础交易策略(移动平均交叉策略)
- 单股与多股策略回测
- 回测数据可视化
- 策略优化与自动提醒开发
二、数据爬取与存储
使用 akshare
和 pandas
获取完整市场行情,并存入 my_stocks_data.db
:
engine = create_engine('sqlite:///my_stocks_data.db') all_stocks_data.to_sql('stock_data', con=engine, index=False, if_exists='append')
三、构建交易策略:移动平均交叉法
- 策略逻辑:当短期均线(如20日)上穿长期均线(如50日)时买入,反之卖出。
- 策略应用于股票代码:600000
signals = moving_average_strategy(stock_data, short_window=40, long_window=100)
图示:买卖信号与股价交叉点:
四、策略回测
构建组合价值与交易记录:
portfolio, trades = backtest(signals, stock_data)
五、股票池筛选与批量回测
通过波动率选出低风险股票构建股票池(下25%波动性):
low_volatility_stocks = all_stocks_data.groupby('股票代码')['波动性'].mean().nsmallest(...)
六、策略优化与性能评估
遍历多个窗口组合寻找最佳参数:
best_params, best_perf = optimize_strategy(data, range(20,60,10), range(80,160,20))
结果示意:
Best Parameters: {'short_window': 50, 'long_window': 100} Best Performance: 0.0134
七、开发自动提醒功能
实时监测股票池个股,触发交易信号发送邮件通知:
monitor_stocks(stock_pool=[600000, 600004, 600007], short_window=40, long_window=100)
Week 4: 使用基础机器学习方法选取特征
本周的目标是从金融时间序列数据中提取有效特征,构建基础机器学习模型,评估其预测能力,并最终生成可用于后续神经网络训练的特征集。
一、时间序列划分(TimeSeriesSplit)
我们使用 TimeSeriesSplit
方法将历史数据划分为训练集和测试集,保持时间上的连续性,防止未来信息泄露。
训练集与测试集划分结果:
- 训练集样本数:1051
- 测试集样本数:210
二、模型训练:Gradient Boosting Regression
我们使用梯度提升回归(GBR)模型进行收盘价预测,损失函数为RMSE:
GradientBoostingRegressor(learning_rate=0.01, n_estimators=500, subsample=0.5)
RMSE指标:2.52(NVDA)
三、特征选择与可视化
从模型中导出特征重要性,分析后决定不剔除原始特征
重要性柱状图展示:
四、弃用复杂模型,测试基础回归器
我们比较了线性回归与决策树:
- Linear Regression RMSE:1.41
- Decision Tree Regressor RMSE:3.51
五、特征预处理函数封装
定义 prepare_features(df)
函数,将原始数据清洗并格式化为训练用特征组,适用于未来实时预测任务。
六、扩充数据样本:获取额外股票历史数据
通过 Alpha Vantage API 获取包括 NVDA、AAPL、AMD、META、MSFT、GOOGL 等19支科技股数据,合并后保存为 all_stock_data.csv
Week 5-6: 回报率预测模型构建与评估
一、预测目标:Daily Return(日收益率)
相比直接预测股价,收益率具备更好的稳定性与统计特性,适合用作模型目标变量:
- 避免价格的量级差异
- 对市场噪声不敏感,预测更可靠
- 更易符合正态分布假设
二、数据处理与日收益率计算
选取四支科技龙头股(AAPL, AMZN, GOOGL, MSFT),合并数据并计算daily return:
apple['daily_return'] = apple['4. close'].pct_change()
查看每日收益率的直方图分布:
三、训练日收益率预测模型(LSTM)
模型结构:
- 输入:滑动时间窗口(20天)
- 网络结构:2层 LSTM + 全连接输出层
- 损失函数:MSE
- 优化器:Adam
model.add(LSTM(units=50, return_sequences=True)) model.add(LSTM(units=50)) model.add(Dense(units=1))
训练损失下降过程:
Epoch 1/50 93/93 [==============================] - 2s 13ms/step - loss: 0.0028 - val_loss: 0.0013 ... Epoch 50/50 93/93 [==============================] - 1s 9ms/step - loss: 0.0012 - val_loss: 4.6233e-04
四、模型评估指标
参考论文建议,评估指标从传统RMSE扩展到 ROI, D-return, VaR, Sharpe Ratio 等:
ROI(算法) | 126.48% | 模型策略收益远超买入持有策略(-0.94%) |
D-return Ratio | 135.59 | 显著优于基准 |
年化收益率 | 30.74% | 年度化超额回报 |
Sharpe Ratio | 12.45 | 单位风险下回报能力极强 |
最大回撤 | 0.78% | 模型表现稳定 |
Calmar Ratio | 3934.65 | 非常高的风险调整收益能力 |
五、结论与下一步
LSTM 模型展示了极强的收益预测能力,适用于策略开发和智能投顾场景。下一阶段将进行策略部署与实盘测试。