把通达信字符串比较公式当成普通的数值判断来写,第一行就会卡住。通达信的公式语言以数值为主体,字符串在里面的地位不一样:它能从数据字段里取出来,能作为文字画到图上,但只有少数几个函数接受它当参数,比较就是其中之一。所以这类公式要回答的重点落在「拿什么比、能比到什么程度」,不在于怎么算。
一、公式里的字符串只从三个地方来
第一个来源是标的自身的属性字段。行业、概念、地域这三类板块名称,各自有对应的字段可以取,取回来的是名称本身,不是编号。字段名随版本变化,可靠的做法是在公式编辑器的函数列表里按「板块」分类查找,不要凭记忆默写。
第二个来源是显示用的代码与名称。这类内容主要给 DRAWTEXT 一类的绘图函数当输出,让图上出现一行字。它们能显示,不等于能参与计算。
第三个来源是写在源码里的文本常量,比如 DRAWTEXT 的第三个参数那对被单引号包住的字。常量是写死的,字段是取来的,两者的区别在于后者会随客户端数据变化。
这三类之外的字符串基本进不了公式。没有从文件读字符串的函数,没有从网页抓字符串的函数,也没有把数值转成任意文本再拼起来的函数。
二、比较只能整串相等,没有包含、截取与模糊
字符串比较函数做的是整串比对:两个参数都是字符串,返回一个数值,用来表示这两个串是否相同。它没有「包含」这种语义。想表达「板块名称里带某某两个字」,函数层面做不到,只能把所有符合条件的板块全名逐个列出,用逻辑或连接起来。
这一点直接决定了写法的形状。需求是「只看某几个板块」时,写法是一串等值比较;需求是「看某一类板块」时,写法是把这一类里的名字枚举完整,漏一个就少一批结果,而且不会报错。
| 需求 | 字符串比较能不能做 | 写法 |
|---|---|---|
| 只看某一个板块 | 能 | 一次等值比较 |
| 看几个指定板块 | 能 | 多次比较,逻辑或连接 |
| 看名称里含某个词的板块 | 不能 | 枚举全名,或改用自定义板块 |
| 按名称前缀分类 | 不能 | 同上,或在板块文件层面先分好 |
也正因为没有包含语义,字符串比较公式的维护成本比数值条件高:板块一改名、一拆分,枚举列表就得跟着改,而这些改动只能靠人发现。
三、比较之前先把脏字符清掉
字符串比对是逐字符的。多一个空格、括号用了全角、字母大小写不一致,比较结果就是「不相等」。客户端里板块名称带空格的情况并不罕见,从别处复制名称贴进公式时,还容易把不可见字符一起带进来。
处理办法不是写清洗函数,通达信没有这类函数。能做的是三条:名称从客户端里直接复制,不要手打;比较的两边都用单引号包住,引号本身要用半角;写完先用一次条件选股跑一遍,结果为零时先怀疑名称对不上,而不是先怀疑逻辑写错。
四、骨架:把比较结果先落成中间量
比较结果是一个数值,条件里要拿它跟一个具体值比。这个具体值代表「相等」还是「不等」,不同版本、不同函数分类里的说明可能有出入,写死之前先用一行测试公式打出来确认,不要凭印象写。
{先取名称,再把比较结果落成中间量}
所属:=HYBLOCK;
比较值:=STRCMP(所属,'半导体');
{用一行测试公式确认:相等时比较值是 1 还是 0}
命中:=比较值=1;
原条件:=CLOSE>MA(CLOSE,20);
结果:命中 AND 原条件;
把比较单独落成一行有两个好处。一是调试时只改这一行就能切换判定方向,不用动主条件;二是复核时能一眼看出「字符串判断」与「数值判断」在哪一层汇合,出问题时先查哪一层很清楚。
主条件与字符串判断的顺序也值得注意。数值条件在前,字符串判断在后,计算量的差别在单只标的上看不出来,但条件选股是对全市场逐只求值,把能快速排除的条件放前面,整套流程的耗时会更短。这一条在自定义数据与全市场扫描里更明显。
五、三种失效:改名、多归属、版本差异
改名导致的失效最隐蔽。板块在客户端里被改名或合并之后,公式里的旧名称不再匹配,条件照常编译通过,结果却变空。它不报错、不提示,只能靠定期回看命中数量发现。这类问题的根子在数据那一端:通达信字符串比较公式里写的名称是常量,被比较的名称来自客户端,两端谁变了都不会有人通知你。
多归属是第二个坑。一个标的的行业归属按字段取回来只有一条名称,概念归属可能挂着好几条,而字段取回来的是其中一条。用它去比「是否属于某个概念」,只能比到那一个,另外几个概念不会命中。需求涉及多个概念时,要么按概念逐个建条件,要么把标的整理进自定义板块再判断。
版本差异是第三个。字段名、函数所在的分类、函数参数的顺序,在不同版本与券商定制版之间可能不同。同一段源码在 A 机器上编译通过,在 B 机器上提示函数不存在,原因多半在这里。遇到这种情况,先在出问题的机器上打开函数列表,按分类找到对应项,再照它的写法改。
六、验证:三行测试比读文档快
第一行打返回值。写一条只输出比较结果的公式,挂到副图上,找一只确定属于目标板块的标的看输出值,再找一只确定不属于的看输出值。两个值一比,「相等对应哪个数」就确定了。
第二行打名称。把取到的板块名称用文字函数画到图上,与客户端里显示的板块名称对照。字形相近的字符、全角与半角、看不见的空格,在这一步会暴露出来。
{两行验证:一行看返回值,一行看名称本体}
所属:=HYBLOCK;
比较值:STRCMP(所属,'半导体');
名称:DRAWTEXT_FIX(1,0.01,0.05,0,所属),COLORWHITE;
第三行打计数。把条件放进条件选股,看命中数量的量级是否符合预期。为零,先查名称;数量远大于预期,先查逻辑或有没有写漏括号,导致判断被短路。
如果需求本身就是一份名单,更好的路径是绕开字符串判断:把标的整理进自定义板块,公式里只判断是否属于该板块,名单的维护交给板块文件。名称变了只改板块,不动公式,这类维护成本能降下来一大截。
| 情形 | 建议路径 |
|---|---|
| 固定几个板块,长期不变 | 字符串等值比较,枚举写全 |
| 名单需要调整 | 自定义板块 + 板块判断 |
| 需要按名称关键词分类 | 先在板块文件层面分好,再判断 |
| 跨平台移植 | 先确认目标平台有没有等价的字符串函数 |
通达信字符串比较公式的边界很清楚:能取到名称,能做整串相等,做不了包含与模糊。把这三点记住,写之前先判断需求落在哪一格,比写完再改省事。口径与名称清单都写进注释,下次改名时才知道要动哪一行。
站内还有 通达信公式编写教程 的条目,讲中间量与输出线的写法;复盘方法与数据工具 里讲板块数据的来源与记录;通达信选股公式与预警 讲条件怎么组合与排序。
本文只作技术研究口径,内容是公式语法与字段取数的说明,不涉及也不构成对任何标的的判断。文中板块名称为示例,请按自己客户端里的实际名称填写。
