简介:这是一份面向通达信用户的技术文档,聚焦“双针探底”这一经典底部形态的主图指标与选股公式实现,适合具备一定公式编写基础、希望把形态识别落地为可执行代码的股票技术分析学习者与量化选股爱好者参考。资源为单个doc文档,压缩包约161KB,内容以源码与说明文字为主,便于直接复制到通达信公式管理器中使用。文档围绕核心逻辑展开:前30天内出现两根最低价一致、且带有长下影的K线,通过TJ、T1、T2、T3等变量完成条件判定,主图部分用DRAWLINE绘制双针连线并标注“双针探底”,配合DRAWICON与DRAWTEXT进行信号提示,选股部分则在同一条件基础上筛选出尚未大幅反弹的标的,形成主图与选股两套可用代码。目前已有一百七十余人学习,适合希望通过源码理解形态判定、并据此搭建自选股监控的读者借鉴与二次修改。
1. 双针探底在通达信里到底要解决什么问题
盘中经常出现这样的画面:一只票连续两天砸出长下影,第二根针的低点跟第一根几乎齐平,第三天收阳。事后看是标准的支撑确认,可当下要么没注意,要么看到了不敢动手。双针探底要做的事就是把这套肉眼判断翻译成通达信公式语言——收盘后自动把两根针标在主图上,同时用同一套条件把全市场符合条件的票筛出来。
标题里的三个词对应三件事:源码是判定逻辑本体,主图是把信号画回 K 线图上,选股是把信号变成可执行的筛选条件。三者共用一套判定,只是输出方式不同。适合手上有通达信、想把自己盯盘经验固化下来、又不打算从零啃公式语法的人。下面从判定逻辑讲起,一路落到能直接粘进通达信公式管理器的源码。
2. 双针探底主图指标源码:先教会公式认出一根针
2.1 判定一根针要用到的四个量:实体、下影、全幅、回溯
任何"探底针"的判定,本质都是比较三个长度之间的关系:K 线实体、下影线、当日全幅。通达信公式里这三个量都不需要额外数据源,直接由 OHLC 算出来。
- 实体长度:
ABS(C-O),收开价差的绝对值,阳线阴线都适用。 - 下影线长度:
MIN(C,O)-L,收开价里较小的那个减去最低价。 - 当日全幅:
H-L,最高价减最低价。
针的形态要求下影线足够长:既要比实体长出一截,也要在当日全幅里占主导。前者保证它是"锤"而不是实心大阴线,后者保证它是"扎下去又拉回"而不是普通震荡。
要把两根针串起来,还得知道上一根针离今天有多远。通达信提供BARSLAST(X),返回上一次条件 X 成立到现在经过的周期数;当日成立时返回 0,昨天成立时返回 1。配合REF(X,N)就能把"上一根针的位置"换算成具体周期。
最小可跑的判定片段长这样:
{ 单根针的最小判定 } BODY:=ABS(C-O); SHADOW:=MIN(C,O)-L; RANGE:=H-L+0.0001; { 加极小值,防一字板全幅为 0 } PIN:=SHADOW>=1.5*MAX(BODY,0.01) { 下影至少是实体的 1.5 倍 } AND SHADOW>=0.5*RANGE; { 下影至少占当日全幅的一半 }这里有两处小写法值得说清楚。MAX(BODY,0.01)是给实体兜底,十字星的实体接近 0,除法比较会失真;H-L+0.0001是给全幅兜底,一字板当天H=L,不做处理会得到 0 分母。这两个兜底值不影响正常 K 线的判定结果,但能让公式在极端行情里不报错、不抽风。
PIN这个变量在通达信里用:=赋值,表示只做中间计算、不输出到图上。真正要画线或输出结果时才用:。这一条区分整个公式体系都成立,后面主图转选股也靠它。
2.2 把两根针连起来:双针探底主图公式完整源码
单根针只是原料,"双针"才是形态。判定链是四步:当前是针 → 找到上一根针的位置 → 两者的低点足够接近 → 位置处于相对低位。写成通达信主图叠加公式如下:
{=========== 双针探底 · 主图叠加 ===========} N:=20; { 两根针之间允许的最大间隔 } K:=1.5; { 下影线 / 实体 的最小倍数 } R:=0.5; { 下影线 / 当日全幅 的最小占比 } TOL:=1.02; { 两根针低点的价格容差,1.02 表示允许 2% } BODY:=ABS(C-O); SHADOW:=MIN(C,O)-L; RANGE:=H-L+0.0001; { 第一步:定义单根针 } PIN:=SHADOW>=K*MAX(BODY,0.01) AND SHADOW>=R*RANGE; { 第二步:当日为针时,回溯上一根针的周期数 } LAST:=REF(BARSLAST(PIN),1)+1; { 第三步:两根针的低点落在容差带内 } NEARHIGH:=L<=REF(L,LAST)*TOL; NEARLOW :=L>=REF(L,LAST)/TOL; NEAR:=NEARHIGH AND NEARLOW; { 第四步:位置过滤,20 日均线之下才算低位探底 } LOWZONE:=C<MA(C,20); XG:=PIN AND LAST<=N AND NEAR AND LOWZONE; { 绘图:所有针画绿色下箭头,成立的双针画红色上箭头并加文字 } DRAWICON(PIN, L*0.98, 2); DRAWICON(XG, L*0.97, 1); DRAWTEXT(XG, L*0.955, '双针探底'), COLORRED;逐段说明判定逻辑。LAST:=REF(BARSLAST(PIN),1)+1是整段代码的关键:BARSLAST(PIN)在昨天那一根 K 线上的取值,等于"从昨天往回数,最近一根针的间隔";加 1 就换算到今天的位置。当日PIN成立时才使用LAST,所以不会出现拿不到参照物的情况。
NEAR用上下两条不等式夹出一个容差带,而不是写ABS(L-REF(L,LAST))<0.01。原因有两个:一是不同价位的股票"绝对差值"没有可比性,容差必须用比例;二是分两行写方便单独调一侧——只想允许第二针略高、不允许破位,就把NEARLOW改成L>=REF(L,LAST)。
LOWZONE:=C<MA(C,20)这条过滤不能省。长下影在高位同样会出现,那往往是冲高回落留下的痕迹,跟探底不是一回事。把位置约束加上,信号数量会明显下降,但剩下的样本干净得多。
绘图部分,DRAWICON(COND, PRICE, TYPE)的第二个参数是画图位置的纵坐标。主图叠加公式的坐标系就是价格,所以用L*0.98把图标放在当日最低价下方一点,不会跟 K 线重叠。DRAWTEXT同理,位置再往下压一档给文字留空间,末尾加, COLORRED单独指定颜色。
2.3 主图公式的四个参数:默认值与调节方向
| 参数 | 含义 | 默认值 | 调大后的效果 | 调小后的效果 |
|---|---|---|---|---|
| N | 两根针之间的最大间隔(交易日) | 20 | 信号变多,形态变松散,容易出现"隔月双针" | 只认近距离双针,信号少但更紧凑 |
| K | 下影线相对实体的倍数 | 1.5 | 要求更长的针,信号变少 | 略带下影就算,噪声明显上升 |
| R | 下影线占当日全幅的比例 | 0.5 | 要求下影主导全天,接近标准锤子线 | 长十字星也会被算进针 |
| TOL | 两根针低点的价格容差 | 1.02 | 允许第二针比第一针低 2%,容错更强 | 接近 1.00 时要求两点几乎齐平 |
这四个值在公式管理器里都可以拖成参数控件,不必每次都改源码。实操中我一般把 N 和 TOL 留在参数框里调,K 和 R 写死在源码中——形态的松紧是审美问题,位置和间隔才是策略问题。另外要注意一点,主图叠加公式必须在公式管理器的"画线方法"里选主图叠加,否则这套带DRAWICON的公式会被塞进副图,价格坐标全乱。
3. 双针探底选股公式源码:同一套逻辑换个输出口
3.1 主图公式改选股公式,哪些语句必须删
主图和选股共用判定段,但后半截完全不能混。通达信选股公式运行在条件选股引擎里,没有坐标轴、没有画布,凡是涉及绘图的函数一律不认。具体要删掉的是这几类:
DRAWICON、DRAWTEXT、DRAWNUMBER:绘图与标注。STICKLINE、DRAWBAND、PARTLINE:画柱、画带、画分段线。DRAWKLINE、DRAWLINE:画 K 线和连线。- 所有带颜色后缀的输出语句,比如
, COLORRED。
还有一条硬规则:选股公式必须有且只有一个用冒号:输出的结果,多一个冒号输出,条件选股引擎会取第一个,后面的白写。中间变量一律用:=,正文里最后一行写XG: 条件 AND 条件;。
顺带说下命名。热词里常能看到"金针探底选股公式源码",那说的是单针版本,判定结束在一根 K 线上;双针多了一层"两根针低点接近"的约束,信号量大约只剩单针的三分之一到五分之一,但胜在要求了二次确认。两者不冲突,可以都建成公式,在不同的行情阶段换着用。
3.2 选股公式完整源码与逐行对照
{=========== 双针探底 · 选股 ===========} N:=20; K:=1.5; R:=0.5; TOL:=1.02; BODY:=ABS(C-O); SHADOW:=MIN(C,O)-L; RANGE:=H-L+0.0001; PIN:=SHADOW>=K*MAX(BODY,0.01) AND SHADOW>=R*RANGE; LAST:=REF(BARSLAST(PIN),1)+1; NEARHIGH:=L<=REF(L,LAST)*TOL; NEARLOW :=L>=REF(L,LAST)/TOL; NEAR:=NEARHIGH AND NEARLOW; LOWZONE:=C<MA(C,20); { 量能过滤:当日量不低于 5 日均量的八成,说明有承接 } VOLOK:=V>=MA(V,5)*0.8; { 唯一输出 } XG:PIN AND LAST<=N AND NEAR AND LOWZONE AND VOLOK;从上往下读,前半段跟主图公式一字不差,这是刻意保留的——两份源码共用同一套判定,主图上看到的信号,选股结果里一定能找到,不会出现"图上有、选不出"的错位。这种错位在改了主图参数却忘了同步选股公式时非常常见,属于最容易踩的坑之一。
LAST那一行的行为和主图完全一致:只有当日为针时才取值,非针日算出来的数字无意义,但因为输出条件里带了PIN,无意义的值永远不会被用到。
VOLOK是新增的量能条件。探底针的有效性跟成交量绑得很紧:缩量探底往往只是没人卖,放量探底才说明有人在低位接。这里只要求当日量不低于 5 日均量的 80%,属于宽松档;如果想把标准提到"明显放量",可以改成V>=MA(V,5)*1.5。这个系数的绝对值不重要,重要的是保持和你的持仓周期匹配——做隔日短打用严格档,做波段留宽松档。
最后一行XG:是唯一输出点。条件之间用AND串联,任意一条不满足,该股就直接被过滤,不会出现在选股结果里。
3.3 加一层趋势结构,把逆势针和顺势回踩分开
只靠形态和位置,选出来的票里仍然混着一类"下跌中继":股价在下降通道里连续出新低,每次探底都留长下影,形态上完全符合双针,但趋势没走完,接进去就是下一段下跌的开始。这类信号很难靠单根 K 线过滤掉,得看更长周期的结构。
一个实用做法是加均线排列约束,要求 20 日线不再陡峭下行:
SLOPE20:=(MA(C,20)-REF(MA(C,20),5))/REF(MA(C,20),5)*100; TRENDOK:=SLOPE20>-1; { 20 日线 5 日内跌幅不超过 1% } XG:PIN AND LAST<=N AND NEAR AND LOWZONE AND VOLOK AND TRENDOK;SLOPE20算的是 20 日均线在最近 5 个交易日的百分比变化,>-1允许它小幅下行但不允许加速下跌。这个门槛比"必须拐头向上"宽容,能保住相当一部分刚见底的票;如果改成SLOPE20>0,信号量会砍掉一半以上,更适合右侧交易者。
另一条可以并行验证的约束是股价与 60 日线的距离。C>MA(C,60)*0.85 AND C<MA(C,60)*1.05这一条能把深跌反弹的票和中枢震荡的票分开:跌破 60 日线太多说明趋势已坏,离得太近则说明还在高位没真正探底。这两条可以做成注释,需要时再打开。
3.4 在通达信公式管理器里建公式并跑一次盘后选股
从源码到能用的信号,中间有五步固定的操作:
- 快捷键打开公式管理器,选择"条件选股公式"→"其他类型"→"新建"。
- 公式名填
SZTAN_DOUBLEPIN,中文描述写"双针探底选股"。把上面 3.2 的源码整段粘进编辑区。 - 点"测试公式",确认底部提示编译通过。报错信息通常会指到具体行号,最常见的错误是漏了分号或是把
:=写成了:导致多输出。 - 保存后回到主界面,走"功能"→"选股器"→"条件选股",在公式列表里找到刚建的公式,选"加入条件"。
- 选股范围选"全部 A 股",选股周期保持日线,点"执行选股"。
盘后跑一次,结果会落在"条件选股结果"板块里。用通达信实时行情刷新时,这个板块会跟着更新,但要注意选股公式用的是当日快照,盘中跑出来的信号在收盘前会变——探底针的下影线在尾盘被吃掉是常事。稳妥的节奏是收盘后跑一遍,第二天开盘再复核一次。
4. 双针探底公式的调参、回检与排错
4.1 从信号数量倒推参数:三个必须先定下来的值
参数不是凭感觉调的,得先明确你这套信号一天想看到多少个结果。全市场四千多只票,双针探底属于低频形态,合理的区间是这样的:
| 期望日信号数 | N | K | TOL | 说明 |
|---|---|---|---|---|
| 30~80 只 | 30 | 1.2 | 1.03 | 宽松档,适合做池子初筛,再人工看图 |
| 8~25 只 | 20 | 1.5 | 1.02 | 默认档,兼顾覆盖率和形态质量 |
| 0~6 只 | 15 | 2.0 | 1.005 | 严格档,要求两根针几乎齐平,适合盯少数票 |
调参顺序建议是:先固定 K 和 TOL,用 N 把数量拉到目标区间;再动 K 收紧形态;最后微调 TOL。反过来调会很难收敛——TOL 一松,形态立刻泛滥,你分不清是哪个参数在起作用。
有一点要提醒:把 K 调到 2.0 以上后,很多票会直接消失在结果里,原因不是形态不好,而是下影线长度赶不上实体的两倍。这种情况下不要急着判定公式坏了,先拿一只明显有双针的票,把PIN、LAST、NEAR分别用:输出到副图,逐层看是哪一步没通过。这比反复改参数有效得多。
4.2 用导出数据做一次可复现的信号回检
通达信自带的信号测试能给出粗略统计,但如果想看清信号出现后 5 日、10 日的分布,导数据到 Python 里算更快。公式逻辑可以一比一翻译:
import pandas as pd def double_pin(df, n=20, k=1.5, r=0.5, tol=1.02, ma_len=20): """df 需包含 open/high/low/close/volume,按时间升序""" body = (df["close"] - df["open"]).abs() shadow = df[["close", "open"]].min(axis=1) - df["low"] rng = df["high"] - df["low"] + 1e-4 pin = (shadow >= k * body.clip(lower=0.01)) & (shadow >= r * rng) # 复现 BARSLAST:记录每根 K 线距离上一根针的周期数 last = pd.Series(index=df.index, dtype=float) gap = None for i, flag in enumerate(pin): last.iloc[i] = gap if gap is not None else 9999 gap = 0 if flag else (gap + 1 if gap is not None else None) prev_low = df["low"].shift(last.astype(int)) near = (df["low"] <= prev_low * tol) & (df["low"] >= prev_low / tol) lowzone = df["close"] < df["close"].rolling(ma_len).mean() return pin & (last <= n) & near & lowzone df = pd.read_csv("sh600000.csv") # 从通达信导出的日线数据 sig = double_pin(df) df.loc[sig, ["close"]].assign( ret5=df["close"].shift(-5) / df["close"] - 1, ret10=df["close"].shift(-10) / df["close"] - 1 ).describe()这段代码的价值在于把BARSLAST显式还原成一次循环。通达信里BARSLAST是黑盒函数,Python 里展开后可以清楚看到:last记录的是"截至当前 K 线,距离上一根针过了多少根"。prev_low用shift取到那根针的最低价,near就复现了容差带判定。拿着导出的历史数据跑一遍,再对照通达信公式在图上标出的位置,两边信号应当完全重合;如果对不上,多半是复权方式不一致——通达信导数据时要选和前复权一致的选项,否则除权日的价格断层会让NEAR判定全乱。
4.3 双针探底源码最常见的五个问题
公式编译通过但图上没图标。十有八九是画线方法选错了。主图叠加公式被当成副图公式,价格坐标和副图坐标差了几个数量级,图标画到了看不见的地方。检查公式管理器中该公式的"画线方法"是否为"主图叠加"。
选股结果和主图标记对不上。通常是主图加了量能、趋势条件,选股公式没同步。把过滤条件抽出来单独维护,两份源码要么完全一致,要么在注释里写明差异。
信号全挤在暴跌日。LOWZONE:=C<MA(C,20)这条约束在普跌行情里会失效,因为几乎所有票都在均线下方。可以再加绝对值约束,例如C>MA(C,60)*0.8,把跌幅过深的票剔掉。
BARSLAST返回 0 导致的误判。如果忘记加PIN作为输出前置条件,非针日算出来的LAST会指向一个很远的周期,REF(L,LAST)可能取到几十天前的低点,恰好和当日形成"容差内"的巧合。XG里必须有PIN AND,这不是可选项。
参数改了以后结果没变化。通达信公式管理器里的参数控件值和源码里写死的常量会打架。如果在源码开头写了N:=20;,参数控件里又设了 30,实际生效的是源码里的 20。要么把:=改成参数声明INPUT:N(20,5,60,1);,要么彻底不用控件。
5. 把双针探底扩成可复用的多针模板
双针是最容易肉眼记忆的版本,但真实走势里更常见的是三根、四根长下影挤在同一价位带。这套逻辑稍微改一改就能泛化,而且泛化之后信号质量往往更高——多根针意味着这个价位被反复测试、反复承接。
改法是把"上一根针"换成"最近 M 根针里至少 K 根落在同一价位带"。通达信没有直接的滚动计数,用COUNT加条件就能近似:
{ 近 20 日内至少 3 根针,且这些针的低点都落在 6% 的区间内 } PINC:=COUNT(PIN,20)>=3; LOWMIN:=LLV(IF(PIN,L,9999),20); LOWMAX:=HHV(IF(PIN,L,0),20); BANDOK:=PIN AND (LOWMAX-LOWMIN)/LOWMIN<0.06; { 当日必须是针,且当日低点落在历史针群区间内 } XG3:PIN AND PINC AND BANDOK AND L<=LOWMAX*1.01 AND L>=LOWMIN/1.01;这里IF(PIN,L,9999)和IF(PIN,L,0)分别把非针日的价格推向两端,LLV/HHV取出来的就是"针群里最低的那根"和"最高的那根"。(LOWMAX-LOWMIN)/LOWMIN<0.06要求这组针压缩在 6% 的价格带里,带宽越窄,支撑越明确。6% 这个数不必死守,小盘股波动大可以放到 10%,大盘股收到 4% 也不为过。
另一个值得做的是跨周期确认。日线选出双针后,切到周线看这根针落在什么位置:如果周线同样处在长期均线附近甚至本身也是一根长下影,信号权重会高一档。通达信支持在条件选股里指定周期,也可以用#WEEK引用跨周期数据,把周线的C和MA(C,10)拉进日线公式做联合判定。这一步会拖慢选股速度,但换来的是把"日内噪声"和"级别支撑"区分开,对于持仓周期超过一周的人,这笔开销值。
最后一个手感上的技巧:双针成立当天不必急着进场。这类形态的第二根针经常在次日早盘被再试探一次,把当日低点打掉一点点再拉回。把选股结果放进自定义板块,观察开盘后 30 分钟的表现,如果低点没有明显跌破前一日的那根针,再考虑动手。这个再确认动作用公式很难写死,但用自选股盯两天就能形成习惯。
本文还有配套的精品资源,点击获取