第2章:数据源与采集:主流金融数据API(Tushare、AKShare)、数据清洗与预处理

做资金流向图分析,第一步不是写代码,而是找数据。

我见过太多人一上来就调包、画图,结果数据源选错了,后面全白干。说白了,数据质量决定了分析的天花板。这一章,我们就来聊聊怎么拿到靠谱的资金流向数据,以及拿到之后怎么处理成能用的样子。

2.1 主流金融数据API选型

国内做量化,绕不开两个库:Tushare 和 AKShare。我个人习惯两个都装,因为各有各的强项。

对比维度 Tushare Pro AKShare
数据覆盖 A股、基金、期货、宏观 A股、港股、美股、期货、外汇、宏观
资金流向 主力资金、北向资金(需积分) 主力资金、北向资金(免费)
调用方式 Token认证,按积分限频 无需Token,直接调用
数据质量 高,字段规范 中高,部分字段需自行清洗
适合场景 专业量化、回测 快速原型、多市场分析
我的建议:如果你做的是A股资金流向分析,优先用Tushare Pro。它的「moneyflow」接口字段非常完整,省去很多清洗工作。AKShare适合做跨市场对比,或者你不想注册账号的时候用。

2.2 Tushare实战:获取个股资金流向

先看Tushare怎么用。你需要先注册拿到token,然后安装库:

pip install tushare

代码示例:

import tushare as ts

# 设置token(记得换成你自己的)
ts.set_token('你的token')
pro = ts.pro_api()

# 获取贵州茅台2024年1月资金流向
df = pro.moneyflow(
    ts_code='600519.SH',
    start_date='20240101',
    end_date='20240131'
)

print(df.head())

返回的字段里,有几个关键指标:

  • buy_lg_amount:超大单买入金额
  • buy_elg_amount:大单买入金额
  • buy_sm_amount:小单买入金额
  • net_mf_amount:净流入金额(正数代表流入)
注意:我曾经踩过一个坑——Tushare的「净流入」是按「买入-卖出」计算的,但不同券商对「大单」的定义不一样。有的按金额阈值(比如100万),有的按成交量占比。所以做跨股票对比时,要确认口径一致。

2.3 AKShare实战:快速获取北向资金

AKShare的好处是免费,而且数据源直接来自东方财富。我经常用它来拉北向资金数据:

import akshare as ak

# 获取北向资金流入流出
df = ak.stock_hsgt_north_net_flow_in_em(symbol="沪股通")
print(df.tail())

这个接口返回的是每日累计净流入。如果你想看个股的北向资金持仓变化,可以用:

# 获取个股北向资金持股
df = ak.stock_hsgt_individual_em(
    market="沪股通",
    indicator="持股市值"
)
print(df.head())

嗯,这里要注意:AKShare的字段名是中文的,比如「持股数量」「持股市值」。做数据分析前,我习惯先统一转成英文列名,方便后续处理。

2.4 数据清洗与预处理

数据拿到手,别急着分析。我见过太多人直接拿原始数据画图,结果发现趋势线是反的——因为数据里有空值或者单位不一致。

清洗流程我总结为三步:

  1. 缺失值处理:资金流向数据偶尔会有空值,尤其是节假日前后。我一般用前向填充(ffill)或者直接删除。
  2. 数据类型转换:金额字段经常是字符串(比如"1.23亿"),需要转成数值。
  3. 异常值过滤:比如某天资金流入突然放大100倍,多半是数据错误,要剔除。

代码示例:

import pandas as pd

# 假设df是原始数据
# 1. 处理缺失值
df = df.dropna(subset=['net_mf_amount'])

# 2. 转换金额单位(从"亿"转为元)
def parse_amount(val):
    if isinstance(val, str):
        if '亿' in val:
            return float(val.replace('亿', '')) * 1e8
        elif '万' in val:
            return float(val.replace('万', '')) * 1e4
    return float(val)

df['net_mf_amount'] = df['net_mf_amount'].apply(parse_amount)

# 3. 过滤异常值(超过3倍标准差视为异常)
mean = df['net_mf_amount'].mean()
std = df['net_mf_amount'].std()
df = df[(df['net_mf_amount'] > mean - 3*std) & 
        (df['net_mf_amount'] < mean + 3*std)]
核心要点:资金流向数据最怕「幸存者偏差」。比如你只分析有数据的股票,但那些停牌或者数据缺失的股票可能才是关键。我建议清洗时记录一下删除了多少行,做到心里有数。

2.5 知识体系总览

下面这张图,是我做资金流向分析时脑子里始终绷着的一根弦。数据源、清洗、存储,每一步都影响最终结果:

资金流向数据采集与预处理流程 数据源层 Tushare / AKShare 清洗预处理层 缺失值 / 类型转换 / 异常过滤 存储层 DataFrame / CSV / DB 子流程详解 1. 数据源选择:根据分析目标选择Tushare(A股专业)或AKShare(多市场) 2. 字段映射:统一字段名(如 buy_lg_amount → large_buy) 3. 时间对齐:确保所有数据在同一时间频率(日/周/月) 4. 质量校验:检查数据完整性,记录清洗日志 图2-1 资金流向数据采集与预处理流程

2.6 避坑指南

最后分享几个我实战中遇到的坑:

  • 数据延迟:Tushare的日频数据一般在收盘后1-2小时更新。如果你在盘中调接口,拿到的是前一日数据。我曾经因为这个原因,在盘中策略里用错了数据,回测曲线漂亮,实盘一塌糊涂。
  • 复权问题:资金流向数据通常不复权。但如果你要结合价格做分析,记得用后复权价格。否则分红送股后,资金流向和价格对不上。
  • 接口限频:Tushare免费版每分钟只能调200次。批量拉数据时,我习惯加个time.sleep(0.5),避免被封。
小技巧:如果你需要长期保存数据,建议每天收盘后拉一次,存到本地CSV或SQLite。这样下次分析时直接读本地,又快又稳。我自己的数据库里,已经攒了3年的资金流向数据了。

好了,数据源和清洗这块就聊到这儿。记住一句话:好数据是好分析的前提。下一章我们会用这些数据,真正开始画资金流向图。


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