资源描述
分析家V5.0公式系统
使用与提高
版权所有©2003深圳市汇天奇电脑有限公司
本手册是分析家《公式设计指南》的补充手册,是对分析家V5.0公式系统新增功能的说明,其基本操作请参阅《公式设计指南》。
深圳市汇天奇电脑有限公司对分析家软件及本手册的内容不做任何形式的保证。用户在使用本软件及手册的过程中造成的必然或偶然之过失,深圳市汇天奇电脑有限公司概不负责。
未经深圳市汇天奇电脑有限公司事先书面许可,本手册的任何部分不得以任何形式进行增删、改编、节选、翻译、翻印或仿制。
本手册的全部内容深圳市汇天奇电脑有限公司可能随时加以更改,此类更改将不另行通知。
©本手册的著作权属于深圳市汇天奇电脑有限公司
分析家V5.0公式系统
分析家V5.0公式系统在兼容旧版本公式系统的基础上,引入了一些全新的概念,为书写、描述更为复杂的公式提供了强有力的工具。对于有一定公式编写基础的用户,可以学习以下内容,掌握分析家新公式系统的强大功能。
一. 分析家新公式系统简介
你是否在编写公式的过程中有以下困惑:
1) 书写很长的而且大量重复的公式
2) 为怎样描述一个特殊的概念而伤透脑筋
3) 希望增加公式系统的函数数量
4) 希望了解计算过程中,中间结果的数值
5) 希望自己编写函数
如果有,那么你就需要使用分析家V5.0公式系统了,新的公式系统全面兼容以前的公式系统,同时还给你带来许多革命性的特性。新公式系统的增加的主要内容有:
1) 新增迭代、分支、循环等标准程序语言语法
2) 强大的字符串和数组运算
3) 内建调试器,方便公式查错
分析家新公式系统为用户提供了两个公式编辑器:一个是专业公式编辑器,通过公式管理器可以进入,它提供了公式编辑、编译、调试等多种功能,是一个功能强大的编辑器;另一个是标准编辑器,它与过去版本界面类似,通过除了公式管理器以外的位置均进入到这个标准编辑器,它短小精干,易于使用。
这些新增的内容有一定的难度,适合具有计算机编程知识的用户阅读。通过下面章节的学习,你将会逐步了解到这些新特性将给你带来的方便。
二. 隐含在公式中的循环
1. 计算的顺序
在公式系统中,每一个公式是按照语句顺序执行的,例如:
V0:=MA(CLOSE,5);
V1:=MA(CLOSE,10);
将首先执行5日均线的计算,然后再计算10日均线,但是我们忽略了一个问题,那就是其中还隐含了一个时间顺序的问题,也就是说先计算昨天的数值再计算今天的数值。这样,我们就有了两个顺序——语句顺序和时间顺序,我们到底以哪一个顺序为优先呢?答案是以时间顺序为优先,也就是说计算第一天的V0,第一天的V1,然后是第二天的V0,第二天的V1…。对于上面这个例子,由于前后语句之间不存在相互影响,所以到底哪个顺序优先并不影响结果,因此很多人都忽略了这个问题,认为因该首先计算完所有的V0,然后再计算V1。但是在看下面例子:
V0:=IF(V1>CLOSE,CLOSE,V1);
V1:=MA(CLOSE,10);
前面的语句引用了后面的数据,这样V1昨天的计算结果就会影响到V0的计算,此时就必须以时间顺序为优先。
有了这个时间顺序优先,我们就可以解决过去前后数据互相引用、变量重新赋值、迭代计算等问题了。
因此我们应当按照这样的方式思考:我们用公式描述一天的情况,而不是描述一条曲线,整个公式又隐含着一个时间循环,当算完一天的数据后,又重新回到公式起点,计算第二天的数据,如此循环直到计算完所有的数据。需要注意的是,这个隐含循环中可能存在前面语句引用后面数据的问题,如上例中第一个语句中引用了V1变量,而V1变量需要到第二句才有赋值,所以此时它的数值是在上一轮循环中第二条语句所赋值的,也就是昨天的10日均线数值。这是不是有点太复杂了,但是我们将看到这种循环为我们带来的好处。
2. 迭代计算
我么在分析中经常会用到迭代的概念,比如说指数平滑移动平均线EMA,今日均线等于昨日均线*(N-1)加上近日收盘价*2,然后再除以N+1。这样的问题还包括SMA、DMA等等。所谓迭代就是用上一周期的数值来计算本周期的数值。
过去由于公式系统不能直接支持迭代,所以只能用函数来实现这些迭代功能,而是用心公式系统后,迭代变得可以自己实现了,而且非常简单。以EMA为例:
V1 := (V1*(N-1) + CLOSE*2) / (N+1);
就这么简单,直接按照其原理书写就可以了。我们来分析一下为什么可以这样写。赋值符号 := 左边的V1表示本周期的数值,而右边的V1由于还没有赋值,还保持着上一周期的数值,因此这个V1就还维持着上次计算的结果,也就是上周期的数值,此时它等同于REF(V1,1)。同样的,SMA可以表述为:
V1 := (V1*(N-1) + CLOSE) / N;
需要注意的是,在本语句之后,由于V1已经被赋值,所以它的数值也就变成本周期的数值了。类似的例子还包括:若上周期V1值大于收盘价,则V1等于最高价,否则等于最低价:
V1:= IF(V1>CLOSE, HIGH, LOW);
前面的例子:
V1 := (V1*(N-1)+CLOSE)/N;
我们可能会问,计算第一天的时候,V1的数值是多少。如无特殊说明,变量的初始数值等于0。显然在这个问题中这个设定是不正确的,因为V1等于0的话,计算结果就等于CLOSE/N,显然他不等于第一天的均值,因此我们需要这样说明:
V1 :=IF(BARPOS=0,CLOSE, (V1*(N-1)+CLOSE)/N);
当计算第一天的时候,V1等于收盘价,随后等于指数平滑移动平均。
迭代这个概念理解起来有一定的难度,但如果能够很好地应用它能为我们解决很多问题。
3. 初始数值及变量声明
任何变量在使用之前必须先赋值,那么迭代就有可能出现一个问题:变量还没有赋值怎么使用。我们需要用变量声明来解决这个问题:直接说明变量的初始数值和变量的类型,其语法如下:
VARIABLE: P=1;
表示声明一个变量P,设定其初始数值为1,也就是说在计算的第一天,它的数值为1。这样就可以在迭代中使用变量P了。变量声明必须写在任何语句之前,但如果有INPUT参数说明,则应当放在它的后面。
一个完整的指数平滑移动平均线公式可以写成:
VARIABLE: V1=0;
V1 :=IF(BARPOS=0,CLOSE, (V1*(N-1)+CLOSE*2)/(N+1));
再举个例子,我们需要知道当前正在计算第几根K线?第一天为1,第二天为2,我们可以写成:
VARIABLE: P=0;
P := P+1;
使用迭代,方便地描述了这个要求,今天的数值等于昨天的数值+1。这个例子也很好地说明了迭代的简洁和功能强大。
在这里需要特别指出的是,变量声明设定的初始值表示计算的第一天的数值,今后每次计算新的一天并不对该变量设定初始值,例如:
VARIABLE: V1=0;
V2:=0;
V1:=V1+1;
V2:=V2+1;
这当中V1、V2的计算结果将截然不同,V1设定了初始数值0,每次隐含循环加1,他的计算结果为1、2、3、4…,是一个递增的序列;而V2则由于每次循环均被重新设定为数值0,因此V2:=V2+1这条语句将V2设置为1。因此,如果我们需要每天决设定初始数值,则需要一条赋值语句来设定;如果我们不需要每天设初始值而是第一天需要,则使用VARIABLE语句声明变量并且赋予初始数值。
4. 参数说明
新公式系统引入参数说明语句:
INPUT: [参数名]([默认值],[最小值],[最大值],[测试步长]);
其中默认值是必需的,其他值若没有指定,则使用其默认值0,100和1。参数说明语句必须放在公式的最前面。
参数说明等同于在公式编辑器中直接在参数输入框中输入参数。系统将参数输入框中和INPUT语句说明的参数累加起来,其总数不能不超过16个。使用参数说明语句,可以使公式程序放在一段文字中,可以方便一部分喜欢这种方式的用户。你可以使用两种方法中的任意一种,他们不存在区别。
我们可以在INPUT语句中说明多个参数,它们之间用逗号分隔。例如:
INPUT: P1(10,0,20), P2(20,0,100);
5. 总结
新公式系统的核心在于:我们只需要描述每一天的行为,如果当天没有改变一个变量,则该变量维持昨天的数值不变。
三. 分支
1. 为什么要分支
所谓分支,就是如果满足某个条件就执行某些指令,否则就指令另外一些指令。有了分支,计算机就有了智能,知道根据具体情况作出不同的动作,这是计算机最重要的功能之一。
2. 以前我们是怎样实现分支的
过去,我们也在函数中隐含地使用了一些分支概念,在函数中直接将分支包含进去。例如绘图函数DRAWTEXT(Cond,Price,Text),表示如果Cond条件满足就输出文字。再例如,IF(Cond,V1,V2)表示如果Cond条件成立就返回V1,否则就返回V2。
但是这种包含在函数中间的条件也有许多缺陷,那就是它只能控制一条语句,而且只在有限的几个函数中包含条件,这极大地限制了分支的应用。例如,我们就无法描述如果条件成立,V1就等于CLOSE,否则V2就等于CLOSE。
3. 分支的描述方法
我们使用IF [条件] THEN [语句] 来描述如果条件成立就执行语句这样一个逻辑,例如
IF CLOSE>OPEN THEN
P := P+1;
它表示如果收盘价大于开盘价,P的数值就增加1,否则P值维持不变,也就是说统计历史阳线的数量。
需要注意,IF语句和IF函数使用同样的关键字,区分它们的办法是在IF语句之后必然存在THEN语句,而IF函数则没有。因此我们不能在IF语句条件部分包含IF函数,例如:
IF IF(CLOSE>OPEN, OPEN, CLOSE)>10 THEN
P := P+1;
该语句将混淆两个IF的作用,可以使用以下方法来解决:
C1 := IF(CLOSE>OPEN, OPEN, CLOSE)>10;
IF C1 THEN
P := P+1;
如果我们想要在条件满足的情况下多做几件事情怎么办?在此我们引入BEGIN…END这样一个语句来形成组合语句,也就是说将它们中间所包含的语句看作一个整体,一起执行。组合语句被认为是一个整体,在接下来的分支、循环等操作中均需要用到。例如:
IF CLOSE>OPEN THEN BEGIN
P := P+1;
Q := MA(CLOSE,10);
END
他表示如果条件成立,将执行对P和Q的赋值语句,否则这两条语句均不执行。
BEGIN…END语句可以嵌套,END与之前面最接近的还没有配对的BEGIN进行配对。例如:
IF CLOSE>OPEN THEN BEGIN (1)
P := P+1;
IF CLOSE>10 THEN BEGIN (2)
P := P+1;
Q := MA(CLOSE,10);
END (3)
END (4)
其中,2-3是配对的,1-4是配对的。
分支语句还有以下形式:IF…THEN…ELSE,他表示如果条件满足就执行某件事,否则就执行另外一件事。例如:
IF CLOSE>OPEN THEN
P := P+1;
ELSE
Q := Q+1;
这段公式表示,如果今天收阳线,则将P的数值增加1,否则将Q的数值增加1,需要注意的是,ELSE必须与IF配对,而且中间只能有一条语句或用BEGIN…END包围起来的组合语句。IF…THEN…ELSE可以嵌套,ELSE与之前最接近的未配对的IF语句进行配对,例如:
IF CLOSE>OPEN THEN (1)
P := P+1;
ELSE IF CLOSE<OPEN THEN (2)
Q := Q+1;
ELSE (3)
R := R+1;
其中第(2)行的ELSE与第(1)行的IF配对,因为她前面只有一个IF;第(3)行的ELSE与第(2)行的IF配对而不与第(1)行的IF配对,因为第(2)行的IF未配对,而且距离第(3)行最近。在使用多层分支嵌套时,要时刻注意这个配对原则。
4. 分支举例
例1:计算上市以来上涨天数和下跌天数的比率:
VARIABLE: UP=0, DN=0;
IF CLOSE>REF(CLOSE,1) THEN
UP := UP+1;
ELSE IF CLOSE<REF(CLOSE,1) THEN
DN := DN+1;
RATIO: IF(DN=0,0,UP/DN);
最后一条语句,判断DN是否为0,用来保护结果不被0除。
例2:计算历史上阳线的平均涨幅和阴线的平均跌幅
VARIABLE:UPR=0,UP=0,DNR=0,DN=0;
R := CLOSE/REF(CLOSE,1)-1;
IF CLOSE>OPEN THEN BEGIN
UPR := UPR + R;
UP := UP+1;
END
ELSE IF CLOSE<OPEN THEN BEGIN
DNR := DNR + R;
DN := DN+1;
END
平均涨幅: IF(UP=0,0,100*UPR/UP);
平均跌幅: IF(DN=0,0,100*DNR/DN);
四. 循环
1. 为什么要循环
循环是计算机程序中一个最重要的概念,他使计算机能够按照用户的意志重复执行某个任务,我们前面所提到的公式系统中存在的隐含循环也是一种沿时间变化的循环。其实我们的函数中也大量包含了循环的概念,比如SUM、MA等等。我们来看看循环的概念。
如果我们计算从1加到100,写成公式:
1+2+3+4+5…+100;
这个公式很长,而且写起来容易出错,如果我们是计算从1加到10000怎么办?这就需要用到循环,我们让计算机循环计算,总共循环10000次,其中第N次循环加N即可解决这个问题:
FOR I=1 TO 10000 DO
SU := SU+I;
等一会儿我们再来解释它。我们看到,有了循环以后,许多繁杂的事情都可以轻松解决了。由于以前没有循环,我们必须在函数内部来实现一些循环,现在有了它,我们可以省去好多函数。例如,SUM表示计算N天数值的总和,写成公式
C + REF(C,1) + REF(C,2)+ … + REF(C,N-1);
由于书写困难而且不灵活,我们引入SUM函数来计算。但是如果我们使用循环:
SU := 0;
FOR I=0 TO N-1 DO
SU := SU+REF(C,I);
FOR循环表示,循环执行SU := SU+REF(C,I)这条语句,第一次循环变量I等于0,每次循环I递增1,直到大于N-1时循环结束。也就是说,REF(C,I)在每次循环中表示今天、昨天、前天…N-1天前的收盘价,将它们累加到SU变量中,完成了累加的功能。
我们需要注意的是,此时的循环与公式中的隐含循环是不一样的,隐含循环不需要书写而且是不可避免的,而循环需要用循环语句写出来。循环语句所描述的循环,是针对某一根K线执行的,整个循环过程中其计算位置是不变的。因此,在整个隐含循环中,每进行一次隐含循环,就要执行一轮循环语句。因此,大量使用循环语句,尤其是嵌套循环语句将大大降低运算速度。我们可以来看看,如果某股票有3000根K线,我们在公式中包含一个100次的循环,则循环将执行3000*100=30万次,如果还存在循环嵌套,也就是循环套循环,如果内外均是100次的循环,则循环次数为3000*100*100=3000万次,其执行速度将非常缓慢。分析家系统限制总的循环次数要小于1亿次,否则不能得到计算结果。
循环分为WHILE和FOR循环两种。
2. WHILE循环
WHILE循环语法:WHILE [条件] DO [语句]
他表示,如果条件成立则循环执行语句,直到条件不成立为止。例如我们计算最近多少天完成100%换手:
HR := VOL;
ND := 0;
WHILE HR<CAPITAL DO BEGIN
ND := ND+1;
HR := HR + REF(VOL,ND);
END
ND就是结果。HR表示最近成交量累加,设初始值为当日成交量,然后循环直到它大于流通盘为止。循环体中,ND每次循环加1,HR每次循环加上ND天前的成交量,也就是说最近ND天的成交量累加。
在循环中必须注意的是,循环条件在循环过程中一定要发生变化,并且会变成条件不成立,否则会形成死循环,也就是说循环条件永远成立,计算机不断地进行循环计算。
在上例中,HR每次递增,当它增大到流通盘以上时,条件变成不成立,从而终止循环。另外一个我们没有注意到的问题是,如果今天是上市第一天,而且换手率没有达到100,则这个循环会出现问题,因为不论ND怎样增大,REF(VOL,ND)总是返回没有数值,也就是说HR的不到递增,也就永远无法破坏循环条件而终止循环,它也是一个死循环。因此我们需要改成:
HR := VOL;
ND := 1;
WHILE HR<CAPITAL AND ND<BARPOS DO BEGIN
HR := HR + REF(VOL,ND);
ND := ND+1;
END
增加一个ND<BARPOS用以阻止超过上市日的向前引用。
从这些例子中我们看到,自己使用循环来实现算法,其功能是强大的,但是需要十分小心,避免死循环的发生。因此,我们能够使用函数来实现的功能,还是尽量使用函数来实现,避免不必要的复杂性。
3. FOR循环
我们大多数的循环是指定循环次数的循环,而且我们证券计算也大量使用向前引用若干天的数据,因此 FOR循环将更加实用。
FOR [变量]=[初值] TO [终值] DO [语句]
它表示使用变量来控制执行循环语句,首先给变量赋初值,然后判断变量是否小于或等于终值,若满足条件则执行语句,然后将变量加1,循环判断变量是否小于等于终值并循环执行,直到条件不满足为止。例如
FOR I=1 TO N DO…
表示循环N次,循环变量从1到N,类似的
FOR I=0 TO N-1 DO…
也表示循环N次,但是循环变量从0到N-1。
循环变量还可以从大循环到小,可以使用
FOR [变量]=[初值] DOWNTO [终值] DO [语句]
此时变量将从大到小变化,直到小于种值为止。
我们在使用中需要注意递增还是递减变化,否则将形成死循环。
使用FOR循环的一个最大的好处在于其循环次数可以控制,不像WHILE循环可能存在潜在的死循环。还以WHILE循环中的换手100%为例:
HR := 0;
FOR I=0 TO BARPOS-1 DO BEGIN
IF HR<CAPITAL THEN BEGIN
HR := HR+REF(VOL,I);
IF HR>=CAPITAL
ND := I+1;
END
END
我们用FOR循环来控制总的循环次数不超过数据总数,从而避免了死循环的发生。在循环中,如果换手未超过流通盘,则继续累加,当换手刚达到流通盘时,将循环次数赋给结果ND。
4. 循环的终止
我们看到,循环过程中必须要有一个终止循环的方法,WHILE语句中使用条件不满足来终止循环,FOR循环中使用变量递增递减来终止循环,是否还有其它的需要呢?
我们看上面的例子,该循环有一个问题,就是无论是否计算出结果,循环都将继续下去,直到计算到上市第一天,这将大大降低效率。我们通过主动终止循环来解决这个问题:
HR := 0;
FOR I=0 TO BARPOS-1 DO BEGIN
HR := HR+REF(VOL,I);
IF HR>=CAPITAL BEGIN
ND := I+1;
BREAK;
END
END
执行BREAK语句将终止循环,无论循环中值条件是否达到。在本例中,当计算到结果,就停止循环。一般说来,BREAK语句总是与IF语句配合使用。使用BREAK语句可以使公式看起来更加简单。
BREAK可以用来终止WHILE循环和FOR循环。
5. 循环的嵌套
我们可以在循环中再套入循环,这就叫做循环嵌套。例如我们想要找到最近100天中收盘价相同的天数:
ND := 0;
FOR I=0 TO 99 DO BEGIN
FOR J=I+1 TO 99 DO BEGIN
IF REF(CLOSE,I)=REF(CLOSE,J) THEN
ND := ND+1;
END
END
我们分成内外两个循环,外层循环使用I作为循环变量,它从0到99循环,得到之前每一天的收盘价REF(CLOSE,I),而内层循环使用J作为循环变量,它I+1到99循环,表示从第I+1天前开始查找等于第I天数值的K线,若找到(条件REF(CLOSE,I)=REF(CLOSE,J)满足),则将ND加1。
使用循环嵌套,我们可以做许多过去无法做的事情了。但是使用嵌套一定要注意,不要是循环次数太大,否则运行速度会很慢。
6. 循环举例
例1.计算N日均线
SU := 0;
FOR I=0 TO N-1 DO
SU := SU+REF(CLOSE,I);
SU / MIN(N,BARPOS);
该例子中有两个技巧,其一,没有可以去避免向前循环超过上市日的问题,因为发生这样情况时SU的数值不会增加,也就是说SU等于上市到现在的总和;其二,如果当前位置小于N,则SU的数值表示上市到现在的总和而不是N日总和,所以平均价格应该为SU/BARPOS,因此我们使用了SU / MIN(N,BARPOS);
例2.计算前十大股东占总股本的比例
SU:=0;
FOR I=1 TO 10 DO
SU := SU + PROFFIN(5002+(I-1)*6,0);
比例: SU/PROFFIN(1001,0)*100;
在本循环中使用了一个技巧,我们发现第一、第二、第三…股东持股量的代码是5002,5008,5014…,它们之间间隔6,所以我们可以使用5002+(I-1)*6来表示这些代码
五. 字符串
1. 字符串的定义
在公式中,我们有时候需要输出一些文字,这就需要使用字符串。字符串常量我们在过去的版本中已经存在,就是使用单引号“’”括起来的字符,这些字符可以在文字输出函数等地方直接使用。
在分析家5.0新公式系统中,我们引入字符串变量这个概念,它可以像数值变量一样自由改变,可以根据具体情况赋给不同的数值。字符串变量和普通变量一样可以赋值、运算、赋初始值等等。例如:
S := ‘CCC’;
我们将变量S赋值‘CCC’;
VARIABLE: S=’ABC’;
表示我们定义了一个字符串变量S,给它赋初始值‘ABC’;
S := STKNAME+ ‘ ’ + STKLABEL;
字符串S等于股票名称后跟股票代码。
我们可以像使用字符产常量一样使用字符串变量,例如在DRAWTEXT函数中。
2. 字符串的计算
字符串可以进行计算,包括字符串比较、求字符串子串、大小写转化、字符串查找等等。字符串的比较是以字母表为顺序的,越靠后的越大,小写字母都大于大写字母。例如:
STRCMP(‘ABC’,’abc’);
比较两个字符串,显然小写字母大于大写字母,所以函数返回1。
在分析家公式系统中引入字符串加法的概念,就是将后面的字符串连接到前面字符串的尾部,我们使用的一个简单的办法:用加号,例如
S := STKNAME+ ‘的代码是’ + STKLABEL;
使用加好直接将后面字符串接到前面字符串的尾部,对于浦发银行来所,字符串S等于“浦发银行的代码是600000”。
更为强大的是,字符串加法还可以直接加数值型的数据。例如:
S := ’今天收盘价:’ + CLOSE;
系统会将收盘价CLOSE的数值转化为字符串连接进来。所以,当我们看到一个字符串加上数值的时候,千万不要以为这是普通的加法。除了这种隐含的转化方法外,我们还可以用函数NUMTOSTR将数值强制转化为字符串,例如:
S := NUMTOSTR(CLOSE);
或者将字符串转化为数值STRTONUM。
六. 数组
本节内容较复杂,一般用户可以跳过本节。
所谓数组,就是一个容器,它可以存放多个数据,我们可以通过序号来访问这些数据。一般说来我们总是将一些相关的数据组织在一起放到数组中,当我们在使用循环的时候,数组就可以发挥它的优势。分析家公式系统目前支持一维数组。
数组在使用之前一定要先声明:
VARIABLE: V[20]=0;
表示定义一个数值型数组V,它总共有20个元素,这些元素的初始值为0。
VARIABLE: S[10]=’A’;
表示定义一个字符串型数组S,它总共有10个元素,这些元素的初始值为’A’。
数组变量声明以后,就可以像普通变量一样使用了。在使用数组变量时,需要在变量名后面带上序号,表示引用数组中的第几个元素,元素的序号从1开始。例如:
P:= V[5]*CLOSE;
表示V的第5号元素乘以收盘价。
数组和普通变量有一个重要的区别,数组是不能够引用过去的数值的,对数组进行引用过去数值的操作将会得到它当天的数值,就是说数组只存在当天的数值,从某种意义上来说它更像一个可以重新赋值的常量。因此,
REF(V[3],1);
MA(V[2],10);
等均会返回一个常数。如果你需要引用过去的数值,可以将数组元素赋值给一个普通变量,例如:
P:=V[3];
MA(P,10);
使用数组以后,我们可以利用数组的序号来访问数据,这给循环带来了方便,我们通过循环可以遍历整个数组了。
七. 专业财务数据
在分析家机构版中,内嵌了二百多项专业财务数据。这些专业财务数据包含了每只股票历史上的每一次变化,对于注重基本分析的用户,我们提供了一整套结合技术分析、基本分析的公式平台。
专业财务数据包括七个函数,分别由来访问、设定专业财务数据。所有的财务数据均带有一个数据类型参数,他表示需要访问具体哪一个数据,例如1001表示总股本,5001表示第一大股东名称等等。这些函数包括:
PROFFIN(N,M), PROFSTR(N,M)访问专业财务数据的数值,他们的区别在于前者得到数值型的财务数据,后者得到字符型的财务数据。N表示数据类型,M表示哪一期数据,0表示最近一期,1表示前一期。
PROFFINON(N,Y,MD), PROFSTRON(N,Y,MD)访问指定日期的财务数据,他们的区别在于前者得到数值型的财务数据,后者得到字符型的财务数据。N表示数据类型,Y表示年,MD表示月日,例如PROFFINON(1001,2001,0101)表示2001年1月1日的总股本。
SETPROFFIN(X)用来设定财务数据属性。财务数据包括季报、中报和年报,适用本函数可以决定是否需要它们中的哪一些类型。X是一个五位数,每一位表示不同的含义,最高位表示是否调整中报季报数据(分别对1季报、中报和3季报的部分财务指标做乘以3、2、4/3的处理),次高位表示是否包含最新财务指标,最低三位表示是否包含季报、中报和年报。这些位置如果为1就表示设置,如果为0就表示不需要。例如:01111就表示不对季报中报调整,数据包含全部的年报中报和季报;00001表示只需要年报。使用本函数后,其它专业财务数据函数将受到它的影响。
八. 其它
1. 数据二
我们经常需要分析两只股票之间的关系,比如它们之间的相关性、贝塔系数等,新公式系统引入数据二概念,它在公式中代表另外一只股票,这只股票可能是K线图上叠加的股票,或者相关性分析中的相关股票。语法:
DATA2.[数据]
其中数据可以是CLOSE、OPEN、HIGH、LOW、VOLUME或AMOUNT,表示引用数据二的开盘价、收盘价等。例如我们可以计算两只股票收盘价之比:
CLOSE/DATA2.CLOSE;
数据二对于相关性分析很重要,所谓相关性就是两个数据的相似程度,该数值分布在-1到+1之间,若等于+1表示两者完全相同,若等于-1表示两者完全相反,若等于0表示二者无关。一般说来,两只股票收盘价的相关性会在0—1之间。相关函数:
RELATE(P1,P2,N);
表示P1和P2之间在最近N天的相似程度。
使用相关性分析不同的数据,得到的意义是不一样的。例如收盘价相关性:
RELATE(CLOSE,DATA2.CLOSE,60);
他描述了两只股票价格走势的相似性,也就是说基本形态走势相像。而涨跌幅相关性:
RELATE(CLOSE/REF(CLOSE,1),DATA2.CLOSE/REF(DATA2.CLOSE,1),60);
表示每日涨跌的相似性。使用该指标所得到的结果可能看起来走势不是十分相似,但在多数情况下它们的涨跌情况是接近的,也就是说同涨同跌。
如果用其它的指标来计算相关性,则其结果可能更难理解,但是真正掌握两只股票某种属性的相似可能会对你的投资带来很的大改变。
2. 自定义数据
分析家机构版V5.0引入自定义数据概念,用户可以利用该功能自己设定若干数据。自定义数据可以从F10资料中提取,可以使用公式计算得到,可以从文本文件引入,也可以自己手工输入。该数据是基于日线的,也就是说我们只能在日线分析周期中使用它。
自定义数据分为四类,分别是
1. 股票相关序列数:每一只股票均有它自己的一组数据,每天一个数据,它和扩展数据非常类似,我们可以用它来存储每日成交笔数、某公式计算结果等数据。
2. 股票无关序列数:所有股票共用一组数据,每天一个数据,它主要用来存储与市场相关的数据,例如每天的流通市值等。
3. 单值数据:每一只股票均有它自己的一个数据,该数据并不随时间发生变化,例如我们可以用它来存储发行价、中签率等。
4. 字符串数据:每一只股票均有它自己的一个字符串数据,该数据并不随时间发生变化,例如我们可以用它来存储板块类别、法人代表等。
用户可以根据自己的需要,设定自定义数据类型,对于从F10提取或使用公式计算得到的自定义数据,可以设定自动更新,当执行收盘作业时,系统将自动执行自定义数据的刷新工作。
每一个自定义数据均有一个名称,我们总是通过它来访问自定义数据。在公式系统中,使用SELFDATA来访问数值型的自定义数据,而使用SELFSTRING来访问字符串型的自定义数据。
在动态显示牌中,我们也可以直接显示自定义数据,方法是用鼠标右键点击标题栏,选择自定义数据并且选中需要的项目即可。
3. 坐标设定
分析家新公式系统中,坐标设定采用公式来实现,方法是:
REFLINE:L1,L2,…LN;
表示在L1、L2、…LN处绘制水平坐标线。
九. 调试
1. 为什么需要调试
公式系统是一个简单的程序设计环境,只要是程序设计就有可能出现差错,有可能出现没有想到的问题,因此多数程序设计工具均提供一个调试工具,让用户可以一步一步地执行程序,查看中间结果等等。
分析家新公式系统为用户提供了一个强大的设计环境,当然需要提供一个调试器用以查找错误。利用分析家公式调试器,你可以单步执行公式程序、连续单步执行、查看变量数值、设置断点,可以方便查看到公式中的任何数值是怎样计算出来的,分支是怎样执行的,循环指定了多少次等。
2. 调试前的准备工作
当你使用专业公式编辑器写完一个公式,或者打开一个现有的公式,即可进入调试。若你得公式没有语法错误,从菜单、工具条选择调试功能,或者直接按F6即可进入调试。进入调试状态后,公式编辑窗口下面出现两个小窗口,分别是变量窗口和图形窗口。
左边的窗口是变量窗口,变量窗口显示公式中所有的变量及其属性、数值,鼠标双击变量可以弹出窗口显示该变量的详细数值,而在执行过程中若数值发生变化就会用红色来显示数值。
右边的窗口是图形窗口,它的上半部分显示待计算的股票K线图,下半部分显示变量数值曲线。在变量窗口中打勾的变量将被显示,用鼠标点击变量前的方块可以改变其显示属性。用鼠标点击图形窗口右侧的股票名称、分析周期可以改变待计算的股票或分析周期。
此时公式第一行的左侧线是一个黄色箭头,它表示当前正在准备执行该语句。我们在整个调试过程中可以看到该标志随着执行过程不断在移动。
3. 运行
调试准备好以后,按F5就可以执行了,此时公式将很快被执行完,然后停在程序的最后一行,此时你可以查看变量内容和图形。
如果按Ctrl+F5表示重新执行程序,系统将重新启动公式并且停留在第一行等待执行。
如果按Shift+F5表示停止执行,这对于跳出一个长时间的循环非常有用。
4. 单步运行
从菜单、工具条选择单步执行,或者按F11可以单步执行,此时每按一次执行一条语句,在执行过程中可以方便地了解到变量的计算过程,程序的执行流程等。我们还可以选择连续单步执行来让电脑自动进行单步运行,此是可以将双手解放出来。
我们会发现,当公式执行到最后一行以后,它有跳回到第一行执行,这和一般的程序可不一样!细心的你可能已经发现,在右下角图形成口中的红色箭头已经悄悄地向右移动了一天,这就是我们所说的隐含循环。程序从第一行执行到最后一行,然后计算第二天的数据,又从程序第一行开始执行了。
5. 执行到指定目标
有时候程序比较长,或者循环太多,使用单步太慢,可以使用执行到指定目标,移动光标到你需要的程序行,然后按F7,公式将执行到该行后停下。
6. 设置断点
断点就是程序每次执行到该行就停下,与F5连续执行配合可以提高工作效率。将光标移到需要设定断点的位置,按F9可以设定或取消断点。断点所在行的左边会有一个紫红色的圆形,表示该行被设置了断点。
7. 查看变量内容
当程序运行到某处停下来后,鼠标双击变量窗口的某变量,可以查看变量内容。对于简单变量,变量窗口中已经显示了它的数值,但对于序列数、数组等变量,可以使用本功能详细了解变量的每一个元素的内容。
8. 运行到指定时间
我们说过,公式中存在一个隐含循环,公式是一天一天执行的。当我们需要执行到时间相对靠后的数据时,可能需要的循环次数就很多,此时可以有鼠标右键点击图形窗口中的你所需要的K线的位置,从弹出菜单中选择执行到该K线或者指定到指定日期就可以跳过前面不必要的循环。
十. 综合举例
1. 均线系统
在以往均线系统的编制需要用到函数MA(X,N),该函数表示求X的N日内平均值。在新公式系统中,没有函数照样可以实现MA(CLOSE,N)。
INPUT:N(5,1,300); {参数申明}
VARIABLE:K=0; {变量申明}
FOR I=0 TO N-1 DO K:=K+REF(CLOSE,I);{把最近 N 天的收盘价累加}
MA1:K/N; {实现MA(C,N)}
K:=0;
2. 指数平滑移动平均线
指数平滑移动平均线与上面的简单均线系统相比,主要在于均线的算法略有区别,简单均线只是将N日内的收盘价相加然后平均,而指数平滑移动平均线中包含昨日的该数值,因此理论上比简单平均更有价值。
指数平均的算法为:
若Y=EMA(X,N),
则Y=[2*X+(N-1)*Y']/(N+1),其中Y'表示上一周期Y值。
如果不使用EMA函数, EMA(CLOSE,N)在新公式系统中可以这样书写:
INPUT:N(5,1,300);
VARIABLE:EMA1=0; {初始化变量}
EMA1:(2*C+(N-1)*EMA1)/(N+1); {新公式系统中可以直接迭代,表示指标
展开阅读全文