欢迎使用金字塔普通技术服务论坛,您可以在相关区域发表技术支持贴。
我司技术服务人员将优先处理 VIP客服论坛 服务贴,普通区问题处理速度慢,请耐心等待。谢谢您对我们的支持与理解。


金字塔客服中心 - 专业程序化交易软件提供商金字塔软件公式模型编写问题提交 → 函数不能在IF THEN FOR循环控制语句中被引用的原理和解决方案

   

欢迎使用金字塔普通技术服务论坛,您可以在相关区域发表技术支持贴。
我司技术服务人员将优先处理 VIP客服论坛 服务贴,普通区问题处理速度慢,请耐心等待。谢谢您对我们的支持与理解。    


  共有39464人关注过本帖树形打印复制链接

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

帅哥哟,离线,有人找我吗?
admin
  1楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:7302 积分:32559 威望:1000 精华:45 注册:2003/12/30 16:34:32
函数不能在IF THEN FOR循环控制语句中被引用的原理和解决方案  发帖心情 Post By:2009/11/2 10:19:35    Post IP:123.113.254.211[只看该作者]

金字塔的公式系统在处于逐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"

 

IF THEN 语句的描述

例如:

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语句之外去执行:

input:atrn1(1,1,10),atrn2(5,2,20);

A1:=REF(CLOSE,1);
MA1:=MA(TR1,atrn1);
MA2:=MA(TR1,atrn2);

if atrn1<atrn2 and vol>20000 then
begin
    TR1:= MAX(MAX((HIGH-LOW),ABS(A1-HIGH)),ABS(A1-LOW));
    ATRn_1:= MA1;
    ATRn_2:= MA2;
end;

这样经过修正的公式就可以正常编译了,此外公式还将两次REF语句引用合并到一个语句中,这样做还可以提高公式系统的运行效率,因为REF统计语句只执行了一次。

 

对于REF较为有效率的使用改进方案

金字塔提供了强大的数组功能,完成可以代替REF函数,使用数组代替REF不仅可以解决不能再IF THEN语句的限制,还可以提高运行效率,我们举例如下:

If   Barpos-1 = N   then
BEGIN
   UpperMove := ref(High,1) ;
end

 

将REF修改为数组模式的代码为

If   Barpos-1 = N   then
BEGIN
   UpperMove := High[Barpos-1] ; //取上一个K线高点
end

 

FOR 等循环语句的描述

虽然金字塔没有限制在FOR等循环语句中使用这类统计性质的函数,但是如果使用不当在循环语句中同样会导致我们的公式出现意外结果。

在序列模式下这类函数每次循环将会为计算而分配内存,如果循环语句循环的次数过多将会消耗大量内存,而最终导致计算机崩溃。

在逐K线模式下虽然没有崩溃的危险,但是如果我们在循环控制语句中使用了BREAK,CONTINUE影响循环流程的控制语句中那么就有可能导致计算结果出现异常,同样如果对循环控制语句使用不当,比如某个周期因为动态变化的原因而导致循环未被执行,那么同样会出现问题,我们分别举例如下:

 

FOR J:=0 TO 10 DO
  BEGIN
   Tmp:=REF(LOW,J);

  END

 

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

 

FOR J:=0 TO BPZ DO
  BEGIN
   Tmp:=REF(LOW,J);

  END

 

上述的代码则存在安全隐患,因为BPZ变量可能因为它为0的时候而导致本次循环没被完整执行。

 

FOR J:=0 TO 10 DO
  BEGIN

   IF ZP = 1 THEN

       BREAK;
   Tmp:=REF(LOW,J);

  END

 

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

 

那么问题该如何解决呢?

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

 

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函数带来的安全隐患,我们可以这样改写程序

 

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)];这样的方式来对数据直接来做处理。

 

 若需要禁止提示循环中的这个问题在代码中的最前面加入如下语句即可:

  WARNING_DISABLE:3;

