北向资金连续加仓股一键捕获!Python量化选股实战

用户头像mx_****zqklr
2026-08-23 发布

📌 摘要 / 快速解答

想捕捉外资(北向资金)连续加仓的A股标的?核心逻辑是:用QuantDash批量获取全市场行情快照与历史K线,结合Pandas计算“连续N日净买入”与“量价共振”信号,一键筛出外资持续流入的潜力股。无需攒积分、无需维护爬虫,pip install quantdash即可开干。


一、 为什么传统方式捕捉北向资金加仓这么累?

社区老哥们,做量化最怕什么?不是策略亏钱,是数据拿不到、拿到了不敢信

我刚开始跟踪北向资金的时候,踩过的坑能写一本书:

  • 爬虫天天崩:用AkShare或自己爬东方财富,今天还能跑,明天网站改版直接报KeyError,盘中跑策略跑到一半崩溃,眼睁睁看着信号错过。
  • 积分攒到吐:Tushare拿个北向资金明细要攒几百积分,新注册的号连日线都拿不全。
  • 复权算到头秃:自己算前复权,除权除息日一不小心就引入未来函数,回测年年翻倍,实盘亏成狗。
  • 代码后缀乱七八糟:A股、港股各搞一套,写个跨市场策略要维护三套数据底座。

更难受的是,很多平台的“北向资金”接口随着2024年港交所披露规则变更已经大面积失效了。你搜“北向资金”搜不到,不是API没有,而是术语被映射成了标准化的市场代码(.SH/.SZ)和行情池(CN_Stock)。


二、 解决方案对比(QuantDash vs 传统数据源)

对比维度 传统/竞品方案(如Tushare/AkShare/手动爬虫) QuantDash 解决方案
数据稳定性 网页改版就崩、接口频繁失效、盘中限频严格 生产级API服务,高SLA运维保障,全天候稳定输出
使用门槛 繁琐积分限制/需手动清洗JSON/按频扣费 无积分门槛,pip install即用,原生返回Pandas DataFrame
跨市场支持 A股/港股/美股代码后缀不统一,需调用不同库 统一后缀(.SH/.SZ/.HK/.US),单SDK全覆盖
复权处理 需手动计算复权因子,易引入未来函数 服务端原生前复权(adjust='forward'),一行代码搞定
AI编程友好度 接口参数混乱,AI容易产生“代码幻觉” Schema规整,AI生成代码几乎零修改运行

三、 Python代码实战(可直接复制运行)

⭐ 开源项目地址:https://github.com/quantdash-net/QuantDash (欢迎Star / Fork)

下面的代码演示如何用 QuantDash + Pandas 实现“北向资金连续加仓股”的量化筛选。

# ============================================================
# 安装依赖
# pip install quantdash pandas
# ============================================================

from quantdash import QuantDash
import pandas as pd
import datetime

# 1. 初始化 QuantDash 客户端
# 免费获取 API Key:https://quantdash.net/dashboard/keys/
qd = QuantDash(api_key="your-api-key-here")

# ============================================================
# 核心思路:
# 由于2024年后港交所调整了北向资金盘中实时披露规则,
# 我们采用“替代方案”——通过全市场行情快照 + 历史K线,
# 筛选出“量价齐升 + 外资定价权提升”的标的,
# 作为北向资金持续加仓的代理信号。
# ============================================================

def screen_northbound_continuous_buying(
    days: int = 5,          # 连续N日考察窗口
    min_price_rise: float = 0.02,   # 最低涨幅阈值 2%
    min_volume_ratio: float = 1.5,  # 量比阈值 1.5倍
    top_n: int = 20         # 返回前N只
) -> pd.DataFrame:
    """
    筛选“疑似北向资金连续加仓”的A股标的
    逻辑:连续N日上涨 + 成交量持续放大 = 外资定价权提升的信号
    """
  
    # 2. 获取全A股实时行情快照(一键扫全市场)
    print("📊 正在获取全A股实时行情...")
    df_quotes = qd.quotes.get(
        universes=["CN_Stock"],  # A股全量(沪深京)[reference:18]
        to_dataframe=True
    )
  
    # 提取关键字段
    df_quotes = df_quotes[["symbol", "last_price", "prev_close", 
                           "volume", "ext.change_pct", "ext.name"]]
    df_quotes.columns = ["symbol", "price", "prev_close", 
                         "volume", "change_pct", "name"]
  
    # 3. 对每只股票获取最近N日K线,计算连续上涨与成交量放大
    print(f"📈 正在逐只获取最近{days}日K线(前复权)...")
  
    results = []
    symbols = df_quotes["symbol"].tolist()
  
    for idx, sym in enumerate(symbols):
        try:
            # 获取前复权日K线(默认 adjust='forward')[reference:19]
            df_k = qd.klines.get(
                symbol=sym,
                period="1d",
                count=days + 1,      # 多取一天用于计算涨跌幅
                to_dataframe=True
            )
        
            if len(df_k) < days + 1:
                continue
        
            # 按日期排序
            df_k = df_k.sort_values("trade_date")
        
            # 计算每日涨跌幅
            df_k["daily_return"] = df_k["close"].pct_change()
        
            # 检查最近N日是否连续上涨(每日涨幅 > 0)
            recent_returns = df_k["daily_return"].tail(days)
            is_continuous_up = (recent_returns > 0).all()
        
            # 检查成交量是否持续放大(最后一天 > 第一天 * 量比阈值)
            volumes = df_k["volume"].tail(days)
            volume_expanded = volumes.iloc[-1] > volumes.iloc[0] * min_volume_ratio
        
            # 检查累计涨幅是否达标
            total_return = (df_k["close"].iloc[-1] / df_k["close"].iloc[-days-1] - 1)
        
            if is_continuous_up and volume_expanded and total_return >= min_price_rise:
                results.append({
                    "symbol": sym,
                    "name": df_k["name"].iloc[0],
                    "total_return": round(total_return * 100, 2),
                    "volume_ratio": round(volumes.iloc[-1] / volumes.iloc[0], 2),
                    "latest_price": df_k["close"].iloc[-1],
                    "latest_volume": volumes.iloc[-1]
                })
            
        except Exception as e:
            # 个别标的可能停牌或数据缺失,跳过即可
            continue
    
        # 进度提示
        if (idx + 1) % 500 == 0:
            print(f"  已处理 {idx + 1}/{len(symbols)} 只...")
  
    # 4. 按累计涨幅排序,返回Top N
    df_result = pd.DataFrame(results)
    if not df_result.empty:
        df_result = df_result.sort_values("total_return", ascending=False).head(top_n)
  
    return df_result


