4、数据获取与清洗:数据源选择与处理

做量化投资,数据就是你的弹药。弹药不行,枪法再好也白搭。我见过太多人,策略逻辑写得天花乱坠,结果一跑回测,发现数据全是坑。今天咱们就聊聊数据获取与清洗这档子事。

核心观点:数据质量决定了策略收益的上限,模型只是去逼近这个上限。数据脏,模型再牛也白搭。

4.1 数据源选择:Wind、Tushare、聚宽

选数据源,说白了就是选「靠谱程度」和「成本」的平衡。我这些年三个都用过,各有各的脾气。

数据源 优势 劣势 适合场景
Wind 数据最全、最权威,机构标配 贵,一年几万起步,个人扛不住 机构实盘、专业研究
Tushare 免费/低价,社区活跃,接口灵活 数据偶尔延迟,稳定性一般 个人研究、策略回测
聚宽 自带回测平台,数据与策略无缝衔接 数据范围有限,深度不够 快速原型、入门学习

我个人习惯:研究阶段用Tushare,便宜又灵活。真要上实盘了,必须上Wind。为什么?因为Wind的数据有完整的复权因子和公司行为记录,这些细节在回测时能要了你的命。

小技巧:如果你用Tushare,建议每天定时拉数据存到本地数据库。别问我为什么——有一次Tushare接口挂了整整两天,我当时的策略正好在调参,差点被坑死。

4.2 数据清洗常见问题

数据拿到手,别急着跑模型。先看看有没有「脏东西」。我总结了三类最常见的问题:

4.2.1 缺失值处理

缺失值,说白了就是某一天的数据没了。为什么会这样?停牌、节假日、数据源漏了,原因很多。

我的处理原则:

  • 停牌日:用前一日收盘价填充,但要注意复权处理
  • 节假日:直接删除,别用插值,会引入未来信息
  • 数据源漏了:用行业均值填充,或者直接丢弃该股票

避坑指南:我曾经在回测时用了线性插值填充缺失值,结果策略收益曲线漂亮得不行。后来发现,插值把未来几天的信息「泄露」到了历史数据里。嗯,那叫一个惨。记住:回测数据绝对不能引入未来信息。

4.2.2 异常值处理

异常值,就是那些明显不合理的数据。比如某只股票一天涨了1000%,或者成交量突然变成0。

怎么发现?

  • 用3σ原则:超过均值±3倍标准差的数据,标记出来
  • 用IQR方法:四分位距法,更稳健
  • 看涨跌停板:A股有±10%限制,超过的肯定是错的

怎么处理?

  • 如果是数据录入错误,直接删除
  • 如果是真实事件(比如新股上市首日),保留但单独标记
  • 我建议:先可视化,看看异常值分布,再决定怎么处理

个人经验:有一次我发现某只股票连续三天涨了30%,以为是数据错了。查了半天,原来是这家公司被借壳上市了。所以,异常值不一定是错误,也可能是你没理解市场发生了什么。

4.2.3 复权处理

复权,这是新手最容易踩的坑。说白了,股票分红、送股、配股之后,股价会「跳空」。不复权的话,你的回测就是扯淡。

三种复权方式:

类型 说明 适用场景
前复权 调整历史价格,让价格连续 技术分析、趋势跟踪
后复权 调整当前价格,保持历史不变 计算真实收益率
不复权 原始价格,有跳空 事件驱动策略

我建议:做回测用前复权,计算收益用后复权。千万别混用,否则你的夏普比率会变成笑话。

避坑指南:我曾经用Wind拉数据,默认是前复权。结果我拿这个数据去算分红收益率,算出来全是负数。为什么?因为前复权把分红从历史价格里扣掉了。你想想看,这能对吗?

4.3 数据对齐

数据对齐,就是把不同频率、不同来源的数据,对齐到同一个时间轴上。这一步做不好,你的策略就是「鸡同鸭讲」。

常见对齐场景:

  • 日频数据对齐:不同股票的交易日期可能不一样(比如A股和港股),需要找到共同交易日
  • 高频数据对齐:不同交易所的撮合时间不同,需要精确到毫秒
  • 财务数据对齐:财报发布日期和实际数据日期不同,要用「实际可用日期」

我的对齐方法:

# 伪代码示例
def align_data(df_list, method='inner'):
    """
    method: 'inner' 取交集, 'outer' 取并集
    """
    common_dates = None
    for df in df_list:
        if common_dates is None:
            common_dates = set(df.index)
        else:
            if method == 'inner':
                common_dates = common_dates & set(df.index)
            else:
                common_dates = common_dates | set(df.index)
    
    aligned_dfs = [df.loc[sorted(common_dates)] for df in df_list]
    return aligned_dfs

小技巧:对齐时一定要用「实际可用日期」,而不是「数据日期」。比如财报数据,虽然Q1结束是3月31日,但实际发布可能是4月20日。如果你用3月31日对齐,那就引入了未来信息。我吃过这个亏,真的。

4.4 本章知识体系

下面这张图,是我梳理的数据获取与清洗的核心逻辑。你照着这个流程走,基本不会出大问题。

数据获取与清洗核心流程 数据源选择 数据获取 数据清洗 缺失值处理 异常值处理 复权处理 数据对齐 干净、对齐的数据集 注意:每一步都可能出现数据质量问题,需要反复迭代清洗

这张图看着简单,但每一步都有坑。我做了这么多年,每次拿到新数据,还是得老老实实走一遍这个流程。别嫌麻烦,数据干净了,后面的工作才能安心。

最后说一句:数据获取与清洗,占了我整个量化工作量的60%以上。别想着跳过,也别想着用「高级模型」来弥补数据问题。数据不行,一切都是空中楼阁。

专注资料整理