第一章 交易模型的编写规则... 4

1.1数据引用... 6

1.2特殊数据引用... 6

1.3公式体构成结构... 7

第二章 金字塔的控制语句... 8

2.1序列变量与数组... 8

2.2循环语句... 10

2.3条件语句... 12

第三章 序列模式和逐周期模式... 14

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

第四章 金字塔的新交易系统... 16

4.1下单模型语句... 16

4.2简单交易系统示例... 16

4.3复杂交易系统示例... 17

第五章 新交易系统的函数... 19

5.1快速入门... 22

5.2常见问题... 25

第六章 交易系统编写范例和常见问题... 27

6.1趋势类交易模型编写范例... 27

6.2振荡类交易模型编写范例... 32

6.3日内交易模型编写范例... 34

6.4常见问题... 36

第七章 金字塔的后台程式化交易... 38

7.1程式化交易系统的函数... 38

7.2程式化交易函数... 40

7.3程式化交易执行语句常用的其它函数... 42

7.4账户函数介绍... 43

第八章 程式化交易测试和优化... 46

8.1完整交易系统的组成... 46

8.2测试平台的基本内容和架构... 46

8.3金字塔的图表程式化交易和后台程式化交易的结构... 48

8.4程式化交易的前提、步骤... 50

第九章 程序化交易的启用... 51

9.1启动图表交易... 51

9.2启动后台程式化交易... 52

第十章 公式系统的编写调试... 54

10.1基于图表公式的调试... 54

10.2基于后台预警和程式化交易的调试... 54

第十一章 VBS公式教程... 55

11.1嵌入式VBSJS脚本... 55

11.2 VBS接口... 55

11.3利用VBS设计公式... 55

第十二章 自定义函数... 58

12.1自定义函数的格式... 59

12.2自定义函数的两种工作模式... 59

第十三章 DLL扩展函数程序调用接口... 62

第十四章 金字塔插件接口... 62

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

      本教程主要介绍金字塔的公式系统编写高级篇,重点介绍金字塔的新图表交易系统和后台程式化交易,本篇教程的读者需要有一定的金字塔PEL语言(金字塔简易语言简称PEL)编写经验,并且里面涉及到的部分功能需要标准版及其以上用户才可以使用。

第一章 交易模型的编写规则

我们在金字塔的程式化交易初级教程里已经对公式模型编写有了一定程度的探讨,这里我们再进行一遍简单的回顾。

在金字塔的主图分析界面,按功能键F3就会出现图4.1公式选择器的界面,

1.1公式选择器

在“交易系统”上按鼠标右键,选“新建公式”,出现图1.2交易系统编辑器

4.2交易系统编辑器

通过该界面我们可以了解该系统的公式设定的内容和相关规则:

A:每一个指标公式必须有一个名称,这个名称由字母和数字组成,公式名称在同类公式中必须是唯一的,例如不能同时存在两个AAA系统公式,公式名称最多16个字符。

B:公式说明是一段文字,用来简单描述该公式的含义,在公式列表时显示这段文字,这段文字不宜过长。

C:计算参数:计算参数用来替代公式中所需要的常数,在使用时可以方便地调节参数,不必修改公式就可以对计算方法进行调节。计算参数包括参数名称、最小值、最大值、缺省值四个部分,参数名称用于标识参数,计算公式时采用缺省值计算,而最小值和最大值是参数的调整范围。

D:公式编辑栏,本栏为公式编辑的文本区。

E:密码保护,选中该栏目为指标公式加密。

F:公式注释是一段文字,相对于公式描述而言它可以很长,主要用来描述一个公式如何使用、注意事项、计算方法等等。

G:周期的设定:数据分析周期就是相邻两组数据的时间间隔,可能是从几秒、1分钟到1000天间的任意间隔;还可以是分笔成交分析周期,这种情况下时间间隔不定。

公式系统的引用周期:应不同的使用者在分析周期习惯上的差异,金字塔特别设定了周期选择。这主要是针对在引用类函数在引用数据时锁定自己所需要的周期,例如在日线上,或者在周线上等等的要求。

H:费率设置和平仓止损,请用户一定根据要监控的品种填写好这里的费率设置,以防止在某些K线图上出现因为资金用尽而没有开平仓信号。

所有的公式系统都是遵守统一的运算法则,统一的格式进行函数之间的计算,所以我们掌握了技术指标公式的基本原理,其他的公式也不会出脱其外。
    例如我们在指标公式系统内写下公式(公式执行体的编写--包括各种符号--都要在英文状态输入法下,否则不被识别,测试时会报错):
    A:=X+Y; B:=A/Z;  C:=B*0.618;
    分析以上公式,我们可以引出以下相关的格式和法则的结论:

1.1数据引用

A、数据来源
   
公式中的基本数据来源于接收的每日行情数据,这些数据有行情函数从数据库中按照一定的方式提取,例如,高开低收,成交量,成交额等等。
B
、数据类型
   
按照公式使用的数据类型,系统可以处理的数据分为两类:变量和常量。
   
所谓变量就是一个随着时间变化而变化的数据,例如成交量;常量就是一个永远不变的数据。例如3,每个函数需要的参数可能是变量也可能是常量,不能随便乱用,函数计算的结果一般是一个变量。
   
例如计算收盘价均线MA(CLOSE,5)MA函数要求第一个参数为变量,而CLOSE函数返回的正是一个变量;MA函数要求的第二个参数是常量,5就是一个常量,所以我们就不能这样书写:MA(5,CLOSE)

1.2特殊数据引用

A、指标数据引用
   
经常地编制公式的过程当中,需要使用另外一个指标的值,如果按照通常的做法,重新编写过这个指标显得很麻烦,因此有必要学习使用如何调用别的指标公式。
   
基本格式为:指标.指标线(参数)

a、指标和指标线之间用顿号分开,一个指标不一定只有一条指标线,所以有必要在指标后标注指标线的名称,但是如果缺失则表示引用最后一条指标线。

b、参数在表达式的末尾,必须用括号括起来,参数之间用逗号分开,通过参数设置可以选择设定该指标的参数,如果参数缺失则表示使用该指标的默认参数设置。

c、整个表达式用引号引在其中,除参数以外。
例如:

“MACD.DEF”26,12,9):表示计算MACD指标的DEA指标线,计算参数为26129

“MACD”26,12,9):表示该指标的最后一条指标线,计算参数是26129

“MACD”:表示该指标的最后一条指标线并且使用公式的默认参数。

 

B、跨周期引用指标数据
   
在金字塔当中允许使用不同分析周期上的指标数据,但是只能是向上引用,不能在原周期上使用比现在周期长度小的周期上的指标数据。

a、基本格式为:指标.指标线#周期(参数),格式上只是比上面指标引用多了一个周期设定,其他内容和方法一样,在周期调用上存在以下对应关系:

MIN11分钟  MIN55分钟......DAY:日线 WEEK:周线 MONTH:月线 YEAR:年线
   
如上所示,MIN1表示的分析周期为1分钟,那么只能是在当前周期为分笔成交图时才可以实现对该周期指标线数据的引用。

例如:当前周期为日线,那么在公式中使用“MACD.DEA#WEEK”(26,12,9)表示使用了当天所在的本周的MACD指标中的数据。

b、以上格式的扩展格式为:“指标.指标线##周期”(参数),该格式比基本格式采用了不同的对齐方式,简而言之,就是说“#”的格式调用的本周期所在的上一级周期的指标数据,那么“##”的格式则表示调用了前一种格式的前一周期的指标数据,举上例而言,“MACD.DEF##WEEK”(26,12,9)表示的是从当天看来的上一周的数据,而基本格式就是当天看来的本周的数据。


C、其他数据引用
    使用以下的格式可以在当前的分析界面下引用大盘的数据或者其他个股的数据实现横向上的对比.

a、引用大盘数据引用大盘数据时使用下列函数:INDEXC/INDEXV,等等!

b、引用个股数据引用个股数据时使用下列格式:“品种代码$数据”,在以上格式当中调用CLOSE,VOL,AMOUNT等等!例如“0002$VOL”表示0002该股本周期的成交量,“1A0001$CLOSE”同样也可以表示为大盘本周期的收盘价,此时的大盘被视为一只个股。

1.3公式体构成结构

A、公式语句
    所有的公式体由若干语句按照一定的格式组成,每个语句表示一个计算结果,根据各个语句的功能分为两大类语句,一类是赋值语句,一类是中间表达式。


B、赋值语句

在技术指标“B:A/Z”和“C:B*0.618”就是分别两条指标线,语言间用冒号隔开。该语句被称为赋值语句,在技术指标当中,赋值语句的计算结果将会被计算机执行形成相应的图形。每个语句可以有一个名称,该名称写在语句的最前面,并用一个冒号将它与语句分隔开。例如:ST:MA(CLOSE,5);表示该语句求收盘价的五日均线,语句的名称为ST,在该语句后的语句中可以直接用ST来替代MA(CLOSE,5),例如:MA(ST,5)表示对收盘价的五日均线再求五日平均。


C、中间语句
    一个语句如果不需要显示,可以将它定义为中间语句,例如在上例当中的第一句“A:=X+Y;”,这样该语句就不会被系统辨认为是指标线了,中间语句用“:=”替代冒号,其他与一般语句完全一样,使用中间语句可以有效降低公式的书写难度,还可以将需要重复使用的语句定义成中间语句以减少计算量。

每个公式最多可以分6个语句,中间公式数量没有限制,所有语句之间需要使用分号隔开。


D、公式计算符
    公式计算符将函数连接成为公式,计算分为算术计算符和逻辑计算符。

a、算术计算符

包括+、-、*、/、&,它们分别对计算符两边的数据进行加减乘除计算,这同一般意义上的算术计算没有差异。 其中&为字符串相加运算

b、逻辑计算符

包括>、<、<>、>=、<=、=、AND、OR八种,分别表示大于、小于、不等于、大于等于、小于等于、等于、逻辑与、逻辑或运算,如果条件成立计算结果就等于1,否则等于0,例如:3+4=7,4>3都等于1,3<=12就等于0,“逻辑与”表示两个条件都成立时结果才成立;“逻辑或”表示两个条件中只要有一个成立结果成立。

例如,4>3 AND 12>=4的结果等于1,4>3 OR 3>12的结果等于1。

注意:运算符的优先级直接决定了表达式执行的先后顺序,用户使用多个算术和逻辑运算符时,要注意运算符的优先级,如果不太确定,最好用括号把紧密的表达式括起来。

E、线形描述符
    对于技术指标公式可以在语句加上线形描述符,用来表示如何画该语句描述的指标线。
    线形描述符号包括以下7种。描述符写在语句后分号前,用逗号将它们与语句分隔开,例如在上例当中加入一句线形描述符,C:B*0.618,COLORSTICK;该语句在被执行时,会在图中添加色彩柱线,该功能在编制MACD等指标的时候会显出它的用处。

STICK:柱状线

COLORSTICK:彩色柱状线,当值为正时显示红色,否则显示绿色

COLORRED:为线形色,RED表示红色

COLORBLUE:为线形色,BLUE表示蓝色

COLORYELLOW:为线形色,YELLOW表示黄色

VOLSTICK:成交量柱状线,当股价上涨时显示红色空心柱,否则绿色

LINESTICK:同时画出柱状线和指标线

LINETHICK:对线体的粗细作出描述

CROSSDOT:小叉线

CIRCLEDOT:小圆圈线

POINTDOT:小圆点线

a、COLORRED等三个线形描述符还可以自定义颜色,格式为COLOR+“BBGGRR”;BB、GG、RR表示蓝色,绿色和红色的分量,每种颜色的取值范围是00-FF,采用了16进制,例如:MA5:MA(CLOSE,5),COLOR00FFFF表示纯红色与纯绿色的混合色;COLOR808000表示淡蓝色和淡绿色的混合色。

b、LINETHICK可以允许对线型的粗细进行自定义的描述,格式“LINETHICK+(0/7)”:参数的取值范围在0-7之间,“LINETHICK0”表示最细的线,而“LINETHICK7”表示最粗的线。

 

第二章 金字塔的控制语句

金字塔是个强大的脚本执行平台,除了我们在基础教程部分介绍的顺序执行语句外,可以执行带条件分支和循环以及无条件跳转都是金字塔的特色功能,金字塔的模型在工作时,由于内部运行机制不同,分为序列模式以及逐周期模式,我们这里先从序列模式介绍公式系统的运行机理,逐周期模式我们在后面会另有介绍。下面我们将逐步向大家介绍如何使用金字塔的控制语句编写模型。

2.1序列变量与数组

在金字塔的新公式系统的增加部分中,需要大量运用并区分数组、单值变量及序列变量的概念,这些概念也是进一步学习编程(比如编DLL)所必需的,因此有必要简单描述并初步掌握这些概念。

2.1.1常数与单值变量

常数,在金字塔中,就是不允许改变的数值,在我们平常写公式时,为了公式更加灵活,大量使用了参数,这些参数就是常数,不允许在公式中改变,比如参数n(1,1,25),表示参数n最小值是1、最大值是25、默认值是1,如果在公式中再写一行“n:=30;”就是非法的。

单值变量,即只有一个数值,不随时间而改变,比如“x:100;”,就是定义了一个单值变量x=100,这个值不随时间而改变,做成副图指标看,今天x是100明天x也是100,直到最后1根K线也是100,即副图指标是一条数值为100的水平直线。

2.1.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,公式代码如下:

variable:A[10]=0; //定义一个含10个元素的数值型数组A,并把所有元素初始化为0;
  例2:定义一个3个元素的字符串型的数组
  公式代码如下:

 

variable:B[3]='abc'; //定义一个含3个元素的字符串型数组B,并把所有元素初始化为'abc'
  例3:把{1,3,5,7,9}定义为数组
  分析:这组数据共有5个数值型数据,因此应定义长度为5的数组,并给每个元素赋值。公式代码如下:

variable:A[5]=0;

A[1]:=1;

A[2]:=3;

A[3]:=5;

A[4]:=7;

A[5]:=9;
  前面所举的关于数组例子,都是概念性的,单纯数组的应用一般都比较复杂,比如,从每天的分笔成交中统计,各个成交价位成交的笔数。等到后面讲完循环有机会时再写具体的代码。

2.1.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线的收盘价,可以写成如下代码:

代码:

fc:=close;//定义一个序列变量,相当于是一个数组

k1:fc[1];//第1根K线的收盘价

k2:fc[2];//第2根K线的收盘价

k3:fc[5];//第5根K线的收盘价

k_end:fc[datacount];//最后1根K线的收盘价
 

2.2循环语句

金字塔的循环语句有两个类别,一个是 FOR TO … ,另一个是REPEAT UNTIL …,这里我们重点介绍FOR循环,REPEAT UNTIL的例子,用户请自行在金字塔软件函数列表中查看使用方法。
2.2.1  FOR递增循环

先从一个的实例开始,求当前股票收盘价的2日算术平均价,为了方便起见,以刚上市不久的600340国祥股价来说明,首先定义序列变量fc为收盘价,根据上一讲我们知道,fc可以看成是一个数组,因此,数组fc的每一个元素如下表所示:

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


  显然, 2日平均收盘价必须是从第2根K线即上市后第2日开始,到最后一天结束,设2日平均股价用序列变量ma2来表示,由于2日平均收盘价等于当日收盘价加昨收盘除以2,如果手工一行一行来写代码计算,则:

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;


分析上面代码,2日平均价的计算特点是:

从第2K线开始计算的

每天的均价都等于(今收盘+昨收盘)/2
直到最后1K线结束
容易知道,如果有1000K线,则要写999行代码,显然效率太低了。
我们来找找规律,如果是中间的某天即第i天,则上面的表达式可以写为

ma2[i]:=(fc[i-1]+fc[i])/2;


