第二章:数据获取基础——用Tushare/Akshare搞定A股行情、北向资金与两融数据

做量化交易,第一步不是写策略,而是搞定数据。我见过太多人把精力花在策略模型上,结果数据源一塌糊涂,回测跑出来全是幻觉。说白了,数据是量化交易的「米」,没有米,再好的厨子也做不出饭。

这一章,我带你手把手把A股行情数据、北向资金数据、两融数据拿下来。我们用两个国内最主流的Python库——TushareAkshare。我个人习惯是: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()
小提示:Token别硬编码在代码里,我习惯放在环境变量或者配置文件中,避免泄露。

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_dateopenhighlowclosevolamount。注意,这里的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())

这个接口返回的是当日北向资金净买入最多的个股排行。我经常用它来筛选「外资加仓」的股票池,作为选股的一个维度。

核心逻辑:北向资金连续3日净流入且金额放大,是看多信号;连续3日净流出且金额放大,是看空信号。但别盲目跟,要结合大盘位置判断。

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())

这个指标如果连续为正且放大,说明杠杆资金在加仓,市场情绪偏乐观。我曾经用这个指标配合北向资金,构建了一个「资金情绪共振」策略,效果还不错。

避坑指南:两融数据在节假日前后会有异常波动,因为融资利息会在特定日期集中扣除。我建议做平滑处理,或者剔除节假日前后3天的数据。

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.mergehow='inner'how='left',根据你的需求来。

2.6 本章知识体系总览

下面这张图,是我自己梳理的数据获取流程。你跟着这个框架走,不会乱:

数据获取知识体系 Tushare 专业数据,需token Akshare 免注册,快速验证 本地存储 CSV/数据库 A股行情数据 北向资金数据 两融数据 日线/分钟线 前复权/后复权 成交量/成交额 北向净流入 个股持仓排行 沪股通/深股通 融资余额/融券余额 两融差额 情绪指标计算

你看,整个流程就是:从两个数据源获取三类数据,然后整合存储。每一步都有坑,但踩过一次就记住了。

2.7 实战小贴士

  • 频率问题:日线数据每天下午5点左右更新,别在盘中频繁拉取,会被限流。我一般设置定时任务,每天收盘后统一拉一次。
  • 数据校验:拉完数据后,简单检查一下:看日期是否连续、价格是否异常(比如出现负数或0)、成交量是否合理。我曾经遇到过某天数据缺失,结果回测时那天的收益率被算成0,严重扭曲了夏普比率。
  • 缓存策略:对于历史数据,拉一次存本地,以后只增量更新当天数据。别每次都全量拉,既慢又容易被封。
我的习惯:每天开盘前,我会先跑一遍数据更新脚本,把北向资金和两融数据的最新值打印出来。看一眼,心里就有数了——今天市场情绪是偏多还是偏空。

好了,数据获取这块就讲到这里。你把这些代码跑通,数据存好,后面做情绪指标计算就有米下锅了。记住,数据质量决定策略上限,别在这步偷懒。


专注资料整理