跌停池 × 炸板池:情绪冰点日的「错杀股」反抽
本文由 StockApi 智能体基于跌停股池、炸板股池、情绪周期与日 K 接口整理撰写,代码可直接运行复现。
引言
情绪冰点日是短线客最难熬、也是赔率最好的一天:跌停几十家、涨停寥寥无几,恐慌到连强势股都被砸出跌停。这种日子的第二天,市场经常出现技术性反抽——不是所有跌停都是该跌的,相当一部分是情绪错杀。
但抄跌停是所有抄底里最危险的姿势:真利空跌停后面还有十个跌停。这个策略的核心是区分「错杀」和「该杀」,靠三个结构证据:封单撤了多少(封不死说明有资金在接)、开板开了几次(反复开板 = 多空在交换筹码,不是单边出逃)、它昨天是不是涨停/炸板(从涨停被砸下来的才叫错杀,阴跌了半个月的跌停叫补跌)。跌停股池、炸板股池、情绪周期三个接口正好把这三件事全部量化。
策略原理
本篇用到的StockApi四个接口
| 接口(中文名) | 路径 | 在策略里做什么 |
|---|---|---|
| 跌停股池 | /v1/base/DTPool |
当日跌停股结构:连续跌停天数、开板次数、封单(交易日 15:30 更新) |
| 炸板股池 | /v1/base/ZBPool |
当日曾涨停但收盘未封住的票,识别"从涨停被砸下来"的错杀路径 |
| 情绪周期 | /v1/base/emotionalCycle |
判定冰点日与恐慌收敛 |
| 股票日/周/月 K 线行情 | /v1/base/day |
次日开盘价与当日均价,确定低吸执行价 |
字段中文对照
| 字段 | 中文含义 | 备注 |
|---|---|---|
days |
连续跌停天数 | = 1 才是首板跌停(错杀候选),≥ 2 的连续跌停不碰 |
oc |
开板次数 | 跌停板打开的次数,≥ 3 说明有资金反复接 |
ceilingAmount |
封单资金 | 跌停口径下是封住跌停的卖单金额,越小越好 |
fba |
板上成交额 | 跌停价位上成交的金额,有成交说明有人接飞刀 |
bombNum |
炸板次数 | 炸板池口径,昨日涨停被砸的次数 |
ztjs / dtjs |
涨停家数 / 跌停家数 | 冰点判定:dtjs ≥ 前5日均值 × 2 且 ztjs < 30 |
close / open |
收盘价 / 开盘价 | 次日低吸的执行参照 |
冰点判定 + 错杀识别(收盘后)
- 冰点日判定(情绪周期接口):当日跌停家数 ≥ 前 5 日均值的 2 倍,且涨停家数 < 30。冰点日是整个策略的触发器,不是冰点日不启动。
- 错杀筛选(跌停股池接口):在当日跌停池里筛
days = 1(首日跌停,不是连续阴跌的补跌)oc ≥ 3(跌停反复被打开,有承接)ceilingAmount / 流通市值 < 0.5%(跌停封单薄,封不死)
- 错杀路径确认(炸板股池接口):候选票昨日出现在涨停池或今日出现在炸板池——从涨停/炸板跌到跌停的票才是情绪错杀;一路阴跌型跌停剔除。
- 次日执行(日 K 接口):次日开盘低开 2%—4% 时买入(低开太深说明有利空未出尽,高开说明反抽已抢跑);当日反抽 ≥ 5% 兑现一半,尾盘留一半;次日收盘前无条件清仓。冰点反抽是 T+1 游戏,不恋战。
为什么"开板次数"是错杀最强的证据
跌停板上的开板,每一场都是多空的一次正面交锋:
| 跌停形态 | 开板次数 | 封单变化 | 本质 | 次日倾向 |
|---|---|---|---|---|
| 一字跌停 | 0 | 封单巨大且增加 | 单边出逃/重大利空 | 继续跌 |
| 尾盘封死 | 0—1 | 收盘才封上 | 恐慌宣泄不充分 | 隔日继续宣泄 |
| 反复开板 | ≥ 3 | 封单被反复打穿 | 有资金在跌停位持续承接 | 反抽概率最高 |
开板次数多意味着跌停价位上实际发生了大量成交——恐慌盘的卖压被吃掉了。配合「封单占比 < 0.5%」,筛出来的就是"想砸的砸完了、想接的接到了"的票。
Python 完整实现
import os
import requests
import pandas as pd
TOKEN = os.getenv("STOCKAPI_TOKEN", "你的Token")
BASE = "//www.stockapi.com.cn/v1"
def call(path, **params):
params["token"] = TOKEN
r = requests.get(f"{BASE}{path}", params=params, timeout=15)
r.raise_for_status()
d = r.json()
if d.get("code") == 20000:
return d["data"]
raise RuntimeError(f"{path} 调用失败: {d.get('msg')}")
# ---------- 1. 冰点判定(情绪周期) ----------
def ice_day(date):
d = call("/base/emotionalCycle")
df = pd.DataFrame(d["contentList"], columns=d["colNameList"])
df["dt"] = pd.to_datetime(df["date1"].astype(str), format="%Y%m%d")
df = df[df["dt"] < pd.Timestamp(date)].sort_values("dt")
dt_cnt = pd.to_numeric(df["dtjs"], errors="coerce")
zt_cnt = pd.to_numeric(df["ztjs"], errors="coerce")
today_dt = dt_cnt.iloc[-1]
return today_dt >= dt_cnt.tail(6).head(5).mean() * 2 and zt_cnt.iloc[-1] < 30
# ---------- 2. 跌停池错杀筛选 ----------
def dt_candidates(date):
df = pd.DataFrame(call("/base/DTPool", date=date) or [])
if df.empty:
return df
for c in ["days", "oc", "ceilingAmount", "flowCapital", "fba"]:
if c in df.columns:
df[c] = pd.to_numeric(df[c], errors="coerce")
df["code"] = df["code"].astype(str).str.zfill(6)
cond = (df["days"] == 1) & (df["oc"] >= 3) & \
(df["ceilingAmount"] / df["flowCapital"].replace(0, pd.NA) < 0.005)
return df[cond]
# ---------- 3. 炸板路径确认 ----------
def path_ok(code, date):
zb = pd.DataFrame(call("/base/ZBPool", date=date) or [])
if zb.empty:
return False
return code in zb["code"].astype(str).str.zfill(6).values
# ---------- 4. 主流程 ----------
def ice_rebound_watchlist(date):
if not ice_day(date):
return "非冰点日,不启动"
cands = dt_candidates(date)
picks = [c for c in cands["code"] if path_ok(c, date)]
return cands[cands["code"].isin(picks)][
["code", "name", "oc", "ceilingAmount", "fba"]]
watch = ice_rebound_watchlist("2026-10-28")
print(watch)
回测指标怎么读
| 指标 | 典型量级(示意) | 说明 |
|---|---|---|
| 冰点日频率 | 每季度 1—3 次 | 策略天然低频,等待是主要成本 |
| 每次入选票数 | 2—8 只 | 冰点日规模越大候选越多 |
| 次日反抽 ≥ 5% 概率 | 50%—60% | 三重结构过滤后的水平 |
| 失败情形 | 次日继续大跌 | 由"低开 2%—4% 才买"与 T+1 清仓兜底 |
回测方式:遍历历史,对每个冰点日执行同一筛选,统计次日开盘买入后的 T+1 收盘收益。三个池子接口都支持按历史日期查询,可完整回放。
参数与风控
| 参数 | 默认 | 调整方向 |
|---|---|---|
| 冰点倍数 | 2×前5日均值 | 收紧到 3× 更极端、更少 |
| 开板次数下限 | 3 | 放宽到 2 信号更多、质量下降 |
| 次日低吸区间 | 低开 2%—4% | 超出区间放弃,宁缺毋滥 |
| 持仓期 | 次日收盘清仓 | 冰点反抽不过夜到第三天 |
风控三条:
- 连续跌停(
days ≥ 2)的票无论结构多好都不碰——首日跌停是情绪,连续跌停大概率是基本面。 - 候选票若当晚出现利空公告(业绩雷、监管问询),次日无论开在哪个位置都放弃。
- 单次冰点反抽总仓位 ≤ 2 成,这是情绪博弈不是价值投资,错了就走。
常见问题(FAQ)
Q:跌停池的 ceilingAmount 在跌停语境下是什么?
A:是封住跌停的卖单金额,方向与涨停池相反。所以这里它是"封死下跌的力量"——越小越封不死、越有承接机会,筛选条件是 < 而不是 >。字段同名方向相反,是这两个池子最容易混淆的地方。
Q:为什么一定要叠加炸板池确认?
A:跌停池只说明"今天跌停了",炸板池说明"它今天曾经涨到过涨停"。有这个路径的票才是从抢筹到踩踏的情绪反转,波动最大、反抽动力最强;而平稳阴跌到跌停的票没有情绪记忆,反抽动力弱。
Q:这个策略和涨停池系的龙头策略什么关系?
A:正好是硬币的两面:13—16 篇做的是情绪进攻端的"强上强",本篇做的是情绪崩溃端的"错杀修复"。两者的环境判定都来自情绪周期接口——涨停家数高做前者,跌停家数极端做后者,刚好填满情绪光谱的两端。
免责声明:本文为策略研究与技术分享,不构成任何投资建议。市场有风险,入市需谨慎。

