以文本方式查看主题

-  金字塔客服中心 - 专业程序化交易软件提供商  (http://weistock.com/bbs/index.asp)
--  公式模型编写问题提交  (http://weistock.com/bbs/list.asp?boardid=4)
----  怎样提高效率?  (http://weistock.com/bbs/dispbbs.asp?boardid=4&id=58651)

--  作者:无极无名
--  发布时间:2013/11/12 0:53:50
--  怎样提高效率?

在引用其它公式指标的时候,速度很慢,需要想办法提高运行效率,有几个问题。

 

比如某个需要引用的公式指标\'ABC.A\',这个公式本身是组K线运行模式,

 

当前代码

A:=STKINDI(\'RU00\',\'ABC.A\',0,DATAPERIOD);  //引用公式\'ABC’的A值

 

问题在于,假设当前图表有N根K,为了得到\'ABC’的A值,每根K线都有要运行一次上述代码,都会去调用并运行ABC,

而公式ABC在计算时也是逐K线的执行到当前图表相对应的周期,于是当前图表从第一根K到第N根K,

ABC运行了1+2+3+4+......+N=(1+N)*N/2次,这将是一个天文数字,而在静态测试情况下,当前代码只运行了N次,

关键是ABC被大量重复运行了。

 

如果是动态行情下运行,只刷最后一根K,每秒刷新两次,则每秒ABC要运行2*(N+1)次,在换K线时当前代码还

是会从头到尾运行一次,则ABC会被运行1+2+3+4+.....N+N+1次,电脑基本动不了了。

 

不知上述推断是否为真。我的想法是,如果能实现在调用ABC时只运行一次,把A值形成数组,再运行当前代码时直接根据数组下标引用就可以了。可否实现?

 

 

 


--  作者:jinzhe
--  发布时间:2013/11/12 8:59:17
--  
用STKINDIEX,里面有限定引用周期数,而且现在逐k线模式的计算方式都有设定为仅刷最后一根k线,也就是最后一根k线会引用一次,进行N次计算
--  作者:无极无名
--  发布时间:2013/11/13 21:05:30
--  
我自己检测了一下,我上面的帖子理解有误,实际情况是这样的:

一、当前公式是序列模式运行,被引用公式也是序列模式运行,那么两个公式都只运行一次;
二、当前公式是序列模式运行,被引用公式是逐K线模式运行,那么当前公式只运行一遍,被引用公式执行N次(假设被数据为N根K);
三、当前公式是逐K线运行,被引用公式是序列模式运行时,当前公式运行N次,被引用公式只运行一次就遍历周期把指标值全部算完,当前公式在逐K线运行时只是完成逐K线对应赋值,不会让被引用公式多次运行;
四、当前公式是逐K线运行,被引用公式也是逐K线运行,当前公式运行N次,被引用公式也是运行N次,而不是上述的(1+N)*N/2次。并且,在引用时有记忆功能。比如,
IF BARPOS=100 THEN A:=STKINDI(\'RU00\',\'ABC.A\',0,DATAPERIOD);
IF BARPOS=300 THEN B:=STKINDI(\'RU00\',\'ABC.A\',0,DATAPERIOD);
第一次引用时,ABC会从RU00的第一根K运行到第100根K,运行了100次,第二次被引用时,ABC不是从第1根K运行到第300根K,而是从第101根K开始运行到第300根K(因为前面100根已经运行过了),运行了200次。

在引用其它品种公式指标时,相当于是把两个图表叠加到一起,大致按K线个数(不按时间)  对齐。
而对于STKINDIEX   函数只能在当前公式是逐K线模式下运行,其目的是为了强制被引用公式计算K线的根数不和当前图表相同。在静态测试情况下,这个函数无用。在动态行情接收时,由于每换一根K,当前公式都会从头到尾运行一遍,造成被引用公式也会从头到尾运行,效率大大降低,STKINDIEX就有用了,前提是不能影响交易信号。

所以,效率的提高关键是被引用公式尽可能高效,能够序列运行最好,不能序列运行应尽可能不写不需要的代码和输出,只需要引用一个指标,就不要计算其它指标,因为在引用时每行代码都会运行。

以上测试结果供菜鸟们共勉。如何知道被引用公式运行了多少次,是如何执行的?我的方法是在被引用公式里面加上一句:
MSGOUT(1,NUMTOSTR(BARPOS,0));

--  作者:王锋
--  发布时间:2013/11/13 23:34:14
--  
勾选“仅刷最后K线”就行了
--  作者:无极无名
--  发布时间:2013/11/14 16:37:16
--  
对于动态行情接收状态,经过我的反复测试,发现和静态测试状态不同,序列模式未必就好。
一、当前公式是逐K(只刷新最后一根,以下同),被引用指标公式也是逐K模式,当前图表换K线时,从头到尾每根K线执行一遍当前公式,被引用公式也是从头到尾执行一遍,这与与静态测试结果一致。在当前没有换K时,每接收一个TICK,当前公式和被引用公式都是执行一次,这就是所谓只刷新最后一根模式。

二、当前是逐K线模式,被引用公式是序列模式时,当前公式的执行情况与上面一样,被引用公式始终是每来一个TICK执行一次,不会从头到尾执行。但是在动态情况下,序列模式所谓只执行一次是是如何运行的?后面还有测试。

三、当前是序列模式,被引用公式也是序列模式,两者都是每来一个TICK运行一次。(但我认为在实盘中这是最慢的方式,见下文)

四、当前是序列模式,被引用公式是逐K线模式,问题来了。当前公式是每来一个TICK执行一次,但是被引用公式却是始终每来一个TICK从头到尾执行一遍,虽然被引用公式应该只刷新最后一根K。这种情况说明了序列模式在动态行情下的执行机制,虽然名义上刷新一次只执行一次,但是每执行一次都要求遍历周期,所以才造成被引用公式每来个TICK都要从头到尾执行。

结论:所谓逐K线模式,是先从上到下执行公式语句,然后从左到右每个BAR重复执行该公式,并把每个BAR上每个变量的结果传递给下一个BAR;所谓序列模式,是每执行一句公式代码都要从左到右遍历周期,然后再执行下一句。
在静态测试情况下,序列模式可能效率占优。但是在动态行情接收状态下,每来一个TICK两者都要执行一遍公式,逐K模式只需要计算最后一个BAR的单值,但序列模式执行时仍然会遍历周期求得变量的序列值(而不是一个单值)。显然,只刷最后一根K线的逐K模式在实盘中效率更高。包括被引用公式,也应该用逐K模式,实盘中用STKINDIEX函数控制需引用的K线个数。

--  作者:readonly
--  发布时间:2013/11/14 17:23:29
--  
STKINDIEX 对于回测不友好,建议只在最后一根k线时,限定k线数才生效。
--  作者:王锋
--  发布时间:2013/11/14 21:26:24
--  
以下是引用readonly在2013/11/14 17:23:29的发言:
STKINDIEX 对于回测不友好,建议只在最后一根k线时,限定k线数才生效。

 

这个应该3.031已经改进了


--  作者:无极无名
--  发布时间:2013/11/15 21:06:48
--  
是的。
--  作者:无极无名
--  发布时间:2013/11/15 21:10:02
--  
另外,如果当前是逐K模式,被引用公式是序列模式,当前公式是每个TICK刷新一次,但是被引用公式是每根K刷新一次,这个会造成引用不到最新的数据。