hx817 2004-2-15 13:39
飞狐公式系统入门(南客)
飞狐公式系统,循环、分支语句入门一
序:
飞狐内嵌的VBScript(或JScript)脚本语言,功能已经非常强大,可以真正在编程的意义上编制各种强大的公式,不比DLL弱,甚至某些无法用DLL实现的功能,亦可在VBScript (或JScript)中实现,但比较明显的弱点是,VBScript(或JScript)语言是解释执行的,速度比DLL慢。
为此,飞狐在3.5以上版本中,开发了内置的循环、判断语句,提供字符串处理函数等功能,可以把飞狐中的序列变量等同于数组处理,任意访问序列变量,进一步加强了飞狐的公式系统。
下面以入门的形式,分若干专题并配以适当的示例、练习、思考,与大家一起共同学习。
由于涉及编程的许多概念比较复杂,因此在讲述的过程,假定大家已经有了一定的编公式的基础,对许多编一般公式的细节不再详述。
网络论坛上开设互动专题,受到诸多条件的局限,不知道大家的学习效果如何,希望能够在专题的贴子后,提出建议、问题,以便下一专题能够及时调整难易程度。此外,我也会尽量抽时间回答贴子中的问题。同时也请高手们帮助解答,并指出专题中的错误!谢谢大家!
一、序列变量与数组:
在飞狐的新公式系统的增加部分中,需要大量运用并区分数组、单值变量及序列变量的概念,这些概念也是进一步学习编程(比如编DLL)所必需的,因此有必要简单描述并初步掌握这些概念。
1、常数与单值变量:
常数,在飞狐中,就是不允许改变的数值,在我们平常写公式时,为了公式更加灵活,大量使用了参数,这些参数就是常数,不允许在公式中改变,比如参数n(1,1,25),表示参数n最小值是1、最大值是25、默认值是1,如果在公式中再写一行“n:=30;”就是非法的。
单值变量,即只有一个数值,不随时间而改变,比如“x:100;”,就是定义了一个单值变量x=100,这个值不随时间而改变,做成副图指标看,今天x是100明天x也是100,直到最后1根K线也是100,即副图指标是一条数值为100的水平直线。
hx817 2004-2-15 13:41
2、数组:
所谓数组,就是有序数据的集合
如{1,2,5,7,9}这样一组有先后顺序的数据,我们可以把它们定义成一个数组,例如定义为A,数组A就表示这组有序的数据,这里A就是数组的名称(即数组名)。
数组中的每1个数据,称之为数组中的一个元素,显然上面所说的数组A,第1个元素是1,第2个元素是2,第3个元素是5......,用A[1]、A[2]、A[3]......来表示,用方括号括起来的部分称之为下标,用下标来表示第几个元素。大家可以看出,在本例中,A[1]等于1,A[2]等于2,A[5]等于7,数组A共5个元素,我们就说数组A的长度是5。
上面所举的例子,数组的每一个元素是数值型的,称之为数值型数组,数组的每个元素也可以是字符串的,即字符串型数组。
一般来说,数组的使用,要先定义,然后初始化(即赋予数组的每个元素一个初始的数据)。在飞狐中,目前只支持一维数组,并且下标是从1开始的。
在飞狐中,如何定义、初始化并使用数组?下面简单示例说明:
例1、在飞狐中,定义一个含10个元素的数值型数组
定义数组的语句是variable,公式代码如下:
[code]
variable:A[10]=0; //定义一个含10个元素的数值型数组A,并把所有元素初始化为0;
[/code]
例2:定义一个3个元素的字符串型的数组
公式代码如下:
[code]
variable:B[3]='abc'; //定义一个含3个元素的字符串型数组B,并把所有元素初始化为'abc'
[/code]
例3:把{1,3,5,7,9}定义为数组
分析:这组数据共有5个数值型数据,因此应定义长度为5的数组,并给每个元素赋值。公式代码如下:
[code]
variable:A[5]=0;
A[1]:=1;
A[2]:=3;
A[3]:=5;
A[4]:=7;
A[5]:=9;
[/code]
例4:把{1,5}和{'a','b','c'}定义为数组
分析:variable语句,可以同时定义多个变量、数组,之间用逗号隔开。公式代码如下:
[code]
variable:A[2]=0,B[3]='';
A[1]:=1;
A[2]:=5;
B[1]:='a';
B[2]:='b';
B[3]:='c';
[/code]
前面所举的关于数组例子,都是概念性的,单纯数组的应用一般都比较复杂,比如,从每天的分笔成交中统计,各个成交价位成交的笔数。等到后面讲完循环时再写具体的代码。
3、序列变量:
我们平时接触最多的是收盘价close,写一行代码“fc:close",就是定义了一个变量fc,并把收盘价赋值给变量fc。这里变量fc就是序列变量,因为fc不是一个值,而是一序列随时间而变化的值(收盘价),在K线图中,从第1根K线到最后1根K线都有一个收盘价,因此fc跟单值变量不同,是由一系列的值组成的变量,因此我们称之为序列变量。事实上,把“fc:close”这行代码做成一个指标,就可以看出fc是一条变化的曲线而不是一条水平直线。
飞狐新的公式系统,可以把序列变量作为一个数组,这是一个特殊的数组,这个数组的最小下标是从序列变量的起始有效位置开始,数组的最大下标是K线数量,其中K线的数量,可以从datacount函数得到。
比如“fc:close;",这行代码,可以把fc看成是一个下标从1开始直到datacount的数组。如果我们想知道第1、2、5、最后1根K线的收盘价,可以写成如下代码:
[code]
fc:=close;
fc[1];
fc[2];
fc[5];
fc[datacount];
[/code]
hx817 2004-2-15 13:42
再看一例“fm:ma(c,5)”,这里的5日均价fm也是一个序列变量,可以看成下标从5开始直到datacount的数组。想想看,为什么起始下标不是从1开始,而是从5开始?我想知道K线图上倒数第2根K线对应的5日均价怎么写公式代码?
今天就说这些,下面提供一些练习与思考:
思考1:如何知道当前股票的K线数?使用什么函数?
思考2:如果“fv:=vol”,那么fv[9]表示什么?
思考3:“fmh:ma(h,5)”,fmh[datacount]表示什么?
试试:在飞狐中新建一个公式,编一段下面的公式代码:
[code]
LL:=MA(Low,10);
A:LL[9];
[/code]
这段代码想表达什么?可以通过吗?为什么?
练习1:根据序列变量可以看成一个数组,编一个公式,求出当前股票的上市日期。
练习2:函数barpos返回当前是第几根K线,由此,设计一个公式,在最后1根K线和倒数第10根K线处,用函数drawicon做一标记。
练习3:画一条从上市第1天开始的水平直线,其高度等于当前股票的历史最高价。
练习4:画一条从上市第1天开始的水平直线,其高度位于当前股票历史最高、最低价之间的一半位置。
练习5:当前股票,2003年最高价是多少?首次出现该最高价的日期是哪天?
hx817 2004-2-15 13:44
飞狐公式系统,循环、分支语句入门二
上讲,介绍了序列变量、数组等概念,这一讲介绍循环语句。
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-2-15 13:47
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-2-15 13:49
咦?什么也没有显示,是怎么回事?
问题出在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-2-15 13:51
现在有输出了,但仔细观察,还有点问题,因为是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-2-15 13:53
这个结果就对了!但大家可能会有疑问了,在前面递增循环中,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、复合语句:
答案是肯定的,请看下面的语句:
[quote]
把多条语句看作一条语句
语法:BEGIN...END
这里,begin和end是成对出现的,被begin和end包围起来的语句可以有很多条,这些语句可以看成是一条复合语句。
[/quote]
下面我们用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-2-15 13:57
小结:
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);意思是求出上市以来的最低价,请用循环语句写出相同的代码来替换这行代码。
[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]
blugman 2004-2-15 15:49
谢了~不过看的头晕
海上看日出 2004-2-15 17:48
好,天天学一点,谢谢!!!
第九交响曲 2004-2-19 21:33
天天学,一定会有收获。一天看懂一点,慢慢就能看懂好多点
龙之焰 2004-2-20 09:18
谢谢了。真是好深奥啊。有没有现成的公式?我想如果参照现成的公式来学习能更加地深入一些。当然,除了以前南客的那个排序公式了。下面是我收集的一些VB公式:
龙之焰 2004-2-20 09:20
下面是我收集的一些VB公式:最好能办个专题,来发布VB公式,期待中:clap:
[[i] 本贴由 龙之焰 于 2004-2-20 09:22 最后编辑 [/i]]
lxy-fxj 2004-2-21 13:42
多谢了!辛苦您啦!
zxl_51 2004-2-21 19:49
谢谢
sxn005006 2004-2-21 20:34
很好
haiyeshot 2004-2-27 22:28
thank you
zxl_51 2004-2-29 11:41
无计算机编程基础的人,难以看懂和操作。
zhuangyi 2004-2-29 20:15
谢谢提供,学习一下!
zxl_51 2004-3-2 00:09
nan nan
杨跃进 2004-3-6 06:47
顶顶顶顶顶顶顶顶顶
hepu 2004-3-12 15:20
很久没有看飞狐新增功能了,看了版主贴子,收益不小啊!
梦仙阁主 2004-3-13 16:20
谢谢! 希望继续讲下去
dajiaha0 2004-3-14 02:34
多谢了!辛苦您啦!
ysxysx 2004-3-14 19:57
谢谢!
freedomly 2004-3-16 02:37
唉,简单的就是最好的,如果可以靠公式来发财,那还会有人赔钱吗,唉,不明白,真的是不明白,怎么这么多人去追求这个.飞狐的软件本身最大的优点不在于其有公式平台,而在于其一目了然
hh0.52 2004-3-19 15:30
谢谢了
wyfa321 2004-3-19 19:26
慢慢来。
谢谢
慢慢来。
天天----- 2004-3-19 22:57
谢了,好好研究。。。。。。
XUH-JUN 2004-3-21 08:48
老师:
请帮忙编写两个飞狐公式:
1、分时图中股价始终大于即时均价的股票;
2、分时图中股价连续一小时不破即时均价的股票。
谢谢
6188a 2004-3-22 11:39
谢了~不过看的头晕
caocaocao 2004-3-23 12:41
辛苦了
辛苦了
sujinyuan 2004-3-23 13:07
谢了~不过看的头晕
sujinyuan 2004-3-23 13:13
谢了~不过看的头晕
sujinyuan 2004-3-23 13:16
aaaaa
sujinyuan 2004-3-23 13:17
123456789
sujinyuan 2004-3-23 13:17
12345678
sujinyuan 2004-3-23 13:18
1234567