hx817 2004-12-18 15:30
飞狐内置循环、判断等控制语句入门二(南客)
上讲,介绍了序列变量、数组等概念,这一讲介绍循环语句。
1、 FOR递增循环:
先从一个的实例开始,求当前股票收盘价的2日算术平均价,为了方便起见,以刚上市不久的600340国祥股价来说明,首先定义序列变量fc为收盘价,根据上一讲我们知道,fc可以看成是一个数组,因此,数组fc的每一个元素如下表所示:
[code]
600340 国祥股份
时间 收盘
fc[1] 2003/12/30 8.92
fc[2] 2003/12/31 8.96
fc[3] 2004/01/02 9.25
fc[4] 2004/01/05 9.64
fc[5] 2004/01/06 9.92
fc[6] 2004/01/07 9.74
fc[7] 2004/01/08 10.44
fc[8] 2004/01/09 9.99
[/code]
显然, 2日平均收盘价必须是从第2根K线即上市后第2日开始,到最后一天结束,设2日平均股价用序列变量ma2来表示,由于2日平均收盘价等于当日收盘价加昨收盘除以2,如果手工一行一行来写代码计算,则:
[code]
ma2[2]:=(fc[1]+fc[2])/2; //今收盘与昨收盘之和除以2,等于今2日平均收盘价
ma2[3]:=(fc[2]+fc[3])/2;
ma2[4]:=(fc[3]+fc[4])/2;
ma2[5]:=(fc[4]+fc[5])/2;
ma2[6]:=(fc[5]+fc[6])/2;
ma2[7]:=(fc[6]+fc[7])/2;
ma2[8]:=(fc[7]+fc[8])/2;
[/code]
分析上面代码,2日平均价的计算特点是:
① 从第2根K线开始计算的
② 每天的均价都等于(今收盘+昨收盘)/2
③ 直到最后1根K线结束
容易知道,如果有1000根K线,则要写999行代码,显然效率太低了。
我们来找找规律,如果是中间的某天即第i天,则上面的表达式可以写为
[code]
ma2[i]:=(fc[i-1]+fc[i])/2,
[/code]
这个i是从第2根K线开始直到最后1根K线。这些计算都是重复同样的计算,只不过i不同罢了。如果有一种方法,可以自动重复计算这些表达式,并且每重复一次,i自动增加1,就可以达到目的了。由此我们定义一种循环语句,可以自动循环、重复运行某一行代码。在飞狐中,循环语句有2种,下面先介绍FOR循环语句
语法:
[code]
FOR var=n1 TO n2 DO expr;
{从 var=n1 开始,直到 var=n2,开始循环执行 expr 语句,每执行一次var加1。这里,var称之为循环变量。}
[/code]
用循环语句表达上面计算2日平均收盘价,公式代码如下:
[code]
fc:=close; //定义序列变量fc为收盘价
for i=2 to datacount do ma2[i] : (fc[i-1]+fc[i])/2;
//从i=2到i=datacount循环执行ma2[i] : (fc[i-1]+fc[i])/2
[/code]
在飞狐中新建一个主图叠加公式,如下图所示,正是我们所需要的结果:
hx817 2004-12-18 15:30
2、FOR递减循环:
上面的FOR循环,循环变量是每次递增1,可称之为递增FOR循环。还有一种FOR循环是递减FOR循环,循环变量是每次递减1,语法如下:
[code]
FOR var=n1 DOWNTO n2 DO expr2;
{从 var=n1 开始到 var=n2 开始循环执行 expr 语句,每执行一次var减1}
[/code]
上面我们设计2日平均收盘价的公式时,是从前面往后面计算的,仔细想想,其实也可以从后面往前面计算,公式代码如下:
[code]
fc:=close;
for i=datacount downto 2 do ma2[i] : (fc[i-1]+fc[i])/2;
[/code]
新建一个公式,输入上面代码,验证一番,结果如下图:
hx817 2004-12-18 15:31
咦?什么也没有显示,是怎么回事?
问题出在ma2,ma2在这里事先没有定义,飞狐不知道ma2是什么变量,因此无法输出。改写公式代码如下:
[code]
ma2:=close; //定义序列变量ma2等于收盘价
fc:=close;
for i=datacount downto 2 do ma2[i]:(fc[i-1]+fc[i])/2;
[/code]
再看看这回的结果图示:
hx817 2004-12-18 15:31
现在有输出了,但仔细观察,还有点问题,因为是2日平均价线,第1根K线的位置应该没有输出才行,现在却有输出?可通过下面我们要讲的“设置序列变量下界语句”来解决。
3、设置序列变量下界语句:
原因是我们把ma2定义成序列值收盘价,在上面的循环代码中,只是从第2根K线开始计算均价,第1根K线的位置没有计算,仍然保留了原来收盘价的数值。怎样去掉第1根K线位置的数值,使得ma2的起始有效位置是从第2根K线开始的?使用下面的语句就可以实现:
设置序列变量下界(有效数据起始下标),函数返回序列下界
用法:
[code]
SETLBOUND(X,N),设置序列变量X的下界(最小下标),N为0或N超过上界则整个序列数据都无效
[/code]
例如:
[code]
VAR1:C;n1:=SETLBOUND(VAR1,10);
[/code]
用“设置序列变量下界”语句setlbound(x,n),改写上面的公式,代码如下:
[code]
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;
[/code]
图示如下:
hx817 2004-12-18 15:31
这个结果就对了!但大家可能会有疑问了,在前面递增循环中,ma2同样没有事先定义,结果却是正确的,这是为什么?回顾一下前面递增循环的代码:
[code]
fc:=close; //定义序列变量为收盘价
for i=2 to datacount do ma2[i] : (fc[i-1]+fc[i])/2;
[/code]
这里ma2[ i]是从前面往后面计算的,对于这种情况,即如果是前面往后计算,则第1次遇到ma2[ i]时,就默认把ma2定义成是序列变量,并把首次计算ma2[ i]的位置作为ma2的起始有效位置。要注意的是,如果是递减循环,就不会做这种默认起始位置的处理。
至此我们体会到了循环语句的强大功能了,不过,大家可能还会产生一个疑问,上面的循环语句,只是让一条语句重复计算,如果我们想让多条语句同时进行重复计算,可以吗?
4、复合语句:
答案是肯定的,请看下面的语句:
引用:
把多条语句看作一条语句
语法:BEGIN...END
这里,begin和end是成对出现的,被begin和end包围起来的语句可以有很多条,这些语句可以看成是一条复合语句。
下面我们用begin…end来改写递增循环计算2日平均收盘价的公式:
[code]
fc:=close; //定义序列变量为收盘价
for i=2 to datacount do
begin
a:= fc[i-1]+fc[i]; //定义一个临时的单值变量a,保存中间计算结果
ma2[i] : a/2;
end;
[/code]
这段代码,就是由2行代码组成的复合语句,被循环执行若干次。为了代码容易分辨,我们特别把复合语句中的2行代码,都向右缩了4格,表明这是2行复合语句,是被循环语句所控制的。以前对于这类分层次的语句,都要进行缩格,便于看懂代码,特别是复杂的代码,如果不进行缩格,时间久了,恐怕连自己都很难看懂,大家一开始就要养成好习惯。
有人会问,书写代码不缩格行吗?不缩格公式会不会出错?答案是,缩格书写代码,仅仅是为了方便看清程序代码的逻辑层次,对公式的运行没有影响。
有了复合语句,循环的功能就更加强大了,可以轻松实现多重循环,即循环中套循环。在计算N日的平均价时会用到,如果事先不知道N是多少,就要用到二重循环。对于循环中要执行的语句,如果重复太多,也可以使用多重循环来简化。以二重循环为例,大致结构如下:
[code]
for i=n1 to n2 do
begin
语句;
…
for j=m1 to m2 do
begin
语句;
…
end;
语句;
…
end;
[/code]
不举具体的例子了,留在练习中,让大家练习。
hx817 2004-12-18 15:32
小结:
1、 今天学习了FOR循环,包括递增循环、递减循环,其中包括序列变量的概念
2、 学习了设置序列变量下界的语句,即setlbound()函数。
3、 讲学习了复合语句begin…end;
4、 初步了解了多重循环
下面给若干思考与练习:
思考1:循环语句,就是让某条语句循环执行若干次,每循环一次,循环变量就递增一次。这种说法对吗?
思考2:循环语句,就是让某条语句循环执行若干次,循环变量总是从1开始,直到对应最后1根K线的位置。这种说法对吗?
思考3:递增循环和递减循环的区别是什么?
思考4:什么是复合语句,由何处开始,到何处结束?
练习1:计算2日平均成交量,请用循环语句写出公式代码。
练习2:计算5日平均收盘价,请用循环语句写出公式代码。
练习3:计算20日平均收盘价,请用循环语句写出公式代码。
练习4:有人写了下面一段代码,你能说出结果是什么吗?
[code]
Fc:=close;
A:=setlbound(fc,datacount/2);
Fc;
[/code]
练习5:读懂下面这段代码,用基本函数来写,相当是什么代码?这段代码可以简化吗?
[code]
Hh:=high;
For i=2 to datacount do
Begin
Hh[i]:=max(Hh[i-1],Hh[i]);
End;
Hh;
[/code]
练习6:LLV(LOW,0);意思是求出上市以来的最低价,请用循环语句写出相同的代码来替换这行代码。
练习7:下面这段代码,改用循环来表达:
[code]
a:=(3*c+l+o+h)/6;
b:(20*a+19*ref(a,1)+18*ref(a,2)+17*ref(a,3)+16*ref(a,4)+15*ref(a,5) +14*ref(a,6)+13*ref(a,7)
+12*ref(a,8)+11*ref(a,9)+10*ref(a,10)+9*ref(a,11)+8*ref(a,12)+7*ref(a,13)+6*ref(a,14)
+5*ref(a,15)+4*ref(a,16)+3*ref(a,17)+2*ref(a,18)+ref(a,19))/210;
d:ma(b,m);
[/code]
lhl311 2004-12-24 08:50
谢谢hx817老师!
hxx816 2005-1-2 18:06
您的举手之劳,对我们是无上的帮助。
股海浪子 2005-1-4 18:34
能办公式学习班更好
清风斜阳 2005-1-24 23:56
感谢老师教导
[quote][i]hx817[/i] 于 2004-12-18 03:30 PM 写道:
上讲,介绍了序列变量、数组等概念,这一讲介绍循环语句。
1、 FOR递增循环:
先从一个的实例开始,求当前股票收盘价的2日算术平均价,为了方便起见,以刚上市不久的600340国祥股价来说明,首先定义序列变量 ... [/quote]
:cool::cool::cool::cool::cool::cool::cool::cool::cool:
ryn 2005-1-29 19:36
谢谢!!!
joneslee 2005-2-16 15:59
fc:=close;
for i=datacount downto 2 do ma2[i] : (fc[i-1]+fc[i])/2;
原野 2005-2-23 13:15
好贴,收藏学习。
peter109 2005-2-28 13:55
正是我所需要的 备份下来 谢谢
qlk90 2005-3-11 08:57
非常感谢南客老师!
股龙王 2005-3-26 11:05
非常感谢南客老师!
天高任鸟飞 2005-3-27 20:48
看帖学习,顶帖拿分!!!!!!!
股海大浪 2005-3-27 23:03
看帖学习,顶帖拿分!!!!!!!
jesse_huch 2005-4-4 22:20
非常感谢
yangtuntao 2005-4-8 13:54
谢谢你的帮助!
趋势之剑 2005-4-19 01:09
:offfff
lph1688 2005-5-4 01:08
见贴就顶~~
ahfyxl 2005-5-15 14:16
谢谢~ 学习
xiaohoo 2005-5-25 19:32
谢谢hx817
xiaohoo 2005-5-25 19:33
谢谢hx817
江花 2005-5-25 21:25
非常感谢南客老师!
:cool::cool::cool::cool::cool:
江花 2005-5-25 21:26
非常感谢南客老师!
缺口 2005-6-5 14:07
看帖学习,顶帖拿分!!!!!!!
zwd8877 2005-6-20 17:03
谢谢!!!
谢谢!!!
xuyi1957 2005-6-25 11:06
谢谢!
zziang 2005-6-26 02:11
[quote]
练习1:计算2日平均成交量,请用循环语句写出公式代码。
练习2:计算5日平均收盘价,请用循环语句写出公式代码。
练习3:计算20日平均收盘价,请用循环语句写出公式代码。
[/quote]
练习1:
[code]fv:=vol;
for i=2 to datacount do maV2[i]:(fv[i]+fv[i-1])/2
[/code]
练习2:
[code]fc:=close;
for i=5 to datacount do ma5[i]:(fc[i]+fc[i-1]+fc[i-2]+fc[i-3]+fc[i-4])/5;
[/code]
练习3:
[code]fc:=close;
for i=20 to datacount do begin
aa:=fc[i];
for j=1 to 19 do aa:=aa+fc[i-j];
ma20[i]:aa/20;
end
[/code]
zziang 2005-6-26 19:01
[quote]
练习4:有人写了下面一段代码,你能说出结果是什么吗?
源码:
Fc:=close;
A:=setlbound(fc,datacount/2);
Fc;
[/quote]
结果是:画出股票上市以来后一半的收盘价格线。
[quote]
练习5:读懂下面这段代码,用基本函数来写,相当是什么代码?这段代码可以简化吗?
源码:
Hh:=high;
For i=2 to datacount do
Begin
Hh[i]:=max(Hh[i-1],Hh[i]);
End;
Hh; [/quote]
相当于:HHV(high,0);
[quote]
练习6:LLV(LOW,0);意思是求出上市以来的最低价,请用循环语句写出相同的代码来替换这行代码。[/quote]
可以参照练习5的思路做,如下:
[code]
Ll:=low;
For i=2 to datacount do
Ll[i]:=max(Ll[i-1],Ll[i]);
Ll;;
[/code]
[quote]练习7:下面这段代码,改用循环来表达:
源码:
a:=(3*c+l+o+h)/6;
b: (20*a+19*ref(a,1)+18*ref(a,2)+17*ref(a,3)+16*ref(a,4)+15*ref(a,5)
+14*ref(a,6)+13*ref(a,7)+12*ref(a,8)+11*ref(a,9)+10*ref(a,10)+
9*ref(a,11)+8*ref(a,12)+7*ref(a,13)+6*ref(a,14)+5*ref(a,15)+
4*ref(a,16)+3*ref(a,17)+2*ref(a,18)+ref(a,19))/210;
d:ma(b,m);
[/quote]
[code]
a:=(3*c+l+o+h)/6;
b:=20*a;
for i=1 to 19 do b:=b+(20-i)*ref(a,i);
b:b/210;
d:ma(b,20);
[/code]
[color=Teal][align=right] 本贴由 zziang 于 2005-6-26 19:06 最后编辑 [/align][/color]
股市骑兵00 2005-6-28 15:38
[quote]Originally posted by [i]zziang[/i] at 2005-6-26 07:01 PM:
结果是:画出股票上市以来后一半的收盘价格线。
相当于:HHV(high,0);
可以参照练习5的思路做,如下:
[code]
Ll:=low;
For i=2 to datacount do
Ll[i]:=max(Ll[i-1],Ll[i]); ... [/quote]
:cool:
zziang 2005-6-29 18:59
谢谢股市骑兵班长的指点,发现了练习6代码的错误,现修正如下:
[code]
Ll:=low;
For i=2 to datacount do
Ll[i]:=min(Ll[i-1],Ll[i]);
Ll;;
[/code]
股票交易人 2005-8-3 00:24
飞狐内置循环、判断等控制语句入门二(南客)
欣儿 2005-8-23 21:25
谢谢南客老师、817老师。
shenmg84 2006-3-25 19:22
感谢!
laopengyou 2006-5-11 07:34
求答案
练习7:下面这段代码,改用循环来表达:
源码:[复制]a:=(3*c+l+o+h)/6;
b:(20*a+19*ref(a,1)+18*ref(a,2)+17*ref(a,3)+16*ref(a,4)+15*ref(a,5) +14*ref(a,6)+13*ref(a,7)
+12*ref(a,8)+11*ref(a,9)+10*ref(a,10)+9*ref(a,11)+8*ref(a,12)+7*ref(a,13)+6*ref(a,14)
+5*ref(a,15)+4*ref(a,16)+3*ref(a,17)+2*ref(a,18)+ref(a,19))/210;
d:ma(b,m);
sxsy 2006-10-15 16:03
谢谢!
cyzpp 2008-4-14 12:53
您的举手之劳,对我们是无上的帮助。:smokin:
页:
[1]