数据源与API:获取行业指数数据

做行业轮动分析,第一步就是搞数据。没有数据,再牛的模型也是空中楼阁。

我个人习惯把数据源分成三类:行情数据、宏观数据、另类数据。今天咱们重点聊前两个。

一、三大主流数据源

国内做量化,绕不开这三个平台。我一个个说。

1. Tushare

Tushare 是个人开发者用得最多的免费数据源。它覆盖了股票、基金、期货、宏观等全品类数据。

优点:文档清晰,社区活跃,免费额度够用。

缺点:积分制,高频数据需要付费。另外,接口偶尔会挂。

我在项目中遇到过 Tushare 凌晨数据更新延迟的情况。嗯,建议把数据抓取任务安排在早上8点以后。

核心接口示例:获取申万一级行业指数日线数据

import tushare as ts

# 初始化(需要你的token)
pro = ts.pro_api('your_token_here')

# 获取申万一级行业指数(2024年数据)
df = pro.index_daily(
    ts_code='801010.SI',  # 申万农林牧渔
    start_date='20240101',
    end_date='20241231',
    fields='trade_date,open,high,low,close,vol'
)

print(df.head())

2. Wind(万得)

Wind 是机构标配。数据质量高,更新及时,但贵。一年几万块的终端费,个人用户基本用不起。

我建议:如果你在机构工作,优先用 Wind。数据清洗的工作量能少一半。

小技巧:Wind 的 Python 接口叫 WindPy,安装后需要先启动 Wind 客户端才能调用。

from WindPy import w

w.start()

# 获取行业指数行情
data = w.wsd(
    "801010.SI",           # 申万农林牧渔
    "open,high,low,close,volume",
    "2024-01-01",
    "2024-12-31",
    "PriceAdj=F"           # 不复权
)

print(data.Data)

3. 东方财富(AkShare)

东方财富的数据可以通过 AkShare 库获取。免费,接口丰富,但文档有点乱。

说白了,AkShare 就是爬虫封装。它把东方财富网页上的数据扒下来,整理成 DataFrame。

import akshare as ak

# 获取申万一级行业指数
df = ak.sw_index_daily(
    index_code="801010",   # 农林牧渔
    start_date="20240101",
    end_date="20241231"
)

print(df.head())

注意:AkShare 依赖网络请求,如果东方财富改版,接口可能会失效。建议做好异常处理。

二、宏观经济数据获取

行业轮动离不开宏观背景。利率、CPI、PMI、社融数据,这些都是驱动因子。

我个人习惯用 Tushare 的宏观接口,数据全,更新快。

# 获取GDP数据
df_gdp = pro.cn_gdp(
    start_q='20200101',
    end_q='20241231',
    fields='quarter,gdp,gdp_yoy'
)

# 获取CPI数据
df_cpi = pro.cn_cpi(
    start_m='202001',
    end_m='202412',
    fields='month,cpi,cpi_yoy'
)

print(df_gdp.head())
print(df_cpi.head())

你想想看,如果宏观数据滞后两个月,你的行业轮动模型还能准吗?所以数据时效性很重要。

三、数据清洗与预处理

数据拿到手,别急着用。80%的时间其实花在清洗上。

我曾经因为没处理缺失值,导致回测结果异常漂亮——后来发现是数据断层了。嗯,血的教训。

1. 缺失值处理

import pandas as pd
import numpy as np

# 检查缺失值
print(df.isnull().sum())

# 方法一:向前填充(行业指数常用)
df['close'] = df['close'].fillna(method='ffill')

# 方法二:删除缺失行(慎用)
df = df.dropna(subset=['close'])

2. 异常值处理

行业指数很少出现极端异常,但个股数据经常有。我一般用3倍标准差法。

# 3倍标准差法剔除异常
mean = df['close'].mean()
std = df['close'].std()
df = df[(df['close'] > mean - 3*std) & (df['close'] < mean + 3*std)]

3. 日期对齐

不同数据源的日期可能不一致。比如 Tushare 用 '20240101',Wind 用 '2024-01-01'。统一格式是第一步。

# 统一日期格式
df['trade_date'] = pd.to_datetime(df['trade_date'], format='%Y%m%d')
df = df.sort_values('trade_date').reset_index(drop=True)

4. 行业分类映射

行业轮动需要把股票映射到行业。申万一级行业有31个,代码从801010到801890。

行业代码 行业名称
801010 农林牧渔
801020 采掘
801030 化工
... ...
801890 综合

建议:把行业映射表存成 CSV,每次直接读取,别硬编码。

四、知识体系总览

下面这张图,是我做数据获取时的完整流程。你看一眼就明白了。

数据获取与清洗流程 Tushare Wind 东方财富 数据获取:行情数据 + 宏观数据 数据清洗:缺失值 → 异常值 → 日期对齐 → 行业映射 输出:干净、对齐的行业指数DataFrame

五、避坑指南

最后,分享几个我踩过的坑。

  • 数据频率不一致:行业指数是日频,宏观数据可能是月频。合并时注意对齐。
  • 复权问题:行业指数一般用不复权数据。个股做回测时,记得用后复权。
  • 接口限流:Tushare 免费版每分钟最多200次请求。批量获取时,加个 time.sleep(0.5)。
  • 数据缓存:每次跑策略都重新拉数据,太慢了。我习惯把原始数据存成 parquet 格式,每天增量更新。

核心原则:数据质量决定策略上限。花80%时间在数据上,20%时间建模,这是值得的。


专注资料整理