通达信引用公式设置里有一条容易被忽略的界线:界面上看得到的数值,并不等于公式里可以按名取用的名字。判断能不能引用,落在一个很具体的点上,对方那个名字是不是一条输出线。这条界线划清之后,同一公式内取历史值、跨公式取别人的输出线、跨周期取大周期数据这三类写法,各自才知道边界在哪里,也才知道取不到数时该往哪一层查。

一、三类引用:同一公式内、跨公式、跨周期

公式语言里的取数分三层,层与层之间的写法不同,来源也不同。写法用错层,直接后果是取值对不上,或者引用列整段是空的。先把三种写法的形状记清楚,再谈判据。

1. 同一公式内取历史值

同一个公式内部,取若干周期之前的数值用 REF(X,N),含义是把 X 往前推 N 根 K 线。X 可以是收盘价这类行情字段,也可以是本公式前面算出来的中间量。写 REF(MA5,1),取的是上一根的 MA5 值;把这种写法放进条件里,可以判断当根与上一根的大小关系。N 取 1 表示上一根,取 5 表示往前五根。往回数的位置超出已有 K 线根数时,前面的位置取不到,会留空。

2. 跨公式引用别的输出线

要取另一个指标上的线条,写法是把公式名与输出线名拼成一个字符串,中间用点号连接,整体用双引号包住,例如 "KDJ.K"。点号前面的公式名,是保存在本机公式库里的名字;点号后面的线名,是对方公式里那条输出线的名字。两个名字都要对得上,取数才成立。

3. 跨周期引用大周期数据

在字符串后面接一个周期后缀,就取该输出线在更大周期上的取值,例如 "KDJ.K#WEEK" 取周线,"MACD.DIF#MONTH" 取月线。周期后缀由本机函数说明给出,可用的后缀以本机为准。跨周期取到的是一条更大周期上的数值,它在当前周期里会连续若干根保持不变,直到大周期进入下一根。

{一、同一公式内取历史值}
MA5:MA(C,5);
PREV:REF(MA5,1);

{二、跨公式引用另一条指标的输出线,公式名与线名用点号连接,整体加双引号}
KF:"KDJ.K";
DF:"MACD.DIF";

{三、跨周期引用,在字符串后面接周期后缀}
KW:"KDJ.K#WEEK";
KM:"MACD.DIF#MONTH";

二、哪些名字能被引用:冒号与冒号加等号的分水岭

通达信引用公式设置能不能成立,先看这个名字在对方公式里有没有进入输出清单。冒号定义的是输出线,冒号加等号定义的只是中间量,这两者的差别决定了名字能不能被别的公式按名取用。

写 MA5:MA(C,5);,MA5 是一条输出线,名字会出现在输出清单里,其它公式可以按名引用。写 TMP:=MA(C,10);,TMP 只在公式内部存在,不进输出清单。在别的公式里写 TMP,编译时会把它当成一个没有定义过的变量,这就是「未定义」提示的来源。

中间量并非没有用。它在同一个公式内部可以继续被后面的算式拿来用,只是名字不对外。把一条线拆成几步来算,用冒号加等号存中间结果,读写更清楚,代价是这些名字不能被别处引用。

带 NODRAW 的输出语句仍是一条输出,区别在于它不往窗口上画线,数值照常参与计算。这样的线能不能按名引用,请以本机公式管理器里列出的输出名为准,不要凭记忆下结论。菜单名称在不同版本里可能略有差异,以本机为准。

{冒号:一条输出线,名字进入输出清单,其它公式可以按名引用}
MA5:MA(C,5);

{冒号加等号:只存中间量,名字不进输出清单}
TMP:=MA(C,10);

{中间量在同一个公式内部可以继续被后面的算式使用}
DOWN:=C < REF(C,1);
CNT:COUNT(DOWN,5);

{带 NODRAW 的输出:仍是一条输出语句,数值在,只是不画线}
HID:MA(C,20),NODRAW;

三、前置条件:存在、编译通过、逐字一致

引用要成立,得先满足几件事。

  • 被引用的公式要已经保存在本机公式目录里,也就是通达信安装目录下的 T0002 目录,并且已经编译通过。
  • 引用时写的公式名与线名,要与被引用公式里的名字逐字一致,包括大小写。大小写不同,被视为不同的名字。
  • 被引用公式改名,或者它里面那条输出线被删掉、改了名,引用处会随之失效。

公式没有编译通过,或者根本没有保存到 T0002,引用处就取不到数。公式在目录里以各自的存放形态落盘,编译过程会生成中间文件,例如 PriGS.dat 一类。改名与删线是影响引用最直接的两个动作:名字一旦改动,原来对得上的点号前后两段就对不上了,引用处随之取不到值。

进公式管理器核对时,选中被引用的公式,点修改,看它列出的输出线名,逐字比一遍,把大小写也比进去。这一步比事后在图上猜取值来源要快。

四、循环引用与参数不通透

通达信引用公式设置在结构上还有两处边界,一处是循环引用,一处是参数不通透。两处都不报显眼的错,但会让取值对不上。

甲公式引用乙公式的输出线,乙公式又反过来引用甲公式的输出线,构成往返依赖。两边的取值互相等待,公式加载时会出问题,表现为报错或者取值异常。整理公式时把依赖方向理一遍,让引用关系朝一个方向流动,避免形成回路。

被引用公式的参数不能由外部传入。引用过来的是它按自身参数算出的那条线,引用处改不了对方的参数。参数不通透意味着:想调整取值口径,要去改被引用公式本身,指望在引用处把参数传进去行不通。

{甲公式里引用乙公式的输出线}
LA:"FORMB.OUTB";

{乙公式里又引用甲公式的输出线,形成往返依赖}
LB:"FORMA.OUTA";

五、失败表现与验证方法

取值出问题时有三种表现,各自往不同方向查。

  • 引用列整段空值:先查被引用公式是否已编译、是否保存在 T0002 目录,再查公式名与线名是否逐字一致。
  • 引用列全为 0:查这条线在被引用公式里是否被赋过值,以及是否引到了只在中间过程出现、没有输出过的名字。
  • 编译提示未定义:查这个名字是否写在别的公式的冒号加等号中间量上。中间量不进输出清单,跨公式写出来就会被当成没有定义过的变量。

跨周期引用还有一层依赖:它取的是本地已下载的大周期数据。本机没有下载周线或月线数据,跨周期取值就没有来源,引用列会缺值,把大周期数据补齐之后再看取值才有效。

验证的方法是:把引用线与直接算出来的那条线画在同一个窗口里,看两条线是否重合。重合说明引用取到的就是目标数值;不重合,就带着这个差异回到上面三处再查。改完公式先点公式管理器里的测试公式,让编译先走一遍,通过之后再挂到图上。测试公式在保存环节之前点,能把编译期的问题提前拦下来。

六、检查清单

把上面的判据压成一份清单,在动手写通达信引用公式设置之前逐条对照。

  • 要引用的对象,在被引用公式里确实是一条输出线,名字进入了输出清单。
  • 被引用公式已保存在 T0002 目录,并且编译通过。
  • 引用处写的公式名与线名,与被引用公式里的名字逐字一致,含大小写。
  • 不在别的公式里引用只由冒号加等号定义的中间量。
  • 引用带 NODRAW 的输出之前,先在本机公式管理器的输出清单里确认线名确实列了出来。
  • 依赖关系里没有形成往返引用,甲引乙的同时,乙不反过来引甲。
  • 需要调整取值口径时,直接改被引用公式的参数,不在引用处等参数传进来。
  • 改完先点公式管理器里的测试公式,再把引用线与直接计算线画在同一窗口核对是否重合。

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

站内还有 新手入门问答、公式编写教程 与 指标原理 可以对照阅读。

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