4. 数据获取与清洗
在金融数据分析Agent的完整链路中,数据获取与清洗是决定后续所有分析可信度的地基。无论Agent后续要做因子挖掘、组合回测还是风险监控,只要原始数据存在缺失、重复、口径不一致或复权错误,模型再强也会输出错误结论。本节聚焦三类主流数据接口——Tushare、AkShare、yfinance,讲清它们的定位差异、获取流程、清洗标准与常见陷阱。
一、核心原理:三类接口的定位与数据边界
金融数据接口的本质是“把交易所、数据商或公开网页上的原始记录,转换为结构化、可编程访问的数据对象”。不同接口的差异,主要体现在数据覆盖范围、授权方式、更新频率和字段规范上。
- Tushare:面向A股、基金、期货、宏观等中文市场,字段规范、积分制授权,适合需要稳定、标准化数据的生产场景。
- AkShare:开源免费,覆盖股票、基金、期货、债券、外汇及另类数据,接口数量多、更新快,适合快速验证与补充数据。
- yfinance:主要覆盖、港股、ETF、外汇与加密货币,基于Yahoo Finance,适合海外资产与跨市场对比。
三者并非互斥,而是互补。一个成熟的Agent通常以Tushare为主数据源,AkShare为补充源,yfinance为海外映射源,并在清洗层统一字段口径。
二、方法流程:从接口调用到标准化数据表
无论使用哪个接口,标准流程都可以归纳为五步:初始化连接、拉取原始数据、字段对齐、质量清洗、落地存储。下面以A股日线为例,展示Tushare与AkShare的典型调用方式。
# Tushare 获取A股日线
import tushare as ts
pro = ts.pro_api("你的")
df = pro.daily(ts_code="000001.SZ",
start_date="20240101",
end_date="20241231")
# AkShare 获取A股日线
import akshare as ak
df = ak.stock_zh_a_hist(symbol="000001",
period="daily",
start_date="20240101",
end_date="20241231",
adjust="qfq")
# yfinance 获取日线
import yfinance as yf
df = yf.download("AAPL", start="2024-01-01", end="2024-12-31")
拿到原始数据后,进入清洗环节。核心动作包括:统一列名、转换日期类型、处理缺失值与重复行、复权处理、时区对齐、异常值检测。建议将清洗逻辑封装为函数,保证不同数据源输出同一套字段结构。
def standardize(df, source):
df = df.rename(columns={
"trade_date": "date", "日期": "date",
"ts_code": "code", "股票代码": "code",
"vol": "volume", "成交量": "volume"
})
df["date"] = pd.to_datetime(df["date"])
df = df.drop_duplicates(subset=["date", "code"])
df = df.sort_values(["code", "date"]).reset_index(drop=True)
df["source"] = source
return df[["date","code","open","high","low","close","volume","source"]]
三、案例场景:多源数据合并与复权处理
假设Agent需要同时分析A股银行股与银行ETF的相关性。Tushare提供A股日线,yfinance提供ETF数据。两者日期格式、时区、复权方式均不同。此时需要先分别标准化,再按日期对齐,最后合并为宽表。
| 清洗维度 | Tushare | AkShare | yfinance |
|---|---|---|---|
| 日期字段 | trade_date(字符串) | 日期(字符串) | Date(索引) |
| 复权方式 | 需手动计算或使用adj_factor | adjust参数可选qfq/hfq | auto_adjust参数控制 |
| 缺失值 | 停牌日无记录 | 停牌日可能为空 | 非交易日无记录 |
| 时区 | 北京时间 | 北京时间 | 美东时间 |
| 字段命名 | 英文缩写 | 中文为主 | 英文标准 |
四、误区与复盘:常见陷阱与排查清单
实际项目中,数据问题往往不是“拿不到”,而是“拿到了但不可用”。以下是最常见的五类误区:
- 忽略停牌与退市:停牌日无数据,直接dropna会丢失交易日结构,建议用交易日历reindex后填充或标记。
- 混用复权口径:同一张表中部分股票前复权、部分不复权,导致收益率计算完全失真。
- 时区未对齐:与A股日期直接merge,会出现大量错配,需统一为UTC或分别对齐交易日。
- 字段类型错误:成交量、成交额被读成字符串,参与计算时静默出错。
- 接口限流与重试:Tushare有积分与频率限制,AkShare依赖网页结构,需加缓存与重试机制。
建议在Agent中内置一张数据质量检查表,每次拉取后自动执行:行数是否合理、日期是否连续、价格是否为正、成交量是否非负、涨跌幅是否超过阈值。只有通过检查的数据才进入下游分析。
def quality_check(df):
assert df["close"].gt(0).all(), "存在非正价格"
assert df["volume"].ge(0).all(), "存在负成交量"
assert df["date"].is_monotonic_increasing, "日期未排序"
assert df["code"].nunique() > 0, "无有效代码"
return True
把获取与清洗做成可复用、可审计、可扩展的模块,Agent才能在面对股票、基金、期货等多品种时保持稳定输出。数据层越干净,上层分析越可信,这也是金融数据分析Agent区别于普通脚本的关键工程能力。