通达信HHV函数用法里有一个参数,写成 20 和写成 0 算出来的是两条完全不同的线:前者看最近二十根,后者从第一根有效数据开始算。这两个结果都不报错,也不会在图上提示参数被忽略了,所以对不上数的时候,第一件事是回去看第二个参数写成了什么。下面按输出含义、参数取值、返回根数、失败来源、参数外置、核对方法六个层次拆开说。

一、HHV 与 LLV 各自输出什么

HHV 是取值函数,作用是在指定的若干根 K 线里找最大值。写法是 HHV(X,N),X 是要比较的序列,N 是要往回看多少根。X 可以是收盘价 C、最高价 H、成交量 VOL,也可以是公式前面算出来的中间量。LLV 是它的反向版本,在同样的窗口里找最小值。

这两个函数的返回值是「窗口内的极值」,不是「极值出现的位置」。这个区别在组合写法里很关键:把 HHV 的输出画成一条线,你看到的是一条台阶状的折线,窗口里没有出现新高时它保持不动;把 HHVBARS 的输出画成线,你看到的是 0、1、2、3 这样的整数序列,它在记录极值距今的根数。

{在最高价上取最近二十根的最高值,画成一条线}
HH20:HHV(H,20);

{在成交量上取最近二十根的最小值}
VV20:LLV(VOL,20);

{窗口里放中间量也可以,先算差值再取极值}
DIFF:=C-REF(C,1);
MAXDIFF:HHV(DIFF,10);

一条输出线要能被别的公式按名引用,用的必须是冒号而不是冒号加等号。上面三行里的 HH20、VV20、MAXDIFF 都是输出线,而 DIFF 只是中间量,名字不进输出清单。这个名字规则在写跨公式引用时会决定成败,站内 公式编写教程 里另有一篇专门讲输出线与中间量的分界。

二、周期参数 N 的两种取值

N 是通达信HHV函数用法里最容易被随手写坏的一处。它接受两种类型的值,含义完全不同。

第一种是正整数。写 HHV(H,20),窗口就是当前根往前数二十根,含当前根。窗口随每根 K 线向后滑动,所以这条线在图上会跟着走。N 写 1 时,窗口里只有当前根,返回值就等于当根的 H,这条线没有筛选意义,但它能用来验证函数本身是否被正确调用。

第二种是 0。写 HHV(H,0),窗口不再固定长度,而是从第一根有效数据起算到当前根。它返回的是「数据以来」的最高值。这个写法的用途是取历史极值,代价是窗口越来越长,参与计算的根数也越来越多。

两种取值混用会带来一个隐蔽的后果:公式在短历史上和在长历史上表现不同。用 HHV(H,0) 的公式,挂在上市时间不同的标的上,第一条线的起点位置不一样;用 HHV(H,20) 的公式则要到第二十根之后才有值。这不是公式错了,是窗口的定义决定的。

参数写成 0 得到的是「从第一根算起」,不是「最近一根」。想把窗口收紧到某一段,只能把 N 写成一个具体的正整数。

三、HHVBARS 与 LLVBARS 返回的是根数

HHVBARS 和 LLVBARS 常被和 HHV、LLV 一起使用,但它们输出的是周期数,不是价格。写 HHVBARS(H,20),返回的是一个整数:在这二十根的窗口里,最高价出现在距今第几根。0 表示最高价就在当前根,1 表示在前面一根,以此类推。

这个 0 的含义与直觉相反,是读数时容易搞错的一处。它表示「就是当根」,不表示「不存在」,也不表示「第一条 K 线」。把它当成位置下标去索引别的序列,取值会整体错开一格,而公式依然能编译通过,画出来的线也是连续的,只是位置对不上。

N 同样接受 0。写 HHVBARS(H,0),返回的是从第一根有效数据算起、最高价距今的根数。这个数字会随着新高的出现而反复归零,也随着时间推移不断增大,用它做条件时要注意它的量纲是根数。

{最高价距今的根数,0 表示最高价就在当根}
B1:HHVBARS(H,20);

{最低价距今的根数}
B2:LLVBARS(LOW,20);

{把根数转换成「距今多少根之前出现过极值」的文字标记位置}
DRAWTEXT(B1=0,HIGH*1.02,'当根极值');
量纲核对的办法:把 HHVBARS 的输出和 BARSCOUNT(C) 的输出画在同一个副图窗口里。前者是极值距今的根数,后者是数据总长度,两者的取值范围必须落在同一个数量级内,量纲混了会立刻看出来。

