2、数据获取入门:使用Tushare/Akshare获取沪深两市日度资金流向数据
做量化投资,数据就是你的弹药库。
没有数据,再牛的策略也是纸上谈兵。我个人习惯把数据获取比作「做饭前的买菜」——菜买不好,厨艺再高也白搭。今天咱们就聊聊怎么用 Python 把沪深两市的资金流向数据「买」回来。
2.1 为什么选 Tushare 和 Akshare?
市面上能拿 A 股数据的库不少,但我最常用的就这俩。原因很简单:
- Tushare:老牌、稳定、数据全。我 2018 年入行时就在用,社区活跃,文档也还算清晰。不过现在部分接口需要积分,门槛稍微高了点。
- Akshare:开源、免费、更新快。说白了就是「穷人的 Tushare」。它直接从各大财经网站爬数据,接口经常变,但胜在零成本。
嗯,这里要注意:两个库的数据源不同,同一只股票同一天的资金流向数据可能会有细微差异。我在项目中遇到过这种情况,后来统一用 Tushare 做主力,Akshare 做备选校验。
2.2 环境准备与安装
先把工具装上。打开你的终端,敲下面两行:
pip install tushare
pip install akshare
如果你用的是 Anaconda,建议先建个虚拟环境。我曾经因为依赖冲突折腾了一下午,后来学乖了:
conda create -n fund_flow python=3.9
conda activate fund_flow
pip install tushare akshare pandas
import tushare as ts
ts.set_token('你的token')
pro = ts.pro_api()
2.3 用 Tushare 获取资金流向数据
Tushare 的资金流向接口叫 moneyflow。它返回的是个股级别的日度数据,包含主力净流入、超大单、大单、中单、小单等字段。
看代码:
import tushare as ts
import pandas as pd
# 初始化
pro = ts.pro_api()
# 获取贵州茅台 2024年1月 的资金流向
df = pro.moneyflow(
ts_code='600519.SH',
start_date='20240101',
end_date='20240131'
)
print(df.head())
返回的数据长这样:
| ts_code | trade_date | buy_sm_vol | buy_md_vol | buy_lg_vol | buy_elg_vol | net_mf_vol |
|---|---|---|---|---|---|---|
| 600519.SH | 20240131 | 123456 | 234567 | 345678 | 456789 | 1234567 |
字段说明:
buy_sm_vol:小单买入量(手)buy_md_vol:中单买入量buy_lg_vol:大单买入量buy_elg_vol:超大单买入量net_mf_vol:主力净流入量(手)
moneyflow 接口需要至少 200 积分才能调用。如果你积分不够,会报错「权限不足」。我曾经因为这个被卡了两天,后来老老实实充了会员。
2.4 用 Akshare 获取资金流向数据
如果你不想花钱,Akshare 是绝佳替代。它的接口叫 stock_individual_fund_flow,用法更直接:
import akshare as ak
# 获取贵州茅台 2024年1月 的资金流向
df = ak.stock_individual_fund_flow(
stock='600519',
market='sh',
start_date='20240101',
end_date='20240131'
)
print(df.head())
返回的数据结构略有不同:
| 日期 | 主力净流入 | 小单净流入 | 中单净流入 | 大单净流入 | 超大单净流入 |
|---|---|---|---|---|---|
| 2024-01-31 | 1.23亿 | -0.45亿 | -0.78亿 | 0.89亿 | 0.34亿 |
你想想看,Akshare 的数据是直接从东方财富网爬的,所以字段名和 Tushare 不一样。但核心逻辑一致——主力净流入 = 超大单净流入 + 大单净流入。
2.5 核心逻辑:资金流向的计算方式
搞懂数据怎么来的,比拿到数据更重要。资金流向的计算其实不复杂:
- 把每一笔交易按金额大小分成四类:超大单(≥100万)、大单(20万-100万)、中单(4万-20万)、小单(≤4万)
- 计算每类的买入金额和卖出金额
- 净流入 = 买入金额 - 卖出金额
- 主力净流入 = 超大单净流入 + 大单净流入
说白了,主力资金就是「大钱」的动向。散户看小单,机构看大单,这就是核心逻辑。
主力净流入 = 超大单净流入 + 大单净流入
如果主力净流入 > 0,说明大资金在买入,短期看涨概率大。
2.6 实战:批量获取全市场资金流向
单只股票的数据不够用。我建议你一次性拉全市场的,然后筛选。下面是我常用的批量获取脚本:
import tushare as ts
import pandas as pd
from datetime import datetime, timedelta
pro = ts.pro_api()
# 获取所有A股列表
stock_list = pro.stock_basic(
exchange='',
list_status='L',
fields='ts_code'
)
# 获取昨天日期
yesterday = (datetime.now() - timedelta(days=1)).strftime('%Y%m%d')
# 批量获取资金流向
all_data = []
for code in stock_list['ts_code'].head(50): # 先试50只
try:
df = pro.moneyflow(
ts_code=code,
start_date=yesterday,
end_date=yesterday
)
if not df.empty:
all_data.append(df)
except:
continue
# 合并数据
result = pd.concat(all_data, ignore_index=True)
print(result.head())
time.sleep(0.5) 控制频率。
2.7 数据清洗与存储
拿到的数据通常需要清洗。我一般做三步:
- 去空值:有些股票当天没有交易,数据是空的,直接删掉
- 类型转换:把字符串日期转成 datetime,方便后续分析
- 计算衍生指标:比如「主力净流入占比 = 主力净流入 / 成交额」
代码示例:
# 清洗函数
def clean_fund_flow(df):
# 去空
df = df.dropna(subset=['net_mf_vol'])
# 日期转换
df['trade_date'] = pd.to_datetime(df['trade_date'])
# 计算占比
df['net_mf_ratio'] = df['net_mf_vol'] / df['amount']
return df
result_clean = clean_fund_flow(result)
存储的话,我习惯存 CSV 或直接入 MySQL。小规模用 CSV 就够了:
result_clean.to_csv('fund_flow_20240131.csv', index=False)
2.8 本章知识体系
下面这张图帮你理清本章的核心逻辑:
2.9 常见问题与避坑
- 数据对不上? 不同平台的数据源不同,差异正常。我一般以 Tushare 为准,Akshare 做交叉验证。
- 接口报错? 检查 token 是否过期,或者网络是否稳定。Akshare 偶尔会因网站改版而失效,关注 GitHub 更新。
- 速度太慢? 用多线程或异步请求。但注意别被封 IP。
好了,数据获取这块就聊到这儿。工具只是手段,理解数据背后的逻辑才是关键。下一章咱们聊聊怎么把这些数据变成真正的交易信号。
公众号:蓝海资料掘金营,微信deep3321