[此贴子已经被作者于2017-1-21 20:34:01编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
陈泉清
  2楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:新手上路 帖子:25 积分:286 威望:0 精华:0 注册:2009/12/4 13:43:34
  发帖心情 Post By:2010/1/20 10:46:37    Post IP:58.54.182.250[只看该作者]

以下是引用admin在2009-11-2 10:19:35的发言:

金字塔的公式系统由于支持IF语句的变量运行,所以像例如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"

例如:

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语句之外去执行:

input:atrn1(1,1,10),atrn2(5,2,20);

A1:=REF(CLOSE,1);
MA1:=MA(atrn1,atrn1);
MA2:=MA(atrn2,atrn2);

if atrn1<atrn2 and vol>20000 then
begin
    TR1:= MAX(MAX((HIGH-LOW),ABS(A1-HIGH)),ABS(A1-LOW));
    ATRn_1:= MA1;
    ATRn_2:= MA2;
end;

这样经过修正的公式就可以正常编译了,此外公式还将两次REF语句引用合并到一个语句中,这样做还可以提高公式系统的运行效率,因为REF统计语句只执行了一次。

[此贴子已经被作者于2009-11-2 10:22:11编辑过]

input:atrn1(1,1,10),atrn2(5,2,20);

A1:=REF(CLOSE,1);
MA1:=MA(atrn1,atrn1);
MA2:=MA(atrn2,atrn2);

if atrn1<atrn2 and vol>20000 then
begin
    TR1:= MAX(MAX((HIGH-LOW),ABS(A1-HIGH)),ABS(A1-LOW));
    ATRn_1:= MA1;
    ATRn_2:= MA2;
end;
这红色的语句有问题吧


 回到顶部
帅哥哟,离线,有人找我吗?
bhwhui
  3楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:论坛游民 帖子:208 积分:1565 威望:0 精华:2 注册:2009/8/23 19:18:53
  发帖心情 Post By:2010/1/22 2:18:18    Post IP:221.7.173.165[只看该作者]

呵呵呵,你好眼力,是笔误。自己看帮助就知道了。。。。。


 回到顶部
帅哥哟,离线,有人找我吗?
敢赢
  4楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:新手上路 帖子:11 积分:212 威望:0 精华:0 注册:2009/12/27 22:21:03
  发帖心情 Post By:2010/5/22 11:00:48    Post IP:116.5.47.37[只看该作者]

还有一处好象有问题!

input:atrn1(1,1,10),atrn2(5,2,20);

A1:=REF(CLOSE,1);
MA1:=MA(tr1,atrn1);  //语句顺序错了!这样tr1会提示没有定义的!应直接把TR1:= MAX(MAX((HIGH-LOW),ABS(A1-HIGH)),ABS(A1-LOW));也放在IF语句外面,并在MA1前面!
MA2:=MA(tr1,atrn2);

if atrn1<atrn2 and vol>20000 then
begin
    TR1:= MAX(MAX((HIGH-LOW),ABS(A1-HIGH)),ABS(A1-LOW));
    ATRn_1:= MA1;
    ATRn_2:= MA2;
end;

[此贴子已经被作者于2010-5-22 11:02:21编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
蔡宛宏
  5楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:论坛游民 帖子:129 积分:473 威望:0 精华:0 注册:2011/12/6 14:06:35
  发帖心情 Post By:2012/2/1 18:04:02    Post IP:219.141.204.130[只看该作者]

图片点击可在新窗口打开查看

 回到顶部
帅哥哟,离线,有人找我吗?
人生如棋
  6楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:论坛游侠 帖子:121 积分:390 威望:0 精华:0 注册:2011/12/9 19:52:04
  发帖心情 Post By:2012/2/1 19:01:02    Post IP:115.197.38.185[只看该作者]

没事挖什么坟。。。。有意思嘛,挖坟又不给你钱,这么起劲。。。

 回到顶部
美女呀,离线,留言给我吧!
momocll
  7楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:新手上路 帖子:6 积分:20 威望:0 精华:0 注册:2012/11/23 14:53:26
  发帖心情 Post By:2012/12/4 14:53:32    Post IP:120.35.20.13[只看该作者]

 

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

 

这样编辑会报“数组越界操作”的错,


 回到顶部
帅哥哟,离线,有人找我吗?
王锋
  8楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:罗宾汉 帖子:11808 积分:20695 威望:0 精华:10 注册:2009/8/18 8:15:13
  发帖心情 Post By:2012/12/4 22:05:30    Post IP:122.225.36.5[只看该作者]

以下是引用momocll在2012-12-4 14:53:32的发言:

 

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

 

这样编辑会报“数组越界操作”的错,

 

在循环代码前,加上对BARPOS的限制防止越界

 

IF BARPOS < N THEN

   EXIT;



金字塔—专业程序化软件提供商

金字塔-技术部

-----------------------------------------------------------------------------------------------------

工作时间:周一至周五 08:30 - 17:30   周末及法定节假日休息

Email:service@weistock.com
 回到顶部
帅哥哟,离线,有人找我吗?
勇敢的心
  9楼 | QQ | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:论坛游侠 帖子:134 积分:5 威望:0 精华:0 注册:2013/3/8 21:51:20
  发帖心情 Post By:2013/11/4 11:35:01    Post IP:180.169.94.178[只看该作者]

您好,按照以上提供的方法,解决IF循环语句中不能实用HHV的问题,

H1:=HHV(H,ENTERBARS);
LONGX1.1 := (H1-AVGENTERPRICE <3*R  AND H1-AVGENTERPRICE ≥2*R);
IF LONGX1.1 AND BUYORDERTHISBAR=0 THEN BEGIN
   MYENTRYPRICE := IF(OPEN>T20HI+MINDIFF ,OPEN ,T20HI+MINDIFF ) ;
MYEXITPRICE := MYENTRYPRICE+1.4*R ;
SELL( _DEBUG ,0,LIMITR,MYEXITPRICE);
POSITION := 0 ;
TURTLEUNITS := 0 ;
END)

但解决后,还是显示HHV在逐K线模式下,不能直接在IF控制语句之内引用。
谢谢。
 

 回到顶部
帅哥哟,离线,有人找我吗?
jinzhe
  10楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:罗宾汉 帖子:46311 积分:50819 威望:0 精华:2 注册:2011/3/23 8:50:25
  发帖心情 Post By:2013/11/4 13:02:36    Post IP:58.246.57.26[只看该作者]

H1定义这一句外面,还有个IF?


金字塔—专业程序化交易量化投资平台

客户服务部

----------------------------------------------------------- 欢迎您参加我公司的技术培训,具体培训需求请发邮件到service@weistock.com

您的宝贵建议或者投诉,请发往邮箱:weiwei@weistock.com

 回到顶部
总数 21 1 2 3 下一页