拿到一份通达信选股公式源码,先看长短、再看有没有注释,是判断方向错了。源码是否值得采用,取决于三件可以在纸面上核实的事:每一行赋值算的是什么量、参数从哪里来、最终输出的是什么形式的结果。读通达信选股公式源码不需要先把它跑起来,把这三件事逐行读出来,就已经能筛掉一批不合用的写法。
下面按可读性的判断标准、逐行结构、命名与参数表、函数可移植性、审读清单、结果边界展开。文中函数名与菜单路径以通达信金融终端个人版为准,券商定制版的函数集可能有差异,以该版本自带的函数列表为准。全文只讨论代码本身的结构与可读性,不涉及任何标的的判断。
一、源码长度与可信度没有关系
行数多并不表示考虑周全。一段长源码,可能是把一句逻辑拆成十几个中间变量,也可能是把同一件事用不同方式重复计算了多次;一段只有六行的源码,也可能每一步都对应一个明确的判断。长度本身不携带信息。
真正能区分源码质量的是另外三处:
- 中间变量是否带含义。命名为
均线偏离的变量,读它的算式应当能看出偏离是怎么算的;命名为X1、X2、A1的变量,读到最后要回头翻到前面才知道它代表什么。 - 阈值是否集中。区间长度、倍数、比例这类会随使用场景调整的量,如果写在文首集中定义,改动时只动一处;如果散落在各个表达式里,改动时要在十几行中逐处寻找,漏掉一处不会报错,但结果会变。
- 输出是否单一。条件选股公式的末尾只应有一个逻辑输出。输出多个变量的写法在图上能显示多条线,放进条件选股公式里则会让判定对象变得不明确。
注释多不等于可读。注释与算式不一致时,注释会让阅读者相信一个错误的结论。读源码时以算式为准,注释只作参考。
二、一段可读的通达信选股公式源码长什么样
把上面三处标准落到一段具体代码上。下面这段没有使用任何平台特有函数,每一步都能用一句中文读出来。
{ 参数集中在文首:区间长度与倍数都在这里 }
N:=20;
倍:=1.5;
{ 中间变量:每个变量对应一个可说的量 }
均线:=MA(C,N);
偏离:=(C-均线)/均线;
量均:=MA(V,N);
{ 条件:拆成可以单独核对的几项 }
放量:=V>量均*倍;
区间高点:=REF(HHV(H,N),1);
突破:=C>区间高点;
偏离在范围内:=偏离>-0.05 AND 偏离<0.08;
{ 输出:条件选股公式只保留一个逻辑输出 }
选股条件:放量 AND 突破 AND 偏离在范围内;
逐行看三处写法:
- 赋值符号的区别。
:=赋值的是中间变量,不输出到图上;:赋值的是输出变量,会画到图上。这段代码里只有最后一行用了:,前面全部用:=,这是条件选股公式的常规写法。 - 参数与常数的位置。
N与倍写在文首,后面所有表达式引用这两个名字。要改区间长度,只改第一行。 - 条件的拆法。三个条件各自占一行,最后用一个
AND合并。合在一行里的写法编译结果相同,但核对时无法单独看某一项是否成立。
这样写出来的源码有一个可检验的特征:把任意一行单独拿出来,都能说出它在算什么。读不懂的源码,先把每一行翻译成中文写在旁边,翻译不出来的那一行就是问题所在。
三、从命名与参数表看出作者的口径
变量名反映作者的口径,而口径不同会让同一段逻辑得到不同的结果。
以「涨幅」为例。写成 (C-REF(C,1))/REF(C,1),得到的是一个小数,例如 0.031;写成 (C-REF(C,1))/REF(C,1)*100,得到的是 3.1。两者相差 100 倍。如果后面的阈值按百分数写成 >3,配上算出小数的表达式,这个条件在一个正常交易日里都不会成立——不加乘 100 就是如此,与行情无关,是单位口径的问题。
参数表与写在正文里的常数是两回事。打开公式编辑器的编辑窗口,参数表是独立的一块,每个参数有三项:参数名、缺省值、最小与最大值。写进参数表的量,使用者在界面上就能调整,不需要改源码;写在正文里的 N:=20;,每次调整都要进编辑窗口改代码。两者的差别不只在便利性:写在参数表里的参数会跟着公式一起保存和分发,写在正文里的常数只存在于源码文本中。
| 位置 | 形态 | 调整方式 |
|---|---|---|
| 参数表 | 参数名 + 缺省值 + 最小 + 最大 | 在公式参数界面直接改,源码不动 |
| 源码正文 | N:=20; |
进编辑窗口改源码,重新保存 |
单位口径要在读源码时就统一记下来:价格用元、成交量用手还是股、比例为小数还是百分数。这三项在源码里对不上,编译不会提示,运行时结果与预期不一致。
四、函数调用:哪些可移植,哪些是本地特有的
读源码的第二步是把函数名逐个标出来。只用到基础统计与比较运算的写法,在多数平台之间的语义一致;出现下列函数时,需要先确认目标平台是否有对应项。
| 函数 | 用途 | 说明 |
|---|---|---|
MA、EMA、SMA |
均线类 | 语义在各平台之间一致 |
REF、LLV、HHV、COUNT、CROSS |
取值与统计 | 语义一致,参数个数与顺序需逐个核对 |
IF、IFF |
条件选择 | 普通含义一致;IFF 是通达信的写法,其它平台未必有同名函数 |
SUMBARSX |
区间内的累加计算 | 通达信特有,官方更新记录中标注为 V7.62 版本新增 |
NAMELIKE |
按名称匹配 | 通达信特有,依赖平台的名称字段 |
ZTPRICE、DTPRICE |
价格限制相关计算 | 通达信特有,其它平台需用价格比较改写 |
ZIG、PEAK、TROUGH |
转向点识别 | 含未来数据:历史段上的标记会随后续行情变化,不适合作为固定清单使用 |
最后一行需要单独说明。含 ZIG 一类函数的写法,在图上回看历史时标记位置清楚,但随着新数据进入,同一段历史上的标记会改变。换句话说,这类源码输出的不是一份固定清单,而是一份随数据截止日期变化的清单。以固定清单为目标核对结果时,这一点会直接导致对不上。
五、审读清单:五处容易藏问题的地方
- 除法。分母取到零或取不到值时,结果无效。核对写法:是否用了
DIV(分子,分母),或者先判断分母不为零。分母含REF(C,1)时,新股首日与复牌当日要单独看。 - 输出变量重名。输出变量命名为
C、O、H、L、V一类会与行情字段重名。编译阶段未必提示,运算时取到的可能是内置字段而不是本意。 - 条件合并的优先级。
AND与OR混用时,括号的位置会改变分组。含两种运算符的表达式逐项加括号,读起来慢一点,但结果确定。 - 跨周期取值。在日线上引用周线数据需要写清周期参数。漏写周期时,函数按当前周期计算,得到的数值水平与预期不同。
- 参数区间越界。参数表的最小值设为 0 时,允许把窗口长度取到 0,含除法或含
LLV的表达式在窗口为 0 时的行为需要提前确认。
六、边界:源码正确不等于结果可用
编译通过只说明语法正确。一份语法正确的通达信选股公式源码,在下面三种情形下仍然会给出与预期不符的清单:
| 情形 | 表现 | 核对方式 |
|---|---|---|
| 本地数据缺段 | 条件长时间不成立,或输出集中在最左边一段 | 先在盘后数据下载里把日线补齐,再复算 |
| 复权设置不一致 | 信号位置整体错开,数量相近但日期对不上 | 把两边的复权方式调成同一项后重新比对 |
| 选股范围包含当日无行情的条目 | 清单长度超出预期,多出的条目没有对应数据 | 核对选股范围设置与停牌过滤项 |
还有一种情形与源码无关,但读源码时能提前发现:条件本身表达的是相对位置比较,窗口长度或比较对象一改,结果就改。这类源码输出的是一份满足表达式的条目清单,清单的长短随参数变化,它不包含任何参与与否的结论,也不构成对任何标的的判断依据。
本文讲的是源码结构与可读性,不涉及具体标的的判断。站内还有 公式编写教程 里关于赋值符号与参数表的条目,选股公式与预警 里讲条件与预警的对应关系,跨平台对比与公式转换 里讲函数替换的处理方式,可对照查看。
