第三章 因子数据获取:数据源选择与清洗

做因子投资,第一步就是搞数据。这步要是没做好,后面再牛的模型也是白搭。我见过太多人,策略回测漂亮得很,一上实盘就崩——十有八九是数据源头出了问题。

今天咱们就聊聊,数据到底从哪来,怎么拿,拿到手之后怎么处理。嗯,这里要注意,数据获取不是简单的“调个API就完事”,里面的坑多着呢。

3.1 数据源怎么选?

国内主流的数据源,我基本都用过。说白了,没有完美的数据源,只有最适合你的。

数据源 优势 劣势 适合人群
Wind 数据最全,财务数据清洗到位 贵,一年几万块 机构、专业团队
Tushare 免费版够用,社区活跃 积分限制,高频数据不全 个人研究者、学生
JoinQuant 回测平台自带数据,方便 导出受限,本地化麻烦 平台用户
AkShare 完全免费,接口丰富 稳定性一般,需自己清洗 预算有限的开发者
我的建议:如果你刚开始做研究,先用Tushare或AkShare跑通流程。等策略稳定了,再考虑上Wind。我个人习惯是Wind做主力,Tushare做备份。

3.2 股票行情数据获取

行情数据是最基础的。日线、分钟线、Tick级数据,需求不一样,获取方式也不同。

拿日线数据举例,用Tushare的话,代码很简单:

import tushare as ts

# 设置token
ts.set_token('你的token')

pro = ts.pro_api()

# 获取平安银行日线数据
df = pro.daily(ts_code='000001.SZ', 
               start_date='20230101', 
               end_date='20231231')

print(df.head())

这里有个坑——复权问题。我曾经在回测时直接用原始价格,结果分红除权后,策略信号全乱了。后来才意识到,因子计算必须用后复权价格。

避坑指南:我曾经因为忘记复权,导致一个年化20%的策略变成亏损。记住:因子计算用后复权,回测用前复权。

3.3 财务数据获取

财务数据比行情数据麻烦得多。为什么?因为财报有季节性,而且经常修正。

获取财务数据时,要注意几个关键点:

  • 财报发布日期 vs 财报期:要用实际可得的日期,而不是财报所属期
  • 数据修正:很多公司会修正前期财报,你得跟踪最新版本
  • 行业分类:不同行业的财务指标可比性差,需要标准化

举个例子,获取某股票的利润表:

# 获取利润表数据
income = pro.income(ts_code='000001.SZ', 
                    start_date='20230101',
                    end_date='20231231',
                    fields='ts_code,end_date,revenue,profit')

# 注意:这里拿到的end_date是财报截止日
# 实际可用日期要查公告日期
print(income.head())

核心要点:财务数据一定要做“前瞻性处理”。也就是说,你在回测时只能用当时已经公布的财报,不能用未来数据。这个错误我见过太多人犯了。

3.4 宏观经济数据获取

宏观数据对因子策略的影响,很多人低估了。GDP、CPI、PMI、利率,这些都会影响因子表现。

获取宏观数据,我推荐几个渠道:

  • 国家统计局:官方数据,最权威,但格式不友好
  • Wind宏观数据库:整理好了,直接调用
  • FRED(美联储):做全球策略必备

用Tushare获取宏观数据也很方便:

# 获取GDP数据
gdp = pro.cn_gdp(start_q='2020Q1', end_q='2023Q4')
print(gdp)

# 获取CPI数据
cpi = pro.cn_cpi(start_m='202301', end_m='202312')
print(cpi)

3.5 数据清洗与预处理

数据拿到手,别急着用。清洗这步,我一般花掉整个数据流程的60%时间。你想想看,脏数据进去,垃圾结果出来,多冤啊。

清洗的核心步骤:

  1. 缺失值处理:是填充还是删除?要看情况
  2. 异常值检测:3倍标准差?还是IQR方法?
  3. 数据对齐:不同频率的数据要对齐到同一时间轴
  4. 去极值:因子值太极端会影响后续分析

我常用的清洗代码:

import pandas as pd
import numpy as np

def clean_factor_data(df, factor_col):
    """因子数据清洗函数"""
    # 1. 删除全空的行
    df = df.dropna(subset=[factor_col], how='all')
    
    # 2. 去极值(MAD方法)
    median = df[factor_col].median()
    mad = np.abs(df[factor_col] - median).median()
    upper = median + 5 * mad
    lower = median - 5 * mad
    df[factor_col] = df[factor_col].clip(lower, upper)
    
    # 3. 标准化
    df[factor_col] = (df[factor_col] - df[factor_col].mean()) / df[factor_col].std()
    
    return df
小技巧:清洗时一定要保留原始数据副本。我习惯在列名上加个"_raw"后缀,这样出了问题还能追溯。

3.6 本章知识体系

下面这张图,是我自己总结的数据获取全流程。你照着这个框架走,基本不会漏掉关键环节。

因子数据获取全流程框架 数据源选择 Wind(机构首选) Tushare(个人) JoinQuant(平台) AkShare(免费) 数据类型获取 行情数据(日线/分钟) 财务数据(季报/年报) 宏观数据(GDP/CPI) 数据清洗与预处理 缺失值处理 异常值检测 数据对齐 去极值标准化

这张图把整个数据流程串起来了。从数据源选择,到具体数据类型获取,再到最后的清洗预处理,每一步都环环相扣。你按照这个框架来,至少能避开80%的坑。

最后说一句:数据获取没有捷径。我做了这么多年,最大的体会就是——花在数据上的时间,永远不会白费。你前期把数据搞扎实了,后面的因子分析、策略构建才能站得住脚。

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