第二章:金融数据基础——获取股票/加密货币历史数据
各位同学,欢迎来到实战课的第二站。这一章我们聊点实在的——数据从哪来,怎么洗干净,怎么算收益率。
说实话,很多做量化的人,模型写得天花乱坠,结果数据源就有问题。我见过最离谱的,有人用错了复权方式,回测曲线漂亮得不行,实盘直接崩了。嗯,咱们别犯这种错。
2.1 数据获取:Yahoo Finance API 实战
我个人习惯用 yfinance 这个库。它封装了 Yahoo Finance 的接口,用起来很顺手。你想想看,几行代码就能拿到几十年的股票数据,多方便。
核心要点:yfinance 返回的是 pandas DataFrame,天然适合做时间序列分析。
import yfinance as yf
import pandas as pd
# 获取苹果公司股票数据
ticker = "AAPL"
data = yf.download(ticker, start="2020-01-01", end="2023-12-31")
print(data.head())
我在项目中遇到过一个问题:Yahoo Finance 对加密货币的支持不太稳定。比如比特币的代码是 BTC-USD,但有时候会返回空数据。我的建议是,多准备几个数据源做备份。
小技巧:可以用 yf.Ticker("AAPL").info 查看股票的基本信息,比如市值、市盈率等。
2.2 数据清洗与预处理
原始数据通常很脏。缺失值、异常值、非交易日的空行……这些都得处理。我曾经因为没处理缺失值,导致强化学习模型在训练时直接报错,排查了半天。
清洗步骤我一般这么来:
- 检查缺失值——用
isnull().sum()看一眼 - 填充或删除——金融数据我倾向于前向填充(ffill)
- 去重——同一个交易日出现两次,肯定有问题
- 排序——确保时间索引是升序
# 数据清洗示例
data = data.dropna() # 删除缺失值
data = data[~data.index.duplicated(keep='first')] # 去重
data = data.sort_index() # 排序
注意:千万别用 dropna() 直接删所有行。如果某列缺失太多,你会丢掉大量有效数据。我建议先看看缺失比例,再决定怎么处理。
2.3 收益率计算与可视化
收益率是量化的基石。说白了,我们做强化学习,目标就是最大化累计收益率。计算方式有两种:
| 收益率类型 | 公式 | 适用场景 |
|---|---|---|
| 简单收益率 | (P_t - P_{t-1}) / P_{t-1} | 日常分析、可视化 |
| 对数收益率 | ln(P_t / P_{t-1}) | 统计建模、强化学习 |
我个人偏爱对数收益率。为什么?因为它具有可加性,而且分布更接近正态。你想想看,强化学习的奖励函数如果用简单收益率,累计起来会很麻烦。
# 计算对数收益率
data['log_return'] = np.log(data['Close'] / data['Close'].shift(1))
# 可视化
import matplotlib.pyplot as plt
data['log_return'].hist(bins=50, figsize=(10, 6))
plt.title('对数收益率分布')
plt.show()
嗯,这里要注意:收益率计算时,第一行会是 NaN,记得用 dropna() 去掉。
2.4 本章知识体系
下面这张图,是我自己总结的数据处理流程。你照着走,基本不会出错。
这张图把整个流程串起来了。你从左边开始,一步步走到右边,数据就准备好了。我当年刚开始做的时候,经常跳过清洗步骤,结果模型训练出来全是噪音。后来学乖了,老老实实每一步都走一遍。
避坑指南:我曾经在收益率计算时,忘了处理除权除息日。结果那天的收益率异常大,模型以为发现了什么规律,疯狂加仓……嗯,后果你懂的。记得用复权价格。
好了,这一章的内容就这些。数据准备好了,下一章我们就能开始搭建强化学习环境了。