这个i是从第2根K线开始直到最后1根K线。这些计算都是重复同样的计算,只不过i不同罢了。如果有一种方法,可以自动重复计算这些表达式,并且每重复一次,i自动增加1,就可以达到目的了。由此我们定义一种循环语句,可以自动循环、重复运行某一行代码。在金字塔中,循环语句有2种,下面先介绍FOR循环语句
语法:

FOR var=n1 TO n2 DO expr;

{从 var=n1 开始,直到 var=n2,开始循环执行 expr 语句,每执行一次var加1。这里,var称之为循环变量。}
用循环语句表达上面计算2日平均收盘价,公式代码如下:

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

 

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

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

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
    
这里,beginend是成对出现的,被beginend包围起来的语句可以有很多条,这些语句可以看成是一条复合语句。
下面我们用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行复合语句,是被循环语句所控制的。以前对于这类分层次的语句,都要进行缩格,便于看懂代码,特别是复杂的代码,如果不进行缩格,时间久了,恐怕连自己都很难看懂,大家一开始就要养成好习惯。
有人会问,书写代码不缩格行吗?不缩格公式会不会出错?答案是,缩格书写代码,仅仅是为了方便看清程序代码的逻辑层次,对公式的运行没有影响。

有了复合语句,循环的功能就更加强大了,可以轻松实现多重循环,即循环中套循环。在计算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 子句。上面代码稍加改进,使用复合语句,使之适用于任意周期:
  例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 这种写法的本意是,“如果收盘价大于开盘价则”,是针对序列变量的每个数据(相当于数组的每个元素),但是在序列模式下是不会得到执行结果的,在金字塔的序列模式运行中,正确的写法应该是这样的:

代码:


 

//如果xx是序列变量,则代码参考如下

fc:=close;

fo:=open;

for i=1 to datacount do

  if fc[i]>fo[i] then

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

  else

    xx[i]:=0;

y:xx;


 

 

第三章 序列模式和逐周期模式

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

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

    逐周期计算时,控制语句比如IF THEN ,FOR 等语句工作机制是每周期都去执行一次,因此在逐周期模式下,可以利用这种灵活的模式来设计我们的策略,比如加仓、减仓、资金管理策略等等。
    序列模式计算时,控制语句条件允许使用序列变量,由于序列模式只执行一次控制语句解析,对于序列变量,仅取最后一个数据做为条件判断。

如:前面我们在序列模式下无法正常工作的公式

fc:=close;

fo:=open;

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

  xx:=1

else

  xx:=0;

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

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

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

 
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) 判断是否最后一个周期的指令,在逐周期模式下,由于是判断到最后一个周期才执行的下面循环,故效率是非常高的。对于序列模式,由于同样使用了ISLASTBAR控制,故符合控制语句取最后一个数据的特点,所以该公式同时可以在两种模式下得到正确执行。
 

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

这样的公式即保证了效率,也可以使编写公式的复杂程度大大降低,提高了公式的可读性
另外逐周期模式下运行的代码,还可以配合使用GOGO语句以及EXIT指令,控制语句的执行流程,达到各种复杂的逻辑运算要求。

第四章 金字塔的新交易系统

使用传统的ENTERLONG程式化交易信号做出的自动交易策略,存在着例如无法进行头寸管理,灵活性不够的缺点,为了对介入价位和仓位进行精确的控制,譬如海龟交易法的头寸管理.,需要金字塔提供扩展性更为强大的程式化交易模式,为此提供了一系列的功能和众多交易函数。这些函数用户可以在公式函数列表的“交易系统”组里找到.但是需要注意的是金字塔的新交易系统,是不能与旧的交易系统比如ENTERLONG混用的.金字塔的新交易系统采取的虚拟仓位和资金再图表做显示和模拟交易的,使用之前用户需要在公式属性里将资金和费率设置正确,以确保能更加贴近实战.真实自动交易时,系统将根据交易指令发出的交易类型和价格以及数量进行下单交易.。此外金字塔的新交易系统只能在逐周期模式下运行,另外该模式仅限标准版及其以上用户才可使用。

4.1下单模型语句

BUY(COND,V,Type,P)              //开多

SELL(COND,V,Type,P)              //平多

BUYSHORT(COND,V,Type,P)      //开空

SELLSHORT(COND,V,Type,P)               //平空

初学者一般会对TYPE有一些疑惑,TYPE可以是本周期收盘(THISCLOSE)、市价(MARKET)、限价单(LIMIT)、停损单(STOP)等交易方式控制符;对于限价单、停损单需要指定的价格P。

 

4.2简单交易系统示例

 

例一:KD交易系统

我们仍然使用前面的KD交易系统为例,将其修改为新版的程式化交易模型。

RSV:=(CLOSE-LLV(LOW,N))/(HHV(HIGH,N)-LLV(LOW,N))*100;

K:=SMA(RSV,M1,1);

D:=SMA(K,M2,1);

//注意看下面两行语句

BUY(CROSS(K,D) AND K<20,V,TYPE,P); 

SELL(CROSS(D,K) AND K>80,V,TYPE,P);

 

例二:一个最简单的3天均线穿越5天均线的多头交易系统

 

资产:ASSET,LINETHICK0;

可用现金:CASH(0),LINETHICK0;

持仓:HOLDING,LINETHICK0;

 

MA3:MA(C,3);

MA5:MA(C,5);

 

BUY(CROSS(MA3,MA5),1,THISCLOSE); //开多1手

SELL(CROSS(MA5,MA3),0,THISCLOSE);//平多0表示平掉全部持仓

 

上述的交易模型都能在图表做显示使用,并可以做图表交易

在交易系统评测中,介入时机与价位,是针对旧交易系统的4种信号指定买卖的介入时机与价位的,这里是以BUY函数的实际指定价格为准。

4.3复杂交易系统示例

例三:30分钟翻转系统

//《日内30分钟翻转系统》

//适用于1分钟周期

//编写日期:20100812-JYL

 

//准备需要的中间变量

h30 := ref(hhv(h,30),1);

l30 := ref(llv(l,30),1);

 

//建立多头的进场条件

long := h>h30 and time>093000 and time<145000;

 

if long then

  begin

  sellshort(holding < 0, 0, limitr, h30);

  buy(holding = 0, 1, limitr, h30);

  end

 

//画出多头的止损线

partline(holding>0, l30,colorred);

 

//开空条件

short := l < l30 and time > 093000 and time < 145000;

 

if short then

  begin

  sell(holding > 0, 0, limitr, l30);

  buyshort(holding = 0, 1, limitr, l30);

  end

 

//画出空头的止损线

partline(holding<0, h30, colorgreen);

 

//收盘前5分钟平仓

if time > 145500 then

  begin

  sell(holding > 0, 0, thisclose);

  sellshort(holding < 0, 0, thisclose);

  end

 

例四:30突破模型

//开盘后前三十分钟最高最低价突破模型--涨停价多单止盈/跌停价空单止盈

//适用于1分钟周期

 

M:=BARSLAST(DATE<>REF(DATE,1) )+1;

h30:=VALUEWHEN(TIME<=093000,HHV(HIGH,M));

l30:=VALUEWHEN(TIME<=093000,LLV(LOW,M));

 

//假设涨停价为 昨收的百分之4

upstop :=ref(c,1)*(1+0.04);

downstop:=ref(c,1)*(1-0.04);

 

//建立多头进场条件

long:=CLOSE>h30 AND TIME<145500 AND TIME>093000; 

if long then

  begin

  sellshort(holding < 0, 0, limitr, h30);

  buy(holding = 0, 1, limitr, h30);

  end

   

//建立多头止盈条件(涨停价多单止盈,不开空仓)

if holding>0 and TIME<145500 AND TIME>093000 then sell(c>upstop-3*mindiff,0,thisclose);

 

//建立空头进场条件

short:=CLOSE<l30 AND TIME<145500 AND TIME>093000;

 

if short then

  begin

  sell(holding > 0, 0, limitr, l30);

  buyshort(holding = 0, 1, limitr, l30);

  end

  

//建立空头止盈条件(跌停价空单止盈,不开多仓)

if holding<0 and TIME<145500 AND TIME>093000

 then sellshort(c<downstop+3*mindiff,0,thisclose);

 

//收盘前5分钟平仓

if time > 145500 then

  begin

  sell(holding > 0, 0, thisclose);

  sellshort(holding < 0, 0, thisclose);

  end

 

资产:ASSET,LINETHICK0;

可用现金:CASH(0),LINETHICK0;

持仓:HOLDING,LINETHICK0;

第五章 新交易系统的函数

交易系统之开多操作,

用法:BUY(COND,V,Type,P);

表示当COND条件成立时,

买入V股(手)当前品种,TYPE表示买入类型,

P表示买入价格,所有参数均可以省略。

V:买入股(手)数或买入资金百分比(N%),省略表示100%;

TYPE:可以是本周期收盘(THISCLOSE),次周期开盘(MARKET),

次周期限价单(LIMIT),次周期停损单(STOP)等交易方式控制符;

P:对于限价单、停损单需要指定的买入价格

例如:BUY(C>O ,1000,THISCLOSE);表示收阳线则在本周期收盘价上买入1000股(手)。

BUY(C>0,50%,LIMIT,CLOSE-0.2);表示在次周期CLOSE-0.2元位置下买入限价单,

若价格达到或低于该价格则用50%资金买入。

 

交易系统之平多操作,

SELL(COND,V,Type,P); 用法同上

 

交易系统之开空操作,

BUYSHORT(COND,V,Type,P); 用法同上

 

交易系统之平空操作,

SELLSHORT(COND,V,Type,P); 用法同上

 

ASSET当前资产

 

户账户客的净自有资产=可用现金+占用保证金-融资(现金+品种市值-融资)

 

AVGENTERPRICE 持仓均价

当前持有品种的平均持仓成本——最近空仓以来计

 

BESTPERCENT 最大利润率

当前位置之前所有交易中利润率最大一次的利润率,其数值在0—1之间

BESTTRADE 最大盈利额

当前位置之前所有交易中盈利最大一次的利润额

 

CASH(N)  现金存量

得到当前帐户的可用资金余额

用法:CASH(N),N表示投资方向 0多头 1空头

例如:CASH(0)表示取当前多头帐户的可用现金余额

 

ENTERBARS  开仓历时

返回上次开仓到当前的周期数,若之前没有开仓记录返回-1

 

ENTERPRICE  上次开仓价

得到当前位置的上次开仓价

 

ENTERVOL  上次开仓量

得到当前位置的上次开仓量

 

EXITBARS  平仓历时

返回上次平仓到当前的周期数,若之前没有开仓记录返回-1

 

EXITPRICE  上次平仓价

得到当前位置的上次平仓价

 

EXITVOL  上次平仓量

得到当前位置的上次平仓量

 

HOLDING  持仓量

得到当前帐户持仓量,多仓返回正数空仓返回负数

 

LIMIT 限价交易

交易方式控制符:加入限价单,次周期达到限价即操作,否则放弃。处于图表交易时按照指定限价报单交易

 

LIMITR 限价交易

交易方式控制符:加入限价单,本周期达到限价即操作,否则放弃。处于图表交易时按照指定限价报单交易

 

Market  市价交易,交易方式控制符:按照次周期开盘价操作。处于图表交易时按照实际交易市价操作

例如:buy(cond ,1000,market);

该控制符仅对交易评测时有效

 

MAXSEQLOSS  最大连续亏损次数

当前位置之前连续亏损交易的最大次数

 

MAXSEQWIN  最大连续盈利次数

当前位置之前连续盈利交易的最大次数

 

NUMLOSSTRADE  亏损次数

当前位置之前总共有多少次亏损的交易,注意每次卖出算一次交易,而买入不算

 

NUMSEQLOSS  连亏次数

当前位置之前连续有多少次亏损的交易,注意每次卖出算一次交易,而买入不算

 

NUMSEQWIN  连盈次数

当前位置之前连续有多少次盈利的交易,注意每次卖出算一次交易,而买入不算

 

NUMWINTRADE  盈利次数

当前位置之前总共有多少次盈利的交易,注意每次卖出算一次交易,而买入不算

 

OPENBAR 开仓历时

上一次仓位=0以来的周期数

 

OPENPROFIT  浮动盈亏

当前浮动盈亏(当前持仓市值与持仓成本之差)

 

PERCENTWIN  交易胜率

当前位置之前盈利交易占总交易次数的比例,其数值在0—1之间

 

SEQLOSS  连亏金额

当前位置之前连续亏损总额,注意每次卖出算一次交易,而买入不算

 

SEQWIN  连盈金额

当前位置之前连续盈利总额,注意每次卖出算一次交易,而买入不算

 

STATE  帐户状态

得到当前帐户状态,无仓输出0;有多头仓输出1;有空头仓输出-1

 

STOP  停损交易

交易方式控制符:加入停损单,或又称突破交易,次周期达到设定价格即操作买入,否则放弃。

所谓停损就是交易价比设定的价格要差,具体说来对于买入或卖空就是高于设定价格,

对于卖出或买空就是低于设定价格

例如:BUY(COND ,1000,STOP,CLOSE-0.01);

该控制符仅对交易评测时有效

 

STOPR  停损交易

为本周期的,其它同上

 

THISCLOSE  收盘价交易

交易方式控制符,按照本周期收盘价操作

例如:BUY(COND ,1000,THISCLOSE);

该控制符仅对交易评测时有效

 

TOTALTRADE  交易次数

当前位置之前总共有多少次交易,注意每次卖出算一次交易,而买入不算

 

TYPE(N)  上N次信号类型

得到当前位置之前上N次信号类型

输出:0、无信号1、开多2、平多3、开空;4、平空

 

TYPEBAR  表示上次信号,

得到当前位置之前上N次信号指定类型距当前周期

TYPEBAR(N,TYPE)N表示上次信号,

TYPE表示信号类型 0、无信号1、开多2、平多3、开空;4、平空

例如:TYPEBAR(2,1)表示:倒数第2个开多信号历时

 

WORSTPERCENT  最大亏损率

当前位置之前所有交易中亏损率最大一次的利润率,其数值在0—1之间

 

WORSTTRADE  最大亏损额

当前位置之前所有交易中亏损最大一次的亏损额

5.1快速入门

1)如何把熟悉的技术指标转换成交易模型?

第一步:把 KDJ 指标公式 COPY 过来,或按“引入公式”按钮,引入

RSV:=(CLOSE-LLV(LOW,N))/(HHV(HIGH,N)-LLV(LOW,N))*100;//算出(收盘价-N周期内的最低价)/N周期的最高价N周期内的最低价)*100 的值,用RSV 来表示。

K:SMA(RSV,M1,1),COLORWHITE;//RSV 的移动加权平均的值用K表示,并且画白色的线。

D:SMA(K,M2,1),COLORYELLOW;//K 的移动加权平均的值用D表示,并且画黄色的线。

J:3*K-2*D,COLORMAGENTA;//3倍的K减去2倍的D的值用J表示,并且画紫色的线。

 

第二步:原有公式主要是画线,所以稍作修改。如下:

RSV:=(CLOSE-LLV(LOW,N))/(HHV(HIGH,N)-LLV(LOW,N))*100;// 第一行不需要修改

K:=SMA(RSV,M1,1);//:后加上=             变为只定义不用画线,把后面的颜色函数(COLORWHITE)也去掉

D:=SMA(K,M2,1);//同上

J:=3*K-2*D;//同上

 

第三步:把自己总结的交易条件写上,就可完成交易模型。如下:

RSV:=(CLOSE-LLV(LOW,N))/(HHV(HIGH,N)-LLV(LOW,N))*100;

K:=SMA(RSV,M1,1);

D:=SMA(K,M2,1);

J:=3*K-2*D;

{开多} ENTERLONG: CROSS(K,D),TFILTER; // K 向上穿越 D,发出开多操作

