调一支自编指标,点「测试公式」之后提示编译没过。提示里带「错误起始位置」的这一类,有一支常被当成逻辑写错的,就是通达信公式双引号错误。它跟变量名、括号、分号都对不上号,出问题的是字符串两端的引号形状:字符被换过,编译器读不到成对的引号,就停在那里报错。

下面按提示指到哪一行、引号在公式里出现在哪几处、全角字符为什么读不进来、从哪几个地方被换掉、改完怎么确认这条线走一遍。函数写法以本机公式编辑器里的函数说明为准,报错文案以本机公式管理器弹出的提示原文为准。

一、先看提示指到哪一行

公式管理器里的「测试公式」给出编译结果时,如果不通过,会带一个位置信息,形如「错误起始位置」后面跟着行号。这个行号指向的是编译器读到语句走不下去的那一处,未必是真凶所在。

引号造成的报错有个特征:缺掉的是闭合的那一个引号,编译器要一路读到语句结束,才发现引号没有配对,于是把位置报到引号所在那一行或它后面。看上去提示在下一行,实际要回上一行看字符串。

{ 引号不配对时的典型写法 }
DRAWTEXT(C>O, LOW, '阳线);
{ 右引号漏了,编译器读到这一句结束才发现没有闭合 }

所以定位的顺序是先看提示行,再往上一行看有没有字符串参数,把字符串两端的引号数一遍。这一步能把范围收窄到几行之内,也是判断这一支错是否属于引号范围的第一道分界。如果提示行与它上一行都没有字符串,就应当转去看别的成因。

还有一种表现是提示位置停在文件末尾,行号比实际代码行数还大。这种情况指向某个开引号一直没有闭合,编译器把后面的内容全当成字符串在读,走到最后才发现字符没了。顺着这个特征往回找第一个不成对的引号,位置就出来了。

二、引号在公式里只出现在三类位置

通达信的公式语言里,需要引号的地方是有限的。写清这一点,排查范围就小了一大半。

出现位置 用哪种引号 写法示例 错成什么样会报错
文字显示类函数的文本参数 英文半角单引号 DRAWTEXT(COND,PRICE,’文字’) 两端换成全角单引号
跨公式引用的目标写法 英文半角双引号 “MACD.DIF” 整体换成全角双引号,或引号被去掉
带字符串项的函数参数 按该函数说明给的引号类型 以本机函数列表的写法为准 引号类型用反,或前后不对称

第一类是文字显示。画线、标注这类函数把要显示的文字作为参数传进去,文字用英文半角单引号包住,引号里可以放中文。第二类是引用,把目标公式名与线名拼成一个字符串,整体用英文半角双引号包住,中间用点连接。第三类分散在若干函数的字符串参数上,取值口径要看本机函数说明,不同版本可能不同。

三类位置合起来,就是通达信公式双引号错误可能落脚的全部范围。排查时不必逐行读代码,只要在这三类位置上找引号。

引用写法里的引号是源码的一部分,不是可省的装饰。写成不带引号的 MACD.DIF,引用会退化成一个普通变量名,报的是未定义,提示位置与引号无关,容易把人带偏。

三、全角引号为什么会被当成普通字符

半角引号与全角引号是两个不同的字符,占的码位不同。键盘在英文状态下敲出来的是半角;中文状态下敲出来的引号是全角,字形更宽,弯向内侧。编译器只把半角的那一对当作字符串的定界符,全角的那一对对它来说只是两个普通字符。

结果就是:字符串没有被定界,引号变成了文字内容的一部分,后面的括号与分号跟着错位,编译器只能在更远处报错。这也是为什么把全角引号改回半角之后,报错位置也跟着移动了。

{ 三种引号的字符差别 }
半角单引号  '      文本定界用
半角双引号  "      引用写法用
全角引号       弯向内侧,只当普通字符
{ 字形接近,字符不同,编译结果也不同 }

字形上有两处可以分辨。半角引号窄,竖直,占的宽度与一个英文字母接近;全角引号宽,占的宽度与一个汉字接近,并且向内侧弯。在一行里混用两种引号,看上去像是一对,实际是两个不同字符。

想确认某一处到底是哪种,把光标停在那两个字符之间,用键盘的左右方向键各按一次。半角引号与它夹住的内容可以在同一步里跨过去,全角引号的移动步数会多一次。这个办法在编辑器里当场就能做,比把字符复制到别处查码位要快。

四、半角被换成全角的三个来源

引号不会自己变形,是被别的环节换掉的。来源主要有三处。

一是输入法状态。在中文输入法下敲引号,出来的是全角。写公式时前后切换了输入状态,两端的引号就成了一个半角一个全角,肉眼不容易分辨。

二是文本美化。网页编辑器、办公软件里的自动更正,会把直引号替换成弯引号,把直单引号替换成弯单引号。源码经过这类工具走一遍,再复制回来就已经不是原来的字符了。

三是跨平台搬运。从别的行情软件或论坛贴出来的源码里复制文字参数,那些源码对字符串的写法与本机用的不同,直接贴进公式编辑器,字符原样带过来,形状对不上就编译不过。

处理办法一致:在公式编辑器里用查找功能定位引号所在位置,逐个改成英文半角,改完再点一次「测试公式」。不要用编辑器的全局替换去猜,先把提示位置附近的那几处改掉,编译通过之后再考虑其它位置。

查找时按字符特征分两步走。先搜半角单引号与半角双引号,看看每一处是否成对出现、前后是否对称;两处引号之间夹的内容,应当是准备显示的文字或准备引用的公式名。再搜全角引号,把搜到的位置逐个替换。通达信公式双引号错误里被全角字符顶替的那一类,用这个顺序能把遗漏压下去。

五、替换之后怎么确认编译通过

改完引号,验证按三步走。

第一步,点「测试公式」,看点输出区是否还有报错。有报错就回到第一步定位,没有报错才进入下一步。测试通过只说明语法层过了,逻辑对不对不在这一步的范围里。

第二步,把公式挂到图上,确认文字按预期位置显示出来。文字显示类函数的参数顺序写错,编译一样能过,但文字会画到别的地方,这一步是查参数顺序。

第三步,进公式管理器,把这一支公式的代码与说明导出一份留存。公式与备份落在安装目录的 T0002 下,备份目录是 gs_bak。下一次从外部粘贴源码时,用留存的这一份做字符对照,引号是不是被换过,一眼就能看出来。

这三步里最容易被跳过的是第二步。编译通过就以为改完了,把公式挂上去才发现文字的位置不对,回去再翻参数顺序,绕一圈。文字类函数的参数顺序在函数说明里写得很清楚,对着说明数一遍参数个数,比在图上试要省事。

全角引号的坑不只出现在文字参数上。参数表里的默认值、说明文字里如果带了全角引号,本身不会导致编译失败,但容易掩盖正文里的那一处,排查时看花眼。定位以编译提示为准,不要凭字形判断。

六、这一支错与其他编译错的分界

编译不通过的成因不止引号一种,变量名与保留字冲突、参数个数不匹配、分号缺失、输出线条数超限,都会报在同一类提示里。引号这一支的辨认特征有两条:提示位置落在带字符串的那几行附近,以及改动引号之后报错位置跟着移动。

如果提示位置稳定不动,改动引号也没变化,那就不在引号的范围内,应当转而去看该行的函数名、参数个数与括号配对。把两类错分开查,比在整段代码里来回找要快。

通达信公式双引号错误属于语法层的报错,不涉及任何标的判断,也不改变公式的计算逻辑。修好引号之后,公式算出来的数一个没变,变的只是它终于能编译过去了。

站内还有 通达信公式报错与卡顿排查 的条目,通达信公式编写教程 讲字符串与函数的写法,通达信新手入门问答 收着上手阶段的问题,可对照查看。

本文只作技术研究口径,不涉及也不构成对任何标的的判断。

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