通达信量化 · 选股 / 监控 / 推送 全套工作流
用 WorkBuddy + 通达信 MCP(tdx-connector)把「选股 → 监控 → 推送企微」全自动化。覆盖 5 套策略(含 D 池·持续吸筹+筹码集中),已实盘压测、含大量避坑经验与可复用脚本骨架。
> 本技能不绑定任何本地文件路径或自动化 ID,所有脚本路径、调度时刻、推送目标均在你的工作区自行配置。下面给出的是经过验证的契约与骨架,agent 照此落地即可,避免临时猜结构带来的不确定性。
0. 环境依赖(必读)
- 连接
tdx-connector(通达信 MCP),工具前缀mcp__tdx-connector__,提供tdx_screener/tdx_quotes/tdx_kline/tdx_lookup_stock/tdx_api_data。 - 选股:
tdx_screener(自然语言条件,pageSize最大 200 可一次取全量)。 - 行情:
tdx_quotes(hasCalcInfo="1"返回主力净流入 InOut、量比 LB、换手 HSL、主力占比 CAZDBP 等)。 - K线:
tdx_kline(period="4"日线,wantNum="60"取 60 根;深市setcode="0"、沪市setcode="1",缺 setcode 直接校验报错)。 - 股东户数:
tdx_api_data(entry="TdxSharePCCW.tdxf10_gg_gdyj" fixedTag="gdrs" code="XXXXXX"取近 4 期户数时间序列,F10 周/月频)。 - ETF 市场码陷阱:所有
5xxxxxETF 在 tdx 里是 沪市 setcode=1,1xxxxx深市 setcode=0;板块指数881xxx查不到,监控名单里直接剔除。 - 推送企微:连接
wecom-cli,工作区放wecom_push.sh+wecom_target.conf(group=群名或user私聊)。群不可达时脚本自动回退私聊。 - 连接器被禁用自查:若
tdx-connector明明连了却 disconnected,先查~/.workbuddy/connectors/<id>/mcp.json里是否有connector:tdx-connector.disabled=true,以及connector-states.v3.json的 enabled 列表是否漏了它。改disabled=false并加回 enabled 列表,重启 WorkBuddy 生效。
1. 五大策略总览
| 策略 | 建议触发时刻 | 数据口径 | 推送条件 |
|---|---|---|---|
| 开盘竞价突破 | 09:26(仅一次) | 9:15–9:25 竞价 | 高开+创20日新高+量比>2+非ST,且竞价换手达标 |
| 盘中因子监控 | 10:25 / 11:25 / 14:15 | 实时 | 因子池 A 新票(当日去重) |
| 持仓恶化监控 | 09:50 / 13:20 | 实时+30日K线 | 紧急 / 中度 恶化信号 |
| 尾盘双类潜力 | 14:25(仅一次) | 14:25 快照 | A突破 + B吸筹,各取前 10 |
| 持续吸筹+筹码集中(D池) | 10:15 / 14:15(两轮独立) | 实时+历史 | 双维度:持续吸筹+筹码集中(详见 §3.5) |
> 每天固定 8 次 agent 触发(A 池 3 + 持仓 2 + 尾盘 1 + 午间 1 + 竞价 1),D 池额外 2 轮独立自动化(10:15 / 14:15),合计 10 次。D 池两轮各跑一次完整 Stage1+Stage2 刷新(screener→quotes/gdrs/kline→组装→后筛→推送),不与 A 池耦合,避免 A 池静默牵连 D 池。
2. 标准四池(选股口径)
- A 因子池(盘中主推):
MACD金叉 且 5日线上穿20日 且 主力净流入—— 资金+技术共振。 - B 量能异动:
量比大于3 且 涨幅大于5%。 - C 趋势突破:
创20日新高 且 涨幅大于5%(不要只用创20日新高,否则 400+ 只刷屏)。 - D 持续吸筹+筹码集中池(盯盘资金流主题):
持续吸筹(当日净额>5000万 且 近5日净流入>0) 且 筹码集中(集中度90<18 且 股东户数连续下降) 且 获利盘>30% 且 涨幅<5%—— 详见 §3.5(主力占比仅参考因CAZDBP失真;软规则:净比>15% 诱多警戒;MACD 降级为加分)。
> 共振 B∩C 已废弃:C 本身要求涨幅>5%,与「不追高」的过滤条件冲突,实战入选为空。
3. 各策略脚本与用法
3.1 开盘竞价突破
- 主池:
高开 且 创20日新高 且 量比大于2 且 非ST;剔除一字板/涨停、ST、高开>8%。 - 竞价换手过滤(关键):对候选逐个拉
tdx_quotes取OpenAmo/Open/LTGB,竞价换手率 =OpenAmo/(Open×LTGB×1e4)×100%;要求 ≥max(0.5, 高开幅度/10),剔除虚高开盘/跳水票(数据缺失保守剔除)。 - 仅 09:25–09:35 窗口执行(9:26 触发+容错),9:35 后静默放弃当天不补推;当日标记
openbreak_done_YYYYMMDD.txt。
3.2 盘中因子监控
- agent 拉 A 池 → 存
screener_data.json(字段 code/name/price/chg/mf)→ 跑脚本。 - 脚本自动:剔除 ST/涨停/涨幅>5%,按
intraday_state.json(按日期自动重置)剔除当日已推票——同一只票当天只推一次。 - 无新票静默不发;推送成功后再跑
--commit落状态。
3.3 持仓恶化监控
- 读
watchlist.txt(每行code setcode,#注释),对每只拉quotes_<code>.txt+kline_<code>.txt。 - 8 类信号:单日重挫≥5% / 跌破20日线 / 均线空头(MA5<MA20) / 主力出逃(InOut/Amount<0) / 跌破开盘价 / 创当日新低 / 高位放量 / 连续缩量。
- 分级:紧急(重挫≥5% 或 破线+出逃 或 信号≥3)、中度(含出逃未达紧急)、轻微(仅破开盘/新低,静默不推)。
- 去重:按个股严重度,仅「新出现 / 升级(轻微→中度→紧急)」时推,避免刷屏。
3.4 尾盘双类潜力
- 主池:
涨幅0.5%-5% 且 主力净流入 且 量比>1 且 非ST;精筛硬门槛:主力净比InOut/Amount≥1%、非ST、数据完整。 - A·尾盘半小时突破:距日高回撤≤2.5%,评分=净比×3+贴高+量比+换手+涨幅舒适区。
- B·尾盘吸筹·次日高开:涨幅≤4%(吸筹压价)+ 位置度=(现价-日内最低)/(日内最高-日内最低)≥0.5(收在区间上部),评分=净比×3+位置度×5+(4-涨幅)×2+量比温和+换手;B 自动排除已入 A 的票(A 优先不重复)。
- B 类阈值初设 3.5%/0.6 实测恒空,调为 4%/0.5(用真实数据校准,别拍脑袋)。
- 两类各取前 10 合并推送;某类无则「暂无」;两空推空池提示。窗口 14:20–14:30 +
tailwatch_done_YYYYMMDD.txt。
3.5 持续吸筹 + 筹码集中(D 池)
画像 = 持续吸筹(主力持续买入)+ 筹码集中(散户退出、筹码向大户归集)。双维度交叉验证,规避"集中但套牢沉淀"和"散户涌入伪集中"两类陷阱。
| 维度 | 指标 | 通达信字段 | 处理方式 |
|---|---|---|---|
| 持续吸筹 | 当日主力净额>5000万 | 主力净额(元) |
Stage1 硬筛 + 脚本兜底 |
| 持续吸筹 | 近5日主力净流入>0 | 主力净额(区间)(screener 直接支持) |
Stage1 硬筛 |
| 筹码集中 | 筹码集中度90<18 | SCRPLUS.集中度90% |
Stage1 硬筛 + 脚本兜底 |
| 筹码集中 | 股东户数连续下降 | 股东人数(多期,F10/tdx_api_data gdyj) |
Stage2 后筛(近4期判连续下降,硬筛) |
| 防诱多/质参 | 主力占比(参考) | 主力占比(%) = quotes CalcInfo.CAZDBP(⚠️实测对微盘/新股/港股失真:优迅910%、深信服202%、江西铜业129%、中国移动-45%,仅 0<值<100 采信) |
Stage2 参考项(不硬杀;超范围标未精查) |
| 辅助 | 主力净比连续3日递增 | 主力净比(%)=InOut/Amount |
Stage2 辅助(滚动日快照,不致命) |
| 软规则 | 净比>15% 诱多警戒 | 主力净比(%) |
Stage2 软告警(降权不硬杀) |
| 加分 | MACD(DIF>0 / 近5日金叉) | 自算 MACD(12,26,9) | Stage2 加分(不硬筛) |
| 防套牢 | 获利盘>30% | CMFZ.获利比例 |
Stage1 硬筛 + 脚本兜底 |
| 防追高 | 当日涨幅<5% | 涨幅(%) |
Stage1 硬筛 |
> 关键认知:筹码集中度低 ≠ 吸筹。若"集中但获利盘也极低"是下跌途中的套牢沉淀,不是吸筹。故 集中度 + 获利盘>30% 必须同屏。
引擎坑(实测,必须两阶段):股东户数连续下降(F10 类)与 主力净流入(当日)/近5日主力净流入(资金类)不能同句 screener 叠加(直接空结果)。筹码集中度90 属行情衍生,可与资金/获利盘同句。故:
- Stage1(screener 一句话,引擎安全):
主力净流入大于5000万 且 近5日主力净流入大于0 且 筹码集中度90小于18 且 获利盘比例大于30% 且 涨幅小于5%
→ 返回候选(含 主力净额/主力净额(区间)/SCRPLUS.集中度90%/CMFZ.获利比例/平均成本/涨幅)。
- Stage2(agent 对每只候选拉数据后跑脚本):
1. tdx_quotes(hasCalcInfo="1") → InOut/Amount 算 主力净比=InOut/Amount×100%;同次取 CalcInfo.CAZDBP 作主力占比%参考(仅 0<值<100 采信,超范围标未精查,不硬杀)。
2. tdx_api_data entry=TdxSharePCCW.tdxf10_gg_gdyj fixedTag=gdrs → 股东人数近 4 期(倒序),要求连续下降 ≥3 期即通过(硬筛)。
3. tdx_kline(code, setcode, period="4", wantNum="60")(≥40 根)→ 自算 MACD(12,26,9),仅加分不硬筛:DIF>0 基础+1,近5日金叉额外+1。
4. 非ST 名称过滤。
输入契约(agent 拉完数据后写成 dpool_input.json,脚本只读它):
{
"candidates": [ {"code":"000630","market":0,"name":"铜陵有色","price":6.59,"chg":2.81,
"main_net":303096544,"net5":48717184,"profit_ratio":57.62,
"avg_cost":6.5,"cm90":18.74,"main_ratio":18.00} ],
"quotes": { "000630": {"inout":278931000,"amount":1771665540} },
"gdrs": { "000630": [866667,342027,269241,288242] },
"kline": { "000630": [6.59, 6.61, ... ] }
}
> kline 为紧凑 list[float](升序旧→新),亦兼容 [{"date","close"}];quotes/gdrs/kline 缺某只标「未精查」不误杀。
refresh_dpool.py 组装器骨架(消费 4 个原始 JSON → 标准 dpool_input.json):
import json
def load(p): return json.load(open(p, encoding="utf-8"))
screener = load("screener_raw.json")["rows"] # [{code,name,price,chg,main_net,net5,profit_ratio,avg_cost,cm90,main_ratio}]
quotes = load("quotes_raw.json") # {code:{"inout","amount"}}
gdrs = load("gdrs_raw.json") # {code:[近4期倒序]}
kline = load("kline_raw.json") # {code:[float×60]}
candidates = []
for r in screener:
c = r["code"]
candidates.append({
"code": c, "name": r.get("name",""), "price": float(r.get("price",0)),
"chg": float(r.get("chg",0)), "main_net": float(r.get("main_net",0)),
"net5": float(r.get("net5",0)), "profit_ratio": float(r.get("profit_ratio",0)),
"avg_cost": float(r.get("avg_cost",0)), "cm90": float(r.get("cm90",99)),
"main_ratio": (float(r["main_ratio"]) if r.get("main_ratio") not in (None,"") else None),
})
out = {"candidates": candidates, "quotes": quotes, "gdrs": gdrs, "kline": kline}
json.dump(out, open("dpool_input.json","w",encoding="utf-8"), ensure_ascii=False, indent=2)
macd_signal 自算 MACD 骨架(仅加分):
def ema(vals, n):
k = 2/(n+1); e = vals[0]; out=[e]
for v in vals[1:]:
e = v*k + e*(1-k); out.append(e)
return out
def macd_signal(closes, recent_days=5):
if len(closes) < 26: return 0, "MACD(未精查)"
e12, e26 = ema(closes,12), ema(closes,26)
dif = [a-b for a,b in zip(e12,e26)]
dea = ema(dif[26-1:], 9) # 对齐索引
score = 1 if dif[-1] > 0 else 0
last = len(dif)-1
for i in range(len(dif)-1):
if dif[i] <= dea[i] and dif[i+1] > dea[i+1]: # 金叉
if (last - i) <= recent_days: score += 1
return score, ("MACD(金叉%d日内+多头)"%recent_days if score>=2 else ("MACD(DIF>0)" if score==1 else "MACD(空头)"))
> 注:上面 dea 索引对齐用 dif[26-1:] 起算,实战脚本里请确保 DEA 与 DIF 同一索引空间再判金叉;此处给思路骨架。
输出:达标票带标注(主力净额/获利盘/主力占比/集中度/户数连降/净比趋势/MACD/近5日),按综合评分排序前 10 推送;全部不达标则静默。
调度(两轮独立自动化,自行在 WorkBuddy 创建):
- 建两个 FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR 自动化,分别 BYHOUR=10;BYMINUTE=15 与 BYHOUR=14;BYMINUTE=15,工作区指向你的脚本目录。
- 两轮 prompt 各跑完整 Stage1+Stage2 刷新链路(screener→逐只 quotes/gdrs/kline→refresh_dpool.py 组装→gen_dpool.py --commit→企微推送),日期去重由 gen_dpool.py 的状态文件保证同日只推一次。交易时段守卫在 prompt 第一步。
> 时点设计(关键):
> - 10:15 早盘窗口:捕捉上午主力净流入趋势。
> - 14:15 尾盘前窗口:刻意早于尾盘偷袭窗口(14:57 后集合竞价几笔大单拉高净比做数据诱多高发),天然规避诱多做盘;「连续3日递增」是同点快照比较,看趋势方向不卡绝对门槛。
> - 两轮独立不耦合:避免 A 池静默牵连 D 池。
积分:每轮 ~1 次选股 + 候选(约 7-9 只)×(1 quotes+1 api_data+1 kline) ≈ +22~28 次行情/财务级调用,两轮合计 ~+50 次/天,相对 8 轮/天 A 池等仍可忽略。
4. 企业微信推送 wecom_push.sh
bash wecom_push.sh "<标题>" "<正文>"
- 正文支持
\n;中文/emoji 经文件传递,规避 Windows 环境变量编码问题。 - 目标由
wecom_target.conf首行决定:group=股票量化预警机器人或user私聊;群不在最近会话时自动回退私聊并告警,保证不漏报。 - agent 调用链:先发 WorkBuddy 消息 → 再
bash wecom_push.sh转发 → 确认success:true后--commit落状态。
wecom_push.sh 核心逻辑(bash,需已连接 wecom-cli):
#!/usr/bin/env bash
# 用法: bash wecom_push.sh "<标题>" "<正文>"
TITLE="$1"; BODY="$2"
CONF="wecom_target.conf"
GROUP=$(grep -m1 '^group=' "$CONF" | cut -d= -f2-)
USER=$(grep -m1 '^user=' "$CONF" | cut -d= -f2-)
# 优先群发,失败回退私聊
wecom-cli send --group "$GROUP" --title "$TITLE" --msg "$BODY" && exit 0
[ -n "$USER" ] && wecom-cli send --user "$USER" --title "$TITLE" --msg "$BODY"
5. 调度 rrule 实战(重点避坑)
- ❌ 不支持
MINUTELY;FREQ=HOURLY;BYHOUR=9下 BYHOUR 不生效——开盘突破实测每小时都触发(反复发、烧积分的根源)。 - ❌
HOURLY;BYMINUTE=5,10,...,55多值只取第一个(实际每小时一次),且每小时都白启动耗基础 token。 - ✅ 精确时刻用
FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR;BYHOUR=X;BYMINUTE=Y—— 已用实验自动化准点触发验证,每天固定 N 次、零白启动。每个时刻单独建一个 WEEKLY 自动化(单值 BYHOUR/BYMINUTE 确定性最高)。 - 脚本内置交易时段守卫(
date +%u周一至五 +%H%M09:30–11:30/13:00–14:55),即使调度异常误触发也会立即静默,不拉数据不推送。
6. 积分节约经验
- agent 每次启动都耗基础 token,静默轮也是成本——别用 11 个轮询拼分钟级(实测每天 71 次 agent 启动)。
- 改成 WEEKLY 精确时刻后:71 次/天 → 8 次/天,约省 90%。
- 恶化监控全量扫描(43 只×2 接口=86 次行情调用/轮)是最大头;后续可上「两级过滤」(先轻量筛可疑票再精查)。
- D 池每天 2 轮,候选少,增量约 +50 次行情级调用/天,可忽略。
7. 红线与免责
- 只筛选 / 监控 / 生成看板,绝不自动下单。
- 消息末尾固定附:
⚠️ 量化筛选仅供参考,不构成投资建议,据此操作风险自担。