第二章:数据获取基础——用Tushare/Akshare搞定A股行情、北向资金与两融数据
做量化交易,第一步不是写策略,而是搞定数据。我见过太多人把精力花在策略模型上,结果数据源一塌糊涂,回测跑出来全是幻觉。说白了,数据是量化交易的「米」,没有米,再好的厨子也做不出饭。
这一章,我带你手把手把A股行情数据、北向资金数据、两融数据拿下来。我们用两个国内最主流的Python库——Tushare和Akshare。我个人习惯是:Tushare做深度分析,Akshare做快速验证。两者互补,基本覆盖了90%的量化数据需求。
2.1 环境准备与库安装
先装好工具。打开你的终端,跑下面这几行:
pip install tushare
pip install akshare
pip install pandas
pip install matplotlib
嗯,这里要注意:Tushare需要注册获取token。去官网(tushare.pro)注册一下,在个人主页找到token。我当初第一次用的时候,忘了配置token,卡了半天,后来才发现是这步没做。
import tushare as ts
import akshare as ak
import pandas as pd
# 设置Tushare token(换成你自己的)
ts.set_token('你的token')
pro = ts.pro_api()
2.2 获取A股行情数据
行情数据是基础中的基础。日线、分钟线、复权数据,一个都不能少。我一般先用Tushare拉日线,因为它的数据质量高,字段全。
2.2.1 日线行情(Tushare)
# 获取平安银行(000001.SZ)2024年1月日线数据
df_daily = pro.daily(
ts_code='000001.SZ',
start_date='20240101',
end_date='20240131'
)
print(df_daily.head())
返回的字段包括:trade_date、open、high、low、close、vol、amount。注意,这里的vol单位是手(1手=100股),amount单位是千元。我在项目中遇到过有人直接把vol当股数用,结果算出来的换手率差了100倍,回测结果完全失真。
2.2.2 复权数据处理
做回测必须用复权数据,否则分红送股会搞乱你的收益率计算。Tushare提供了前复权和后复权接口:
# 前复权
df_adj = pro.daily(
ts_code='000001.SZ',
start_date='20240101',
end_date='20240131',
adj='qfq' # 前复权
)
我个人习惯用前复权做回测,因为前复权调整了历史价格,使得价格序列连续,计算收益率更准确。后复权则更适合看真实涨幅。
2.2.3 用Akshare快速获取行情
如果你只是临时看看数据,不想折腾token,Akshare是个好选择。它直接从东方财富等网站抓数据,免注册:
# 获取平安银行日线(Akshare)
df_ak = ak.stock_zh_a_hist(
symbol="000001",
period="daily",
start_date="20240101",
end_date="20240131",
adjust="qfq"
)
print(df_ak.head())
你看,代码更简洁。但注意,Akshare的数据源是网页爬虫,偶尔会因网站改版而失效。我建议把它当辅助工具,核心数据还是用Tushare。
2.3 北向资金数据
北向资金,就是外资通过沪港通、深港通买入A股的资金。这玩意儿是市场情绪的重要指标。我观察过,北向资金连续大幅流入时,市场往往有一波行情;连续流出时,大概率要调整。
2.3.1 北向资金流向(Tushare)
# 获取北向资金每日流向
df_north = pro.moneyflow_hsgt(
start_date='20240101',
end_date='20240131'
)
print(df_north[['trade_date', 'north_money', 'south_money']].head())
字段说明:north_money是北向资金净流入(亿元),正数代表外资买入。我一般会把这个数据和沪深300指数叠加画图,一眼就能看出背离关系。
2.3.2 北向资金个股持仓(Akshare)
有时候你想看外资具体买了哪些股票。Akshare提供了个股级别的北向资金数据:
# 获取北向资金个股持仓排行
df_north_stock = ak.stock_hsgt_north_net_flow_in_em(symbol="北上")
print(df_north_stock.head())
这个接口返回的是当日北向资金净买入最多的个股排行。我经常用它来筛选「外资加仓」的股票池,作为选股的一个维度。
2.4 两融数据(融资融券)
两融数据反映了杠杆资金的情绪。融资余额增加,说明市场看多情绪浓;融券余额增加,说明做空力量在积聚。我一般用融资余额的变化率作为情绪指标。
2.4.1 两融余额(Tushare)
# 获取两融余额数据
df_margin = pro.margin(
start_date='20240101',
end_date='20240131'
)
print(df_margin[['trade_date', 'rzye', 'rqye']].head())
字段:rzye是融资余额(亿元),rqye是融券余额(亿元)。注意,融券余额通常比融资余额小一个数量级,别搞混了。
2.4.2 两融差额与情绪指标
我个人习惯计算一个「两融情绪指标」:
# 计算两融差额(融资-融券)
df_margin['margin_diff'] = df_margin['rzye'] - df_margin['rqye']
# 计算日变化率
df_margin['margin_diff_pct'] = df_margin['margin_diff'].pct_change() * 100
print(df_margin[['trade_date', 'margin_diff', 'margin_diff_pct']].tail())
这个指标如果连续为正且放大,说明杠杆资金在加仓,市场情绪偏乐观。我曾经用这个指标配合北向资金,构建了一个「资金情绪共振」策略,效果还不错。
2.5 数据整合与存储
数据拿下来之后,别每次都重新拉。我习惯存到本地CSV或者数据库里,每天增量更新。下面是一个简单的整合示例:
# 合并三个数据源
df_all = pd.DataFrame()
df_all['trade_date'] = df_daily['trade_date']
df_all['close'] = df_daily['close']
df_all['north_flow'] = df_north['north_money']
df_all['margin_diff'] = df_margin['margin_diff']
# 保存到CSV
df_all.to_csv('emotion_data.csv', index=False)
print("数据已保存")
嗯,这里要注意日期对齐。不同数据源的交易日可能不完全一致(比如北向资金在港股通关闭日没有数据),合并时建议用pd.merge的how='inner'或how='left',根据你的需求来。
2.6 本章知识体系总览
下面这张图,是我自己梳理的数据获取流程。你跟着这个框架走,不会乱:
你看,整个流程就是:从两个数据源获取三类数据,然后整合存储。每一步都有坑,但踩过一次就记住了。
2.7 实战小贴士
- 频率问题:日线数据每天下午5点左右更新,别在盘中频繁拉取,会被限流。我一般设置定时任务,每天收盘后统一拉一次。
- 数据校验:拉完数据后,简单检查一下:看日期是否连续、价格是否异常(比如出现负数或0)、成交量是否合理。我曾经遇到过某天数据缺失,结果回测时那天的收益率被算成0,严重扭曲了夏普比率。
- 缓存策略:对于历史数据,拉一次存本地,以后只增量更新当天数据。别每次都全量拉,既慢又容易被封。
好了,数据获取这块就讲到这里。你把这些代码跑通,数据存好,后面做情绪指标计算就有米下锅了。记住,数据质量决定策略上限,别在这步偷懒。