{平多} EXITLONG: CROSS(J,100),TFILTER; // J向上穿越100,发出平多操作

{开空} ENTERSHORT: CROSS(D,K),TFILTER; //K 向下穿越 D,发出开空操作

{平空} EXITSHORT: CROSS(0,J),TFILTER; //J向下穿越0,发出平空操作

图表交易模型就完成了,其仓位控制在第5页图中设置

 

对于新交易系统模型,可用下面4句代替

SELLSHORT(CROSS(0,J) and HOLDING<0, HOLDING,market); //J向下穿越0,发出平空操作
BUY(CROSS(K,D) and HOLDING=0,30%,market);// K 向上穿越 D,发出开多操作

SELL(CROSS(J,100) and HOLDING>0,HOLDING,market); // J向上穿越100,发出平多操作
BUYSHORT(CROSS(D,K) and HOLDING=0,30%,market); //K 向下穿越 D,发出开空操作

其中,HOLDING为持仓函数,30%表示按可用资金的30%交易,market表示交易类型为市价委托。后为文字说明,编写模型时不用写出。

 

2)如何把自编变色 K 线转换成交易模型

模型说明:第一根 K 线变红时买,第一根 K 线变蓝时卖

指标源码:

 

//如果最新值比满足条件的“高值”高,说明在上涨,红色K线

//如果最新值比满足条件的“低值”低,说明在下跌,绿色K线

//若最新值界于“高值”和“低值”之间,则与前一周期的颜色相同

 

HH1:=IF(H<REF(H,2) AND REF(H,1)<REF(H,2),REF(H,2),0);

LL1:=IF(L>REF(L,2) AND REF(L,1)>REF(L,2),REF(L,2),0);

HH2:=VALUEWHEN(HH1>0,HH1);  //寻找“高值”---比+1周期和+2周期都高

LL2:=VALUEWHEN(LL1>0,LL1);  //寻找“低值”---比+1周期和+2周期都低

K1:=IF(CLOSE>HH2,-3,IF(CLOSE<LL2,1,0));

{最新值 与“高值”比:

若最新值比“高值”高,返回-3;

   否则

最新值 与“低值”比

若最新值比“低值”低,返回1;

若最新值界于“高值”和“低值”之间---即中间值,返回0;}

K2:=VALUEWHEN(K1<>0,K1);//寻找第一个比“高值”高 或者 比“低值”低的

G:=IF(K2=1,HH2,LL2); //若找到的第一个 比“低值”低,返回当时的“高值”

若找到的第一个 比“高值”高,返回当时的“低值”

G1:=VALUEWHEN(ISLASTBAR,G);  //是否是最后一个周期

W1:=K2;

W2:=OPEN-CLOSE;  

HT:=IF(OPEN>CLOSE,OPEN,CLOSE); 

LT:=IF(OPEN<CLOSE,OPEN,CLOSE); 

//以上是在定义变量,转换成模型时直接引用

STICKLINE(W1>0,OPEN,CLOSE,8,1),COLORCYAN; 

STICKLINE(W1<=0,OPEN,CLOSE,8,1),COLORRED;

STICKLINE(W2>0 AND W1<=0,OPEN,CLOSE,8,0),COLORRED; 

STICKLINE(W2>0 AND W1>0,OPEN,CLOSE,8,0),COLORCYAN;

 

利用STICKLINE 里的条件W1,再加上交易指令即可改写为交易模型

修改为交易模型如下:

HH1:=IF(H<REF(H,2) AND REF(H,1)<REF(H,2),REF(H,2),0); 

LL1:=IF(L>REF(L,2) AND REF(L,1)>REF(L,2),REF(L,2),0);

HH2:=VALUEWHEN(HH1>0,HH1); 

LL2:=VALUEWHEN(LL1>0,LL1); 

K1:=IF(CLOSE>HH2,-3,IF(CLOSE<LL2,1,0)); 

K2:=VALUEWHEN(K1<>0,K1); 

G:=IF(K2=1,HH2,LL2);

G1:=VALUEWHEN(ISLASTBAR,G); 

W1:=K2; 

W2:=OPEN-CLOSE;  

图表交易模型就完成了,其仓位控制在第5页图中设置

对于新交易系统模型,可用下面4句代替

//交易系统之平空操作

SELLSHORT(CROSS(W1,0) OR (CROSS(W2,0) AND CROSS(W1,0)),HOLDING,market);

//交易系统之开多操作

BUY(CROSS(W1,0) OR (CROSS(W2,0) AND CROSS(W1,0)),30%,market);

//交易系统之平多操作

SELL(CROSS(0,W1) OR (CROSS(W2,0) AND CROSS(0,W1)),HOLDING,market);

//交易系统之开空操作

BUYSHORT(CROSS(0,W1) OR (CROSS(W2,0) AND CROSS(0,W1)),30%,market);

 

3)如何合并两个不同的交易模型?

在两个模型方向相同时才开仓,两个模型指令不同时就平仓

参数 N:最小值 0 最大值  100   缺省值  8

源码:

 

模型A

X:=BARSLAST(HIGH=HHV(HIGH,N));

LL:=MIN(REF(LOW,X+3),MIN(REF(LOW,X+2),MIN(REF(LOW,X),REF(LOW,X+1))));

Y:=BARSLAST(LOW=LLV(LOW,N));

HH:=MAX(REF(HIGH,Y+3),MAX(REF(HIGH,Y+2),MAX(REF(HIGH,Y),REF(HIGH,Y+1))));

A:=BARSLAST(CLOSE>=HH);

B:=BARSLAST(CLOSE<=LL);

AB:=IF(A>B,HH,LL);

SELLSHORT(CROSS(CLOSE,AB) and HOLDING<0,HOLDING,market); //平空操作

BUY(CROSS(CLOSE,AB) and  HOLDING=0,30%,market);//开多操作

SELL(CROSS(AB,CLOSE) and HOLDING>0,HOLDING,market); //平多操作

BUYSHORT(CROSS(AB,CLOSE) and HOLDING=0,30%,market); //开空操作

 

模型B

HH1:=IF(H<REF(H,2) AND REF(H,1)<REF(H,2),REF(H,2),0);

LL1:=IF(L>REF(L,2) AND REF(L,1)>REF(L,2),REF(L,2),0);

HH2:=VALUEWHEN(HH1>0,HH1);

LL2:=VALUEWHEN(LL1>0,LL1);

K1:=IF(CLOSE>HH2,-3,IF(CLOSE<LL2,1,0));

K2:=VALUEWHEN(K1<>0,K1);

SELLSHORT(K2=-3 and HOLDING<0,HOLDING,market); //平空操作

BUY(K2=-3 and  HOLDING=0,30%,market);//开多操作

SELL(K2=1 and HOLDING>0,HOLDING,market); //平多操作

BUYSHORT(K2=1 and HOLDING=0,30%,market); //开空操作

 

利用并且( AND )和或者( OR )这些逻辑语句,将AB模型合并为模型C

X:=BARSLAST(HIGH=HHV(HIGH,N));

LL:=MIN(REF(LOW,X+3),MIN(REF(LOW,X+2),MIN(REF(LOW,X),REF(LOW,X+1))));

Y:=BARSLAST(LOW=LLV(LOW,N));

HH:=MAX(REF(HIGH,Y+3),MAX(REF(HIGH,Y+2),MAX(REF(HIGH,Y),REF(HIGH,Y+1))));

A:=BARSLAST(CLOSE>=HH);

B:=BARSLAST(CLOSE<=LL);

AB:=IF(A>B,HH,LL);

HH1:=IF(H<REF(H,2) AND REF(H,1)<REF(H,2),REF(H,2),0);

LL1:=IF(L>REF(L,2) AND REF(L,1)>REF(L,2),REF(L,2),0);

HH2:=VALUEWHEN(HH1>0,HH1);

LL2:=VALUEWHEN(LL1>0,LL1);

K1:=IF(CLOSE>HH2,-3,IF(CLOSE<LL2,1,0));

K2:=VALUEWHEN(K1<>0,K1);

SELLSHORT(CROSS(CLOSE,AB) OR K2=-3 and HOLDING<0,HOLDING,market); //平空操作

BUY(CROSS(CLOSE,AB) AND K2=-3 and  HOLDING=0,30%,market);//开多操作

SELL(CROSS(AB,CLOSE) OR K2=1 and HOLDING>0,HOLDING,market); //平多操作

BUYSHORT(CROSS(AB,CLOSE) AND K2=1 and HOLDING=0,30%,market); //开空操作

5.2常见问题

1)LIMIT和STOP指令的区别和联系

LIMIT------加入限价单,交易评测时按照次周期达到限价即操作,否则放弃;处于图表交易时按照指定限价报单交易。

所谓限价就是交易价优于设定的价格。具体说来对于买入或卖空就是低于设定价格,对于卖出或买空就是高于设定价格。

STOP------加入停损单,或又称突破交易,交易评测时按次周期达到设定价格即操作买入,否则放弃;处于图表交易时按照指定停损价格报单交易。

所谓停损就是交易价比设定的价格要差(就是说和价格运动方向无关,只要比下的价格差,就下单,不管价格是由好到坏还是有坏到好。)具体说来对于买入或卖空就是高于设定价格,对于卖出或买空就是低于设定价格

 

BUY(holding=0, 1, LIMIT, 4000);

//如果无多头持仓,以4000挂单子

//结果:成交价≤4000

SELL(holding>0,0,LIMIT,4000);

//如果有多头持仓,以4000价格挂单子;

//结果:成交价≥4000

 

BUY(holding=0, 1, STOP, 4000);

//如果无多头持仓

//当最新价≥4000,以当时的对手价买一手单子

//结果:成交价根据行情而定

//相当于-----条件单,当价格突破某个值时,买开仓。

 

SELL(holding>0,0,STOP,4000);

//如果有多头持仓,4000是止损触发价(所能接受的最大损失的最低值)。

//当最新价≤4000,以当时的对手价卖出全部持仓。

//结果:成交价根据行情决定。

//相当于----止损----条件单,当价格下跌到某个值时,卖平仓。

 

BUYSHORT(holding=0, 1, STOP, 2020);

//如果无空头持仓

//当最新价≤2020时,以当时的对手价买一手单子

//结果:成交价根据行情而定

//相当于-----条件单,当价格下跌某个值时,卖开仓。

 

SELLSHORT(holding<0,0,STOP,2020);

//如果有空头持仓,2020是止损触发价(所能接受的最大损失的最高值)。

//当最新价≥2020,以当时的对手价卖出全部持仓。

//结果:成交价根据行情决定。

//相当于----止损----条件单,当价格突破某个值时买平仓。

 

2)金字塔下的交易都支持哪些交易指令,有什么区别?

金字塔对于所有的可交易品种,均支持4种交易指令,即限价、市价、停损、限价停损。但是这几种交易指令是通过不同方式完成工作的,限价指令是所有平台都支持的,对于市价和停损单,下面几种交易平台如下:

CTP综合交易平台 除了上期所不支持市价外,其他3个交易所均支持市价指令,在上期所的品种下市价单金字塔是采用加N个变动价位实现,默认是3个,用户可在交易设置中更改。除了大连交易所支持停损指令外,其他交易均不支持停损指令,在不支持停损指令的交易所下停损单时金字塔是采用内部监控模式实现,最新价触及停损价位后立即按照市价发出委托单。金字塔CTP平台不支持限价停损指令,用户使用限价停损指令发出为委托单时,实际会按照停损指令发出。

IB(美国赢透)交易平台 这个平台支持所有限价、市价、停损、限价停损这个4个指令。在IB平台发出停损指令后会将指令单发送到IB的交易服务器上保存,等待触发。

 

第六章 交易系统编写范例和常见问题

6.1趋势类交易模型编写范例

1)均线类

均线排列模型

关键函数:MA

使用周期:任意

模型说明:MA5,MA10,MA20多头排列时做多,空头排列时做空。编者以一个周期内这三条均线的大小关系为判断标准举例,大家也可以使用多个周期的比较来判断多/空头排列关系。

MA5:=MA(CLOSE,5);

MA10:=MA(CLOSE,10);

MA20:=MA(CLOSE,20);

{开多} ENTERLONG: MA5>MA10 AND MA10>MA20,TFILTER;

{平多} EXITLONG: MA5<MA10 AND MA10<MA20,TFILTER;

{开空} ENTERSHORT: MA5<MA10 AND MA10<MA20,TFILTER;

{平空} EXITSHORT: MA5>MA10 AND MA10>MA20,TFILTER;

图表交易模型就完成了,其仓位控制在第5页图中设置

图表交易模型中不能使用交易函数和程式化函数

 

对于新交易系统模型,可用下面4句代替

SELLSHORT(MA5>MA10 AND MA10>MA20 and HOLDING<0,HOLDING,market); //平空操作

BUY(MA5>MA10 AND MA10>MA20 and  HOLDING=0,30%,market);//开多操作

SELL(MA5<MA10 AND MA10<MA20 and HOLDING>0,HOLDING,market); //平多操作

BUYSHORT(MA5<MA10 AND MA10<MA20 and HOLDING=0,30%,market); //开空操作

 

 

容易犯的编写错误:

 

A、交易模型中不允许使用只写:(即定义并画线)的写法。

如:MA5:=MA(CLOSE,5);

错误写成MA5:MA(CLOSE,5);

 

B、对于三个数的比较,大家往往习惯写成MA5>MA10>MA20这样,而在金字塔的模型编写中,目前只能两个变量之间进行比较,也就是说此类三个以上变量连续比较需要像模型中那样拆分来写:MA5>MA10 AND MA10>MA20

 

C、缺少计算函数。

如:求均线时,写为MA5:(CLOSE,5),而缺少了MA,此类错误语法检测无法识别,往往造成软件应用错误。

 

均线金死叉模型

关键函数:MAEMAEMA2CROSS

使用周期:所有 K 线周期。

模型说明:短期均线上穿长期均线(金叉)做多,短期均线下穿长期均线(死叉)

做空。

 

参数设置:

参数 N1 ,最小值 0,最大值 100,缺省值 5

参数 N2 ,最小值 0,最大值 100,缺省值 30

A、简单移动平均线:

P1:=MA(CLOSE,N1);

P2:=MA(CLOSE,N2);

BPK :=CROSS(P1,P2);

SPK :=CROSS(P2,P1);

B、指数加权平均线:

P1:=EMA(CLOSE,N1);

P2:=EMA(CLOSE,N2);

BPK :=CROSS(P1,P2);

SPK :=CROSS(P2,P1);

C、线性加权平均线:

P1:=EMA2(CLOSE,N1);

P2:=EMA2(CLOSE,N2);

BPK :=CROSS(P1,P2);

SPK :=CROSS(P2,P1);

{开多} ENTERLONG: BPK,TFILTER;

{平多} EXITLONG: SPK,TFILTER;

{开空} ENTERSHORT: SPK,TFILTER;

{平空} EXITSHORT: BPK,TFILTER;

图表交易模型就完成了,其仓位控制在第5页图中设置

 

对于新交易系统模型,可用下面4句代替

SELLSHORT(BPK and HOLDING<0,HOLDING,market); //交易系统之平空操作

BUY(BPK and  HOLDING=0,30%,market);//交易系统之开多操作

SELL(SPK and HOLDING>0,HOLDING,market); //交易系统之平多操作

BUYSHORT(SPK and HOLDING=0,30%,market); //交易系统之开空操作

 

均线结合 MACD 模型

关键函数:EMA

使用周期:日线

模型说明:  利用 DIFF DEA 的比较和收盘价的 15 日指数加权和最新价的比较作为买卖依据进行交易。

DIFF := EMA(CLOSE,12) - EMA(CLOSE,26);

DEA:= EMA(DIFF,9);

EMA15:=EMA(CLOSE,15);

BPK :=DIFF>DEA AND CLOSE>EMA15;