四、取数对不上的三类来源

用通达信HHV函数用法时,窗口里的值算出来和预期不一样,原因集中在三个可枚举的地方。

1. 有效数据不足 N 根

窗口要求二十根,但标的只有十二根有效 K 线。前面的位置凑不满窗口,函数取不到值,那一部分留空。公式没有报错,只是线上有断口。核对办法是把数据长度一起画出来,看断口的位置是不是正好落在 BARSCOUNT(C) 小于 N 的区间里。

2. 参数写成了 0,却按有限窗口去理解

窗口实际从第一根算起,返回的极值覆盖整段历史。表现是这条线的起点比预期早、数值比预期极端。这类差异在窗口很短的公式上不明显,在取极值的公式上会被放大。

3. 序列本身换了周期

同一个函数挂在不同的周期上,X 的含义会变。日线上 HHV(H,20) 是二十个交易日的最高价,周线上同一行语句是二十周的最高价,月线上是二十个月。周期变了而参数没变,输出自然不是原来那条线。核对办法是切到目标周期,用十字光标在第一根和最后一根上分别读数,再对照窗口定义反推。

三类来源都不产生编译错误。判断问题时不要先怀疑函数不存在,先看窗口、参数、周期这三处。

五、把 N 做成外部参数

把窗口长度硬编码在算式里,每次调试都要进公式编辑器改源码。通达信的公式可以带参数表,把 N 提出来之后,同一份源码可以带几组不同的窗口值。

参数表的每一项由名称、最小值、最大值、缺省值四个字段构成。写入参数表之后,源码里的 N 就直接是参数值,不需要另外赋值。参数值在挂载公式时从参数面板选择或输入,改动不需要重新编译源码。

{参数表:名称 N,最小 1,最大 250,缺省 20}
{源码里直接用参数名,不再单独赋值}
HIGHN:HHV(H,N);
LOWN:LLV(LOW,N);
BARS:HHVBARS(H,N);

参数的下限不要设成 0。参数表里的 0 和源码里的 0 走的是同一条分支,但参数面板上看到一个可以拖到 0 的下限,容易在调试时把窗口误设成无限长。把最小值设成 1,需要取历史极值时另写一行固定为 0 的输出,两件事分开。

多个输出共用同一个参数时,改一处会同时影响几条线。核对方法是:改完参数先只挂这一条公式,把参数面板里的取值和线上读到的极值对一遍,确认一致之后再和别的公式叠加。

六、逐根核对的验证方法

窗口类函数的验证要落到具体根上,只看整条线的形状看不出对错。按下面的顺序做,每一步都能给出一个可以比对的数。

  • 先把 N 设成 1,看 HHV(H,1) 是否等于当根的 H。这一步验证的是函数调用本身,不是窗口逻辑。
  • 再把 N 设成 3,用十字光标停在某一根上,把这一根和它前面两根的 H 读出来,手工挑最大值,和 HHV(H,3) 的读数比。三个数里挑最大没有歧义,这一步能把「含不含当根」这个口径钉下来。
  • 把 N 设成 0,看这条线的起点是否落在第一根有效数据上,而不是落在某一段硬编码的位置上。
  • 把 HHVBARS(H,3) 与上一步手工找出的最大值位置对照,确认返回的是根数:当根极值返回 0,前一根极值返回 1。
  • 切到周线周期,重复第二步。周线上的一根等于五个交易日,读数差异会很明显,这一步用来确认周期确实是取数的一部分。

验证通过之后再挂到主图上。挂载时把 HHV(H,N) 的输出和手工挑出的极值放在同一个窗口,两条线重合说明取数口径一致;不重合就带着具体哪一根对不上回到第四节的三个来源里查。

另外一点:参数表里的上限不必设得很大。窗口长度超过本机已有的数据根数,取值区间会一直留空,把上限设在本机数据长度附近,参数面板上就不会出现一个永远取不到值的档位。本机的数据长度可以在数据管理界面里看,不同版本入口位置有差异,以本机为准。

本文只作技术研究口径,不涉及也不构成对任何标的的判断。通达信HHV函数用法里真正需要记住的只有两点:N 是窗口定义的一部分,BARS 系列输出的是根数。把这两点钉住,取数对不上的问题会收敛到很小的范围。

站内还有 公式编写教程、指标原理与参数 与 选股公式与预警 可以对照阅读。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。