最近在回答社区问题时,碰到不少用户反馈的“Bug”或者“奇怪问题”,只要一看代码就会发现根源还是序列函数问题。这真是个老生常谈的问题,从2010年起几乎每年的培训都会提及,只是没想到直到今天错误使用的频率还这么高!看来还是必须再絮叨一下,让每个新老用户都能彻底搞明白,避免以后再踩坑。
一、什么是序列函数?
序列函数就是函数内部的参数或变量中使用了序列变量的函数。如果一个函数自己不是序列函数但调用了序列函数,也算是序列函数。
理解了上面的定义,我们就不难判断一个函数是否是序列函数。下面随便举几个例子:
——Highest和Lowest函数:
——CloseD函数:
——大家喜欢用的CrossOver和CrossUnder函数:
看到了吧,大家经常使用的这些函数都是序列函数。判断也很简单,只要打开函数源码,看到参数或变量中有序列变量的就是序列函数。当然也有隐藏得深的:
著名的ATR指标,看公式代码,调用的是AvgTrueRange函数。
AvgTrueRange函数,没有任何序列参数或变量。但它调用了Average函数,我们继续挖……
Average函数也没有序列参数或变量,但它调用了Summation函数,继续……
终于现出原形了!Summation函数是序列函数,根据上面的定义Average、AvgTrueRange也都是序列函数。
通过这两个例子,如何判断一个函数是否序列函数,相信大家应该都会了吧?
好,接着谈问题。
二、序列函数的错误用法
序列函数在使用的时候要特别注意,不能放在条件语句、循环语句的程序体内,也不能放在包含逻辑运算符的条件表达式中。下面举几个错误写法的示例:
示例1:
错误原因:序列函数Lowest放在条件语句内。
示例2:
错误原因:序列函数放在条件语句判断条件中了。
示例3:
错误原因:序列函数放在包含逻辑运算符的条件表达式中。
如果像上面这些示例一样使用序列函数,结果会怎样呢?——结果就是,公式运算出来的结果跟您想象的大相径庭,甚至会让您觉得这是平台出了Bug。
那么为什么这么用就会出问题呢?真要说清这个问题还是挺复杂的,我们这里只说结论。因为上述用法,不能保证每根BAR上该函数都会被调用,所以会导致函数内部的序列参数或序列变量,不是在每个BAR上都有正确的值,从而导致函数返回值不正确。
听起来不太好懂,对吧?没关系,不懂也不影响我们解决这个问题。我们只要记住正确的做法就可以了,至于根本原因,有兴趣研究的我们以后再讨论。
三、彻底告别序列函数问题
序列函数永远不再踩坑,非常简单!只要记住一个方法即可。所有序列函数在使用之前赋值给一个替身——简单变量,然后由替身替它出场即可。
上面的三个示例,只要这么改一下就都是正确的代码。
示例1(正确写法):
示例2(正确写法):
示例3(正确写法):
看到没有,直到今天还在困扰TB新老用户的序列函数问题,只要采取这个简单方法,就可彻底解决,永不踩坑。把这篇文章转发给您身边每一位已经使用或将要使用TB的朋友吧,他们会因此少走很多弯路。
Open, Close, High, Low 本身也是序列变量,为什么可以写在FOR 或 IF 里面
严格来说,读取可以随便写,写入就要放在在控制结构外面
但是有一些写入,就算放在控制结构里面,只要算法是正确的,也没问题。
不要钻牛角尖
接上条,请问老师,怎么把NthCon这个序列函数放到For循环的外面,因为该函数里面有 i 。。
请问,如果是 For循环里面使用了序列函数呢?
比如
Cond=Highest(H,3)==H(2);
For i=1 To 20
{
KK=NthCon(Cond,i);
commentary(\"KK=\"+text(KK));
}
请问老师,怎么把NthCon这个序
老师,我是小白,能帮我写个程序吗
为什么哟按你的方式写,编译的时候提示错误,要求两边同样是数值序列?
麻烦您把您写的代码贴上来。
蔡老师,您好!
能否把您2018年8月15的学习视频 《趋势线交易策略》里面的源代码 分享下,用于学习和借鉴,
本来是个线匠,想找个趋势线的程序表示方法
谢谢
https://pan.baidu.com/s/1tHV_TWpxTEX6aanVprJKCw,提取码:cs2s
老师您好:
能帮忙写一下DKX(文华多空线)B线上穿D线平空(若有空单)开多,下穿平多
不错
通俗易懂,哈哈,棒棒的