SPK :=DEA>DIFF AND EMA15>CLOSE;

{开多} ENTERLONG: BPK,TFILTER;

{平多} EXITLONG: SPK,TFILTER;

{开空} ENTERSHORT: SPK,TFILTER;

{平空} EXITSHORT: BPK,TFILTER;

图表交易模型就完成了,其仓位控制在第5页图中设置

 

对于新交易系统模型,可用下面4句代替

SELLSHORT(BPK and HOLDING<0,HOLDING,market); //交易系统之平空操作

BUY(BPK and  HOLDING=0,30%,market);//交易系统之开多操作

SELL(SPK and HOLDING>0,HOLDING,market); //交易系统之平多操作

BUYSHORT(SPK and HOLDING=0,30%,market); //交易系统之开空操作

 

2 通道类

唐奇安通道模型

关键函数:HHVLLVREFCROSS

使用周期:日线

 

模型说明:  突破前 20 天最高价做多,突破前 20 天最低价做空。

参数设置:N,最小值 5,最大值 100,缺省值 20

input:N(20,5,100,1),NS(10,0,60,1);

持仓:HOLDING,LINETHICK0;

总次数: TOTALTRADE,LINETHICK0;

盈利:NUMWINTRADE,LINETHICK0;

胜率:ROUNDS(100*PERCENTWIN,1),LINETHICK0;

连亏:MAXSEQLOSS,LINETHICK0;

连盈:MAXSEQWIN,LINETHICK0;

 

BK:=CROSS(H, hhv(ref(h,1),N));

SK:=CROSS(llv(ref(l,1), N),L);

Price:=AVGENTERPRICE;//持仓价位

图表交易模型中不能使用交易函数和程式化函数,故在第64页图中有图表唐奇安通道模型

 

SELLSHORT(BK and 持仓<0,持仓,market);

SELLSHORT(持仓<0,持仓,Stopr,Price+NS);

BUY(BK and NOT(TYPE(1)=1),30%,market);

 

SELL(SK and 持仓>0,持仓,market);

SELL(持仓>0,持仓,Stopr,Price-NS);

BUYSHORT(SK and NOT(TYPE(1)=3),30%,market);

其中,NS为止损点数

 

容易犯的编写错误:

 

最高价高于前 20 周期最高价。应写为 HIGH>REF(HHV(HIGH,20),1),常见错误是

直接写为 HIGH>HHV(HIGH,20);

 

布林通道结合阴阳 K 线模型

关键函数:STDCROSSISUPISDOWN

使用周期:日线

模型说明:收盘价向上突破布林通道下轨并前当根K线收阳做多,收盘价向下突破布林通道上轨并前当根 k 线收阴做空。

参数设置:N,最小值1,最大值100,    缺省值26

                M,最小值1,最大值100,               缺省值26

MID:=MA(CLOSE,N);

TMP2:=STD(CLOSE,M);

TOP:=MID+2*TMP2;

BOTTOM:=MID-2*TMP2;

BPK :=CROSS(CLOSE,BOTTOM) AND ISUP;

SPK :=CROSS(TOP,CLOSE) AND ISDOWN;

{开多} ENTERLONG: BPK,TFILTER;

{平多} EXITLONG: SPK,TFILTER;

{开空} ENTERSHORT: SPK,TFILTER;

{平空} EXITSHORT: BPK,TFILTER;

图表交易模型就完成了

 

对于新交易系统模型,可用下面4句代替

SELLSHORT(BPK and HOLDING<0,HOLDING,market); //交易系统之平空操作

BUY(BPK and  HOLDING=0,30%,market);//交易系统之开多操作

SELL(SPK and HOLDING>0,HOLDING,market); //交易系统之平多操作

BUYSHORT(SPK and HOLDING=0,30%,market); //交易系统之开空操作

 

3 )其他类

宝塔线

关键函数:REFHHVLLV

使用周期:日线

模型说明: 宝塔线变红做多,宝塔线变绿做空。因为金字塔并未公布宝塔线的后台公式,所以此指标的显示结果与金字塔系统中的宝塔显示结果有一定的区别。

C1:=REF(CLOSE,1);

C2:=REF(CLOSE,2);

C3:=REF(CLOSE,3);

C4:=REF(CLOSE,4);

CMAX:=HHV(CLOSE,2);

CMIN:=LLV(CLOSE,2);

BPK :=(CLOSE=CMAX AND (C1>=C2 OR C1>=C3) OR C1=CMAX AND (C2=CMIN OR C3=CMIN) AND CLOSE>=C2 OR C2=CMAX AND C3=CMIN AND CLOSE>=C1 OR C3=CMAX AND CLOSE>=C1 AND CLOSE>=C2);

SPK :=(CLOSE=CMIN AND (C1<C2 OR C1<C3) OR C1=CMIN AND (C2=CMAX OR C3=CMAX) AND CLOSE<C2  OR C2=CMIN AND C3=CMAX AND CLOSE<C1 OR C3=CMIN AND CLOSE<C1 AND CLOSE<C2);

{开多} ENTERLONG: BPK,TFILTER;

{平多} EXITLONG: SPK,TFILTER;

{开空} ENTERSHORT: SPK,TFILTER;

{平空} EXITSHORT: BPK,TFILTER;

图表交易模型就完成了

 

对于新交易系统模型,可用下面4句代替

SELLSHORT(BPK and HOLDING<0,HOLDING,market); //交易系统之平空操作

BUY(BPK and  HOLDING=0,30%,market);//交易系统之开多操作

SELL(SPK and HOLDING>0,HOLDING,market); //交易系统之平多操作

BUYSHORT(SPK and HOLDING=0,30%,market); //交易系统之开空操作

 

 

分形

 

关键函数:MAREFREFX(未来函数)BARSLASTCROSSVALUEWHEN

使用周期:日线

模型说明:向上突破分形做多,向下突破分形做空

MA13:=MA(CLOSE,13);

HO:=H>REF(H,1) AND H>REF(H,2) AND H>=REFX(H,1) AND IF(H=REFX(H,2),H>REFX(H,3),H>REFX(H,2));

FXH:=CROSS(HO,0.9);

HH:=REF(H,BARSLAST(FXH));

LO:=L<REF(L,1) AND L<REF(L,2) AND L<=REFX(L,1) AND IF(L=REFX(L,2),L<REFX(L,3),L<REFX(L,2));

FXL:=CROSS(LO,0.9);

LL:=REF(L,BARSLAST(FXL));

A:=VALUEWHEN(CROSS(CLOSE,HH),REF(LL,1));

A1:=VALUEWHEN(CROSS(CLOSE,HH),CLOSE);

B:=VALUEWHEN(CROSS(LL,CLOSE),REF(HH,1));

B1:=VALUEWHEN(CROSS(LL,CLOSE),CLOSE);

BK :=(CROSS(CLOSE,HH) AND CLOSE>MA13) OR CROSS(CLOSE,B);

SP :=(CLOSE>A1 AND CROSS(MA13,CLOSE)) OR CROSS(A,CLOSE);

SK :=(CROSS(LL,CLOSE) AND CLOSE<MA13) OR CROSS(A,CLOSE);

BP :=(CLOSE<B1 AND CROSS(CLOSE,MA13)) OR CROSS(CLOSE,B);

 

{开多} ENTERLONG: BK,TFILTER;

{平多} EXITLONG: SP,TFILTER;

{开空} ENTERSHORT: SK,TFILTER;

{平空} EXITSHORT: BP,TFILTER;

图表交易模型就完成了

 

对于新交易系统模型,可用下面4句代替

SELLSHORT(BP and HOLDING<0,HOLDING,market); //交易系统之平空操作

BUY(BK and  HOLDING=0,30%,market);//交易系统之开多操作

SELL(SP and HOLDING>0,HOLDING,market); //交易系统之平多操作

BUYSHORT(SK and HOLDING=0,30%,market); //交易系统之开空操作

由于用到未来函数,仅作示范参考

 

 

SAR 模型

关键函数:ABS,SAR

使用周期:任意

模型说明:SAR 指标出现红点买平开,蓝点卖平开

N:最小值  1         最大值  100   缺省值  4

STEP:  最小值 0.01    最大值  0.2   缺省值  0.02

M1:最小值  0.01   最大值  1     缺省值  0.2

SARLINE:=ABS(SAR(N,STEP,M1));

BPK :=CLOSE>SARLINE;

SPK :=CLOSE<SARLINE;

{开多} ENTERLONG: BPK,TFILTER;

{平多} EXITLONG: SPK,TFILTER;

{开空} ENTERSHORT: SPK,TFILTER;

{平空} EXITSHORT: BPK,TFILTER;

图表交易模型就完成了

 

对于新交易系统模型,可用下面4句代替

SELLSHORT(BPK and HOLDING<0,HOLDING,market); //交易系统之平空操作

BUY(BPK and  HOLDING=0,30%,market);//交易系统之开多操作

SELL(SPK and HOLDING>0,HOLDING,market); //交易系统之平多操作

BUYSHORT(SPK and HOLDING=0,30%,market); //交易系统之开空操作

 

容易犯的编写错误:

直接写CLOSE>SARLINE是不对的,CLOSE恒大于0,而SARLINE有正有负,应将SARLINE

取绝对值。如下:

SARLINE:=ABS(SAR(4,0.02,0.2));

再用 CLOSE 进行比较

 

6.2振荡类交易模型编写范例

1)主动买与主动卖模型

关键函数:BUYVOL(), SELLVOL(),CROSS,VALUEWHEN,TIME

模型说明:现价大于当日开盘价并且主动买大于主动卖时买平开,现价小于开盘价并且主动卖大于主动买时卖平仓。

使用周期:分钟线

 

ZB:=SUM( BUYVOL(),5); 

ZS:= SUM( SELLVOL(),5); 

BPK := CLOSE > OPEN AND CROSS(ZB,ZS); 

SPK := CLOSE < OPEN AND CROSS(ZS,ZB);

{开多} ENTERLONG: BPK,TFILTER;

{平多} EXITLONG: SPK,TFILTER;

{开空} ENTERSHORT: SPK,TFILTER;

{平空} EXITSHORT: BPK,TFILTER;

图表交易模型就完成了

 

对于新交易系统模型,可用下面4句代替

SELLSHORT(BPK and HOLDING<0,HOLDING,market); //交易系统之平空操作

BUY(BPK and  HOLDING=0,30%,market);//交易系统之开多操作

SELL(SPK and HOLDING>0,HOLDING,market); //交易系统之平多操作

BUYSHORT(SPK and HOLDING=0,30%,market); //交易系统之开空操作

 

2)ROC(变动速率)与价格趋势变动背离:

关键函数:REF,CROSS,MA,HHV

使用周期:所有 K线周期。

模型说明:价格创新高,ROC未配合上升,显示上涨动力减弱;价格创新低,ROC 未配合下降,显示下跌动力减弱

参数设置:参数 N ,最小值 5,最大值 100,缺省值 24

参数 M,最小值 5,最大值 100,缺省值 20

ROC:=(CLOSE-REF(CLOSE,N))/REF(CLOSE,N)*100;

ROCMA:=MA(ROC,M);

SPK :=C>REF(HHV(C,N1),1) AND ROC<ROCMA;

BPK :=C<REF(LLV(C,N1),1) AND ROC>ROCMA;

{开多} ENTERLONG: BPK,TFILTER;

{平多} EXITLONG: SPK,TFILTER;

{开空} ENTERSHORT: SPK,TFILTER;

{平空} EXITSHORT: BPK,TFILTER;

图表交易模型就完成了

 

对于新交易系统模型,可用下面4句代替

SELLSHORT(BPK and HOLDING<0,HOLDING,market); //交易系统之平空操作

BUY(BPK and  HOLDING=0,30%,market);//交易系统之开多操作

SELL(SPK and HOLDING>0,HOLDING,market); //交易系统之平多操作

BUYSHORT(SPK and HOLDING=0,30%,market); //交易系统之开空操作

 

3)三减六日乖离模型:

关键函数:REFMA,HHV,LLV

使用周期:所有 K 线周期。

模型说明:乖离值为正数时,未能突破前期高值,卖出;反之,买进。

 

参数设置:参数 N ,最小值 0,最大值 20,缺省值 5

B36 := MA(CLOSE,3)-MA(CLOSE,6);

B612 : =MA(CLOSE,6)-MA(CLOSE,12);

SPK :=REF(B36>REF(HHV(B36,N),1),1) AND B36<REF(B36,1);

BPK :REF(B36<REF(LLV(B36,N),1),1) AND B36>REF(B36,1);

{开多} ENTERLONG: BPK,TFILTER;

{平多} EXITLONG: SPK,TFILTER;

{开空} ENTERSHORT: SPK,TFILTER;

{平空} EXITSHORT: BPK,TFILTER;

图表交易模型就完成了

 

对于新交易系统模型,可用下面4句代替

SELLSHORT(BPK and HOLDING<0,HOLDING,market); //交易系统之平空操作

BUY(BPK and  HOLDING=0,30%,market);//交易系统之开多操作

SELL(SPK and HOLDING>0,HOLDING,market); //交易系统之平多操作

BUYSHORT(SPK and HOLDING=0,30%,market); //交易系统之开空操作

 

 

6.3日内交易模型编写范例

1)开盘价突破模型

关键函数:REF,VALUEWHEN,TIME,CROSS,DATE

使用周期:五分钟

 

模型说明:五分钟周期开盘第一根K线的收盘价与当日开盘价比较及最新价和当日开盘价的比较作为买卖依据进行交易,尾盘平仓不留隔夜单。

 

A:=VALUEWHEN(TIME=90500,CLOSE);

B:=VALUEWHEN(DATE<>REF(DATE,1),OPEN);

BK :=A<B AND CROSS(CLOSE,B) AND TIME<145000;

SP :=(A>B AND CROSS(B,CLOSE)) OR TIME>=145000;

SK :=A>B AND CROSS(B,CLOSE) AND TIME<145000;

BP :=(A<B AND CROSS(CLOSE,B)) OR TIME>=145000;

{开多} ENTERLONG: BK,TFILTER;

{平多} EXITLONG: SP,TFILTER;

{开空} ENTERSHORT: SK,TFILTER;

{平空} EXITSHORT: BP,TFILTER;

图表交易模型就完成了

 

对于新交易系统模型,可用下面4句代替

SELLSHORT(BP and HOLDING<0,HOLDING,market); //交易系统之平空操作

BUY(BK and  HOLDING=0,30%,market);//交易系统之开多操作

SELL(SP and HOLDING>0,HOLDING,market); //交易系统之平多操作

BUYSHORT(SK and HOLDING=0,30%,market); //交易系统之开空操作

 

容易犯的编写错误:

A、所选周期与所用模型时间上不统一

5 分钟周期最小能取到的时间点就是 5 分钟,如 145500145000144500 这样,所以其最后一根 K 线的 145500 这根。而如果您使用的是 3 分钟周期,那么 145500 就不是最后一根 K 线了,因为 3 分钟周期上所能取到的时间点为每 3 分钟,如 145400145700,那么就需要作出相应修改,如 BP :=TIME=145500;就需要修改为 BP :=TIME=145700;

 

B、开仓漏写时间控制

进行日内交易时注意时间函数的使用,不仅平仓条件中需要使用时间函数控制,有时开仓条件也需要使用时间函数来进行控制。

例如:上面的模型,1450 进行平仓,不仅需要在平仓条件中写入时间 145000,还需要写入开仓条件,否则可能会在 145000 平仓后,继续开仓进行交易。

 

C使用这种 VALUEWHEN(TIME=AA,DATA)格式的交易模型,一定要注意限制开仓时间在时间 AA 之后,否则在开盘到 AA 之前,对比的是昨日的 DATA

 

2)开盘后前三十分钟最高最低价突破模型

关键函数:REF,VALUEWHEN,TIME, DATE,HHV,LLV,BARSLAST

使用周期:五分钟

模型说明:以最新价与开盘 30 分钟内的最高最低价进行比较开仓,在收盘前平仓。

M:=BARSLAST(DATE<>REF(DATE,1) )+1;

B:=VALUEWHEN(TIME<=093000,HHV(HIGH,M));

D:=VALUEWHEN(TIME<=093000,LLV(LOW,M));

BK :=CLOSE>B AND TIME<145500 AND TIME>090000;

SP :=TIME=145500;

SK :=CLOSE<D AND TIME<145500 AND TIME>090000;

BP :=TIME=145500;

{开多} ENTERLONG: BK,TFILTER;

{平多} EXITLONG: SP,TFILTER;

{开空} ENTERSHORT: SK,TFILTER;

{平空} EXITSHORT: BP,TFILTER;

图表交易模型就完成了

 

对于新交易系统模型,可用下面4句代替

SELLSHORT(BP and HOLDING<0,HOLDING,market); //交易系统之平空操作

BUY(BK and  HOLDING=0,30%,market);//交易系统之开多操作

SELL(SP and HOLDING>0,HOLDING,market); //交易系统之平多操作

BUYSHORT(SK and HOLDING=0,30%,market); //交易系统之开空操作

 

单均线模型。

关键函数:MA,TIME

使用周期:1 分钟 K 线

模型说明:开盘后15分钟再根据均线与收盘价之间的关系进行日内买卖,尾盘平仓。

MAN:=MA(CLOSE,15);

BK :=TIME>=091500 AND TIME<145500 AND CLOSE>MAN AND BARSLAST(CROSS(CLOSE,MAN ))>=3;

SP :=TIME>=145500 OR (CLOSE<MAN AND BARSLAST(CROSS(MAN,CLOSE ))>=3);

SK :=TIME>=090000 AND TIME<145500 AND CLOSE<MAN AND BARSLAST(CROSS(MAN,CLOSE ))>=3;

BP :=TIME>=145500 OR (CLOSE>MAN AND BARSLAST(CROSS(CLOSE,MAN ))>=3);

{开多} ENTERLONG: BK,TFILTER;

{平多} EXITLONG: SP,TFILTER;

{开空} ENTERSHORT: SK,TFILTER;

{平空} EXITSHORT: BP,TFILTER;

图表交易模型就完成了

 

对于新交易系统模型,可用下面4句代替

SELLSHORT(BP and HOLDING<0,HOLDING,market); //交易系统之平空操作

BUY(BK and  HOLDING=0,30%,market);//交易系统之开多操作

SELL(SP and HOLDING>0,HOLDING,market); //交易系统之平多操作

BUYSHORT(SK and HOLDING=0,30%,market); //交易系统之开空操作

注:加入BARSLAST函数过滤,避免短时间段内频繁交易。

 

6.4常见问题

1) AND OR关系书写不完整明确,使得语句执行的结果与实际想要表达的内容不符。如:MACD 数值为正时,5 日线金叉 10 日线或者 10 日线金叉 30 日线时进行交易的条件语句不可直接写作:

MACD>0 AND CROSS(MA5,MA10) OR CROSS(MA10,MA30);

而应该使用括号将后面的均线条件括起来:

MACD>0 AND (CROSS(MA5,MA10) OR CROSS(MA10,MA30));

 

注:不要吝啬使用 () ,只有准确的书写了语句才能达到想要的结果。

 

2) 编写时掉入逻辑思维的陷阱,在考虑模型条件时,不需要考虑什么条件下不进行交易,而是正向的去考虑一定要达到何种条件时才会进行交易,这样在编写语句的时候,只需将要求的各个条件逐个罗列出来,使用操作符连接即可。

例如,均线与 MACD 结合编写模型时,要求均线金叉时,MACD 数值不得为负

值,那么正向考虑,均线金叉时MACD 的数值应该大于等于0,直接编写为:

MACD>0 AND CROSS(MA5,MA30)

 

3) 买卖方向容易混淆,比如平多单对应的是 SP 而不是 BP

如示例,这样就不是一个完整的开平仓。BP 是指平空单,而不是平多单。

A:=VALUEWHEN(TIME=091500,HIGH);

B:=VALUEWHEN(TIME=091500,LOW);

BK :=TIME>091500 AND CROSS(CLOSE,B) AND TIME<145000;

BP :=TIME>145000;

正确书写:

A:=VALUEWHEN(TIME=091500,HIGH);

B:=VALUEWHEN(TIME=091500,LOW);

BK :=TIME>091500 AND CROSS(CLOSE,B) AND TIME<145000;

SP :=TIME>145000;

 

 

4) 模型存在过滤机制的前提下,BARSLAST函数求的是上次满足条件到当前的周期数,可能取到的只是满足条件处,而非实际执行指令位置,在求开仓位置时,要合理使用此函数。如:

A:=VALUEWHEN(TIME=091500,HIGH);

B:=VALUEWHEN(TIME=091500,LOW);

BK :CROSS(CLOSE,B);

SP :=CROSS(A,CLOSE);

如果你想求开仓位置的最高价,写为

N:=BARSLAST(CROSS(CLOSE,B))

HH:REF(HIGH,N);

是不对的。由于开仓后曾多次满足此条件,但是相应持仓并未平掉,所以此指令被自动过滤。这样写求的可能是上次满足开仓条件的位置,而非实际开仓位置。

 

 

5)进行日内交易时注意时间函数的使用,不仅平仓条件中需要使用时间函数控制,开仓条件也需要使用时间函数来进行控制。另外如果采取了 当前 K线走完后发出交易指令 的交易策略,更加要注意时间轴刻度与语句执行时间的关系。

如:

MAN:=MA(CLOSE,15);

BK :=TIME>=091500 AND TIME<145500 AND CLOSE>MAN;

SP :=TIME>=145500 OR CLOSE<MAN;

SK :=TIME>=090000 AND TIME<145500 AND CLOSE<MAN;

BP :=TIME>=145500 OR CLOSE>MAN;

SELLSHORT(BP and HOLDING<0,HOLDING,market); //交易系统之平空操作

BUY(BK and  HOLDING=0,30%,market);//交易系统之开多操作

SELL(SP and HOLDING>0,HOLDING,market); //交易系统之平多操作

BUYSHORT(SK and HOLDING=0,30%,market); //交易系统之开空操作

说明:5 分钟周期,0915 之后进行日内交易,1455 进行平仓,不仅需要在平仓条件中写入时间 145500,还需要写入开仓条件,否则可能会在 145500 平仓后,继续开仓进行交易。

另外如果勾选当 K 先走完发出交易指令,该机制是出现指令的下一根 K 线开盘时发委托,由于尾盘平仓是在 145500 是最后一根 K 线,所以今天不会发指令,而是在明天第一根开盘时发委托,一定要注意掌握使用。

 

8)追踪止赢功能(按点数)

input:NS(10,1,100,1);{高点或低点回来10点}
{可自设开平仓条件}

持仓: holding;

tt0:=time<145000;
tt2:=time>145700;//收盘时间

SELLSHORT(tt0 and BP and 持仓<0,持仓,market);
SELLSHORT(tt0 and 持仓<0,持仓,Stopr,LLV(L,ENTERBARS)+NS);
BUY(tt0 and BK and  持仓=0,20%,market);

 

SELL(tt0 and SP and 持仓>0,持仓,market);
SELL(tt0 and 持仓>0,持仓,Stopr,HHV(H,ENTERBARS)-NS);
BUYSHORT(tt0 and SK and 持仓=0,20%,market);

 

9)追踪止赢功能(按回调比例)

input:NS(5,1,100,1);{ 回调比例}
持仓: holding;

tt0:=time<145000;
tt2:=time>145700;//收盘时间

SELLSHORT(tt0 and BP and 持仓<0,持仓,market);
SELLSHORT(tt0 and 持仓<0,持仓,Stopr, LLV(L,ENTERBARS)*(1+NS/100));
BUY(tt0 and BK and  持仓=0,20%,market);

SELL(tt0 and SP and 持仓>0,持仓,market);
SELL(tt0 and 持仓>0,持仓,Stopr, HHV(H,ENTERBARS)*(1-NS/100));
BUYSHORT(tt0 and SK and 持仓=0,20%,market);

 

其中,条件 and 持仓=0为单方向只开一次仓,即不连续开仓

上述模型仅供参考,据此交易风险自负。

第七章 金字塔的后台程式化交易

金字塔提供功能性和扩展性更为强大的基于后台预警模式的程式化交易模式,可以在不影响用户前台图形操作情况下,可以高效与预警系统一起工作来实现自动交易,由于后台程式化交易是金字塔在后台进行,不需要图表打开不占用过多的资源,由于只只需要最后一个周期的信号,所以原则上公式不要多余计算,故效率高,便于对多个品种同一个策略进行轮循监控.用户前期编写的自动交易策略是需要先在图表上和程式化交易评测上通过后才可以放到后台去执行程式化交易。为了让用户更快的编写和熟悉金字塔的后台程式化交易,金字塔的程式化交易函数,前面都在交易系统函数名称前加 T 字母,比如BUY改为TBUY, 使用方法大致相同.户仔细注意查看函数的使用说明。与图表显示的交易系统函数不同的是,后台程式化交易的函数都使用的实际的用户持仓和资金。

金字塔的后台程式化交易只能在专业版及其以上版本使用,他可以运行在序列和逐周期两种模式,但是推荐序列模式运行,这样可以极大提高后台执行的效率。

用以显示再图表做测试的后台程式化交易不能使用图表交易功能,且图表交易和后台交易的函数不能混用,即后台交易系统中不允许使用ENTERLONG等交易信号,传统的ENTERLONG交易信号里也不允许出现后台程式化交易系统的函数。

此外,后台程式化交易由于用户无法直接在图表上看到信号的整个出现过程,故对用户的公式编写水平有一定的要求,用户需要对金字塔的后台交易系统工作机理有比较深的了解,并且要对自己的公式系统有清晰的认识,这样一旦遇到问题也能及时找到问题的原因。后台交易过程中,一旦遇到问题,建议用户仔细阅读后面第八章的有关后台程式化交易的调试部分。

本章主要讲述交易测试系统函数、程序化交易系统函数,更具体的程序交易环节暨流程请同时参阅“金字塔程式化交易设计指南”。

7.1程式化交易系统的函数

将前面用在显示图表的交易的公式改为实盘后台的交易的公式如下:

MA3:MA(C,3);

MA5:MA(C,5);

 

TBUY(CROSS(MA3,MA5),1,LMT,C); //按照最新价限价开多

TSELL(CROSS(MA5,MA3),0,LMT,C);//按照最新价限价平多,0表示平掉全部持仓

 

请注意TBUY和TSELL函数的参数出现了变化,真正的下单时,需要指定下单类型和价格的,否则系统会按照市价进行交易。

 

用以模拟交易的函数和真实交易的函数,大部分只是有了前面T字母差别,大部分的用以交易评测的交易系统,只要将交易函数部分前面加T字母即可解决,唯一区别最大的就是TBUY,TSELL,TBUYSHORT,TSELLSHORT 这4个函数与模拟交易用的函数区别较大,请仔细辨别。

 

请注意交易控制符 THISCLOSE 在真实交易中被 LMT 等真实交易控制符所取代,金字塔的模拟交易控制符和真实交易控制符两者不能通用。金字塔的真实下单函数只支持LMT限价 MKT市价 STP止损 STPLMT限价止损 这4个交易控制符。

真实下单交易函数,下单数量不再支持百分比模式。

 

程式化交易的函数介绍

程式化交易系统之开多操作:

用法:TBUY(COND,V,[Type,P1,P2,AC,STOCK]);表示当COND条件成立时,

买入V股(手)当前品种,

TYPE表示开仓类型,LMT限价 MKT市价 STP止损 STPLMT限价止损

P1表示开仓价格,当TYPE为LMT和STP,STPLMT时为指定限价和止损价格,其他情况填0

P2为止损限价,当TYPE为STPLMT时,必须指定P2的止损限价,其他情况填0,当P1止损价触发时按照P2价格止损操作.

TYPE参数省略时,为市价开仓。AC为帐户ID,为空时为系统默认帐户,否则将下单到指定帐户中

STOCK为品种代码,比如'SH600215',为空或者不填时为当前品种

 例如:TBUY(C>O ,1000,LMT,C);表示收阳线则在本周期收盘价上买入1000股(手)。

TBUY(C>0,1000,STP,CLOSE+0.2);表示收阳线则在本周期收盘价高于0.2元下1000股(手)止损单,当盘中价格到了触发价时按市价开仓止损.

TBUY(C>0,1000,STPLMT,CLOSE+0.2,CLOSE);表示收阳线则在本周期收盘价高于0.2元下1000股(手)止损单,当盘中价格到了触发价时按CLOSE价格开仓止损。

 

程式化交易系统之平多操作:

TSELL(COND,V,[Type,P1,P2,AC,STOCK]); 用法同上

 

程式化交易系统之开空操作:

TBUYSHORT(COND,V,[Type,P1,P2,AC,STOCK]); 用法同上

 

程式化交易系统之平空操作:

TSELLSHORT(COND,V,[Type,P1,P2,AC,STOCK]); 用法同上

 

注意:程式化交易系统的函数中交易类型Type与交易测试系统的差别

 

唐奇安通道模型

input:N(20,5,100,1),NS(10,0,60,1);

资产:asset,noaxis,colorgreen;

持仓:HOLDING,LINETHICK0;

总次数: TOTALTRADE,LINETHICK0;

盈利:NUMWINTRADE,LINETHICK0;

胜率:ROUNDS(100*PERCENTWIN,1),LINETHICK0;

连亏:MAXSEQLOSS,LINETHICK0;

连盈:MAXSEQWIN,LINETHICK0;

 

BPK:=CROSS(H, hhv(ref(h,1),N));

SPK:=CROSS(llv(ref(l,1), N),L);

Price:=AVGENTERPRICE;//持仓价位

 

SELLSHORT(BPK and 持仓<0,持仓,market);

SELLSHORT(持仓<0,持仓,Stopr,Price+NS); //止损

BUY(BPK and 持仓=0,30%,market);

 

SELL(SPK and 持仓>0,持仓,market);

SELL(持仓>0,持仓,Stopr,Price-NS);//止损

BUYSHORT(SPK and 持仓=0,30%,market);

 

将交易模型转换成程式化交易系统,主要是涉及交易系统函数的转化,即在交易系统函数前加“t”,以及交易类型的改动;并且程式化交易函数都是在后台运行,不能在图表中显示;交易数量不能用30%的写法,只能用具体数量。

 

因此,唐奇安通道模型转化为可程式化交易的系统:

input:N(20,0,60,1) ,NS(30,0,100,1);

 

持仓:=tHOLDING,LINETHICK0;

KCS:= intpart(tasset*0.3/(close*multiplier));//也表示30%的开仓数

 

BUY1:=hhv(ref(h,1),N);

SELL1:=llv(ref(l,1),N);

BPK:=CROSS(H,BUY1);

SPK:=CROSS(SELL1,L);

Price:=tAVGENTERPRICE; //持仓价位

 

tSELLSHORT(BPK and 持仓<0,t持仓,mkt);

tSELLSHORT(持仓<0,持仓,Stp,Price+NS);

tBUY(BPK and 持仓=0, KCS,mkt);

 

tSELL(SPK and 持仓>0,持仓,mkt);

tSELL(持仓>0,持仓,Stp,Price-NS);

tBUYSHORT(SPK and 持仓=0, KCS,mkt);

 

若想与交易模型完全一样,后6句则需这样写:

tSELLSHORT(ref(BPK,1) and 持仓<0,t持仓,mkt);

tSELLSHORT(持仓<0,持仓,Stp,Price+NS);

