金字塔程式化交易设计指南--高级篇2(3)

2019-03-15 12:32

2.2.2 FOR递减循环

上面的FOR循环,循环变量是每次递增1,可称之为递增FOR循环。还有一种FOR循环是递减FOR循环,循环变量是每次递减1,语法如下:

FOR var=n1 DOWNTO n2 DO expr2;

{从 var=n1 开始到 var=n2 开始循环执行 expr 语句,每执行一次var减1}

上面我们设计2日平均收盘价的公式时,是从前面往后面计算的,仔细想想,其实也可以从后面往前面计算,公式代码如下: fc:=close;

for i=datacount downto 2 do ma2[i] : (fc[i-1]+fc[i])/2;

2.2.3设置序列变量下界语句

原因是我们把ma2定义成序列值收盘价,在上面的循环代码中,只是从第2根K线开始计算均价,第1根K线的位置没有计算,仍然保留了原来收盘价的数值。怎样去掉第1根K线位置的数值,使得ma2的起始有效位置是从第2根K线开始的?使用下面的语句就可以实现:

设置序列变量下界(有效数据起始下标),函数返回序列下界 用法:

SETLBOUND(X,N),设置序列变量X的下界(最小下标),N为0或N超过上界则整个序列数据都无效 例如:

VAR1:C;n1:=SETLBOUND(VAR1,10);

用“设置序列变量下界”语句setlbound(x,n),改写上面的公式,代码如下:

ma2:=close; //定义序列变量ma2等于收盘价

aa:=setlbound(ma2,2); //设置序列变量ma2的下界为2,起始有效位置是从第2根K线开始 fc:=close;

for i=datacount downto 2 do ma2[i]:(fc[i-1]+fc[i])/2;

2.2.4复合语句 复合语句注释:

把多条语句看作一条语句 语法:BEGIN...END

这里,begin和end是成对出现的,被begin和end包围起来的语句可以有很多条,这些语句可以看成是一条复合语句。

下面我们用begin…end来改写递增循环计算2日平均收盘价的公式: fc:=close; //定义序列变量为收盘价 for i=2 to datacount do begin

a:= fc[i-1]+fc[i]; //定义一个临时的单值变量a,保存中间计算结果 ma2[i] : a/2; end;

这段代码,就是由2行代码组成的复合语句,被循环执行若干次。为了代码容易分辨,我们特别把复合语句中的2行代码,都向右缩了4格,表明这是2行复合语句,是被循环语句所控制的。以前对于这类分层次的语句,都要进行缩格,便于看懂代码,特别是复杂的代码,如果不进行缩格,时间久了,恐怕连自己都很难看懂,大家一开始就要养成好习惯。

11

有人会问,书写代码不缩格行吗?不缩格公式会不会出错?答案是,缩格书写代码,仅仅是为了方便看清程序代码的逻辑层次,对公式的运行没有影响。

有了复合语句,循环的功能就更加强大了,可以轻松实现多重循环,即循环中套循环。在计算N日的平均价时会用到,如果事先不知道N是多少,就要用到二重循环。对于循环中要执行的语句,如果重复太多,也可以使用多重循环来简化。以二重循环为例,大致结构如下:

for i=n1 to n2 do begin 语句; ?

for j=m1 to m2 do begin 语句; ? end; 语句; ? end; 2.3条件语句

条件语句的语法如下: IF条件语句

语法:IF cond THEN expr1 ELSE expr2

如果 cond 条件成立,则执行语句 expr1,否则执行 expr2 语句。 说明:

1、在条件判断比较简单的情况下,ELSE expr2 子句可以省略。

2、条件 cond 可以是单值变量,也可以为序列变量。当为序列变量时,cond将取最后一个周期的值做为条件判断语句。

条件语句的语法比较简单,但使用时却容易出错,下面举若干示例。

例1:修改成交量公式VOL,当流通盘不为零且当前周期为日以上周期时,显示换手率,代码参考如下(仿此,大家绕过指标模组,可以自行设计,“绑定”到周期、券种等的公式) 代码:

VOL,VOLSTICK; MA1:MA(VOL,M1); MA2:MA(VOL,M2); MA3:MA(VOL,M3);

if capital>0 and DATATYPE>=6 then

换手率:vol/capital; //日以上周期及非指数个股,显示换手率

当切换到60分钟及以下周期,或者切换到大盘(此时流通盘=0),会发现“换手率”指标线、名称及数值都不显示。 以上是较简单的情况,没有使用 ELSE expr2 子句。上面代码稍加改进,使用复合语句,使之适用于任意周期:

12

例2,修改成交量公式,流通盘不为0时,显示换手率(60分钟及以下周期,计算当日最新的换手率),代码参考如下: 代码:

VOL,VOLSTICK; MA1:MA(VOL,M1); MA2:MA(VOL,M2); MA3:MA(VOL,M3);

IF CAPITAL>0 then //如果换手率>0,则

IF DATATYPE>=6 then //如果周期为日及以上的较长周期,则 b:=VOL/CAPITAL*100; else //否则

begin //复合语句开始,即以下3条语句,视为1条语句,end表示复合语句结束 tj:=DAY>REF(DAY,1) or BARSSINCE(CLOSE)=0; ts:=BARSLAST(tj)+1; b:=SUM(VOL,ts)/CAPITAL*100; end; 换手率:b;

