通达信公式逻辑运算符写错的时候,公式不会报错。编译通过,绘图正常,只是结果和预期对不上:该被排除的留下了,该留下的没有出现。这类问题常常落在 AND 与 OR 的结合顺序上,把括号补上就恢复正常。看懂运算符的优先级,比逐句加输出语句去试要快得多。

下面按三种运算符的分工、运算对象的性质、结合顺序、括号用法、取反写法、与数值区间的对照以及结果异常的排查顺序七层讲。文中运算符的写法与优先级为通达信公式的通用规则,不同版本对符号形式与允许嵌套的层数可能存在差异,请以你所用客户端的帮助文档与实际编译结果为准。

一、三种运算符各管什么

通达信公式逻辑运算符在客户端里用英文词表示,写成 AND、OR、NOT 三种形式。它们的作用是把若干个布尔结果合成一个新的布尔结果。

运算符 含义 成立的条件
AND 且 两侧同时成立
OR 或 至少一侧成立
NOT 非 被作用的那一项不成立

三种运算符都要处理布尔值,所以两侧写的必须是能判断真假的比较式或已经赋值为布尔序列的变量名。把两个数值序列直接写在 AND 两侧,编译会通过,但结果没有意义,因为非零被当作成立、零被当作不成立,得到的是数值意义上的真假而不是你要的条件。

二、运算对象是序列,不是单个数

这是理解逻辑运算符最容易卡住的地方。公式里的每一个比较式算出来的不是一个真假值,而是一条由 1 和 0 组成的序列,长度与图表上的 K 线根数一致。AND 是逐根对应的元素做运算,第 30 根的结果只由第 30 根的三个条件决定。

{ 条件 A、B、C 各自是一条 1 / 0 序列 }
A AND B        { 逐根取交集 }
A OR B         { 逐根取并集 }
NOT A          { 逐根取反 }
{ 序列长度随图表数据变化,不是固定值 }

由此推出一件事:公式在图上显示一个标记,表示的是「那一根上条件成立」,而不是「这一段里条件成立」。要做区间判断,得先规定区间的起止,再用计数函数把窗口内的成立情况汇总成一个新的序列。

序列的性质还带来一个容易忽略的后果:两个条件在不同时间段落上各自成立,用 OR 连起来之后得到的是两段分开的标记,而不是一整段连续的标记。想让结果表现为连续的一段,需要另外用区间或计数的方式来描述,逻辑运算符本身做不到这件事。

三、结合顺序:AND 先于 OR

同一层里没有括号时,AND 的结合优先级高于 OR。也就是说 A AND B OR C 的算法是先算 A AND B,再拿这个结果与 C 做 OR,而不是先算 B OR C。

这个差别在条件写得不多的时候不明显,一旦条件增加到四五个,两种结合顺序给出的名单会差出不少。判断方式是把它翻译回中文:A AND B OR C 读作「同时满足 A 与 B,或者满足 C」,而不是「满足 A,并且同时满足 B 或 C」。

{ 两种读法对应两种写法,结果不同 }
A AND B OR C        { 读作:( A 且 B ) 或 C }
A AND (B OR C)      { 读作:A 且 ( B 或 C ) }

在同一条算式里混用多种通达信公式逻辑运算符,是括号缺失最集中的位置,因为不同运算符的优先级要逐层回忆。

写条件时把每一段都用括号围起来,不是为了改变结果,而是为了让人读的时候不用回头查优先级。公式写完过几天再改,靠记忆判断优先级迟早出错。

四、括号的三种用法

第一种是分组,把需要先算的部分围起来,作用与数学里的括号一致。第二种是分层,先算出几个中间条件并赋给变量名,再用变量名做组合,这样上级条件的读法会清楚不少。第三种是消除优先级带来的歧义,即使按优先级算出来的结果正确,也把括号补上。

{ 用中间变量分层,代替一长串连写 }
强势:=C>MA(C,20);
放量:=V>MA(V,5);
{ 组合时读起来是一句人话,不是一串符号 }
候选:强势 AND 放量;
{ 需要放宽时只改这一行,不用动上面两行 }

把中间条件单独赋值还有一个附带好处:每个中间变量都是可见的输出项,可以先把它们分别显示在图上,确认各自判断的位置对不对,再合成最终条件。排查时逐个看中间项,比看合成后的总结果快。

五、NOT 与否定条件的写法

取反有两种写法,一是用 NOT 包住整个条件,二是在比较方向上取反。同一件事用两种写法得到的结果一致,但可读性差别很大:NOT (C>MA(C,20)) 与 C<=MA(C,20) 是相邻的两段,前者读作「不在均线上方」,后者读作「在均线及下方」,对包含相等位置的处理需要仔细核对。

需要注意的只有一处:取反的范围。NOT 只作用于紧随其后的那一项,如果这一项是一串未加括号的组合,取反的就是按优先级算完的结果,而不是你想要的那一部分。要取反一整组条件,先用括号围起来。

六、与数值区间写法的对照

描述一个数值落在某段范围里,可以写成两个比较式的 AND,也可以直接用一个范围判断。两种写法的结果一致,差别在于边界是否包含。

想表达的意思 组合写法 需要核对的地方
落在区间内部 两个比较式用 AND 连接 两端是否都要包含,两个比较方向要一致
落在区间外部 两个比较式用 OR 连接 写成 NOT 包住内部区间更不容易漏边界
落在两端之外但不含端点 两个严格比较式用 OR 连接 端点那一根会不会被漏掉

第二行的写法值得单独说。区间外部的正确组合是 OR 而不是 AND,因为在同一根上大于上界与小于下界不可能同时成立,用 AND 连起来会得到一个恒为 0 的结果。公式不报错、图上什么都不显示,问题就出在这里。

七、结果全是 0 或全是 1 时的排查顺序

第一步,把每个中间条件单独画出来,看它们各自成立的位置对不对。第二步,确认连接词用的是 AND 还是 OR,特别是描述区间外部的那种情况。第三步,检查括号的范围,确认取反作用在哪一段。第四步,核对比较方向与边界符号,看端点被算进了哪一侧。

{ 中间条件单独输出,用来定位问题在哪一段 }
条件一:强势;
条件二:放量;
{ 分别看图上的标记位置,再决定改哪一个 }
合计:条件一 AND 条件二;

这四步的顺序是按判断成本排的。第一步不需要逻辑推理,只看位置;第二步和第三步只改连接词与括号;第四步最容易漏,放在最后核对。跳着查会在几种可能之间来回换,反而更慢。

排查时还有一个更直接的做法:把最终条件临时拆成两行输出,一行只算前半段,一行只算后半段,看哪一行的成立位置与预期不符。哪一行不对,问题就落在那一行包含的比较式上。这个方法不需要理解优先级,只需要看图上的标记位置,对不熟悉结合顺序的人更友好。

八、写条件的建议

通达信公式逻辑运算符本身只有三个,容易出问题的地方是它们的组合。条件超过三个就分层赋给中间变量,每层都用一个说得清楚的变量名;需要组合时一律加括号,不依赖优先级;取反时先围括号再取反。做到这三条,条件出错的位置基本只剩下比较方向和边界符号两处。

条件写法与赋值符号的关系见 通达信公式编写教程 一栏;条件合成之后如何落到名单与排序上,见 通达信选股公式与预警 一栏。

文中运算符写法与结合优先级为通达信公式的通用规则;不同版本与券商定制版对逻辑运算符的符号形式、允许嵌套层数与比较层级存在差异,具体请以你所用客户端的帮助文档与实际编译结果为准。本文只讨论公式语法与写法,不构成任何投资建议。

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