tBUY(ref(BPK,1) and 持仓=0, KCS,mkt);

 

tSELL(ref(SPK,1) and 持仓>0,t持仓,mkt);

tSELL(持仓>0,持仓,Stp,Price-NS);

tBUYSHORT(ref(SPK,1) and 持仓=0, KCS,mkt);

 

7.2程式化交易函数

程式化交易函数共有41个,主要适于实际程式化交易,在后台运行,而不会在图表中显示。

大部分是在测试交易系统函数后加“T”,如:

程式化交易系统之开多操作,

用法:TBUY(COND,V,[Type,P1,P2,AC,STOCK]);表示当COND条件成立时,

买入V股(手)当前品种,

TYPE表示开仓类型,LMT限价 MKT市价 STP止损 STPLMT限价止损

P1表示开仓价格,当TYPE为LMT和STP,STPLMT时为指定限价和止损价格,其他情况填0

P2为止损限价,当TYPE为STPLMT时,必须指定P2的止损限价,其他情况填0,当P1止损价触发时按照P2价格止损操作.

TYPE参数省略时,为市价开仓。

AC为帐户ID,为空时为系统默认帐户,否则将下单到指定帐户中

STOCK为品种代码,比如'SH600215',为空或者不填时为当前品种

例如:TBUY(C>O ,1000,LMT,C);表示收阳线则在本周期收盘价上买入1000股(手)。

TBUY(C>0,1000,STP,CLOSE+0.2);表示收阳线则在本周期收盘价高于0.2元下1000股(手)止损单,当盘中价格到了触发价时按市价开仓止损.

TBUY(C>0,1000,STPLMT,CLOSE+0.2,CLOSE);表示收阳线则在本周期收盘价高于0.2元下1000股(手)止损单,当盘中价格到了触发价时按CLOSE价格开仓止损

 

程式化交易系统之平多操作,

TSELL(COND,V,[Type,P1,P2,AC,STOCK]); 用法同上

 

程式化交易系统之开空操作,

TBUYSHORT(COND,V,[Type,P1,P2,AC,STOCK]); 用法同上

 

程式化交易系统之平空操作,

TSELLSHORT(COND,V,[Type,P1,P2,AC,STOCK]); 用法同上

注意:程式化交易系统的函数中交易类型Type与交易测试系统的差别

 

DEBUGOUT(STR,NUM) 调试输出

用户可以在程式化交易中通过输出指定的字符串来实现调试的目的,可以借助这个功能来完成监控程式化交易的各种细节参数,因为在后台执行程式化交易时,用户在前台的图表上是看不到内部数据的。

用法:DEBUGOUT(STR,NUM),STR为用户指定输出的一个行文字,NUM为用户指定的一个监控数字.

例如:DEBUGOUT('当前资产为%.2f',1234),将在程式化交易的监控部分打印出来 "当前资产为1234.00"

"%.2f"为一个打印的控制符号,系统会将他替换为指定的一个数字输出,%.2f为显示两位小数,%.0f则表示不显示小数.

该函数仅在做程式化交易时有效

 

SLEEP(D)  延时

当位于最后一个周期时,延时指定数量时间后再执行下条语句。

用法:SLEEP(D),D为延时的设置时间,单位为毫秒(1秒钟等于1000毫秒)。

例如:SLEEP(1000)表示等待1秒后再执行下行语句。

 

TODAYHOLDING  今持仓量

得到当前帐户的今日持仓量,多仓返回正数空仓返回负用法:TODAYHOLDING

 

 

TSUBMIT(N) 委托单历时

用法:TSUBMIT(N)仍未成交时,函数返回未成交历时的秒数,有效值范围为(1-1000);成交函数返回0.

N为委托方向.0所有方向;1开多;2平多;3开空;4平空;

便于控制未成交交易,采取其他补救措施

 

TTOTALDAYTRADE 日内交易次数

当前位置之前总共有多少次当日的交易,注意每次卖出算一次交易,而买入不算

用法:TTOTALDAYTRADE

 

其它的程式化交易函数,类似,请自己依次查看

注意:在公式编辑中,点击  [ << ] 可弹出函数列表,可按类查找需要的函数,如果需要可直接也双击改函数即可引入。公式中的蓝色字段为函数名,将鼠标放在未知的蓝色字段上,将看到该函数的描述和基本用法。

7.3程式化交易执行语句常用的其它函数

MINDIFF  最小变动价位

返回当前品种最小变动价位(可在交易—合约信息设置中设置)。

若市场分类小数点为2时最小变动价位则为0.01

注意:该函数返回常数

 

VOLUNIT  每手单位

返回每手单位(可在市场管理中设置),注意:该函数返回常数

 

MULTIPLIER  乘数

当前品种的乘数或单位

用法:MULTIPLIER

 

OPENTIME(N)  开盘时间

返回交易所的指定时段的开盘时间

用法:OPENTIME(N),N表示对应市场分类中交易所交易时间设置的节数(自上而下)1表示第一个

函数返回有效值范围为(000000-235959),此函数返回常数,对于日线及更长周期此函数无效.

 

CLOSETIME(N)  收盘时间

返回交易所的指定时段的收盘时间

用法:CLOSETIME(N),N表示对应市场分类中交易所交易时间设置的节数(自上而下),特设0表示最后一节的节数(即日收盘的节数)

函数返回有效值范围为(000000-235959),此函数返回常数,对于日线及更长周期此函数无效.

 

PLAYSOUND  播放声音文件

播放一首指定位置的一个声音文件,可以是MP3或者WAV等格式.

用法:PLAYSOUND(COND,PATH),当最后一个周期得COND条件成立时,播放指定位置PATH的一个声音文件

声音文件可以是绝对路径,也可以只是一个声音文件,只有一个文件名时用户需要将它安放在DOCUMENT目录.

例如:PLAYSOUND(CLOSE>OPEN,'D:\ONTIFY.MP3'),当最后一个周期为阳线时播放D:\ONTIFY.MP3位置的声音文件.

 

SENDMAIL  发送邮件

发送一封邮件到指定的邮箱.

用法:SENDMAIL(COND,MAILTO,SUB,CON),当最后一个周期得COND条件成立时,发送到MAILTO用户,标题为SUB,内容为CON

例如:SENDMAIL(CLOSE>OPEN,'ABC@SINA.COM;XYZ@WEISTOCK.COM','警报','大阳线'),

表示当最后一个周期为阳线时,往ABC@SINA.COM和XYZ@WEISTOCK.COM这两个邮箱发送邮件,标题是'警报',内容是'大阳线'.

用户使用该功能之前,需要预先设置邮件发送的SMTP信息,具体操作位置在 工具->网络->邮件发送设置里,并需要勾选'允许程式化交易'选项.

DYNAINFO(4)  取得最新动态行情: 今开

 

DYNAINFO(5)  取得最新动态行情: 最高

 

DYNAINFO(6)  取得最新动态行情: 最低

 

DYNAINFO(7)  取得最新动态行情: 最新

 

DYNAINFO(28)  取得最新动态行情: 买一价

 

DYNAINFO(34)  取得最新动态行情: 卖一价

DYNAINFO(54)  取得最新动态行情: 涨停

 

DYNAINFO(55)  取得最新动态行情: 跌停

 

 

7.4账户函数介绍

为了方便交易员编写资金管理程序,金字塔增加了账户函数(43个),今后还将扩充更多头寸管理函数。

 

TACCOUNT(1); 交易帐户: 返回当前交易帐户ID(该函数返回字符串类型数值)

 

TACCOUNT(2); 帐户类型: 返回当前交易帐户类型(0 盈透;1 CTP)

 

TACCOUNT(3); 现金余额: 返回当前交易帐户中的现金余额

 

TACCOUNT(4); 浮动盈亏: 返回当前交易帐户中的浮动盈亏

 

TACCOUNT(6); 平仓净值: 返回当前交易帐户中的平仓净值

 

TACCOUNT(19); 当前可用资金: 返回当前交易帐户中的当前可用资金

 

TACCOUNT(20); 当前流动资产: 返回当前交易帐户中的当前流动资产

 

TACCOUNT(26); 上次结算准备金: 返回当前交易帐户中的上次结算准备金(CTP专有)

 

TACCOUNT(27); 结算准备金: 返回当前交易帐户中的期货结算准备金(CTP专有)

 

TACCOUNT(28); 占用保证金: 返回当前交易帐户中的占用保证金(CTP专有)

 

TACCOUNT(29); 可取资金: 返回当前交易帐户中的可取资金数量(CTP专有)

 

TACCOUNT(30); 平仓盈亏: 返回当前交易帐户中的平仓盈亏数额(CTP专有)

 

TACCOUNT(31); 手续费: 返回当前交易帐户中的手续费(CTP专有)

 

TACCOUNT(32); 入金金额: 返回当前交易帐户中的入金金额(CTP专有)

 

TACCOUNT(33); 出金金额: 返回当前交易帐户中的出金金额(CTP专有)

 

TACCOUNT(34); 上次信用额度: 返回当前交易帐户中的上次信用额度(CTP专有)

 

TACCOUNT(35); 上次质压: 返回当前交易帐户中的上次质压(CTP专有)

 

TACCOUNT(36); 质压金额: 返回当前交易帐户中的质压金额(CTP专有)

 

TACCOUNT(36); 信用额度: 返回当前交易帐户中的信用额度(CTP专有)

 

。。。

TACCOUNT(43)

其它的账户函数,请自己依次查看

 

注意:在公式编辑中,点击  [ << ] 可弹出函数列表,可按类查找需要的函数,双击该函数将直接引入公式。公式中的蓝色字段为函数名,将鼠标放在未知的蓝色字段上,将看到该函数的描述和基本用法。

1)如何编制简单价差类型的套利模型

CLOSE 为两个品种的价差。

当价差小于 300 时,买入开仓前一品种RB05,卖出开仓后一品种RB03

当价差大于500时,卖出平仓前一品种,买入平仓后一品种

当价差大于 600 时,卖出开仓前一品种,买入开仓后一品种

当价差小于400时,买入平仓前一品种,卖出平仓后一品种

由于涉及到需要同时下单到不同的品种,这里直接使用后台程式化交易系统编写。

C1:=RB05close”-“RB03close”;

TBUY(CROSS(300,C1),10, mkt,0,0,'','SQRB05');//开多

TBUYSHORT(CROSS(300,C1),10,mkt, 0,0,'','SQRB03'); //开空

 

TSELL(CROSS(C1,500),10,mkt, 0,0,'', 'SQRB05'); //平多

TSELLSHORT(CROSS (C1,500),10,mkt, 0,0, '', 'SQRB03'); //平空

 

TBUYSHORT(CROSS(C1,600),10,mkt, 0,0, '','SQRB05'); //开空

TBUY(CROSS(C1,600),10, mkt, 0,0,'', 'SQRB03');//开多

 

TSELLSHORT(CROSS (400,C1),10,mkt, 0,0, '', 'SQRB05'); //平空

TSELL(CROSS (400,C1),10,mkt, 0,0, '', 'SQRB03'); //平多

注意在后台程式化交易监控中,用户至少需要监控RB05或者RB03其中的一个。

 

2)如何编制技术指标的套利模型:

C1:=RB05close”-“RB03close”;

DIFF := EMA(C1,12) - EMA(C1,26);

DEA := EMA(DIFF,9);

MACD:=2*(DIFF-DEA);

BKSK :=MACD>0;

SPBP :=MACD<0;

TSELLSHORT(SPBP,10, mkt, 0,0, '', 'SQRB03'); //平空

TBUY(BKSK,10,mkt, 0,0,'', 'SQRB05');//开多

TSELL(SPBP,10, mkt, 0,0,'', 'SQRB05'); //平多

TBUYSHORT(BKSK,10,mkt, 0,0, '', 'SQRB03'); //开空

 

3)如何编制技术指标的多账户模型:

账户1:16801

账户2:16802

DIFF := EMA(C,12) - EMA(C,26);

DEA := EMA(DIFF,9);

MACD:=2*(DIFF-DEA);

IF THOLDING<0 THEN

BEGIN

TSELLSHORT(MACD>0 and THOLDING<0, THOLDING, mkt, 0,0,'16801'); //平空

TSELLSHORT(MACD>0,10, mkt, 0,0, '16802'); //平空

END

IF THOLDING=0 THEN

BEGIN

TBUY(MACD>0 and THOLDING=0,10,mkt, 0,0, '16801');//开多

TBUY(MACD>0,10,mkt, 0,0, '16802');//开多

END

IF THOLDING>0 THEN

BEGIN

TSELL(MACD<0 and THOLDING>0, THOLDING,10, mkt, 0,0,'16801'); //平多

TSELL(MACD<0,10, mkt, 0,0,'16802'); //平多

END

IF THOLDING=0 THEN

BEGIN

TBUYSHORT(MACD<0 and THOLDING=0,10,mkt, 0,0,'16801'); //开空

TBUYSHORT(MACD<0,10,mkt, 0,0, '16802'); //开空

END

 

上面3个例子用到了程式化交易函数

所有上述模型仅供参考,据此交易风险自负。

 

第八章 程式化交易测试和优化

8.1完整交易系统的组成

“交易系统是完整的交易规则体系”,首先一套最简单的完整的交易系统,包括最基本的交易点组成的框架,也就是由两个点组成,一个是买入点的切入和卖出点的切出,整个的交易系统就是围绕着这两个基本的点形成的循环,整个的交易系统的确立、测试和优化,简单讲只是围绕这两个基本点的确认而展开。

但是,一个交易系统绝对不只是局限于得到两个点的工作,买入和卖出的有机结合,交易资金的合理分配使用,根据市场状况的变动相应的调整以适应新的变化等等后期的跟踪和再优化,以及保证交易循环的连续性都是一个“完整的交易规则体系”的要求。


一个完整的交易系统由以下的步骤组成:
1、交易策略的提出
2、交易对象的筛选
3、交易策略的公式化
4、交易系统的统计检验
5、交易系统的外推实验
6、交易系统的实战检验 (包括前期的实时行情模拟和小仓位实盘)
7、交易系统的检测与维护

实际上,简单的讲来就是将一些的经验和方法首先通过量化和公式化,变成计算机可以识别的语言,并且在历史的数据中进行统计和成功率检验。首先通过了不同的市场,不同的历史环境的数据检验后付之实战,最终在实践的考验中不断完善和进步。

 

无论是指标、条件选股,或者交易系统的编制,都是一个循序渐进的过程。这一点在交易系统中表现得尤为突出,从一个方案的提出,到量化,编制公式,然后在以后的不断的检验--历史数据下的静态检验,当前数据下的动态检验,实战检验,任何其中的一个环节如果发现有不合理的,不准确的的地方都需要我们对整个公式系统进行修改,使之更加完美,也许可以将之称为优化
在金字塔1.90的版本中,突出了这个功能的实现,可以通过测试平台对所有的公式化分析工具或者交易工具进行全方位的测评,并提交一份详实可信的测试报告,在以下的几节中,我们将通过融合测试平台的使用对指标、条件选股以及交易系统的公式进行优化。

8.2测试平台的基本内容和架构

在金字塔中为技术指标、条件选股以及交易系统建立了统一的测试平台。在【交易】栏中选“程式化交易评测”,或按Ctrl + F7 ,出现如图8.1公式测试系统

8.1公式测试系统

    假设我们选择了技术指标当中的MA进行测试,在设定好一定的买入条件和卖出条件以及测试的市场模型之后即可对任意的指标、公式等进行测试。金字塔中提供了两种不同的测试模型,一种是针对全部信号的单个股票测试,另外一种是为了最佳的模拟真实的买入和卖出条件,以及参与市场的投资策略的测试模型,具体的内容和区别请看后面的说明。
开仓信号,选择模型和分析周期。

