2、Python金融数据处理基础:Pandas库核心操作、NumPy数组运算、金融数据获取与清洗
说实话,做量化回测这么多年,我最大的体会就是——数据才是真正的老大。策略再牛,模型再花哨,数据一塌糊涂,结果就是垃圾进垃圾出。这一章,咱们就把金融数据处理的基础打扎实。
2.1 NumPy数组运算:量化计算的基石
NumPy这东西,说白了就是Python里的数学引擎。我刚开始做量化时,用纯Python列表算收益率,一个回测跑下来要半小时。后来换成NumPy,十几秒搞定。差距就这么大。
核心操作速览
| 操作 | 代码示例 | 说明 |
|---|---|---|
| 创建数组 | np.array([1,2,3]) |
从列表创建 |
| 向量化运算 | prices * 1.1 |
每个元素都乘1.1 |
| 统计函数 | np.mean(returns) |
计算均值 |
| 矩阵运算 | np.dot(A, B) |
矩阵乘法 |
重点记住:NumPy的向量化操作比Python循环快几十倍。能用数组运算就别写for循环。
import numpy as np
# 模拟股票价格序列
prices = np.array([100, 102, 101, 105, 108])
# 计算日收益率(向量化,一行搞定)
returns = np.diff(prices) / prices[:-1]
print("日收益率:", returns)
# 计算年化波动率
volatility = np.std(returns) * np.sqrt(252)
print("年化波动率:", round(volatility, 4))
我在项目中遇到过一个问题:用纯Python算5000只股票的协方差矩阵,跑了整整一个晚上。换成NumPy的np.cov(),3分钟出结果。嗯,这就是差距。
2.2 Pandas核心操作:时间序列的瑞士军刀
Pandas就是为金融数据而生的。它最牛的地方在于——天然支持时间序列索引。你想想看,股票数据、期货数据、宏观经济数据,哪个不是按时间排列的?
DataFrame基础操作
import pandas as pd
# 创建时间序列数据
dates = pd.date_range('2024-01-01', periods=5, freq='D')
data = {
'close': [100, 102, 101, 105, 108],
'volume': [10000, 12000, 9000, 15000, 11000]
}
df = pd.DataFrame(data, index=dates)
print(df.head())
常用操作一览
- 数据选取:
df['close']选列,df.loc['2024-01-03']选行 - 条件筛选:
df[df['volume'] > 10000] - 缺失值处理:
df.dropna()或df.fillna(method='ffill') - 滚动计算:
df['close'].rolling(window=5).mean()
我的习惯:拿到数据第一件事,先看df.info()和df.describe()。花30秒了解数据全貌,能避免后面踩很多坑。
2.3 金融数据获取:Tushare与Yahoo Finance
数据从哪来?国内用Tushare,国外用Yahoo Finance。这两个我都在用,各有千秋。
Tushare获取A股数据
import tushare as ts
# 设置token(需要去tushare官网注册)
ts.set_token('your_token_here')
pro = ts.pro_api()
# 获取贵州茅台日线数据
df = pro.daily(ts_code='600519.SH',
start_date='20240101',
end_date='20240131')
print(df.head())
注意:Tushare的免费版有调用频率限制,每分钟最多200次。我建议把数据存到本地,别每次都去拉。
Yahoo Finance获取美股数据
import yfinance as yf
# 获取苹果公司数据
aapl = yf.download('AAPL', start='2024-01-01', end='2024-01-31')
print(aapl.head())
我曾经犯过一个错:直接用Yahoo Finance拉A股数据,结果发现数据对不上。后来才明白,Yahoo Finance的A股数据延迟严重,而且复权处理有问题。所以我现在坚持:A股用Tushare,美股用Yahoo Finance。
2.4 数据清洗与预处理:80%的时间花在这
说实话,量化交易里最枯燥的就是数据清洗。但这一步做不好,后面全是白费。我见过太多人,策略写得很漂亮,结果因为数据里有几个空值,回测结果完全失真。
常见问题与处理
| 问题 | 处理方法 | 代码示例 |
|---|---|---|
| 缺失值 | 前向填充或插值 | df.fillna(method='ffill') |
| 异常值 | 3倍标准差剔除 | df[np.abs(df - df.mean()) <= 3*df.std()] |
| 重复数据 | 去重 | df.drop_duplicates() |
| 日期对齐 | 重采样 | df.resample('D').last() |
实战:完整的数据清洗流程
def clean_stock_data(df):
"""
我的标准清洗流程
"""
# 1. 去除全空的行
df = df.dropna(how='all')
# 2. 前向填充缺失值(用前一天的数据)
df = df.fillna(method='ffill')
# 3. 如果还有缺失,用后向填充
df = df.fillna(method='bfill')
# 4. 去除重复索引
df = df[~df.index.duplicated(keep='first')]
# 5. 排序索引(确保时间顺序)
df = df.sort_index()
return df
# 使用示例
clean_df = clean_stock_data(raw_df)
核心原则:数据清洗没有银弹。每只股票、每个市场都有自己的脾气。我的建议是——先可视化看看数据长什么样,再决定怎么清洗。
2.5 本章知识体系总览
下面这张图,是我自己总结的数据处理流程。每次做新项目,我都会先过一遍这个流程。
你看这个流程,其实就三步:拿数据 → 处理数据 → 用数据。但每一步都有坑。我刚开始做量化时,在数据清洗上栽过跟头——用错了填充方法,导致回测结果虚高。后来学乖了,每次清洗完都做一遍可视化检查。
避坑指南:我曾经因为没处理停牌数据,导致回测收益率虚高20%。记住:停牌日的价格是无效的,必须用前一天的收盘价填充,或者直接剔除。
好了,这一章的内容就这些。记住我说的:数据质量决定回测质量。把Pandas和NumPy练熟了,后面的路就好走了。