例3、通过参数N,控制调整均线数,代码参考如下: 代码:

input:p1(5,0,300),p2(10,0,300),p3(20,0,300),p4(30,0,300),n(4,1,4);{参数定义} IF n>0 then MA1:MA(CLOSE,P1);{如果n>=1则输出ma1指标线} IF n>1 then MA2:MA(CLOSE,P2);{如果n>=2则输出ma1指标线} IF n>2 then MA3:MA(CLOSE,P3);{如果n>=3则输出ma1指标线} IF n>3 then MA4:MA(CLOSE,P4);{如果n>=4则输出ma1指标线}

在使用条件语句“IF cond THEN”中,序列模式下,cond如果是序列变量,那么IF语句只取最后序列值做为条件判断,比如: 代码:

fc:=close; fo:=open;

if fc>fo then //这里的fc、fo是序列变量,因此只取最后一个周期的条件做为判断依据 xx:=1; else xx:=0; y:xx;

这里,if fc>fo then 这种写法的本意是,“如果收盘价大于开盘价则”,是针对序列变量的每个数据(相当于数组的每个元素),但是在序列模式下是不会得到执行结果的,在金字塔的序列模式运行中,正确的写法应该是这样的:

13

代码:

//如果xx是序列变量,则代码参考如下 fc:=close; fo:=open;

for i=1 to datacount do begin

if fc[i]>fo[i] then

xx[i]:=1; //请注意这里跟上面代码的不同 else xx[i]:=0; end y:xx;

第三章 序列模式和逐K线模式

金字塔公式系统工作两种模式,即序列和逐K线两种模式。序列模式公式系统每次刷新时解析公式按照序列或者常数计算返回结果,整个执行过程只解析一遍公式系统,我们前面所讲的控制语句的用法都是基于序列模式下运行的。逐K线模式为从第1个K线直到最后一个K线逐个解析公式系统,每根K线都会解析整个公式系统一遍,返回值也只有数值类型这一种,故这种模式运行时效率要比序列模式低,但此种模式下由于是逐根周期执行运算的,故我们可以在编写公式时使用各种更加灵活的控制语法。

3.1控制语句在两种不同模式下的运行特点

逐K线计算时,控制语句比如IF THEN ,FOR 等语句工作机制是每周期都去执行一次,因此在逐K线模式下,可以利用这种灵活的模式来设计我们的策略,比如加仓、减仓、资金管理策略等等。

序列模式计算时,控制语句条件允许使用序列变量,由于序列模式只执行一次控制语句解析,对于序列变量,仅取最后一个数据做为条件判断。

如:前面我们在序列模式下无法正常工作的公式 fc:=close; fo:=open;

if fc>fo then //这里的fc、fo是序列变量,因此只取最后一个周期的条件做为判断依据 xx:=1 else xx:=0;

但是在逐K线模式下,该公式是可以正常工作的。因为逐K线每根K线都得到了执行,故不需要向序列运行那样在后面用FOR循环重新赋值一遍了。

为了更能说明金字塔两种模式下的公式运行特点,特制作一个计算移动平均线的公式,如下:

14

//用于序列模式下运行的公式: INPUT:N(5,2,500); //参数申明 RUNMODE:1; //运行于序列模式 VARIABLE:I=0,S=0; VAR1:=C;//变量申明

FOR J=1 TO DATACOUNT DO BEGIN S:=S+VAR1[J]; IF J>=N THEN BEGIN IF J>N THEN S:=S-VAR1[J-N];

MA1[J]:S/N; //实现MA(C,N) I:=0; END; END;

上述公式使用序列模式运行,但是如果在逐K线模式下运行上述公式就会变得异常缓慢,由于金字塔逐K线模式在每个周期上都要执行一遍这样的循环,效率自然就变得非常低了。鉴于金字塔的特点,如果将上述公式改进一下,则可以高效的在序列和逐K线模式同时高效运行,公式如下:

INPUT:N(5,2,500); //参数申明 VARIABLE:I=0,S=0; //全局变量申明 VAR1:=C; //金字塔下放在这里的变量为序列赋值 //为了加快运算速度,只有最后一个周期时才循环计算 IF NOT(ISLASTBAR) THEN EXIT; FOR J=1 TO DATACOUNT DO BEGIN S:=S+VAR1[J]; IF J>=N THEN BEGIN IF J>N THEN S:=S-VAR1[J-N];

MA1[J]:S/N; //实现MA(C,N) I:=0; END; END;

上述公式中增加了 IF NOT(ISLASTBAR) 判断是否最后一个周期的指令,在逐K线模式下,由于是判断到最后一个周期才执行的下面循环,故效率是非常高的。对于序列模式,由于同样使用了ISLASTBAR控制,故符合控制语句取最后一个数据的特点,所以该公式同时可以在两种模式下得到正确执行。

为了更能说明逐K线的运行特点,计算移动平均线的公式还可以这样写 INPUT:N(5,2,500); //参数申明 RUNMODE:0; //工作于逐K线模式 IF BARPOS <= N THEN //从计算周期开始计算

15


金字塔程式化交易设计指南--高级篇2(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:王子工程质量评估报告

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: