TradeBlazer公式入门教程

更新时间:2023-12-25 18:21:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

TradeBlazer公式入门教程(1)

Step 1、在开始写公式之前,我们先了解以下基本概念

Bar数据:

公式在进行计算时,都是建立在基本数据源(Bar数据)之上,我们这里所谓的Bar数据,是指商品在不同周期下形成的序列数据,在单独的每个Bar上面包含开盘价、收盘价、最高价、最低价、成交量及时间。期货等品种还有持仓量等数据。所有的Bar按照不同周期组合,并按照时间从先到后进行排列,由此形成为序列数据,整个序列称之为Bar数据。 公式如何执行:

TradeBlazer公式在计算时按照Bar数据的Bar数目,从第一个Bar到最后一个Bar,依次进行计算,如果公式中出现了调用Bar数据函数的,则取出当前Bar的相应值,进行运算。公式执行从上至下,Bar从左到右执行。

Step 2、接下来,我们从TradeBlazer公式的HelloWorld开始 该贴前期已经发过,因此在此只给出链接: TradeBlazer公式的HelloWorld!

Step 3、建立一个简单的指标:成交量

对于交易开拓者界面不熟悉的朋友可以参看以下帖子: 如何在交易开拓者中编写技术指标?

新建指标简称: MyVol

1. 2. 3.

Begin

PlotNumeric(\End

复制代码

Begin和End宣告公式正文的开始和结束,公式语句应该放到Begin 和End之间。 并且总是以\作为语句结束的标志。

PlotNumeric表示输出一个数值型组成的数组;公式中“”内所引用的是字符串的常量,内容文字即在图表中所输出的技术指标的名称

关于PlotNumeric的使用 函数原形:

Numeric PlotNumeric(String Name,Numeric Number,Integer Color=-1,Integer BarsBack=0)

参数:

Name 输出值的名称,不区分大小写; Number 输出的数值;

Color 输出值的显示颜色,默认表示使用属性设置框中的颜色; BarsBack 从当前Bar向前回溯的Bar数,默认值为当前Bar。

技术指标属性的设置

在属性里的常规下填写公式的简称、名称、分类以及注释。也可更改参数等设置:

在“线型”里选择更改技术指标的输出形态,如线条、柱状图、十字图等,并且选择自己爱好的颜色,

以更加个性化的表现形式来迎合您的看盘习惯。 Step 4:

前面我们所建的技术指标MyVol,可以输出成交量,但成交量只能设置为属性所选的一种颜色。如下图:

很多朋友习惯于看红绿色表示涨跌的成交量。

下面我们来实现带红绿颜色的成交量指标,代码如下:

1. 2. 3.

Begin

PlotNumeric(“Vol”,Vol,IIf(Close>=Open,Red,Green)); End

复制代码

使用的情形如下: 关于IIF 函数原形:

Numeric IIF(Bool Conditon,Numeric TrueValue,Numeric FalseValue) 参数:

Conditon 条件表达式;

TrueValue 条件为True时的返回值; FalseValue 条件为False时的返回值。

针对上面的使用IIF进行成交量颜色指定的脚本, 我们还有另外一种写法:

1. Begin

2. 3. 4. 5. 6.

If(Close>=Open)

PlotNumeric(“Vol”,Vol,Red); Else

PlotNumeric(“Vol”,Vol,Green); End

复制代码

PlotNumeric由输出的名字来区分是否为同一条线!

关于IF语句

If语句是一个条件语句,当特定的条件满足后执行一部分操作。 语法如下:

If (Condition) {

TradeBlazer公式语句; }

TradeBlazer公式语句是一些语句的组合,如果TradeBlazer公式语句是单条,您可以省略{},二条或者二条以上的语句必须使用{}。

Step5

关于条件表达式 ?

逻辑操作符

逻辑运算符常常用于比较两个True/False的表达式,共有三个逻辑操作符:AND(&&),OR(||),NOT(!)。

表达式1 AND 表达式2 表达式1 OR 表达式2 NOT表达式1

如下图表所示可以让大家更清晰地理解逻辑操作符在表达式中的运算结果 Step6

前面第一贴已经讲过了IF语句,接下来要讲解条件语句的另外三种表达方式: If-Else If-Else-If If-Else的嵌套

关于If-Else语句

If-Else语句是对指定条件进行判断,如果条件满足执行If后的语句。否则执行Else后面的语句。

语法如下:

1. 2. 3. 4. 5. 6. 7.

If (Condition) {

TradeBlazer公式语句1; }Else {

TradeBlazer公式语句2; }

复制代码

Condition是一个逻辑表达式,当Condition为True的时候,TradeBlazer公式语句1将会被执行;Condition为False时,TradeBlazer公式语句2将会被执行。Condition可以是多个条件表达式的逻辑组合,Condition必须用()括起来。

TradeBlazer公式语句是一些语句的组合,如果TradeBlazer公式语句是单条,您可以省略{},二条或者二条以上的语句必须使用{}。

例如,比较当前Bar和上一个Bar的收盘价,如果Close > Close[1],Value1 = Value1 + Vol;否则Value1 = Value1 - Vol,脚本如下:

1. 2. 3. 4.

If (Close > Close[1]) Value1 = Value1 + Vol; Else

Value1 = Value1 - Vol;

复制代码

关于If-Else-If的语句

If-Else-If是在If-Else的基础上进行扩展,支持条件的多重分支。

语法如下:

1. 2. 3. 4. 5. 6. 7. 8. 9.

If (Condition1) {

TradeBlazer公式语句1; }Else If(Condition2) {

TradeBlazer公式语句2; }Else {

TradeBlazer公式语句3;

10. } 复制代码

Condition1是一个逻辑表达式,当Condition1为True的时候,TradeBlazer公式语句1将会被执行,Condition1为False时,将会继续判断Condition2的值,当Condition2为True时,TradeBlazer公式语句2将会被执行。Condition2为False时,TradeBlazer公式语句3将会被执行。Condition1,Condition2可以是多个条件表达式的逻辑组合,条件表达式必须用()括起来。

TradeBlazer公式语句是一些语句的组合,如果TradeBlazer公式语句是单条,您可以省略{},二条或者二条以上的语句必须使用{}。

If-Else-If的语句可以根据需要一直扩展,在最后的Else之后再加If(Condition)和新的执行代码即可。当然您也可以省略最后的Else分支,语法如下:

1. 2. 3. 4. 5. 6. 7.

If (Condition1) {

TradeBlazer公式语句1; }Else If(Condition2) {

TradeBlazer公式语句2; }

复制代码

If-Else的嵌套

If-Else的嵌套是在If-Else的执行语句中包含新的条件语句,即一个条件被包含在另一个条件中。

语法如下:

1. 2. 3. 4. 5. 6. 7. 8. 9.

If (Condition1) {

If (Condition2) {

TradeBlazer公式语句1; }Else {

TradeBlazer公式语句2; }

10. }Else 11. {

12. If (Condition3) 13. {

14. TradeBlazer公式语句3; 15. }Else 16. {

17. TradeBlazer公式语句4; 18. } 19. } 复制代码

Condition1是一个逻辑表达式,当Condition1为True的时候,将会继续判断Condition2的值,当Condition2为True时,TradeBlazer公式语句1将会被执行。Condition2为False时,TradeBlazer公式语句2将会被执行。当Condition1为False的时候,将会继续判断Condition3的值,当Condition3为True时,TradeBlazer公式语句3将会被执行。Condition3为False时,TradeBlazer公式语句4将会被执行。Condition1,Condition2,Condition3可以是多个条件表达式的逻辑组合,条件表达式必须用()括起来。

TradeBlazer公式语句是一些语句的组合,如果TradeBlazer公式语句是单条,您可以省略

{},二条或者二条以上的语句必须使用{}。

例如,在一个交易指令中,条件设置如下:当前行情上涨的时候,如果收盘价高于开盘价时,则产生一个以收盘价买入1张合约;否则产生一个以开盘价买入1张合约。当前行情没有上涨的时候,如果收盘价高于开盘价,则产生一个以收盘价卖出1张合约;否则产生一个以开盘价卖出1张合约。脚本如下:

1. 2. 3. 4. 5. 6. 7. 8. 9.

If (Open > High[1]) {

If (Close>Open) {

Buy(1,close); }Else {

Buy(1,open); }

10. }Else 11. {

12. If (Close > Open) 13. {

14. Sell(1,close); 15. }Else 16. {

17. Sell (1,open); 18. } 19. } 复制代码

Step7

现在再回到成交量指标

有人喜欢在成交量指标上加均线,我们来看如何实现这样的功能。

1. 2. 3. 4.

Begin

PlotNumeric(“Vol”,Vol);

PlotNumeric(“AvgVol5”,AverageFC(Vol,5)); End

复制代码

如下图中所示便是加了均线的成交量 Step8

关于Average和 AverageFC

Average和AverageFC都是内建的用户函数,目的都是用来求N个Bar以来的平均值,您可以直接看到实现的代码。 如下: Average

1. 2. 3. 4. 5. 6. 7. 8. 9.

Params

NumericSeries Price(1); Numeric Length(10); Vars

Numeric AvgValue; Begin

AvgValue = Summation(Price, Length) / Length; Return AvgValue; End

复制代码

AverageFC

1. 2. 3.

Params

NumericSeries Price(1); Numeric Length(10);

4. 5. 6. 7. 8. 9.

Vars

Numeric AvgValue; Begin

AvgValue = SummationFC(Price, Length) / Length; Return AvgValue; End

复制代码

Average和AverageFC有什么不同呢?AverageFC是指FastCalculate,即快速计算。当这两个函数的第二个变量,即N个Bar是常量时,使用AverageFC,提高计算效率。当N是不确定的变量时,则必须使用Average,否则会出现计算问题。

单看Average和AverageFC似乎是一样的,唯一不同的是AvgValue的计算方式用到的是Summation和SumamtionFC。

Summation和SumamtionFC

现在再来看看Summation与SumamtionFC的不同之处。公式表达如下:

Summation

1. 2. 3. 4. 5. 6. 7. 8. 9.

Params

NumericSeries Price(1); Numeric Length(10); Vars

Numeric SumValue(0); Numeric i; Begin

If (CurrentBar >= Length-1) {

10. for i = 0 to Length - 1 11. {

12. SumValue = SumValue + Price[i]; 13. }

14. }Else 15. {

16. SumValue = InvalidNumeric; 17. }

18. Return SumValue; 19. End 复制代码

SummationFC

1. 2. 3. 4. 5. 6. 7. 8.

Params

NumericSeries Price(1); Numeric Length(10); Vars

NumericSeries SumValue(0); Numeric i; Begin

If ( CurrentBar < Length || Price[Length] == InvalidNumeric || SumValue[1] == InvalidNumeric )

9. {

10. for i = 0 to Length - 1 11. {

12. SumValue = SumValue + Price[i]; 13. } 14. }Else 15. {

16. SumValue = SumValue[1] + Price - Price[Length] ; 17. }

18. Return SumValue; 19. End 复制代码

关于Average函数的参数

Numeric Average(NumericSeries Price, Numeric Length); Price 需要进行平均的序列变量 Length 平均时回溯的Bar数量

Step9

接下来我们再说一下常量与变量的定义 常量

是用来代替一个数或字符串的名称,在公式整个执行过程中不发生改变。 变量

是一个存储值的地址,当变量被声明之后,就可以在脚本中使用变量,可以对其赋值,也可以在其他地方引用变量的值进行计算,要对变量进行操作,直接使用变量名称即可。

变量的主要用处在于它可以存放计算或比较的结果,以方便在之后的脚本中直接引用运算的值,而无需重现计算过程。

例如,我们定义一个变量Y,我们把一个收盘价(Close)乘上8%的所得的值存储在Y中,即Y = Close *8%。那么一旦计算出Close * 8%的值,便赋给变量Y。而无需在公式中输入计算过程,只需调用变量名称即可引用变量的值。

变量有助于程序的优化,这是TradeBlazer公式必须重复调用一些数据,这些数据可能是某些函数(如:Bar数据),或通过表达式执行计算和比较的值。因此,在表达式频繁使用的地方使用变量可提高程序的运行速度和节约内存空间。

使用变量也可以避免输入错误,使程序的可读性提高,示例如下:

未使用变量的公式代码:

1. 2. 3. 4.

If(Close > High[1] + Average(Close,10)*0.5) {

Buy(100, High[1] + Average(Close,10)*0.5); }

复制代码

如果使用变量,则整个代码变得简洁:

1. 2. 3. 4. 5.

Value1 = High[1] + Average(Close,10)*0.5; If (Close > Value1) {

Buy(100,Value1); }

复制代码

如果一些表达式的组合经常在不同的公式中被调用,这个时候变量就不能实现功能,变量只能在单个公式的内部使用,这个时候我们需要建立用户函数来完成这些功能,详细说明参见用户函数(在TB软件里按F1便会出现联机帮助--公式系统--公式应用--用户函数)。

变量类型

TradeBlazer公式支持有三种基本数据类型:数值型(Numeric)、字符串(String)、布尔型(Bool)。为了通过用户函数返回多个值,我们对三种数据类型进行了扩展,增加了引用数据类型。另外,为了对变量,参数进行回溯,我们增加了序列数据类型。因此,我们的数据类型共有九种。但对于变量定义,引用类型是无效的,剩余六种数据类型中分为简单和序列两大类,简单类型变量是单个的值,不能对其进行回溯,序列类型变量是和Bar长度一致的数据排列,我们可以通过回溯来获取当前Bar以前的任意值。

9种数据类型

Bool 布尔型。 BoolRef 布尔型引用。

BoolSeries 和周期长度一致的Bool型序列值。 Numeric 数值型。 NumericRef 数值型引用。

NumericSeries 和周期长度一致的Numeric型序列值。 String 字符串。 StringRef 字符串引用。

StringSeries 和周期长度一致的String型序列值。

变量声明

在使用变量之前,必须对变量进行声明,TradeBlazer公式使用关键字\来进行变量宣告,并指定变量类型。可以选择赋默认值,也可以不赋默认值。

变量定义的语法如下:

1. 2. 3. 4.

Vars

变量类型 变量名1(初值); 变量类型 变量名2(初值); 变量类型 变量名3(初值);

复制代码

下面是一些变量定义的例子:

1. 2.

Vars

NumericSeries MyVal1(0); //定义数值型序列变量MyVal1,默认值为0;

3. Numeric MyVal2(0); //定义数值型变量MyVal2,默认值为0;

4. Bool MyVal3(False); //定义布尔型变量MyVal3,默认值为False;

5. String MyVal4(\定义字符串变量MyVal4,默认值为Test。

复制代码

变量定义的个数没有限制,变量名称的命名规范详细说明参见命名规则。

整个公式中只能出现一个Vars宣告,并且要放到公式的开始部分,在参数定义之后,正文之前。

变量的默认值

在声明变量时,通常会赋给变量一个默认值。例如上例中的0,False,\等就是变量的默认值。如果某个变量没有赋予默认值,系统将会自动给该变量赋予默认值。数值型变量的默认值为0,布尔型变量的默认值为False,字符串的默认值为空串。

变量的默认值是在当公式在执行时,给该变量赋予的初值,使该变量在引用时存在着有效的值。在该公式每个Bar的执行过程中,改变量的默认值都会被重新赋值。

变量赋值

变量声明完成之后,您可以在脚本正文中给变量指定一个值。

语法如下:

1. Name = Expression;

复制代码

\是变量的名称,表达式的类型可以是数值型、布尔型、字符串中的任何一种。不过表达式的类型一定要和变量的数据类型相匹配。如果变量被指定为是数值型的,那么表达式一定要是数值型的表达式。

例如:下面的语句将Close的10周期平均值赋值给变量Value1:

1. Value1 = Average(Close , 10);

复制代码

在下面这个语句中,声明了一个名为\的逻辑型变量,然后又把计算的值赋给它。

1. 2. 3. 4. 5. 6.

Vars

Bool KeyReversal(False); Begin

KeyReversal = Low < Low[1] AND Close > High[1]; ... End

复制代码

变量使用

变量定义、赋值之后,在表达式中直接使用变量名就可以引用变量的值。例如在下面的语句

中计算了买入价格后,把值赋给数值型变量EntryPrc,在买入指令中便可直接应用变量名,通过变量名便可引用变量的值:

1. 2. 3. 4. 5. 6. 7. 8. 9.

Vars

Numeric EntryPrc(0); Begin

EntryPrc = Highest(High,10); If (MarkerPosition <> 1) {

Buy(1,EntryPrc); } End

复制代码

接下来的例子,我们计算最近10个Bar最高价中的最大值(不包括当前Bar),对比当前High,然后通过If语句,产生报警信息。

1. 2. 3. 4. 5. 6. 7. 8. 9.

Vars

Bool Con1(False); Begin

Con1 = High > Highest(High[1],10); If(Con1) {

Alert(\ } End

复制代码

其实我们并不一定都要应用条件为True的情况,有时候我们需要判断条件为False的时候执行某些代码,如下的例子:

1. 2. 3.

Vars

Bool Con1(False); Begin

4. 5. 6. 7. 8. 9.

Con1 = High < Highest(High[1],10) AND Low > Lowest(Low[1],10); If(Con1==False) {

Alert(\ } End

复制代码

序列变量

1. 2. 3. 4.

Vars

NumericSeries MyNumSVal(0);

BoolSeries MyBoolVal(False); StringSeries MyStrVal(\

复制代码

序列变量和简单变量一样,可以对其赋予默认值。

序列变量定义之后,您可以象简单变量一样的对其使用,不会有任何的不同。除了支持全部简单变量的功能之外,序列变量还可以通过\来回溯以前的变量值,详细说明参见变量回溯。

对于序列变量,TradeBlazer公式在内部针对其回溯的特性作了很多的特殊处理,也需要为序列变量保存相应的历史数据,因此,和简单变量相比,执行的速度和占用内存空间方面都作了一些牺牲。因此,尽管您可以定义一个序列变量,把它当作简单变量来使用,但是,我们强烈建议您只将需要进行回溯的变量定义为序列变量。

成交量指标的扩充

回到成交量指标上,在成交量和均线的基础上再增加输出一条线,显示成交量和5日均线的差值。

1. 2. 3.

Params

Numeric Length(5); Begin

4. 5. 6. 7.

PlotNumeric(“Vol”,Vol);

PlotNumeric(“AvgVol”,AverageFC(Vol, Length)); PlotNumeric(“VolDiff”,Vol-AverageFC(Vol,Length)); End

复制代码

这样的写法效率较低,因此我们引入变量来进行处理。

对成交量指标的优化

我们通过使用变量来使代码变得简洁,并提高执行效率。上面的公式修改如下:

1. 2. 3. 4. 5. 6. 7. 8. 9.

Params

Numeric Length(5); Vars

Numeric AvgVol5; Begin

AvgVol5 = AverageFC(Vol, Length); PlotNumeric(\

PlotNumeric(\ PlotNumeric(\

10. End 复制代码

如下图所示是增加了差值的成交量: Step10

回到加均线的成交量指标

刚才的成交量指标输出的5周期均线,有的人希望使用10周期均线,为了方便使用,我们使用参数来处理这种需求。

1. 2.

Params

Numeric Length(5);

3. 4. 5. 6.

Begin

PlotNumeric(“Vol”,Vol);

PlotNumeric(“AvgVol”,AverageFC(Vol, Length)); End

复制代码

在上述公式中只要将参数Numeric Length后面的数值(5)改成(10)便可以啦。

关于参数

参数

参数是一个预先声明的地址,用来存放输入参数的值,在声明之后,您就可以在接下来的公式中使用该参数的名称来引用其值。

参数的值在公式的内部是不能够被修改,在整个程序中一直保持不变,不能对参数进行赋值操作(引用参数是个特例)。参数的好处在于您可以在调用执行技术分析,交易指令的时候才指定相应的参数,而不需要重新编译。

例如,我们常用的移动平均线指标,就是通过不同的Length来控制移动平均线的周期,在调用指标时可以随意修改各个Length的值,使之能够计算出相对应的移动平均线。您可以指定4个参数为5,10,20,30计算出这4条移动平均线,也可以修改4个参数为10,22,100,250计算出另外的4条移动平均线。

参数的修改很简单,在超级图表调用指标的过程中,您可以打开指标的属性设置框,切换到参数页面,手动修改各项参数的值,然后应用即可(如下图),交易开拓者将根据新的参数设置计算出新的结果,在超级图表中反映出来。

另外,参数的一个额外的优点是,我们可以通过修改交易指令不同的参数,计算交易指令组合的优劣,达到优化参数的目的。 参数类型

在介绍参数类型之前,我们需要对于TradeBlazer公式的六种类型作一些说明,用户函数是六种公式中比较特殊的一类,它自身不能被超级图表,行情报价这样的模块调用,只能被其他五类公式或者用户函数调用,因此它的参数类型也和其他几种不一样。

用户函数的参数类型可以包含TradeBlazer公式的九种类型,而其他五类公式只能使用三种简单的基本类型。

三种简单类型参数通过传值的方式将参数值传入公式,公式内部通过使用参数名称,将参数值用来进行计算或赋值。

引用参数是在调用的时候传入一个变量的地址,在用户函数内部会修改参数的值,在函数执行完毕,上层调用的公式会通过变量获得修改后的值,引用参数对于需要通过用户函数返回多个值的情况非常有用。

序列参数可以通过回溯获取以前Bar的值,具体介绍可参见参数回溯。 参数声明

在使用参数之前,必须对参数进行声明,TradeBlazer公式使用关键字\来进行参数宣告,并指定参数类型。可以选择赋默认值,也可以不赋默认值。如果某个参数没有赋予默认值,则这个参数之前的其他参数的默认值都将被忽略。

参数定义的语法如下:

1. 2. 3. 4.

Params

参数类型 参数名1(初值); 参数类型 参数名2(初值); 参数类型 参数名3(初值);

复制代码

下面是一些参数的例子:

1. 2.

Params

Bool bTest(False); //定义布尔型参数bTest,默认值为False;

3. Numeric Length(10); //定义数值型参数Length,默认值为10;

4. NumericSeries Price(0); //定义数值型序列参数Price,默认值为0;

5. NumericRef output(0); //定义数值型引用参数output,默认值为0;

6. String strTmp(\定义字符串参数strTmp,默认值为Hello;

复制代码

参数名称的命名规范详细说明参见命名规则。

整个公式中只能出现一个Params宣告,并且要放到公式的开始部分,在变量定义之前

参数的默认值

在声明参数时,通常会赋给参数一个默认值。例如上例中的False,10,0等就是参数的默认值。用户函数的默认值是在当用户函数被其他公式调用,省略参数时作为参数的输入值,其他五种公式的默认值是用于图表,报价等模块调用公式时默认的输入值。

参数的默认值的类型在定义的时候指定,默认值在公式调用的时候传入作为参数进行计算。只能够对排列在后面的那些参数提供默认参数,例如:

1. 2. 3. 4.

Params

Numeric MyVal1; Numeric MyVal2(0); Numeric MyVal3(0);

复制代码

您不能够使用以下方式对参数的默认值进行设定:

1. 2. 3. 4.

Params

Numeric MyVal1(0); Numeric MyVal2(0); Numeric MyVal3;

复制代码

参数的使用

在声明参数之后,我们可以在脚本正文中通过参数名称使用该参数,在使用的过程中要注意保持数据类型的匹配,示例如下:

1. 2. 3. 4. 5. 6. 7. 8.

Params

NumericSeries Price(1); Vars

NumericSeriss CumValue(0); Begin

CumValue = CumValue[1] + Price; Return CumValue; End

复制代码

在以上的公式中,首先定义了一个数值型序列参数Price,并将其默认值设置为1。接着定义了一个变量CumValue。脚本正文中,将CumValue的上一个Bar值加上Price,并将值赋给CumValue,最后返回CumValue。

通过上述的公式可以看到,我们只需要调用参数名,就可以使用参数的值进行计算了,如果要对序列参数进行回溯,请参见参数回溯。 引用参数

TradeBlazer公式的用户函数可以通过返回值,返回函数的计算结果,返回值只能是三种简单类型。当我们需要通过函数进行计算,返回多个值的时候,单个的返回值就不能满足需求了。在这种情况下,我们提出了引用参数的概念,引用参数是在调用的时候传入一个变量的地址,在用户函数内部会修改参数的值,在函数执行完毕,上层调用的公式会通过变量获得修改后的值。因为引用参数的使用是没有个数限制,因此,我们可以通过引用参数返回任意多个值。

例如,用户函数MyFunc如下:

1. Params

2. 3. 4. 5. 6. 7. 8. 9.

NumericSeries Price(0); NumericRef oHigher(0); NumericRef oLower(0); Vars

Numeric Tmp(0); Begin

Tmp = Average(Price,10);

oHigher = IIf(Tmp > High,Tmp,High);

10. oLower = IIf(Tmp < Low,Tmp,Low); 11. Return Tmp; 12. End 复制代码

以上代码通过两个数值型引用参数返回10个周期的Price平均值和最高价的较大值oHigher,以及10个周期的Price平均值和最低价的较小值oLower,并且通过函数返回值输出10个周期的Price平均值。在调用该用户函数的公式中,可以通过调用该函数获得3个计算返回值,示例如下:

1. 2. 3. 4. 5. 6. 7. 8.

Vars

Numeric AvgValue; Numeric HigherValue; Numeric LowerValue; Begin

AvgValue = MyFunc(Close,HigherValue,LowerValue); ... End

复制代码

Step11

创建稍复杂的指标

我们以MACD指标为例,介绍一般指标的写法。

MACD的技术指标包含参数,变量和正文三部分。

如下所示:

MACD输出4条线。包括线条和变色柱状线及零线。

Step12

关于价差指标-Spread 如何进行商品叠加?

交易开拓者的超级图表支持商品叠加的显示,当叠加的图表调用各项公式时,可能有需要使用叠加的商品对应的基础数据,针对这样的需求,TradeBlazer公式提供了叠加数据的支持。详细请参照贴子如何在超级图表中叠加商品,并进行价差运算 价差指标的公式代码

下面我们就举一个简单例子,两个商品以收盘价来计算的价差:

1. 2. 3. 4. 5. 6.

Begin

If(Data0.Close != InvalidNumeric && Data1.Close != InvalidNumeric) {

PlotNumeric(\ } End

复制代码

有些人习惯将价差作为K线形式表现出来,如下图所示:

图中蓝线就代表了两个商品收盘价的价差

关于在价差基础上扩展出的SpreadEX

有些人还习惯于将不同商品的开盘价、收盘价、最高价以及最低价的价差再集中体现在同一图表上,如下例:

1. 2. 3. 4. 5. 6.

Begin

If(Data0.Close !=InvalidNumeric && Data1.Close != InvalidNumeric0 {

PlotNumeric(\ PlotNumeric(\

PlotNumeric(\

max(Data0.High

-

Data1.High,Data0.Low - Data1.Low); 7.

PlotNumeric(\

min(Data0.High

-

Data1.High,Data0.Low - Data1.Low)); 8. 9.

} End

复制代码

最后这四个指标在两个商品中的价差得到的K线图示如下:

Step13

数据回溯

在TradeBlazer公式中有三种类型的数据回溯:变量回溯、参数回溯和函数回溯。

如何使用回溯表达? XXX[nOffset]

nOffset是要回溯引用的Bar相对于当前Bar的偏移值,该值必须大于等于0,当nOffset = 0时,即为获取当前Bar的参数值。并且nOffset不能大于当时的CurrentBar,这样会导致数据访问越界。造成不可预知的计算结果。

变量回溯

TradeBlazer公式共支持九种数据类型,但对于变量定义,引用类型是无效的,剩余六种数据类型中分为简单和序列两大类,简单类型变量是单个的值,不能对其进行回溯,序列类型变量是和Bar长度一致的数据排列,我们可以通过回溯来获取当前Bar以前的任意值。

要使用变量回溯,需要在变量的后面,使用中括号\,nOffset是要回溯引用的Bar相对于当前Bar的偏移值,该值必须大于等于0,当nOffset = 0时,即为获取当前Bar的变量值。

例如,我们定义如下技术指标:

1. 2. 3. 4. 5. 6.

Vars

NumericSeries MyVal; Begin

MyVal = Average(Close,10); PlotNumeric(\End

复制代码

以上公式定义数值型序列变量MyVal,MyVal等于收盘价的10个周期的平均值,然后将序列变量MyVal的前3个Bar数据输出。

以上公式MyVal的前9个数据因为需要计算的Bar数据不足,返回无效值,从第10个Bar开始,MyVal获取到正确的平均值,但是我们需要输出的数据是MyVal[3],即前3个Bar的数据,因此,直到第12个Bar,有效的数据才会被输出。以上公式的12是该公式需要的最少引用周期数,如果将输出信息画到超级图表中,前11个Bar是没有图形显示的。

当nOffset>CurrentBar或者nOffset<0时,对于变量的回溯都将越界,这种情况下,将返回无效值。 参数回溯

TradeBlazer公式支持的九种基本类型,在用户函数的参数定义中全部支持,在其他的公式

5. 6. 7. 8. 9.

Numeric AvgValue; Begin

AvgValue = Summation(Price, Length) / Length; Return AvgValue; End

复制代码

对于使用多个输出的情况,即使用引用参数的情况,我们以求N周期最大值为例进行描述,假定我们需要编写一个用户函数,该函数需要求出序列变量Price在最近Length周期内的最大值,并且要求出最大值出现的Bar和当前Bar的偏移值。脚本如下:

1. 2. 3. 4. 5. 6. 7. 8. 9.

Params

NumericSeries Price(1); Numeric Length(10); NumericRef HighestBar(0); Vars

Numeric MyVal; Numeric MyBar; Numeric i; Begin

10. MyVal = Price; 11. MyBar = 0;

12. For i = 1 to Length - 1 13. {

14. If ( Price[i] > MyVal) 15. {

16. MyVal = Price[i]; 17. MyBar = i; 18. } 19. }

20. HighestBar = MyBar; 21. Return MyVal; 22. End

复制代码

用户函数的调用

用户函数成功创建之后(编译/保存成功),您可以在其他的用户函数、技术分析、交易指令等公式中调用用户函数,调用用户函数时需要注意保持参数类型的匹配,即用户函数参数的声明数据类型需和调用时传入参数的数据匹配,这是所指的匹配是指基本数据类型:数值型,布尔型,字符串三种类型匹配,并且保持序列参数和传入变量类型的对应。我们可以对用户函数定义为Numeric或者NumericRef的参数使用Numeric类型的变量作为传入参数;但不能将在定义为NumericSeries类型的参数时传入Numeric。具体的对应关系如下表:

对于函数的返回值,您也可以将用户函数的Numeric返回值赋值给NumericSeries或NumericRef变量。即在用户函数的返回值使用时,忽略其扩展数据类型。比如我们在调用Average求平均值时,可以这样调用:

1. 2. 3. 4. 5. 6.

Vars

Numeric Value1; Begin

Value1 = Average(Close,10); ... End

复制代码

我们也可以按照以下方式进行调用:

1. 2. 3. 4. 5. 6.

Vars

NumericSeries Value1; Begin

Value1 = Average(CloseTmp,10); ... End

复制代码

A用户函数调用自身,我们称之为直接递归;A用户函数可以调用B用户函数,同时B用户函数也可以调用A用户函数,对于这种的情况,我们称之为间接递归;

不管是直接递归还是间接递归,用户函数在执行的时候,都可能遇到递归调用没有出口,导致死循环的情况。因此,我们在编写公式的时候,要注意避免使用递归算法,如果一定需要使用递归算法,要注意保证递归算法都有出口。

用默认参数调用用户函数

用户函数在被调用的时候,如果传入的参数和参数的默认值一样,可以省略输出参数,使用默认值来调用用户参数。只能够对排列在后面的那些参数使用默认参数,默认参数的定义参见参数。

对于用户函数的直接递归调用,默认参数调用有一些特殊的意义,如下所示,用户函数Fun1:

1. 2. 3. 4. 5. 6. 7. 8. 9.

Params

NumericSeries Price(1); Vars

Numeric CumValue(0); Begin

If(CurrentBar == 0) {

CumValue = Price; }else

10. {

11. CumValue = Fun1[1] + Price; 12. }

13. Return CumValue; 14. End 复制代码

技术指标Ind1调用Fun1的代码如下:

1. Value1 = Fun1(Close);

复制代码

以上的用户函数通过默认参数调用Fun1的意思不是调用Fun1(1),而是将Ind1调用Fun1的Close传递下去,即求Fun1(Close)的上一个Bar的值。以上Ind1调用Fun1的计算结果和调用如下的Fun2计算结果一致。

用户函数Fun2:

1. 2. 3. 4. 5. 6. 7. 8. 9.

Params

NumericSeries Price(1); Vars

Numeric CumValue(0); Begin

If(CurrentBar == 0) {

CumValue = Price; }else

10. {

11. CumValue = Fun1(Close)[1] + Price; 12. }

13. Return CumValue; 14. End 复制代码

Step16

用户字段

用户字段因为暂时还末用到,所以这部分就先跳过不讲了

技术指标

技术指标是最常用的一类公式,它通过计算一系列的数学公式,在每个Bar都返回值,这些

值在图表模块中输出为线条、柱状图、点等表现形式,通过分析图形特点、走势和曲线帮助客户分析行情走势,得出合理的交易判断。

当技术指标应用在图表中时,您可以设置技术指标各输出值的表现形式,以及颜色、粗细等,如下图的点,线,柱状图所示:

技术指标的使用规则归纳如下:

支持三种基本类型的参数定义,支持指定参数默认值;

不支持使用引用参数;

支持六种类型的变量定义,支持指定变量的默认值;

可以访问Data0-Data49个数据源的Bar数据;

可以访问行情数据、属性数据;

必须通过PlotNumeric、PlotBool、PlotString返回数据,返回数据类型为三种基本类型的组合;

可以输出多组数据,通过PlotNumeric、PlotBool、PlotString的第一个参数,即输出名称来区分输出数据;

可以支持Alert来进行报警;

技术指标可以调用所有的用户函数进行计算;

技术指标可以根据设置调用部分的系统函数;

技术指标在执行时,必须要指定相应的数据源和周期,需要调用历史数据的,只有历史数据存在的情况下才能返回正确的值。

示例,技术指标RSI,脚本如下:

1. 2. 3. 4. 5. 6. 7. 8. 9.

Params

Numeric Length(14); Numeric OverSold(20); Numeric OverBought (80); Vars

Numeric RSIValue(0); Numeric RSIColor(-1); Begin

RSIValue = RSI(Close,Length);

10. If (RSIValue > OverBought) 11. {

12. RSIColor = RED;

13. }Else If (RSIValue < OverSold) 14. {

15. RSIColor = CYAN; 16. }

17. PlotNumeric(\18. PlotNumeric(\超卖\19. PlotNumeric(\超买\20.

21. If CrossOver(RSIValue,OverSold) 22. {

23. Alert(\24. }

25. If CrossUnder(RSIValue, OverBought) 26. {

27. Alert(\28. } 29. End 复制代码

技术指标RSI调用RSI内建用户函数计算出结果,然后判断其返回值和超买,超卖的关系,设置显示颜色,并产生报警信息。

技术指标在输出数据时,我们是通过输出值的名称来进行识别,名称相同则认为是一个数据,如下的代码,后面语句的输出数据将会覆盖前面语句的输出数据。

1. 2.

PlotNumeric(\PlotNumeric(\

复制代码

最后\输出的数据为20,而不是10。

K线型态

K线型态是另外一种形式的技术分析公式,它对满足设定条件的Bar进行标记,使之醒目,便于客户进行分析。

当K线型态应用在图表中时,您可以设置其输出值的颜色、风格和粗细,如图所示:

K线型态的使用规则归纳如下:

支持三种基本类型的参数定义,支持指定参数默认值;

不支持使用引用参数;

支持六种类型的变量定义,支持指定变量的默认值;

可以访问Data0-Data49个数据源的Bar数据;

可以访问行情数据、属性数据;

必须通过PlotBar返回数据;

只能输出一组数据,用名称进行区分;

可以支持Alert来进行报警;

K线型态可以调用所有的用户函数进行计算;

K线型态可以根据设置调用部分的系统函数;

K线型态在执行时,必须要指定相应的数据源和周期,需要调用历史数据的,只有历史数据存在的情况下才能返回正确的值。

示例,K线型态十字星,脚本如下:

1. 2. 3. 4. 5. 6. 7. 8. 9.

Vars

Bool Condition(False); Begin

Condition = (Abs(Close-Open)*10<(High-Low)) And (High <> Close) And (Low <> Close); If (Condition) {

PlotBar(\ }

10. End 复制代码

K线型态十字星判断条件,条件满足的情况下用PlotBar输出信息。

特征走势

特征走势是另外一种形式的技术分析公式,它对满足设定条件的Bar进行标记,使之醒目,便于客户进行分析。特征走势和K线型态有很多相似之处,最大的不同在于,K线型态和特征走势的数据输出方式。

当特征走势应用在图表中时,您可以设置其输出值的表现形式,以及颜色、风格和粗细,如

图所示:

特征走势的使用规则归纳如下:

支持三种基本类型的参数定义,支持指定参数默认值;

支持使用引用参数;

支持六种类型的变量定义,支持指定变量的默认值;

可以访问Data0-Data49个数据源的Bar数据;

可以访问行情数据、属性数据;

必须通过PlotNumeric、PlotBool、PlotString返回数据,返回数据类型为三种基本类型的组合;

只能输出一组数据,用名称进行区分;

可以支持Alert来进行报警;

特征走势可以调用所有的用户函数进行计算;

特征走势可以根据设置调用部分的系统函数;

特征走势在执行时,必须要指定相应的数据源和周期,需要调用历史数据的,只有历史数据存在的情况下才能返回正确的值。

示例,特征走势创历史新高,脚本如下:

1. 2. 3. 4.

Params

Numeric Length(5); Vars

Bool Condition(False);

5. 6. 7. 8. 9.

Begin

Condition = (High ==Highest(High,Length)) ; If (Condition) {

PlotNumeric(\

10. } 11. End 复制代码

特征走势创历史新高判断条件,条件满足的情况下用PlotNumeric、PlotBool、PlotString输出信息。

交易指令

TradeBlazer公式提供一种简单的方法表达您的交易思想,那就是使用交易指令,一个简单的交易指令如下:

1. 2.

If (Condition) Buy (1,Close);

复制代码

以上的语句表达的意思是:当某些条件满足了,将用当前Bar的收盘价买入1手指定商品。就像您平时通过经纪商进行交易操作一样,TradeBlazer公式提供四个系统函数和现实中的四种交易动作进行对应,如下:

交易指令的使用规则归纳如下:

支持三种基本类型的参数定义,支持指定参数默认值;

不支持使用引用参数;

支持六种类型的变量定义,支持指定变量的默认值;

可以访问Data0-Data49个数据源的Bar数据;

可以访问行情数据、属性数据;

通过Buy、Sell、SellShort和BuyToCover产生交易动作,也可以使用各种内建平仓指令产生交易动作;

每个交易指令至少包含一个交易动作;

交易指令可以调用所有的用户函数进行计算;

交易指令可以根据设置调用部分的系统函数;

交易指令在执行时,必须要指定相应的数据源和周期,需要调用历史数据的,只有历史数据存在的情况下才能返回正确的值。

示例,交易指令MACD_LE,脚本如下:

1. 2. 3. 4. 5. 6. 7. 8. 9.

Params

Numeric FastLength( 12 ); Numeric SlowLength( 26 ); Numeric MACDLength( 9 ); Numeric BuyLots(1); Vars

NumericSeries MACDValue; NumericSeries AvgMACD; Numeric MACDDiff;

10. Bool Condition1; 11. Bool Condition2; 12. Begin

13. MACDValue = XAverage( Close, FastLength ) -

14. XAverage( Close, SlowLength ) ; 15. AvgMACD = XAverage(MACDValue,MACDLength); 16. MACDDiff = MACDValue - AvgMACD;

17. Condition1 = CrossOver(MACDValue, AvgMACD) ;

18. Condition2 = MACDValue > 0; 19. if (Condition1 And Condition2) 20. {

21. Buy(BuyLots,Close); 22. } 23. End 复制代码

MACD_LE在零轴之上,当MACDValue向上穿过AvgMACD值时为产生多头买入指令。

关于Delay

默认情况下,4个交易函数产生的委托单即时发送;当参数Delay=True时,委托单将延迟到下一个Bar发送,这样设计的原因在于:只有延迟的委托单才会保证发送的交易指令的正确性。

假定在某商品A的周期为5分钟的数据上应用交易指令,A商品每1秒钟会产生一个Tick数据,因此一段时间内(<5分钟)A商品最后一个Bar的数据的收盘价,最高价,最低价以及成交量等数据,会随着Tick的变化和累计而产生相应的变化。在某种情况下,上一个Tick更新时,Buy的预设条件可能为False,下一个Tick更新时,Buy的预设条件为True。如果不延迟,将会马上发送该委托单到交易所。但是,当更多的Tick累计,产生一个新的Bar时,Buy的预设条件可能会变成False。在这种情况,前面产生的委托单将会丢失,不会在测试和优化报表中出现。该委托单实际上是由于噪音数据产生的错误讯号导致,为了避免这种情况的出现,一定要等最后Bar数据更新结束之后,新Bar产生第一个Tick时,才会发送上一个Bar产生的委托单。

当交易函数的延迟设置为False。将会实时发送产生的委托单,按Tick进行更新。在使用该参数时,需要确认自己所编写的公式不会用到这些无效的中间数据,从而影响交易结果。 注意: Delay参数对交易会产生重要的影响,请在确认理解含义之后才进行真实的交易。 关于内建平仓指令

除了上节的Sell和BuyToCover可以进行平仓之外,TradeBlazer公式提供了额外的八种平仓函数,通过合理的应用内建平仓函数,可以帮助您有效的锁定风险并及时获利。

您可以组合使用内建平仓函数,也可以在自己的交易指令中调用内建平仓函数进行平仓,八个内建平仓函数如下:

关于ExitPosition

上述多个平仓函数都用到了参数ExitPosition,作为平仓函数仓位控制的重要参数,有必要对该参数进行单独说明。

ExitPosition是布尔型参数,当ExitPosition=True时,表示将当前所有的持仓作为一个整体,根据其平均建仓成本,计算各平仓函数的盈亏,当条件满足时,会将所有仓位一起平掉;当ExitPosition=False时,表示单独对每个建仓位置进行平仓,单独计算各平仓函数盈亏时,当单个建仓位置条件满足后,平掉该建仓位置即可。

Step17

在技术分析中设置报警

公式报警

TradeBlazer公式提供报警功能,您可以在3类技术分析(技术指标,K线型态,特征走势)

中通过Alert函数来实现报警。

您可以在这3类公式中按照以下方式来编写自己的报警:

1.

2.

Vars

Bool Condition1;

3.

Begin

4. 5.

Condition1 = 您设定的条件表达式; If(AlertEnabled AND Condition1)

6.

7.

{

Alert(\报警信息...\

8. 9.

} End

复制代码

当公式编译保存成功之后,您可以将其应用在超级图表中,通过报警属性页(帮助--公式系统--TradeBlazer公式应用--公式属性)启动报警。当条件满足之后,将会产生报警信息,并发送到消息中心(帮助--系统基础--消息中心)。

Step18

交易策略-完整的交易系统

通常单个交易指令只完成建仓或平仓的单个动作,而一个完整的交易策略应该至少包含建仓、平仓交易指令,并且根据需要加上止损,获利等锁定风险和收益的交易指令。多个交易指令的组合才能更加有效的帮助我们完整的进行交易,因此,我们将多个交易指令的有效组合称之为交易策略。

交易策略的运行机制

假定我们创建一个交易策略,该交易策略由以下交易指令组成,并按照如下顺序应用到超级图表中。

当我们将该交易策略应用到超级图表上时,TradeBlazer公式将会从图表的第一个Bar开始执行交易策略,在第一个Bar上首先执行多头建仓指令A,可能会产生交易委托(开仓),该委托可能被设置为在当前Bar执行,也可以被设置为延迟到下一个Bar执行。当多头建仓指令A执行完成之后,将按顺序调用多头平仓指令B,同时该指令会判断当前的持仓状态,仓位等信息,当条件满足的时候会产生交易委托(平仓)。依次执行止损平仓指令C和获利平仓指令D,当四个交易指令在第一个Bar上都执行完之后,将会移到第二个Bar执行,这时候,系统会首先读取上一个Bar是否有延迟的交易委托,如果有延迟的交易委托,对这些委托先进行处理,然后像第一个Bar一样,依次调用各个交易指令。以此类推,从图表的第一个Bar到最后一个Bar,全部执行完成之后,整个交易策略执行完毕。在整个执行过程产生的所有交易委托被保存下来供超级图表模块显示或进行性能测试分析。

当交易策略应用在超级图表中时,您可以设置交易策略开平仓的显示风格以及颜色、线条等, 使之显示在超级图表中,如下图所示:

交易策略测试引擎

为了真实准确的模拟交易策略在过去时段的表现,并能在实时数据更新时使交易策略沿着预定的方向发展,TradeBlazer公式提供了一个强大的交易策略测试引擎,该处理引擎收集交易策略在历史过程中产生的所有委托单,将其应用在对应的图表中,并能根据交易设置创建交易策略性能测试报表供客户参考。

交易策略测试引擎包括了两大功能:历史数据测试和实时自动交易。历史数据测试分析交易策略在历史过程中的交易动作并计算出交易盈亏,收益等性能指数。实时自动交易收集实时数据,并根据实时数据生成相应的交易动作,条件满足时,将委托单直接发送到交易券商。

Step19

交易策略参数优化

在超级图表中插入一个或一个以上交易指令后,菜单和工具栏中的交易策略参数优化选项将会有效,您可以通过点击菜单项或工具栏使用该功能。

交易策略参数优化模块可对多个交易指令组合的所有参数进行优化,您可以通过参数设置界面对需要优化的参数进行设置,界面如下: 参数优化目标有以下七种选项:

净利润最大: 以优化结果中的净利润最大为目标,保留指定数量的记录数; 交易次数最大: 以优化结果中的交易次数最大为目标,保留指定数量的记录数; 平均净利润最大: 以优化结果中的平均净利润最大为目标,保留指定数量的记录数; 盈利因子最大: 以优化结果中的盈利因子最大为目标,保留指定数量的记录数; 收益率最大: 以优化结果中的收益率最大为目标,保留指定数量的记录数; 盈亏比率最大: 以优化结果中的盈亏比率最大为目标,保留指定数量的记录数; 回报率最大: 以优化结果中的回报率最大为目标,保留指定数量的记录数。 通过双击参数项或点击参数设置按钮,对选中的参数项进行步长设置,界面如下: 您可以设置参数的最小值,步长及最大值,系统将会根据设置,产生从最小值到最大值之间按步长分布的参数列表。

在各项参数设置完成之后,点击确定按钮,将会进行参数优化的计算,参数优化计算过程中会显示优化的进程,时间,当前参数,最优参数以及优化目标等信息,您可以通过点击取消按钮终止计算。

寻找最优的参数。需防止过度优化。 寻找最稳定的系统。而不是最大化的系统。

注意: 根据优化参数设置的多少,优化时间可能长达几小时甚至数天,优化过程中,CPU将会大量被占用,您可以选择空闲的时间进行大量参数优化计算。 参数优化计算完成之后,将会显示出最优的记录,您可以通过工具栏的交易设置按钮修改交易参数,也可以通过重新优化按钮进行重新计算。

Step20

交易策略性能测试

在超级图表中插入一个或一个以上交易指令后,菜单和工具栏中的交易策略测试报表选项将会有效,您可以通过点击菜单项或工具栏使用该功能。 交易策略测试报表界面如下:

帐户分析按照五个方面对帐户进行分析,包括交易汇总、交易分析、交易记录、平仓分析、阶段总结、资产变化、图表分析和系统设置。

交易汇总:按照多头交易、空头交易和全部交易列出当前交易策略的交易统计信息。 交易分析:对当前策略的交易情况进行分析,包括交易分析、盈亏分析和连续盈亏分析。

交易记录:按开仓平仓对所有交易进行配对组合,并计算盈亏及累计盈亏。 平仓分析:按平仓记录对交易情况进行分析和汇总。

阶段总结:按年、月对交易盈亏及次数进行统计。 资产变化:列出资产的变化记录及统计信息。

图表分析:按资产图表和盈亏图表两大类共十三小类对帐户进行图表分析。 系统设置:显示交易策略的参数,设置以及数据等内容。

本文来源:https://www.bwwdw.com/article/afcx.html

Top