2、数据获取基础:使用Tushare/AkShare获取A股日线行情数据、数据清洗与预处理

做量化交易,第一步就是搞定数据。没有数据,再牛的策略也是空中楼阁。

我个人习惯把数据获取比作「做饭前的买菜」。菜不新鲜,或者买错了,后面炒菜再厉害也白搭。今天我们就聊聊怎么用 Python 把 A 股的日线行情数据「买」回来,再「洗」干净。

2.1 两大主流数据源:Tushare vs AkShare

国内做量化,绕不开这两个库。我当年刚入行时,数据源还靠手动下载 Excel,现在想想真是原始人。

对比项 Tushare AkShare
数据丰富度 非常全面,含财务、因子等 覆盖广,包含另类数据
使用门槛 需注册获取 token,部分接口收费 开源免费,pip install 即用
数据质量 较高,有专业团队维护 依赖爬虫,偶有异常值
适合场景 专业研究、实盘策略 快速原型、学习练手

说白了,如果你只是自己研究玩玩,AkShare 完全够用。但如果是做产品或者跑实盘,我建议用 Tushare Pro,数据更稳。

我的小建议:两个库可以搭配使用。Tushare 拿核心数据,AkShare 做补充验证。我在项目中就经常这样干,万一一个接口挂了,另一个还能顶上。

2.2 实战:用 Tushare 获取日线数据

先装库:pip install tushare。然后去官网注册,拿到你的 token。

import tushare as ts

# 初始化(token 换成你自己的)
pro = ts.pro_api('你的token')

# 获取平安银行 2024年1月 日线数据
df = pro.daily(
    ts_code='000001.SZ',
    start_date='20240101',
    end_date='20240131'
)

print(df.head())

输出长这样:

   ts_code trade_date  open  high   low  close  pre_close  change  pct_chg  vol  amount
0  000001.SZ   20240131  9.50  9.55  9.30   9.35       9.48   -0.13   -1.37  123456  1.17e+09
1  000001.SZ   20240130  9.60  9.65  9.45   9.48       9.58   -0.10   -1.04  98765  9.38e+08

嗯,这里要注意:Tushare 返回的字段名是英文的,vol 是成交量(手),amount 是成交额(元)。我刚开始做回测时,就搞混过单位,结果算出来的仓位全错了。

2.3 实战:用 AkShare 获取日线数据

AkShare 更简单,不用注册,直接装库就能用。

import akshare as ak

# 获取平安银行日线数据
df = ak.stock_zh_a_hist(
    symbol="000001",
    period="daily",
    start_date="20240101",
    end_date="20240131",
    adjust="qfq"  # 前复权
)

print(df.head())

输出字段是中文的,看着更亲切:

   日期    开盘    收盘    最高    最低    成交量    成交额    振幅    涨跌幅    涨跌额    换手率
0  2024-01-31  9.50  9.35  9.55  9.30  123456  1.17e+09  2.64  -1.37  -0.13  0.85
核心区别:Tushare 返回的是原始数据,需要你自己处理复权。AkShare 默认返回前复权数据,对回测更友好。我个人建议做策略回测时用前复权,做实时交易用后复权。

2.4 数据清洗:把脏数据洗干净

数据拿到手,别急着用。你想想看,网络波动、停牌、除权除息……各种情况都会导致数据异常。我曾经有一次回测跑出来年化 200%,兴奋得不行,结果发现是数据里混入了空值,算收益率时全乱了。

清洗步骤一般分三步:

  1. 处理缺失值——停牌日的数据通常是 NaN
  2. 处理异常值——比如某天涨幅超过 100% 这种明显错误
  3. 统一格式——日期转 datetime,数值转 float
import pandas as pd

# 假设 df 是从 Tushare 拿到的原始数据
df = df.sort_values('trade_date')  # 按日期排序

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

# 2. 填充或删除缺失值
# 停牌日:用前一天的收盘价填充
df['close'].fillna(method='ffill', inplace=True)

# 3. 处理异常值:涨幅超过 ±10% 的标记为异常
df['pct_chg'] = df['pct_chg'].astype(float)
df.loc[df['pct_chg'].abs() > 10, 'pct_chg'] = None

# 4. 日期统一
df['trade_date'] = pd.to_datetime(df['trade_date'])

print(df.info())
避坑指南:我曾经遇到过某只股票连续停牌一个月,复牌后直接跌停。如果用前向填充,那一个月的数据全是同一个价格,回测里看起来风平浪静,实盘直接爆仓。所以停牌超过 5 天的,我建议直接删除那段时间的数据。

2.5 数据预处理:为策略分析做准备

数据洗干净了,接下来就是「加工」环节。说白了,就是把原始数据变成能直接喂给策略的格式。

常用的预处理操作:

  • 计算收益率df['return'] = df['close'].pct_change()
  • 计算移动平均线df['ma5'] = df['close'].rolling(5).mean()
  • 计算成交量变化率df['vol_ratio'] = df['vol'] / df['vol'].shift(1)
  • 标记主力资金流向:结合大单数据(这个后面章节会细讲)
# 完整预处理示例
def preprocess_stock_data(df):
    """数据预处理函数"""
    # 排序
    df = df.sort_values('trade_date').reset_index(drop=True)
    
    # 计算收益率
    df['daily_return'] = df['close'].pct_change()
    
    # 计算均线
    df['ma5'] = df['close'].rolling(5).mean()
    df['ma20'] = df['close'].rolling(20).mean()
    
    # 计算成交量均线
    df['vol_ma5'] = df['vol'].rolling(5).mean()
    
    # 标记放量(成交量超过5日均量2倍)
    df['volume_surge'] = (df['vol'] > df['vol_ma5'] * 2).astype(int)
    
    return df

df_clean = preprocess_stock_data(df)
print(df_clean[['trade_date', 'close', 'daily_return', 'volume_surge']].tail())

2.6 本章知识体系总览

下面这张图,是我自己总结的数据获取与处理流程。每次做新项目,我都会先过一遍这个框架。

数据获取与处理流程 数据源选择 Tushare Pro AkShare 数据获取 日线行情 · 复权处理 · 多股票批量 数据清洗 缺失值处理 · 异常值过滤 · 格式统一 · 停牌处理 数据预处理 收益率计算 · 技术指标 · 成交量分析 · 主力资金标记
我的经验:数据清洗这一步,往往比写策略还花时间。我一般会写一个通用的清洗函数,把停牌处理、异常值过滤、复权计算都封装好。这样每次拿到新数据,跑一遍函数就行,省心。

好了,数据基础就聊到这儿。记住一句话:垃圾数据进,垃圾策略出。把数据搞扎实了,后面的分析才能站得住脚。


公众号:蓝海资料掘金营,微信deep3321