第一章:课程导论与数据准备
各位同学,欢迎来到《多因子时序预测模型实战训练营》。我是你们这趟旅程的向导,一个在量化领域摸爬滚打了七八年的老工程师。今天咱们开篇,不讲虚的,直接上手干活。
多因子时序预测,说白了就是:用一堆历史数据,去猜未来。你想想看,股票价格、天气变化、商品销量,本质上都是时间序列。而多因子,就是咱们找来的各种“线索”——成交量、市盈率、新闻情绪、甚至天气数据。把这些线索组合起来,预测未来走势。
我个人习惯,学任何新东西,先把环境搭好,把数据搞到手。这就好比做饭,你得先有厨房和食材。今天这一章,咱们就干这三件事:搭环境、拿数据、洗数据。
本章核心目标:让你能在自己的电脑上,跑通第一个数据获取和清洗的脚本。别小看这一步,我见过太多人卡在环境配置上,一卡就是半天。
1.1 多因子时序预测概述
先聊聊概念。时序预测,就是根据过去一段时间的数据,预测未来某个点的值。比如用过去30天的股价,预测明天的收盘价。多因子呢,就是不止看价格本身,还要看成交量、MACD指标、市场情绪等等。
为什么要用多因子?单看价格,就像盲人摸象。我记得2018年做CTA策略时,只用了价格动量,结果遇到震荡行情,回撤大得吓人。后来加入了波动率因子和持仓量因子,效果立马不一样了。说白了,多因子就是给模型装上“多双眼睛”。
常见的因子类型
| 因子类别 | 举例 | 数据来源 |
|---|---|---|
| 价格因子 | 收盘价、最高价、最低价 | Tushare / Yfinance |
| 成交量因子 | 成交量、成交额、换手率 | Tushare / Yfinance |
| 技术指标因子 | MACD、RSI、布林带 | 通过价格计算得到 |
| 基本面因子 | 市盈率、市净率、ROE | Tushare 财务数据 |
| 另类数据因子 | 新闻情绪、搜索热度 | 爬虫 / API |
我的经验:刚开始做多因子模型,别贪多。3-5个核心因子就够了。我曾经一口气加了20个因子,结果模型过拟合得一塌糊涂。记住,少即是多。
1.2 环境配置
好,咱们开始动手。环境配置这块,我推荐用 Anaconda。为什么?因为它把 Python、常用库、Jupyter Notebook 都打包好了,省心。
第一步:安装 Anaconda
去 Anaconda 官网下载对应系统的安装包。我建议下载 Python 3.9 或 3.10 版本,太新的版本有些库可能不兼容。安装时一路默认就行,但记得勾选“Add Anaconda to my PATH environment variable”。
注意:Windows 用户安装时,如果遇到“是否添加环境变量”的选项,一定要勾上。不然后面在命令行里找不到 conda 命令,你会很崩溃。我曾经帮一个学员远程调试,就因为这个卡了半小时。
第二步:创建虚拟环境
我个人习惯,每个项目建一个独立的虚拟环境。这样不同项目的依赖不会打架。
# 打开终端(Windows 用 Anaconda Prompt)
conda create -n quant_env python=3.9
# 激活环境
conda activate quant_env
# 安装核心库
pip install pandas numpy matplotlib seaborn scikit-learn
# 安装 Jupyter
conda install jupyter
# 启动 Jupyter
jupyter notebook
看到浏览器弹出 Jupyter 界面,就说明环境搭好了。嗯,这里要注意,如果浏览器没自动弹出,把终端里显示的 URL 复制到浏览器打开就行。
第三步:安装金融数据库
# 安装 Tushare(国内股票数据)
pip install tushare
# 安装 Yfinance(美股数据)
pip install yfinance
小技巧:安装时如果速度慢,可以加国内镜像源:pip install tushare -i https://pypi.tuna.tsinghua.edu.cn/simple
1.3 数据获取
环境搭好了,咱们来拿数据。我主要用两个数据源:Tushare 拿 A 股数据,Yfinance 拿美股数据。
使用 Tushare 获取 A 股数据
Tushare 需要注册获取 token。去 tushare.pro 注册,然后在个人中心找到 token。
import tushare as ts
# 设置 token(换成你自己的)
ts.set_token('你的token_here')
# 初始化接口
pro = ts.pro_api()
# 获取贵州茅台(600519.SH)2023年的日线数据
df = pro.daily(
ts_code='600519.SH',
start_date='20230101',
end_date='20231231'
)
# 查看数据
print(df.head())
跑完这段代码,你会看到类似这样的输出:
ts_code trade_date open high low close pre_close change pct_chg vol amount
0 600519.SH 20231229 1720 1735 1710 1728 1715 13.0 0.76 2.5 43200
1 600519.SH 20231228 1700 1725 1695 1715 1690 25.0 1.48 3.1 52800
...
关键点:Tushare 返回的数据是按日期降序排列的,最新的在最上面。做时序预测时,记得按日期升序排列:df = df.sort_values('trade_date')
使用 Yfinance 获取美股数据
import yfinance as yf
# 获取苹果(AAPL)2023年的日线数据
aapl = yf.download('AAPL', start='2023-01-01', end='2023-12-31')
# 查看数据
print(aapl.head())
Yfinance 返回的数据是 MultiIndex 列名,包含 Open、High、Low、Close、Volume、Adj Close。我个人习惯只保留 Close 和 Volume。
# 只保留收盘价和成交量
aapl_simple = aapl[['Close', 'Volume']]
aapl_simple.columns = ['close', 'volume']
1.4 数据清洗与预处理
拿到原始数据后,千万别直接扔进模型。真实数据里全是坑——缺失值、异常值、不同频率的数据怎么对齐?这些都是大问题。
我在项目中遇到过最典型的情况:某只股票因为停牌,中间缺了10天的数据。如果不处理,模型会以为这10天价格没变,预测结果直接崩掉。
处理缺失值
# 检查缺失值
print(df.isnull().sum())
# 方法1:向前填充(适合金融数据)
df.fillna(method='ffill', inplace=True)
# 方法2:线性插值
df.interpolate(method='linear', inplace=True)
# 方法3:删除缺失行(慎用,会破坏时间连续性)
df.dropna(inplace=True)
避坑指南:我曾经直接用 dropna 删除了缺失行,结果导致时间序列不连续,模型训练时出现了奇怪的跳跃。后来我改用向前填充,效果就好多了。金融数据里,缺失值用前一个交易日的数据填充,是最合理的做法。
处理异常值
异常值怎么判断?我常用 3-sigma 法则或 IQR 方法。
# 3-sigma 法则
mean = df['close'].mean()
std = df['close'].std()
df['close_zscore'] = (df['close'] - mean) / std
# 标记异常值(|z-score| > 3)
df['is_outlier'] = df['close_zscore'].abs() > 3
# 用中位数替换异常值
median = df['close'].median()
df.loc[df['is_outlier'], 'close'] = median
数据标准化
不同因子的量纲不一样,比如价格是几百块,成交量是几千万股。直接扔进模型,价格会主导训练过程。所以要做标准化。
from sklearn.preprocessing import StandardScaler
# 初始化标准化器
scaler = StandardScaler()
# 对收盘价和成交量做标准化
df[['close_scaled', 'volume_scaled']] = scaler.fit_transform(df[['close', 'volume']])
多因子数据对齐
如果你有多个数据源,比如价格数据来自 Tushare,基本面数据来自另一个接口,它们的日期可能不一致。这时候要对齐。
# 假设 price_df 和 fundamental_df 都有 date 列
# 以价格数据的日期为基准,左连接基本面数据
merged_df = price_df.merge(
fundamental_df,
on='date',
how='left'
)
# 对齐后,基本面数据缺失的日期用前向填充
merged_df.fillna(method='ffill', inplace=True)
我的习惯:数据对齐后,我会检查一下对齐后的数据长度。如果发现数据量少了很多,说明两个数据源的日期覆盖范围差异太大,需要重新考虑数据源的选择。
本章小结
好了,第一章的内容就到这里。咱们做了三件事:搭好了 Python 环境,学会了用 Tushare 和 Yfinance 拿数据,还掌握了数据清洗的基本方法。这些看起来基础,但基础不牢,地动山摇。
你想想看,如果数据都是脏的,模型再厉害也白搭。我见过太多人花90%的时间调模型,却只花10%的时间处理数据。结果模型上线后,因为数据质量问题,回测曲线漂亮得不行,实盘却亏得一塌糊涂。
下一章,咱们会深入特征工程,教你怎么从原始数据里挖出真正有用的因子。但今天,先把这些基础打扎实。去跑一遍代码,有问题随时在群里问我。