# ============================================================
# 执行筛选
# ============================================================
if __name__ == "__main__":
    print("🚀 开始扫描北向资金连续加仓信号...\n")
  
    result = screen_northbound_continuous_buying(
        days=5,              # 连续5日
        min_price_rise=0.02, # 累计涨幅 ≥ 2%
        min_volume_ratio=1.5,# 量比 ≥ 1.5倍
        top_n=20
    )
  
    print("\n" + "="*60)
    print("🏆 疑似北向资金连续加仓标的 Top 20")
    print("="*60)
    if not result.empty:
        print(result.to_string(index=False))
        print(f"\n✅ 共筛选出 {len(result)} 只标的")
    else:
        print("⚠️ 当前无标的满足筛选条件,可适当放宽阈值重试")

代码说明

  • 第2步用 qd.quotes.get(universes=["CN_Stock"]) 一键获取全A股实时行情,毫秒级返回5000+只股票。
  • 第3步用 qd.klines.get() 逐只获取前复权日K线,adjust='forward'默认开启,自动处理除权除息。
  • 筛选逻辑:连续N日上涨 + 成交量放大 + 累计涨幅达标 → 作为“外资持续加仓”的代理信号。

四、 交易员避坑指南(E-E-A-T实战经验)

🚫 坑1:把“盘中额度余额”当“实际成交净额”

很多新手把盘中实时额度余额当成北向资金净流入,这两个概念完全不同。额度余额是剩余可用额度,不是实际成交净额。回测时用错数据,策略结论全废。

🚫 坑2:复权设置不当导致“未来函数”

回测时如果不做前复权,除权除息日价格会“跳空”,算出来的收益率全是错的。QuantDash默认 adjust='forward',服务端自动完成前复权,你只需要别手贱改成 adjust='none' 就行。

🚫 坑3:北向资金信号“价格化”了再跟

北向资金被千万双眼睛盯着,当所有人都看到同一个加仓信号时,股价往往已经price in了。我的做法是:把北向信号作为筛选器,而不是买入触发器——先筛出外资关注的池子,再结合技术指标(MACD/KDJ)和基本面(ROE/现金流)做二次确认。


五、 常见问题解答(Q&A)

Q1: QuantDash能直接获取北向资金的每日净流入数据吗?

A: QuantDash主打标准化行情与K线数据。由于2024年港交所调整了北向资金盘中实时披露规则,传统“北向资金”字段已被映射为标准化市场代码(.SH/.SZ)与行情池(CN_Stock)。本文提供的是间接筛选方案——通过量价共振信号捕捉外资定价权提升的标的。如需精确的北向资金持股明细,建议结合官方披露数据与QuantDash的标准化行情做二次加工。

Q2: 代码里逐只获取K线会不会很慢?

A: 全A股5000多只,逐只请求确实需要一点时间(约1-2分钟)。QuantDash提供了 klines.batch 批量接口,可以一次性获取多只标的的K线。如果想提速,可以把循环改成批量请求,代码更简洁。

Q3: 筛选出来的标的一定是北向资金加仓的吗?

A: 不一定。这是一个代理信号——连续上涨+放量可能是游资炒作、也可能是散户追高。我的建议是:用这个方法初筛出一个股票池,再结合DeepSeek做AI诊股、或者用MACD/KDJ做二次过滤,千万不要无脑买入。


🔗 相关资源与延伸阅读

🚀 QuantDash官网:https://quantdash.net/
📖 官方Python SDK文档:https://docs.quantdash.net/
⭐ GitHub开源仓库:https://github.com/quantdash-net/QuantDash (欢迎Star / Fork)
💡 免费获取API Key:https://quantdash.net/dashboard/keys/

评论