入场规则,入场条件设定测试时段,也即测试的时间区间,金字塔默认的区间为20000101到当前。如果默认的入场规则无法满足您的要求,可以在模型当中编制您的入场条件。
出场规则,金字塔提供以上7种平仓条件,包括卖出指令和止损指令:
目标周期为终点,到时自动平仓,20周期以后的收盘价平仓;
目标利润为终点,到时自动平仓,10%帐面盈利以后的收盘价平仓;
以及5类止损平仓:分别设定不同类型下的规避风险条件。
交易费用:按证券和期货,根据成交额和成交量计算佣金。

市场模型:金字塔提供两类市场模型供测试分析。
测试报告

 

 

系统测评报告

8.2系统测评报告

系统信号指示和资金曲线同图显示

 

 

8.3金字塔的图表程式化交易和后台程式化交易的结构

8.3.1前台图表交易

金字塔前台图表交易是将交易系统指标放在图表上进行显示和下单交易的,金字塔图表交易适用ENTERLONG,EXITLONG,ENTERSHORT,EXITSHORT这四种交易信号来分别表示多空头的进出场描述.

除此之外,金字塔还提供了功能更为强大的新交易系统函数,可以使用BUY,SELL,BUYSHORT,SELLSHORT,函数,对介入价位和仓位进行精确的控制,可以对譬如海龟交易法的头寸管理.金字塔的新交易系统函数,用户可以在公式函数列表的“交易系统”组里找到.但是需要注意的是金字塔的新交易系统,是不能与旧的交易系统比如ENTERLONG混用的.金字塔的新交易系统采取的虚拟仓位和资金再图表做显示和模拟交易的,使用之前用户需要在公式属性里将资金和费率设置正确,以确保能更加贴近实战.真实自动交易时,系统将根据交易指令发出的交易类型和价格以及数量进行下单交易.

 

8.3.2后台程式化交易

金字塔的后台程式化交易在金字塔公式系统里用户可以在“后台程式化交易”函数组里找到,后台程式化交易是基于预警模式进行工作, 由于后台程式化交易是金字塔在后台进行,不需要图表打开不占用过多的资源,由于只需要最后一个周期的信号,所以原则上公式不要多余计算,故效率高,便于对多个品种同一个策略进行轮循监控.用户前期编写的自动交易策略是需要先在图表上和程式化交易评测上通过后才可以放到后台去执行程式化交易。为了让用户更快的编写和熟悉金字塔的后台程式化交易,金字塔的程式化交易函数,前面都在交易系统函数名称前加 T 字母,比如BUY改为TBUY, 使用方法大致相同.户仔细注意查看函数的使用说明。与图表显示的交易系统函数不同的是,后台程式化交易的函数都使用的实际的用户持仓和资金.

 

8.3.3金字塔程式化交易的特点和与TradeStation等软件的不同点

金字塔为了满足不同层次用户的需要,提供两种程式化交易,前台图表程式化交易和后台程式化交易.

前台图表自动交易是为基础用户所设立,即可使用ENTERLONG,EXITLONG,ENTERSHORT,EXITSHORT这4种传统的交易信号,也可使用交易系统函数来实现下单.交易过程是基于图表之上的,用户事先将交易信号的公式添加到图表上,然后再来启动交易.

后台程式化交易是基于后台的预警模式,金字塔提供了一系列的功能和众多交易函数,可以在不影响用户前台图形操作情况下,可以高效与预警系统一起工作来实现自动交易,并且可以一个交易策略同时交易几个品种。而TradeStation是必须在图表上才能实现交易的.

TradeStation程式化交易时,图表上只有最后一个周期走完才发出交易指令,而金字塔提供了两种模式,一种是基于预警轮询模式,在一个K线周期内会被多次执行交易判断(频率取决于预警时间间隔这个选项),这样可以保证在出现信号时能够以最快速度的发出交易指令,但是用户不用担心一个周期内多次重复交易问题,因为金字塔可以自动防止此现象(可以使用ALLOWREPEAT控制符允许反复开平仓)。另外金字塔也提供K线走完再发信号这种工作模式,与TradeStation保持了一致.

由于程式化交易模式不同,所以用金字塔做自动交易时应特别注意几个问题:①②

1)使用了即时发出预警信号选项时,自动交易不局限于最后的K线走完,所以可能会导致中间发出信号,而价格变动后信号消失

2)使用了即时发出预警信号时,预警时间间隔控制轮询的频率,用户应该根据交易公式所用到的周期合理的分配间隔时间,防止由于间隔时间不合适而导致例如上传下破等指标信号漏掉的情况。

 

 

8.3.4使用金字塔自动交易的常见问题和注意事项

1)前台图表ENTERLONG控制指令和BUY等图表显示函数是不能放在后台做监控交易的,但是将"允许程式化交易"勾去掉后单独做预警是可以的。

2)不带T的交易系统所有函数,均不能与ENTERLONG等传统的交易系统混用。

3)只有少数的带T的后台交易函数允许使用在Enterlong和BUY前台图表交易策略中. Tholding, TAVGENTERPRICE,Taccount, Tasset,但是金字塔强烈不建议使用,因为这样会造成图表上的交易信号与实际的下单记录不符。

4)金字塔的后台交易部分,使用手工闪电下单的记录,将无法通过比如TENTERPRICE等与交易记录有关函数中得到结果,但可以通过程式化交易监控中的手工下单干预功能完成此项目的。

5)金字塔的后台交易,查询持仓和资产均为用户当前的实际数值,如果多个策略同时多一个品种或通一个帐户进行操作会产生相互干扰现象,解决办法就是通过使用交易系统使用虚拟持仓和资金,这样就完全可以避免这种共振现象,但是推荐高级用户使用,因为需要很多技巧需要处理。

6)传统的交易信号ENTERLONG虽然功能较弱,但是由于不需要头寸管理,故金字塔可以使用公式的特殊算法达到高效运行,故在不需要介入点和仓位控制的策略中,尽量避免使用BUY等新交易系统,尤其在使用了BUY的新交易系统的策略中,使用未来函数更会导致效率下降。同样如此,如果在同一个策略中使用TBUY和BUY函数,也会导致在后台自动交易时的效率下降。

7)用以图表显示的交易系统和后台程式化交易的交易指令函数,参数有明显的不同,用户不能简单的将BUY函数加个T就可以直接后台交易,使用前应该将鼠标放在TBUY函数上认真看看函数说明。

 

 

 

 

 

同名交易系统函数与程式化交易函数的差别:

 

 

前台图表交易模型

后台交易系统

开多

BUY

TBUY

平多

SELL

TSELL

开空

BUYSHORT

TBUYSHORT

平空

SELLSHORT

TSELLSHORT

其中TYPE:次周期限价

LIMIT

REF(条件,1),LMT

TYPE:本周期限价

LIMITR

LMT

TYPE:次周期停损

STOP

REF(条件,1),STP

TYPE:本周期停损

STOPR

STP

TYPE:次周期市价

MARKET

REF(条件,1),MKT

开仓百分比

30%

KCS:= intpart(tasset*0.3/MULTIPLIER/close);

语句

语句

T语句

函数

可在图表上显示

不能在图表上显示

 

总之,通过函数列表,了解他们的细微差别。

 

8.4程式化交易的前提、步骤

1) 有良好的交易策略,最好程式化交易前能够基本稳定盈利

2) 根据交易策略,进行量化,建立交易系统,年回报率可能降低,但可以扩大规模,提高绝对收益;
3) 用交易系统函数建立交易模型,按步骤,选定有关规则,
进行交易评测
 
按单手合约进行,若考虑的滑移后仍能取得稳定盈利,恭喜你!
  根据测评报告的因素,如连续亏损次数、最大亏损、最大浮动亏损、平均盈亏比、平均交易周期等,将头寸调整(资金管理)加入交易策略,改进模型;
  若改进模型能够取得更好的稳定盈利,恭喜你!
4)可使用前台图表程式化交易和程式化交易函数替代模型相关的几个交易系统函数,
使用模拟账户进行实盘模拟测试和调试,经过一段时间的自动交易模拟,如果仍能取得稳定盈利,恭喜你,你离成功更近了;

5) 拿出资金的一小部分,进行实盘测试和和调试
6)
使用规模资金,进行实盘测试和和调试,稳定后数钱就是,恭喜你成功了!
当然能够成功的只是少数,但你可能就是其中一员。
    在使用金字塔程式化交易之际,我们
特别提醒任何一个交易策略如果测试结果过好,都可能存在某些不易发现的纰漏,一定要慎重, 金字塔和CTP提供了极接近实盘的模拟账户,请您一定要经过一段时间纸账户的运行,确保万无一失,再进行真实账户操作。为了您和家人,保护好您的财富。

另外不要过度优化,要保持相对稳定性,但使用过程中仍要注意交易系统的适用性,经过一段时间正常运行,若某些交易标的的特征明显变化,需做相应调整,其分寸较难掌握到火候,应逐渐积累经验。
    在交易过程中,
当个人盘感极强时,可以进行人工干预金字塔在这方面预留的相应功能,如直接开仓、平仓、撤单、暂停和调整某参数,而不影响交易系统正常运作,被视做交易系统的一部分,方便交易员发挥主观能动性,逐渐做到人机合一,达到更高境界。如图



当然也可以实现全自动无人值守。

也就是说:用金字塔,可以进行纯主观的手动交易(如炒单使用闪电下单等)、系统信号加主观过滤的交易程式化交易加主观干预的半自动或准自动交易全自动交易等多种交易方式,完全可以满足各类交易员的需求,也可供交易员自身转换手法。

 

使用金字塔还有一种非常灵活的方式
-----
良好头寸管理下的主观交易模式

利用一套具有良好头寸管理的交易策略,进行主观交易。

1、 启动该交易系统,在程式化交易过程中,暂停系统运行;
2、 根据有关图形和交易盘感进行交易;
3、 开仓后,再启动该交易系统;
4、 系统自动加码、止损、获利平仓;
5、 直至有盘感手工开仓,。。。,再启动,。。。
充分发挥主观能动性和头寸管理系统的长处,做到人机合一,达到更高境界。

用金字塔制作交易系统,就像飞行员、驾驶员的自动导航仪,特殊情况一定要经验丰富的人来驾驶,但到典型情况,如天气良好、路况很好可以暂时交给电脑自动导航,稍事休息、放松一下、听听音乐、看看电影。

听上去很美,问题是谁能事先知道前面是什么气象呢?

从气象良好到恶劣总有个演变过程,当不是良好,就已经预警,准备人工干预,不用等到较差、恶劣天气,再不知所措。可根据变化速度调整干预时机。交易更多是反应式的。

总而言之,你有什么离奇古怪的想法,金字塔也有可能帮你实现。这样金字塔真正成为交易员的得力助手。

 

第九章 程序化交易的启用

9.1启动图表交易

1)选择交易模型

从“查看管理面板”,我们就可以看到用户可以通过管理面板方便的编辑、使用相关模型。管理面板中主要有技术指标、条件选股、交易系统、五彩K线等四大项。

从左边的“管理面板--交易系统”里选择模型,双击,右边主图即会显示模型。图例是名为Formu002的模型。

9.1加载交易模型

2)选择【交易】【图表程式化交易】,将出现

9.2图表程序化交易

3)设置好相关参数,点击【启动交易】,确认之后,将开始程式化交易,交易详情会记录在表格上。交易结束,点击【停止交易】

9.2启动后台程式化交易

选择“交易后台程序化交易”或按Ctrl + A会出现图7.3本地预警交易。

7.3本地预警交易

1)选“新增条件”,将出现图7.4程式化条件设定

7.4程式化条件设定

2) 参数设置 

第一步:首先,点“指标公式”,选择你的模型和使用周期;

第二步:加入要监控的品种;

第三步:其它各种设置,

注意:打勾“允许程式化交易”,其中,可将“下单需手工确认”关闭,如勾选自定义分品种下单,会出现确认对话框,请用户详看出现的每一个提示确认对话框;设定“预警时间间隔”及“时间范围启用”;等等然后按“确认” ;

最后点击“启动预警”。

3)在程式化交易过程中,用户可随时点击【监控】,观察系统运行情况,并可在信心爆棚时,手工加减仓干预。如图7.5程序化交易明细

7.5程序化交易明细

 

 

第十章 公式系统的编写调试

10.1基于图表公式的调试

用户在编辑指标过程当中,避免不了进行中间调试,这涉及到遇到中间的变量在某个周期的数值等于多少。比较简单的处理方法是在公式中加以例如:

 A:B+C;

这种方式输出A变量的值在图表显示加以查看,但是有时刻意的将中间变量A输出到图表上显示会破坏图表显示格式,处理方法是在语句后加 ,LINETHICK0 控制符例如:

A:B+C,LINETHICK0;

强制只做变量在图表输出,但不做画线显示,然后用户在主图双击鼠标打开十字光标,查看A变量在指定周期的数值,进行调试。

 

10.2基于后台预警和程式化交易的调试

      由于后台程式化交易和预警我们无法从前台图表上直接看到,因此金字塔提供了一些调试模式供用户使用,由于预警系统是只执行最后一个周期的信号,故这里只针对这个特点进行讨论。

供后台调试金字塔提供了两个函数 DEBUGOUT 和 DEBUGFILE,其中DEBUGOUT是只针对程式化交易使用,在Ctrl+A预警设置窗口点击“监控”按钮后的程式化交易监控窗口,将显示出当前每个品种的监控过程以及下单动作,DEBUGOUT函数的描述如下:

DEBUGOUT(STR,NUM),STR为用户指定输出的一个行文字,NUM为用户指定的一个监控数字.

例如:DEBUGOUT('当前资产为%.2f', TASSET),将在程式化交易的监控部分打印出来 "当前资产为1234.00",(假设当前的资产为1234)

"%.2f"为一个打印的控制符号,系统会将他替换为指定的一个数字输出,%.2f为显示两位小数,%.0f则表示不显示小数.

用户最常见的问题就是,从图表上看明明应该某个时间段应该是开平仓了,但是结果确没有反应,后台并没有按预计发出交易指令,这种情况用户一般需要基于下面原因考虑:

1)用于交易的品种历史数据是否补齐,因为金字塔的历史数据是基于点播模式补充的,处于后台交易的品种如果缺失数据将会导致交易信号出现不可预料的情况。

2)用户所选择的交易系统周期是否合理,预警监控间隔时间是否合理,甚至用户是否选中了“允许程式化交易”复选框。

比如:

MA3:MA(C,3);

MA5:MA(C,5);

BK:= CROSS(MA3,MA5);

BP:= CROSS(MA5,MA3);

TBUY(BK,1,LMT,C); //按照最新价限价开多

TSELL(BP,0,LMT,C);//按照最新价限价平多,0表示平掉全部持仓

这样一个简单的公式,是否出现交易信号,完全取觉于BK和BP这两个变量的计算结果,只要这样

MA3:MA(C,3);

MA5:MA(C,5);

BK:= CROSS(MA3,MA5);

BP:= CROSS(MA5,MA3);

DEBUGOUT(‘BK=%.0f’,BK);

DEBUGOUT(‘BP=%.0f’,BP);

TBUY(BK,1,LMT,C); //按照最新价限价开多

TSELL(BP,0,LMT,C);//按照最新价限价平多,0表示平掉全部持仓

用户可以在程式化交易监控窗口看到整个变量在不断循环中的值变化了,方便用户调试的。不过上述只显示了BK,BP这两个信号,可能并不能让用户最终找到问题原因,要找到,用户可能还得将MA3,MA5的变量值变化也打印输出,只要一直这样往上逐个筛选每个结果数据,就能最终找到问题的原因。

      金字塔的另一个函数DEBUGFILE,可以将调试日志记录文件中,方便用户查询更长的历史记录,如果用户不习惯使用DEBUGOUT的窗口输出模式,可以使用DEBUGFILE做输出,使用其他文本工具打开。另外,DEBUGFILE与DEBUGOUT不同之处在于他不限于一定运行在后台程式化交易环境中,DEBUGFILE描述如下:

