第二章:金融数据基础——获取股票/加密货币历史数据

各位同学,欢迎来到实战课的第二站。这一章我们聊点实在的——数据从哪来,怎么洗干净,怎么算收益率。

说实话,很多做量化的人,模型写得天花乱坠,结果数据源就有问题。我见过最离谱的,有人用错了复权方式,回测曲线漂亮得不行,实盘直接崩了。嗯,咱们别犯这种错。

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 数据清洗与预处理

原始数据通常很脏。缺失值、异常值、非交易日的空行……这些都得处理。我曾经因为没处理缺失值,导致强化学习模型在训练时直接报错,排查了半天。

清洗步骤我一般这么来:

  1. 检查缺失值——用 isnull().sum() 看一眼
  2. 填充或删除——金融数据我倾向于前向填充(ffill)
  3. 去重——同一个交易日出现两次,肯定有问题
  4. 排序——确保时间索引是升序
# 数据清洗示例
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 本章知识体系

下面这张图,是我自己总结的数据处理流程。你照着走,基本不会出错。

金融数据预处理流程 数据获取 Yahoo Finance API 数据清洗 缺失值·去重·排序 收益率计算 对数/简单收益率 可视化 关键注意事项 • 检查数据源稳定性,加密货币建议备用接口 • 缺失值处理:金融数据用前向填充(ffill) • 收益率计算:强化学习推荐对数收益率 • 可视化:分布图+时间序列图都要看

这张图把整个流程串起来了。你从左边开始,一步步走到右边,数据就准备好了。我当年刚开始做的时候,经常跳过清洗步骤,结果模型训练出来全是噪音。后来学乖了,老老实实每一步都走一遍。

避坑指南:我曾经在收益率计算时,忘了处理除权除息日。结果那天的收益率异常大,模型以为发现了什么规律,疯狂加仓……嗯,后果你懂的。记得用复权价格。

好了,这一章的内容就这些。数据准备好了,下一章我们就能开始搭建强化学习环境了。

蓝海数据掘金营,专注资料整理