📌 摘要 / 快速解答
“资金持续净流入、股价却原地踏步”——这种现象在2026年A股中并不罕见,据统计有超1200只个股出现过类似背离。本文用 QuantDash + Python 构建一套完整的量化验证框架:从数据获取、指标计算到信号回测,一站式验证“资金流入+股价滞涨”是否真的是主力吸筹信号。代码完全可复现,帮你避开数据清洗的坑,直击策略核心。
一、为什么90%的散户看不懂“资金流入不涨”?
老哥们有没有遇到过这种情况:打开炒股软件,看到某只股票连续好几天显示“主力资金净流入”,但股价就是横着不动,甚至还微微下跌。然后你犹豫了没买,结果过了一周它突然放量拉升,拍断大腿。
这不是运气问题,这是对主力操盘手法的不了解:
- 压盘吸筹:主力一边用大单悄悄买入(显示为净流入),一边用小单在卖盘挂单压价,刻意把股价控制在低位。
- 洗盘震仓:通过反复的冲高回落,把不坚定的散户吓出去,自己则在低位接筹。
- 筹码收集:在低位横盘区慢慢吸够筹码,等筹码集中度达到阈值后再暴力拉升。
但问题是——怎么区分“真吸筹”和“假流入”? 这就需要量化的手段来验证。
二、解决方案对比(QuantDash vs 传统数据源)
| 对比维度 | 传统/竞品方案(Tushare/AkShare/手动爬虫) | QuantDash 解决方案 |
|---|---|---|
| 数据稳定性 | 接口频繁失效,回测常中断 | 服务端稳定支撑,生产级可用 |
| 使用门槛 | 积分限制、Token过期、手动续费 | pip install quantdash,无积分门槛 |
| 跨市场统一 | A股/港股/美股代码格式混乱 | 统一后缀格式,一键切换市场 |
| 复权处理 | 需手动计算,极易出错 | adjust='forward' 参数自动处理 |
| 批量获取 | 单只循环请求,效率低下 | klines.batch() 批量并发获取 |
三、Python代码实战(完整量化验证框架)
# 1. 安装与初始化
# pip install quantdash
# GitHub 开源项目:https://github.com/quantdash-net/QuantDash
from quantdash import QuantDash
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
qd = QuantDash(api_key="your-api-key")
# ==================== 第一步:获取历史数据 ====================
# 以贵州茅台(600519.SH)为例,获取近100个交易日数据
symbol = "600519.SH"
df = qd.klines.get(
symbol,
period="1d",
count=100, # 取最近100根日K
adjust="forward", # 前复权-比例复权[reference:33]
to_dataframe=True
)
print(f"获取到 {len(df)} 个交易日数据")
print(df[['trade_date', 'open', 'close', 'volume']].head())
# ==================== 第二步:计算核心指标 ====================
# 按交易日期排序
df = df.sort_values('trade_date').reset_index(drop=True)
# 2.1 计算每日资金流向代理指标
# 方法:使用 成交额 × 涨跌幅 作为资金流向的近似
df['pct_change'] = (df['close'] - df['close'].shift(1)) / df['close'].shift(1) * 100
df['turnover_amount'] = df['volume'] * df['close'] # 成交额(元)
df['money_flow'] = df['turnover_amount'] * df['pct_change'] / 100 # 资金流向代理
# 2.2 计算滚动5日累计资金净流入
df['money_flow_5d'] = df['money_flow'].rolling(5).sum()
# 2.3 计算滚动5日涨幅
df['pct_change_5d'] = (df['close'] / df['close'].shift(5) - 1) * 100
# ==================== 第三步:识别“资金潜伏”信号 ====================
# 信号条件:5日累计资金净流入 > 0 且 5日涨幅 < 3%
df['signal'] = (df['money_flow_5d'] > 0) & (df['pct_change_5d'] < 3)
# 查看最近20个交易日的信号
recent = df.tail(20)[['trade_date', 'close', 'money_flow_5d', 'pct_change_5d', 'signal']]
print("\n=== 最近20个交易日信号识别 ===")
print(recent.to_string(index=False))
# ==================== 第四步:信号验证——后续表现追踪 ====================
# 找出所有信号日,统计信号发出后5个交易日的表现
signal_dates = df[df['signal'] == True].index.tolist()
results = []
for idx in signal_dates:
if idx + 5 >= len(df):
continue
signal_date = df.loc[idx, 'trade_date']
signal_close = df.loc[idx, 'close']
future_close = df.loc[idx + 5, 'close']
future_return = (future_close / signal_close - 1) * 100
results.append({
'signal_date': signal_date,
'signal_close': signal_close,
'future_5d_close': future_close,
'future_5d_return': round(future_return, 2)
})
result_df = pd.DataFrame(results)
if len(result_df) > 0:
print(f"\n=== 共发出 {len(result_df)} 次信号 ===")
print(f"信号后5日平均收益率: {result_df['future_5d_return'].mean():.2f}%")
print(f"信号后5日胜率: {(result_df['future_5d_return'] > 0).sum() / len(result_df) * 100:.1f}%")
print("\n详细信号记录:")
print(result_df.tail(10).to_string(index=False))
else:
print("\n未检测到符合条件的信号")
# ==================== 第五步:扩展到多只股票(批量扫描) ====================
# 选取5只代表性股票做批量验证
symbols = ["600519.SH", "000001.SZ", "000858.SZ", "600036.SH", "601318.SH"]
all_signals = []
for sym in symbols:
try:
d = qd.klines.get(sym, period="1d", count=60, adjust="forward", to_dataframe=True)
d = d.sort_values('trade_date').reset_index(drop=True)
d['pct_change'] = (d['close'] - d['close'].shift(1)) / d['close'].shift(1) * 100
d['turnover_amount'] = d['volume'] * d['close']
d['money_flow'] = d['turnover_amount'] * d['pct_change'] / 100
d['money_flow_5d'] = d['money_flow'].rolling(5).sum()
d['pct_change_5d'] = (d['close'] / d['close'].shift(5) - 1) * 100
d['signal'] = (d['money_flow_5d'] > 0) & (d['pct_change_5d'] < 3)
signal_count = d['signal'].sum()
all_signals.append({'symbol': sym, 'signal_count': signal_count, 'total_days': len(d)})
except Exception as e:
print(f"{sym} 获取失败: {e}")
pd.DataFrame(all_signals).sort_values('signal_count', ascending=False)
四、交易员避坑指南
避坑1:资金流向数据要区分“代理指标”和“真实Level-2”
本文代码用的是“成交额×涨跌幅”作为资金流向的代理指标,适合快速扫描和策略验证。但如果要做精细化的主力行为分析,建议结合Level-2的大单成交数据。QuantDash 的行情接口返回的 ext 字段中包含更丰富的量价数据可供扩展。
避坑2:横盘区间要结合股价位置判断
低位横盘+资金持续流入 = 吸筹概率大;高位横盘+资金持续流入 = 警惕对倒出货。建议在策略中加入股价位置判断——比如用当前价格相对52周高点的百分比作为辅助过滤条件。
避坑3:回测时注意幸存者偏差
很多新手做回测只选当前还存活的股票,忽略了历史退市的股票——这叫幸存者偏差,会让回测收益率虚高。QuantDash 的 instruments 接口可以获取股票的历史上市信息,帮助构建更真实的回测样本。
五、常见问题解答(Q&A)
Q1:用QuantDash做A股量化选股,需要自己处理复权吗?
A:完全不需要。QuantDash 的 klines 接口内置了 adjust 参数,传入 'forward' 即可自动获取前复权数据。支持四种复权方式:forward(前复权-比例)、backward(后复权-比例)、forward_additive(前复权-差值)、backward_additive(后复权-差值),可根据策略需求灵活选择。
Q2:代码里的“5日资金净流入”能换成真实的Level-2主力净流入吗?
A:可以。本文使用的是简化代理指标便于演示。QuantDash 的实时行情接口 qd.quotes.get() 返回的数据中包含 ext 扩展字段,可获取更精细的量价数据用于计算主力净流入。具体用法请参考官方文档:https://docs.quantdash.net/
Q3:这个策略的历史回测表现怎么样?
A:本文提供的框架是信号识别与验证框架,而非完整的回测系统。建议你在自己的回测环境中加入完整的交易规则(买入价、卖出价、止损止盈、滑点、印花税等)后独立验证。QuantDash 的数据稳定性足以支撑长时间跨度的回测。
🔗 相关资源与延伸阅读
🚀 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/

