第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 数据清洗与预处理
数据拿到手,别急着分析。我见过太多人直接拿原始数据画图,结果发现趋势线是反的——因为数据里有空值或者单位不一致。
清洗流程我总结为三步:
- 缺失值处理:资金流向数据偶尔会有空值,尤其是节假日前后。我一般用前向填充(ffill)或者直接删除。
- 数据类型转换:金额字段经常是字符串(比如"1.23亿"),需要转成数值。
- 异常值过滤:比如某天资金流入突然放大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 知识体系总览
下面这张图,是我做资金流向分析时脑子里始终绷着的一根弦。数据源、清洗、存储,每一步都影响最终结果:
2.6 避坑指南
最后分享几个我实战中遇到的坑:
- 数据延迟:Tushare的日频数据一般在收盘后1-2小时更新。如果你在盘中调接口,拿到的是前一日数据。我曾经因为这个原因,在盘中策略里用错了数据,回测曲线漂亮,实盘一塌糊涂。
- 复权问题:资金流向数据通常不复权。但如果你要结合价格做分析,记得用后复权价格。否则分红送股后,资金流向和价格对不上。
- 接口限频:Tushare免费版每分钟只能调200次。批量拉数据时,我习惯加个time.sleep(0.5),避免被封。
小技巧:如果你需要长期保存数据,建议每天收盘后拉一次,存到本地CSV或SQLite。这样下次分析时直接读本地,又快又稳。我自己的数据库里,已经攒了3年的资金流向数据了。
好了,数据源和清洗这块就聊到这儿。记住一句话:好数据是好分析的前提。下一章我们会用这些数据,真正开始画资金流向图。
公众号:蓝海资料掘金营,微信deep3321