调一支自编指标,点「测试公式」之后提示编译没过。提示里带「错误起始位置」的这一类,有一支常被当成逻辑写错的,就是通达信公式双引号错误。它跟变量名、括号、分号都对不上号,出问题的是字符串两端的引号形状:字符被换过,编译器读不到成对的引号,就停在那里报错。
下面按提示指到哪一行、引号在公式里出现在哪几处、全角字符为什么读不进来、从哪几个地方被换掉、改完怎么确认这条线走一遍。函数写法以本机公式编辑器里的函数说明为准,报错文案以本机公式管理器弹出的提示原文为准。
一、先看提示指到哪一行
公式管理器里的「测试公式」给出编译结果时,如果不通过,会带一个位置信息,形如「错误起始位置」后面跟着行号。这个行号指向的是编译器读到语句走不下去的那一处,未必是真凶所在。
引号造成的报错有个特征:缺掉的是闭合的那一个引号,编译器要一路读到语句结束,才发现引号没有配对,于是把位置报到引号所在那一行或它后面。看上去提示在下一行,实际要回上一行看字符串。
{ 引号不配对时的典型写法 }
DRAWTEXT(C>O, LOW, '阳线);
{ 右引号漏了,编译器读到这一句结束才发现没有闭合 }
所以定位的顺序是先看提示行,再往上一行看有没有字符串参数,把字符串两端的引号数一遍。这一步能把范围收窄到几行之内,也是判断这一支错是否属于引号范围的第一道分界。如果提示行与它上一行都没有字符串,就应当转去看别的成因。
还有一种表现是提示位置停在文件末尾,行号比实际代码行数还大。这种情况指向某个开引号一直没有闭合,编译器把后面的内容全当成字符串在读,走到最后才发现字符没了。顺着这个特征往回找第一个不成对的引号,位置就出来了。
二、引号在公式里只出现在三类位置
通达信的公式语言里,需要引号的地方是有限的。写清这一点,排查范围就小了一大半。
| 出现位置 | 用哪种引号 | 写法示例 | 错成什么样会报错 |
|---|---|---|---|
| 文字显示类函数的文本参数 | 英文半角单引号 | DRAWTEXT(COND,PRICE,’文字’) | 两端换成全角单引号 |
| 跨公式引用的目标写法 | 英文半角双引号 | “MACD.DIF” | 整体换成全角双引号,或引号被去掉 |
| 带字符串项的函数参数 | 按该函数说明给的引号类型 | 以本机函数列表的写法为准 | 引号类型用反,或前后不对称 |
第一类是文字显示。画线、标注这类函数把要显示的文字作为参数传进去,文字用英文半角单引号包住,引号里可以放中文。第二类是引用,把目标公式名与线名拼成一个字符串,整体用英文半角双引号包住,中间用点连接。第三类分散在若干函数的字符串参数上,取值口径要看本机函数说明,不同版本可能不同。
三类位置合起来,就是通达信公式双引号错误可能落脚的全部范围。排查时不必逐行读代码,只要在这三类位置上找引号。
三、全角引号为什么会被当成普通字符
半角引号与全角引号是两个不同的字符,占的码位不同。键盘在英文状态下敲出来的是半角;中文状态下敲出来的引号是全角,字形更宽,弯向内侧。编译器只把半角的那一对当作字符串的定界符,全角的那一对对它来说只是两个普通字符。
结果就是:字符串没有被定界,引号变成了文字内容的一部分,后面的括号与分号跟着错位,编译器只能在更远处报错。这也是为什么把全角引号改回半角之后,报错位置也跟着移动了。
{ 三种引号的字符差别 }
半角单引号 ' 文本定界用
半角双引号 " 引用写法用
全角引号 弯向内侧,只当普通字符
{ 字形接近,字符不同,编译结果也不同 }
字形上有两处可以分辨。半角引号窄,竖直,占的宽度与一个英文字母接近;全角引号宽,占的宽度与一个汉字接近,并且向内侧弯。在一行里混用两种引号,看上去像是一对,实际是两个不同字符。
想确认某一处到底是哪种,把光标停在那两个字符之间,用键盘的左右方向键各按一次。半角引号与它夹住的内容可以在同一步里跨过去,全角引号的移动步数会多一次。这个办法在编辑器里当场就能做,比把字符复制到别处查码位要快。
四、半角被换成全角的三个来源
引号不会自己变形,是被别的环节换掉的。来源主要有三处。
一是输入法状态。在中文输入法下敲引号,出来的是全角。写公式时前后切换了输入状态,两端的引号就成了一个半角一个全角,肉眼不容易分辨。
二是文本美化。网页编辑器、办公软件里的自动更正,会把直引号替换成弯引号,把直单引号替换成弯单引号。源码经过这类工具走一遍,再复制回来就已经不是原来的字符了。
三是跨平台搬运。从别的行情软件或论坛贴出来的源码里复制文字参数,那些源码对字符串的写法与本机用的不同,直接贴进公式编辑器,字符原样带过来,形状对不上就编译不过。
处理办法一致:在公式编辑器里用查找功能定位引号所在位置,逐个改成英文半角,改完再点一次「测试公式」。不要用编辑器的全局替换去猜,先把提示位置附近的那几处改掉,编译通过之后再考虑其它位置。
查找时按字符特征分两步走。先搜半角单引号与半角双引号,看看每一处是否成对出现、前后是否对称;两处引号之间夹的内容,应当是准备显示的文字或准备引用的公式名。再搜全角引号,把搜到的位置逐个替换。通达信公式双引号错误里被全角字符顶替的那一类,用这个顺序能把遗漏压下去。
五、替换之后怎么确认编译通过
改完引号,验证按三步走。
第一步,点「测试公式」,看点输出区是否还有报错。有报错就回到第一步定位,没有报错才进入下一步。测试通过只说明语法层过了,逻辑对不对不在这一步的范围里。
第二步,把公式挂到图上,确认文字按预期位置显示出来。文字显示类函数的参数顺序写错,编译一样能过,但文字会画到别的地方,这一步是查参数顺序。
第三步,进公式管理器,把这一支公式的代码与说明导出一份留存。公式与备份落在安装目录的 T0002 下,备份目录是 gs_bak。下一次从外部粘贴源码时,用留存的这一份做字符对照,引号是不是被换过,一眼就能看出来。
这三步里最容易被跳过的是第二步。编译通过就以为改完了,把公式挂上去才发现文字的位置不对,回去再翻参数顺序,绕一圈。文字类函数的参数顺序在函数说明里写得很清楚,对着说明数一遍参数个数,比在图上试要省事。
六、这一支错与其他编译错的分界
编译不通过的成因不止引号一种,变量名与保留字冲突、参数个数不匹配、分号缺失、输出线条数超限,都会报在同一类提示里。引号这一支的辨认特征有两条:提示位置落在带字符串的那几行附近,以及改动引号之后报错位置跟着移动。
如果提示位置稳定不动,改动引号也没变化,那就不在引号的范围内,应当转而去看该行的函数名、参数个数与括号配对。把两类错分开查,比在整段代码里来回找要快。
通达信公式双引号错误属于语法层的报错,不涉及任何标的判断,也不改变公式的计算逻辑。修好引号之后,公式算出来的数一个没变,变的只是它终于能编译过去了。
站内还有 通达信公式报错与卡顿排查 的条目,通达信公式编写教程 讲字符串与函数的写法,通达信新手入门问答 收着上手阶段的问题,可对照查看。
本文只作技术研究口径,不涉及也不构成对任何标的的判断。
