金字塔决策交易系统

 找回密码
 

微信登录

微信扫一扫,快速登录

搜索
查看: 2127|回复: 0

函数不能在IF THEN FOR循环控制语句中被引用的原理和解决方案

[复制链接]

14

主题

223

帖子

308

积分

Rank: 9Rank: 9Rank: 9

等级: 管理员

注册:
2021-5-18
曾用名:
发表于 2021-6-3 17:41 | 显示全部楼层 |阅读模式
     金字塔的公式系统在处于逐k线模式计算时,像例如REF,MA等带有统计性质的函数,以及指标公式引用无法直接使用在IF语句之中(序列运行模式可以),因为带变量判断的IF语句会在某些周期无法调用这些统计函数而导致计算结果出现错误。解决办法是将这些函数放到IF语句之外去执行或者修改为数组模式。
     目前有下列函数受此限制:

"RET","LOD","HOD","VALUEWHEN","MD","LAST","ANY","SETVAL","FILTERX","BARSCOUNT","BARSLAST","BARSSINCE","COUNT","HHV","HHVBARS","LLV","LLVBARS","MA","DMA","EMA","FILTER","REF","WMA","TMA","SMA","SUM","SUMBARS","CROSS","LONGCROSS","AVEDEV","DEVSQ","FORCAST","SLOPE","STD","STDP","VAR","VARP","SAR","BETA","COVAR","ALL","BACKSET","REFX","PARTLINE","SFILTER","RELATE","ALIKE","FILLRGN","NEWHBARS","NEWLBARS","DRL","GEOMEAN","HARMEAN","KURT","SKEW","PEARSON","RSQ","STEYX","INTERCEPT","REFDATE","IMA","TRMA","DATEPOS","FTest","LARGE","MODE","PERCENTILE","PERCENTRANK","PROB","QUARTILE","SMALL","TRIMMEAN","TTEST","ZTEST","TOPRANGE","LOWRANGE","TREND","GROWTH","LINEST","LOGEST"

(1)IF THEN 语句的描述
例如:
[PEL] 复制代码
input:atrn1(1,1,10),atrn2(5,2,20);
if atrn1<atrn2 and vol>20000 then
begin
TR1:= MAX(MAX((HIGH-LOW),ABS(REF(CLOSE,1)-HIGH)),ABS(REF(CLOSE,1)-LOW));
ATRn_1:= MA(TR1,atrn1);
ATRn_2:= MA(TR1,atrn2);
end

上述公式语句由于将REF和MA函数放在了IF语句之中,所以该公式无法正常编译。解决办法是将他们放到IF语句之外去执行:
[PEL] 复制代码
input:atrn1(1,1,10),atrn2(5,2,20);
A1:=REF(CLOSE,1);TR1:= MAX(MAX((HIGH-LOW),ABS(A1-HIGH)),ABS(A1-LOW));
MA1:=MA(TR1,atrn1);
MA2:=MA(TR1,atrn2);
if atrn1<atrn2 and vol>20000 then
begin
ATRn_1:= MA1;
ATRn_2:= MA2;
end

    这样经过修正的公式就可以正常编译了,此外公式还将两次REF语句引用合并到一个语句中,这样做还可以提高公式系统的运行效率,因为REF统计语句只执行了一次
(2)对于REF较为有效率的使用改进方案
    金字塔提供了强大的数组功能,完成可以代替REF函数,使用数组代替REF不仅可以解决不能再IF THEN语句的限制,还可以提高运行效率,我们举例如下:

[PEL] 复制代码
If   Barpos-1 = N   then
begin
UpperMove := ref(High,1) ;
end

将REF修改为数组模式的代码为
[PEL] 复制代码
If  Barpos-1 = N   then
begin
UpperMove := High[Barpos-1] ; //取上一个K线高点
end


(3)FOR 等循环语句的描述
     虽然金字塔没有限制在FOR等循环语句中使用这类统计性质的函数,但是如果使用不当在循环语句中同样会导致我们的公式出现意外结果。
     在序列模式下这类函数每次循环将会为计算而分配内存,如果循环语句循环的次数过多将会消耗大量内存,而最终导致计算机崩溃。
     在逐K线模式下虽然没有崩溃的危险,但是如果我们在循环控制语句中使用了BREAK,CONTINUE影响循环流程的控制语句中那么就有可能导致计算结果出现异常,同样如果对循环控制语句使用不当,比如某个周期因为动态变化的原因而导致循环未被执行,那么同样会出现问题,我们分别举例如下:

[PEL] 复制代码
FOR J:=0 TO 10 DO
begin
Tmp:=REF(LOW,J);
end

上述的代码在逐K线模式下使用则不会出现问题,因为这样的语法保证了在每根K线周期都能完整的执行到REF函数。

[PEL] 复制代码
FOR J:=0 TO BPZ DO
begin
Tmp:=REF(LOW,J);
end

上述的代码则存在安全隐患,因为BPZ变量可能因为它为0的时候而导致本次循环没被完整执行。
[PEL] 复制代码
FOR J:=0 TO 10 DO
begin
IF ZP = 1 THEN
BREAK;
Tmp:=REF(LOW,J);
end

上述代码同样存在安全隐患,因为会在执行循环过程中被BREAK终止循环而导致REF在本次K线周期未必执行到。

那么问题该如何解决呢?
其实我们在大部分的FOR循环语法使用的时候,基本都是在对序列数组进行循环的操作,我们其实可以利用数组来解决这些问题,我们举例如下:

[PEL] 复制代码
PT:=HIGH;
FOR I=0 TO BARPOS DO
begin
PointCond:=1;
FOR J=0 TO N_SS-1 DO
begin
PointCond:=(REF(PT,I+N_SS)>REF(PT,I+J) );  
end
TmpPrice:=REF(PT,I+N_SS);
end

上述代码嵌套了2层FOR循环语句,里面其实都利用了对序列变量PT的引用,为了在FOR循环中避免使用REF函数带来的安全隐患,我们可以这样改写程序
[PEL] 复制代码
PT:=HIGH;
FOR I=0 TO BARPOS DO
begin
PointCond:=1;
FOR J=0 TO N_SS-1 DO
begin
PointCond:=PT[BARPOS-(I+N_SS)]>PT[BARPOS-(I+J) ];  
end
TmpPrice:=PT[BARPOS-(I+N_SS)];
end

     通过直接使用数组下标的方式在循环语句里处理即可得到我们需要的效果。当然上述代码PT:=HIGH;其实我们还可以省略掉,因为金字塔对HIGH这类序列数据已经内置了数组的引用方式,我们可以直接使用 HIGH[BARPOS-(I+N_SS)];这样的方式来对数据直接来做处理。
     若需要禁止提示循环中的这个问题在代码中的最前面加入如下语句即可:

[PEL] 复制代码
WARNING_DISABLE:3;





金字塔提供一对一VIP专业技术指导服务,技术团队实时响应您的日常使用问题与策略编写。联系电话:021-20339086
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 微信登录

本版积分规则

手机版|小黑屋|上海金之塔信息技术有限公司 ( 沪ICP备13035422号 )

GMT+8, 2024-12-22 13:20 , Processed in 0.179054 second(s), 21 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表