2、数据获取与清洗:北向资金数据源介绍

做北向资金分析,第一步就是搞定数据。我见过太多人,策略想得天花乱坠,结果卡在数据获取这一步。说白了,数据源选不对,后面全是白搭。

今天咱们就把这事聊透。我会把市面上主流的几个数据源挨个捋一遍,再手把手带你写代码把数据抓下来,最后做清洗。嗯,这套流程我在实盘项目里跑了两年多,踩过的坑不少,今天一并告诉你。

2.1 三大主流数据源对比

我个人习惯把数据源分成三类:官方源、商业源、开源源。各有各的脾气,咱们一个一个看。

数据源 类型 数据质量 获取难度 更新频率 费用
港交所 官方 ★★★★★ 日频 免费
Wind 商业 ★★★★★ 实时
Tushare 开源 ★★★★ 日频

2.1.1 港交所:最权威,但最折腾

港交所官网每天会发布北向资金的持股明细和资金流向。数据绝对准确,毕竟是官方一手货。但问题来了——它没有API接口。

你想想看,每次都得手动去下载Excel文件。一天两天还行,长期做量化分析,这谁受得了?我曾经试过写爬虫去抓,结果人家页面结构三天两头改,维护成本高得离谱。

适用场景:做历史数据回测,或者只需要偶尔拉一次数据做验证。

2.1.2 Wind:真香,但贵

Wind金融终端,业内老大哥。数据全、更新快、接口稳定。用Python的WindPy库,一行代码就能拉数据。

但价格嘛...一年几万块。个人投资者基本不用想。我在机构的时候用过两年,说实话,体验确实好。但如果你是自己做研究,我建议先看看别的选择。

适用场景:机构用户,或者预算充足的团队。

2.1.3 Tushare:个人玩家的首选

Tushare是我个人最推荐给个人投资者的。免费版就能拿到北向资金的日频数据,包括持股明细和资金流向。注册后获取token,用Python调接口就行。

数据质量嘛,我对比过港交所的官方数据,误差在0.5%以内。做策略分析完全够用。

适用场景:个人量化研究、中小团队。

我的建议:如果你刚开始做北向资金分析,先用Tushare上手。等策略跑通了,再考虑要不要上Wind。别一上来就花大价钱买数据,不值当。

2.2 Python数据获取实战

好,理论说完了,咱们直接上代码。我用Tushare演示,因为大家都能用。

2.2.1 安装与配置

# 安装Tushare
pip install tushare

# 导入并设置token
import tushare as ts
ts.set_token('你的token')
pro = ts.pro_api()

token怎么拿?去Tushare官网注册,在个人中心就能看到。嗯,这一步别省,没有token啥也干不了。

2.2.2 获取北向资金每日流向

# 获取2024年1月的北向资金数据
df = pro.moneyflow_hsgt(
    start_date='20240101',
    end_date='20240131'
)
print(df.head())

返回的数据长这样:

trade_date gt_amt sgt_amt north_amt
20240102 12.5亿 8.3亿 20.8亿
20240103 -3.2亿 5.1亿 1.9亿

字段说明:gt_amt是沪股通,sgt_amt是深股通,north_amt是两者之和。

2.2.3 获取个股持股明细

# 获取北向资金持股明细
df_stock = pro.hk_hold(
    ts_code='600519.SH',
    start_date='20240101',
    end_date='20240131'
)
print(df_stock.head())

这里要注意,ts_code的格式是「股票代码.交易所」,上交所是.SH,深交所是.SZ。

小技巧:我习惯把常用股票的代码存成一个列表,循环去拉数据。这样一次能拉几十只,省时间。

2.3 数据清洗与预处理

数据拉下来,你以为就能直接用?太天真了。原始数据里全是坑,不洗一洗,策略跑出来全是噪音。

2.3.1 常见问题与处理

我总结了一下,北向资金数据常见的脏数据有这几类:

  • 缺失值:节假日没有交易,数据是空的
  • 异常值:某天资金突然暴增或暴减,可能是数据录入错误
  • 重复值:同一日期的数据出现多次
  • 格式问题:日期是字符串,金额是带「亿」的文本

咱们一个一个处理。

import pandas as pd
import numpy as np

# 1. 处理缺失值
df = df.dropna(subset=['gt_amt', 'sgt_amt'])  # 删除关键字段为空的行
df = df.fillna(0)  # 其他字段用0填充

# 2. 处理重复值
df = df.drop_duplicates(subset=['trade_date'])

# 3. 转换日期格式
df['trade_date'] = pd.to_datetime(df['trade_date'])

# 4. 清洗金额字段(去掉"亿"字,转为数值)
def clean_amount(x):
    if isinstance(x, str):
        return float(x.replace('亿', ''))
    return x

df['gt_amt'] = df['gt_amt'].apply(clean_amount)
df['sgt_amt'] = df['sgt_amt'].apply(clean_amount)

避坑指南:我曾经遇到过一个问题——某天数据里出现了「--」这种占位符。直接用pd.to_numeric会报错。我的处理方式是先转成字符串,替换掉特殊字符,再转数值。

2.3.2 异常值检测

异常值怎么找?我一般用3σ原则。说白了,就是看数据偏离均值多少个标准差。

# 3σ异常值检测
mean = df['north_amt'].mean()
std = df['north_amt'].std()
threshold = 3

df['is_outlier'] = np.abs(df['north_amt'] - mean) > threshold * std

# 查看异常值
outliers = df[df['is_outlier']]
print(f"发现 {len(outliers)} 个异常值")

发现异常值后怎么办?别急着删。先看看是不是特殊事件导致的。比如某天突然有大量资金流入,可能是MSCI调整成分股。这种情况应该保留,而不是删除。

2.3.3 最终数据格式

清洗完之后,我习惯把数据存成这样的格式:

trade_date gt_amt sgt_amt north_amt is_outlier
2024-01-02 12.5 8.3 20.8 False
2024-01-03 -3.2 5.1 1.9 False

日期是datetime格式,金额是浮点数,异常值打了标记。这样后面做分析,直接拿来用就行。

核心要点:数据清洗不是一次性的活。每次拉新数据,都要跑一遍清洗流程。我建议你把清洗逻辑封装成一个函数,每天定时跑。省心。

2.4 本章知识体系

下面这张图,是我自己梳理的北向资金数据获取与清洗的完整流程。你照着这个走,基本不会出大问题。

北向资金数据获取与清洗流程 数据源选择 港交所 Wind Tushare Python数据获取 数据清洗与预处理 清洗步骤详解 ① 缺失值处理 dropna / fillna ② 重复值去除 drop_duplicates ③ 日期格式转换 pd.to_datetime ④ 金额字段清洗 去除"亿",转数值 ⑤ 异常值检测 3σ原则标记 ⑥ 最终格式输出 datetime + float + 标记

这张图把整个流程串起来了。从左到右,从上到下,每一步都清楚。你写代码的时候,就照着这个流程走,不会漏掉任何一步。


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