用法:DEBUGFILE(PATH,STR,NUM),PATH为用户的本地计算机路径,STR为用户指定输出的一个行文字,NUM为用户指定的一个监控数字.

例如:DEBUGFILE('D:\TEST.TXT','当前资产为%.2f',1234),将在程式化交易的监控部分输出到D:\TEST.TXT文件, "当前资产为1234.00","%.2f"为一个打印的控制符号,系统会将他替换为指定的一个数字输出,%.2f为显示两位小数,%.0f则表示不显示小数。

 

第十一章 VBS公式教程

11.1嵌入式VBSJS脚本

在各种高级语言中,熟悉和精通VB的人无疑是最多的。VBScript 是 VB 的一个子集,它提供的各种语句和语法、常量和变量、函数和过程的规则与VB完全相同,并且也提供了许多基本的计算、处理函数。VBScript是标准的脚本语言,广泛应用于动态网页、大型电子商务系统、Windows系统管理等领域。因此,选用 VBScript作为自己的公式脚本语言(之一),使其公式系统具有强大的计算能力、扩展能力和生命力。

金字塔采用嵌入脚本语言的方式引入VBScript,编制方法类似制作ASP动态网页。采用这种方式可以保持原有公式系统的兼容性,避免一些冲突(例如原条件函数IF与条件语句IF的关键字冲突)。另外,这种方式便于将来再引入新的脚本语言,这就大大提升了公式系统的扩展性和生命力。

VBScript所能进行的计算、处理能力非常强大,甚至可进行文件操作等,所以,只要是想得到的计算,都应该能够实现。类似编制ASP、PHP动态网页,可在公式中多处嵌入脚本(用<%...%>括起即可),可在脚本中定义函数、过程供脚本自己调用。

提醒VBS公式只能在序列模式下运行,无法在逐周期模式工作,这就意味着只能使用ENTERLONG等简单图表交易模型和TBUY等后台交易模式,无法使用图表的BUY交易模型。

11.2 VBS接口 

VBS与金字塔公式系统之间,必须通过接口才能交换数据,也就是说,公式系统中的数据不能直接被VBS处理,同样VBS中运行的结果,也不能直接被公式系统使用。 

VBS目前提供的接口有: 

1FFL.VarData("变量名"),传递常量、数组变量数据。

2FFL.StrVarData("变量名"),传递字符串常量、数组变量数据。 

3FFL.VarStartIndex("变量名"),传递数组变量有效数值起始位置,若脚本处理过程中不改变变量有效数值起始位,则无须调用。  

4FFL.Color("变量名"),用于指定指标输出变量的颜色;(可程序实现渐变色)。 

5FFL.LineThick("变量名"),用于指定指标输出变量的线宽;(可程序实现线宽)。 

11.3利用VBS设计公式 

VBS脚本语句,必须使用“<%”“%>”框起来,以便让公式系统能够识别,在一个指标公式中,可以多次调用VBS脚本,即可以有多组由“<%%>”框起来的脚本。 

在公式系统中无法实现而需要调用VBS的实例通常较复杂,为了学习VBS,所举的实例从简单开始,大多可以在原公式系统中实现。 

以下通过具体实例,解剖一下VBS设计的公式。  

例一:设计一个公式,计算收盘价对应的涨停价位(设涨停板为10% 

代码如下: 

spj:=close; 

<% 

vspj=ffl.vardata("spj") 

 

last=ubound(vspj) 

 

for i=0 to last 

vspj(i)=vspj(i)*1.1 

next 

 

ffl.vardata("spj")=vspj 

%> 

vspj 

以下详细解释公式代码: 

1spj:=close--定义一个序列变量spj,其值等于序列收盘价(对日K线而言,等于从上市首日直到最后一天的一系列收盘价,故名为序列变量)。 

 接着是一段由“<%”“%>”框起来的VBS程序代码。

2vspj=ffl.vardata("spj")--将序列变量spj传递到VBS中,其数据放入数组vpj中。有关数组概念,可参阅Vbs55.chm 

这里对数组稍加解释,VBS中的数组,是由一系列元素构成的,本例中为Vspj(0)vspj(1)......,这里括号中的01......等称为数组的下标,VBS数组下标是从0开始的。其中vbs(0)是数组的第一个元素,对应序列变量的第一个值(即首日收盘价),依此类推,直到最后一个。那么,数组vspj的最后一个元素是哪个?这很重要,因为在涉及相关计算时必须知道。看下一行代码: 

3last=ubound(vspj)--ubound(vspj)是计算数组vspj最大下标。本行语句,是把vspj的最大下标的值赋给变量last,也就是说last此后就等于vspj的最大下标值。 

4)接着的三行语句是VBS的循环,此处的for...... nexe语句的VBS循环语句中的一种。循环是起什么作用的?我们来看看,要计算从第一天到最后一天的涨停价位,如果逐条语句来写,大致如下: 

vspj(0)=vspj(0)*1.1--把第一天的收盘价vspj(0)乘以1.1,再赋回给vspj(0),运算后vspj(0)就不再等于收盘价,而是原价的涨停价位。 

vspj(1)=vspj(1)*1.1--vspj(1)运算后等于第二天的涨停价位。 

vspj(2)=vspj(2)*1.1 

 vspj(last)=vspj(last)*1.1--最后一天的运算。 

一共须写last+1条语句,显然效率太低了。这些语句用循环语句来写,只须3条就行了,即 

for i=0 to last 

vspj(i)=vspj(i)*1.1 

next 

 

解释如下: 

for i=0 to last--循环首,让循环变量i1开始,每次增加递增1循环执行循环体,直到i=last时跳出循环。 

vspj(i)=vspj(i)*1.1--循环体,这里只有一条语句,可以有多条语句。当i=0时,执行的是vspj(0)=vspj(0)*1.1,随着i的递增,最后一次执行的是vspj(last)=vspj(last)*1.1,共执行last+1次。 

next--循环尾,与for配套对应,执行到此处时,跳回到对应的循环首for重新执行。当for语句判断i=last+1时,for语句将会跳出循环,即跳过next,到next的下一条语句。 

5)执行完循环后,我们需要的所有运算都完成了,接着要做的是把VBS中的结果送回到金字塔公式系统中。 

ffl.vardata("spj")=vspj--按字面上通俗理解,本行意思是通过接口ffl.vardata(),让金字塔公式系统中的序列变量spj等于vbs中的数组vspj,即VBS中的数据传递到金字塔公式系统。 

6)金字塔公式系统输出spj,注意此时的spj已经不等于原来的序列收盘价了。

 

有关VBS公式更详细的说明和教程,请参阅我们的软件使用帮助。

示例:

交易系统:

背景:假定买入信号发生的条件是创200天新高,第一次达到条件时发出买入信号,略去随后的买入信号,利润目标是10%,最大亏损是8%,达到止赢止损点发出止损卖出信号,这样的交易系统可用VBS脚本语言实现。该实例综合应用了循环语句、条件语句和数组操作,请注意变量数据是怎样被转入、转出的。

请看代码:

 

{ 买入信号临时变量:收盘创200天新高 }

MYBUY:= CLOSE = HHV(CLOSE,200);

{ 初始化卖出信号临时数组变量给下面的脚本用,任意赋给一个有效数值起始位置为0的数组变量即可,注意,若SELL:=0则表示SELL为数值而非数组 }

MYSELL:= c;

{ 初始化收盘价临时数组变量给下面的脚本用 }

CLOSEPRICE:= CLOSE;

{   <% ......%> 嵌入脚本语言,类似编写ASP  }

<%

   ' 将公式系统变量转入VBScript

    close = FFL.VarData("CLOSEPRICE")

    buy = FFL.VarData( "MYBUY" )

    sell = FFL.VarData("MYSELL")

 

    ' 该变量保存买入价,也表示开仓、平仓状态。如为0则表示空仓(平仓)

    lastbuyprice = 0

 

    ' 遍历数组

    for i = 0 to UBound( close )

 

       sell( i ) = 0

       ' 若已买入而且未平仓略去随后的买入信号

       if( lastbuyprice > 0 ) then

          buy( i ) = 0

       end if

 

       '若满足买入条件取买入价,也用于设置开仓

       if ( lastbuyprice = 0 ) AND (buy( i ) = 1) then

          lastbuyprice = close( i )

       end if

 

       ' 若已买入且满足卖出条件,产生卖出信号并平仓

       if (lastbuyprice >0 ) AND ( ( close( i ) > ( 1.1 * lastbuyprice ) )  OR  ( close( i ) < ( 0.92 * lastbuyprice ) ) ) then

        

          sell( i ) = 1

          lastbuyprice = 0

       end if

 

    next

 

   ' VBScript变量转出为公式系统变量

    FFL.VarData("MYBUY") = buy

    FFL.VarData("MYSELL") = sell

%>

ENTERLONG: MYBUY;

EXITLONG: MYSELL;

有关VBS公式的更多描述信息,请参考帮助里的更详细描述。

有关VBS语法的更多帮助描述信息,请参阅帮助菜单中的“编程信息”。

 

第十二章 自定义函数

可以利用Visual Basic的优势,用来完成那些复杂逻辑以及迭代要求功能的函数,使用户不必借助DLL也可以进一步来扩充公式系统的功能。并且自定义函数的使用方法与其他函数是相同的。

自定义函数与VBS公式都是基于VBS的语法扩充,但是他们两个都有什么区别呢?

1VBS公式只能将VBS代码内嵌在公式模型中,用户只能使用VBS内置的语法和函数进行编程工作,VBS中的计算结果只能与该公式交互。但是自定义函数可以使用金字塔内置的全部对象,内容十分丰富,并且自定义函数可以在不同的公式模型中调用,就像一个普通的公式系统函数。

2VBS公式只支持序列模式运行,但是自定义函数可以在序列模式和逐周期模式两种情况下运行。

 

可以通过两种方法添加自定义函数:

1、在公式编辑器界面中,鼠标在自定义函数解释定义区单击右键,然后选择添加自定义函数

2、在Visual Basic工程管理器中选择Function模块,进入Visual Basic编辑界面,然后选择插入菜单中的过程

 

12.1自定义函数的格式

每个自定义函数都会有一个Formula对象,即使没有参数的自定义函数也至少有这么一个对象参数存在。每次公式系统执行遇到自定义函数的时候,会不断的依次调用它,直至整个公式解释完毕。

示例

创建一个计算CYC日收盘价移动平均线的自定义函数,CUSTOM_MA2(CYC),"添加自定义函数"对话框上名称输"CUSTOM_MA2",在参数位置输入"CYC"后单击确定,然后在随即弹出的VBS编辑器界面上,输入下面代码:

'计算指定周期长度的收盘价均价
Function CUSTOM_MA2(Formula,cyc)
    '
得到K线数据对象
Set History = Formula.ParentGrid.GetHistoryData()
'
若当前周期尚未到计算周期,不参与计算
if Formula.IndexData < cyc-1 then
  CUSTOM_MA2 = 0
  exit function
end if

DataCount = 0                       
    for i = Formula.IndexData-cyc+1 to Formula.IndexData
     '
累加收盘价
     DataCount = DataCount + history.close(i)
    next
CUSTOM_MA2 = DataCount / cyc
End Function

以上代码输入完毕后按下 Shift+F5启动VBS教本运行,然后就可以在公式编辑中使用我们刚刚创建的自定义函数了. 

 

12.2自定义函数的两种工作模式

金字塔公式系统工作两种模式,即序列和逐周期两种模式。序列模式公式系统每次刷新只会调用一次自定义函数,传递的参数数据类型有数组和常数两种,自定义函数根据自身的计算类型,返回一个数值或者一个数组。逐周期模式为从第1周期逐个周期解析公式系统,每个周期都会调用自定义函数一次,传递的参数只有数值类型,返回值也只有数值类型这一种,此时我们可以通过Formula.IndexData属性来得到当前执行到现在的周期。

序列模式由于解析时只会调用自定义函数一次,故效率是非常高的;逐周期模式,主要是为了实现具有头寸管理的交易系统而设计,可以实现我们通常的逐次加仓,多次平仓等算法,公式的编写灵活性很高,可以在公式里实现各种控制语句。

下面两个自定义公式示例,很好的说明了两种工作原理的不同:

 

'逐周期模式
Function CU_MA2(Formula,cyc)
   
'防止公式序列模式时调用
    If Formula.WorkMode = 1
        Exit Function
    End If
    '得到K线数据对象
    Set History = Formula.ParentGrid.GetHistoryData()
    '若当前周期尚未到计算周期,不参与计算
    if Formula.IndexData < cyc-1 then
    CU_MA2 = 0
        exit function
    end if

    DataCount = 0
    for i = Formula.IndexData-cyc+1 to Formula.IndexData
        '累加收盘价
        DataCount = DataCount + history.close(i)
    next
  
 '因为是每个周期都会调用一次,因此我们只要计算当前被执行的周期的均价即可
    CU_MA2 = DataCount / cyc
End Function

 

'序列运行模式
Function CU_MA1(Formula,CLOSE,Cyc)
    CU_MA1=0

   
'防止公式逐周期模式时调用
    If Formula.WorkMode = 0 Then
        Exit Function
    End If

   
'CLOSE数组数据长度一定会与Formula.DataSize-1相等
    DataCount = UBound(CLOSE)
    If DataCount <> Formula.DataSize-1 Then
        Exit Function
    End If

   
'定义一个计算返回的数组
    Dim ResultMa
    Redim ResultMa(DataCount)

    For i = Cyc-1 To Formula.DataSize-1
        Count = 0
        For k = i-(Cyc-1) To i
            Count = Count + CLOSE(k)
        Next
        ResultMa(i) = Count / Cyc
    Next

   
'返回一个计算完毕的均线数组
    CU_MA1 = ResultMa
End Function

大家注意到了序列模式多了一个CLOSE数组参数,在公式系统,他是这样被调用的
MA1:CU_MA1(CLOSE,5);
   
CLOSE的序列收盘价带到自定义函数中去执行。逐周期模式为什么就不带了?因为是每个周期都会执行,即便带入了CLOSE参数也是当前执行周期的价格,故意义不大,而是采用了公式中调用系统内部的收盘价数据计算。

注意:通常自定义函数只能执行一种模式的运算,不要在序列和逐周期这两种模式下混用。

有关自定义函数和VBS语法描述的更多帮助描述信息,请参阅帮助菜单中的“编程信息”

第十三章 DLL扩展函数程序调用接口

         对于熟悉C++的用户来说,可以通过DLL方式,编写函数,然后与金字塔的公式系统交互使用。DLL公式的使用方式例如如下方式:"DLLNAME@FNCNAME"(P1,P2) 引用DLLNAME.DLLFNCNAME函数,计算参数为P1,P2

         有关DLL扩展函数接口更详细的描述,请参阅帮助菜单中的“编程信息”中的有关描述。另外,在金字塔的安装目录 FmlDevelope.zip 压缩文件内包含了完整DLL扩展接口的接口示例以及在.H头文件里的接口使用信息描述。

第十四章 金字塔插件接口

      我们前面介绍的DLL扩展函数调用接口,只能是做为扩展函数的做法使用,存在灵活性不够,无法充分发挥C++优势,因此金字塔提供了功能和扩展性更强的接口规范,利用该接口规范,我们可以调用金字塔各种数据资源,得到系统的各种信息反馈例如成交回报等等,可以通过插件功能,极大扩展金字塔交易以及分析功能。

有关插件接口更详细的描述,请参阅帮助菜单中的“编程信息”中的有关描述。另外,在金字塔的安装目录AddinDemo.rar 压缩文件内包含了完整插件接口的接口示例以及在.H头文件里的接口使用信息描述。