共计 2115 个字符,预计需要花费 6 分钟才能阅读完成。
开篇:A 股数据源的现实挑战
做量化策略开发的朋友都知道,A 股数据源是个让人又爱又恨的存在。不同于美股成熟的数据生态,A 股市场的数据获取常常面临几个典型问题:

- 数据碎片化 :基础行情、财务数据、龙虎榜等分散在不同平台
- 更新延迟 :T+1 settlement(T+ 1 结算)机制下,部分数据次日才能获取
- 接口不稳定 :免费 API 经常调整访问规则,商业 API 又存在调用频率限制
这些问题如果不解决好,策略回测和实盘交易的效果可能会天差地别。下面我就结合自己的实战经验,分享几种主流解决方案。
技术方案对比
1. 免费方案:Tushare 与 AKShare
这两个是 Python 开发者最常用的免费库:
- Tushare Pro:
- 优势:数据齐全(包含历史行情、财务指标等),社区活跃
- 限制:需要积分换取调用权限,基础接口有 QPS 限制
- 破解思路:
- 注册多账号轮询
- 使用本地缓存减少重复请求
# Tushare Pro 基础调用示例
import tushare as ts
pro = ts.pro_api('your_token')
def get_daily(symbol, start_date, end_date):
try:
return pro.daily(ts_code=symbol, start_date=start_date, end_date=end_date)
except Exception as e:
print(f"Tushare 请求失败: {e}")
return None
- AKShare:
- 优势:完全免费,数据源直接对接交易所 / 券商官网
- 限制:接口稳定性依赖第三方网站的反爬策略
2. 商业方案:Wind vs 同花顺
当策略对数据实时性要求较高时,商业数据服务是更稳妥的选择:
| 对比维度 | Wind | 同花顺 i 问财 |
|---|---|---|
| 数据延迟 | 实时推送 | 3-15 秒延迟 |
| API 成本 | 年费 5 万 + | 按调用量计费 |
| 特色数据 | 宏观行业数据库 | 舆情情感分析 |
建议根据策略类型选择:
– 高频交易优先考虑 Wind
– 基本面分析可以选用 i 问财的财务因子库
3. 私有化部署方案
对机构用户,推荐自建数据中台架构:
- 数据采集层 :
- 使用 Docker 部署多个数据采集节点
-
通过 IP 代理池规避反爬
-
存储层 :
- 行情数据用 InfluxDB 时序数据库
-
基本面数据存 MySQL 关系库
-
服务层 :
- 用 FastAPI 提供统一数据接口
- 添加 JWT 鉴权控制访问权限
核心代码实现
多数据源 fallback 机制
这是保证数据连续性的关键设计:
class DataFetcher:
def __init__(self):
self.sources = [
self._fetch_tushare,
self._fetch_akshare,
self._fetch_backup_file
]
def get_daily_data(self, symbol, date):
"""尝试多个数据源直到成功"""
for source in self.sources:
data = source(symbol, date)
if data is not None and self._validate(data):
return data
raise Exception("所有数据源获取失败")
def _validate(self, df):
"""校验数据完整性"""
return not df.empty and len(df) > 100 # 示例校验逻辑
日 K 线数据处理
用 Pandas 处理常见的两个坑:
-
复权计算 :
def adjust_price(df, method='后复权'): """method: [' 前复权 ',' 后复权 '] 使用交易日收盘后公布的复权因子进行计算 """if method ==' 后复权 ': df['close'] = df['close'] * df['adj_factor'] / df['adj_factor'].iloc[-1] # 其他字段同理... return df -
时区统一 :
# 确保所有时间戳带时区信息 df['trade_date'] = pd.to_datetime(df['trade_date']).dt.tz_localize('Asia/Shanghai')
生产环境注意事项
1. 反爬策略应对
- 设置合理的请求间隔(建议≥500ms)
- 使用 Rotating User-Agent:
from fake_useragent import UserAgent headers = {'User-Agent': UserAgent().random}
2. 分钟级数据存储
建议采用 Parquet 列式存储 +Snappy 压缩,相比 CSV 可节省 70% 空间:
df.to_parquet('data.parquet', engine='pyarrow', compression='snappy')
3. 实时行情选型
| 技术 | 延迟 | 适用场景 |
|---|---|---|
| WebSocket | <1 秒 | 高频价格监控 |
| REST | 1- 3 秒 | 批量获取历史数据 |
开放问题讨论
财报数据有个经典难题:上市公司公告发布日期和实际数据可获取日期存在时间差。比如:
– 财报公告日:2023-04-30
– 数据商更新日:2023-05-03
这会导致回测出现未来函数(future leak)。我的临时解决方案是:
- 在回测中统一将财报数据生效日期延后 3 个交易日
- 建立财报日历数据库,记录每个数据的实际可用时间
大家有什么更好的处理方法?欢迎在评论区分享你的方案。
正文完
