TB编程从入门到进阶_第1页
TB编程从入门到进阶_第2页
TB编程从入门到进阶_第3页
TB编程从入门到进阶_第4页
TB编程从入门到进阶_第5页
已阅读5页,还剩100页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1TB编程从入门到进阶

2公式基础知识1交易策略实现4技术指标编写2TB编程进阶5

TB公式基本概念什么是TB公式?

TB公式类型用户函数公式应用(包括技术指标、交易指令等)如何创建和应用公式?公式导入(*.fbk)

或新建公式应用,粘贴代码,校验保存公式(编译)打开超级图表,选择交易品种,插入公式应用

修改公式应用设置启动自动策略交易系统3

Bar数据(K线数据)当前时间周期下所有K线的相关数据,按照时间从先到后的顺序排列而成的序列数据。每根K线中包含的数据如下:4Bar数据含义Date当前K线的日期Time当前K线的开始时间Open当前K线的开盘价High当前K线的最高价Low当前K线的最低价Close当前K线的收盘价(最新价)Vol当前K线成交量OpenInt当前K线持仓量CurrentBar当前K线的索引值(K线的编号,从0开始)BarStatus当前K线的状态值(0—第一根K线、2—最后即最新一根K线、1—其他K线)

Bar数据的使用Bar数据是TB公式运行的基础。Bar数据是序列数据,可以回溯读取(图示)。举例:

比较今天的最高价是否突破了昨天的最高价

表达式为:High>High[1]比较今天的最高价是否突破了前两天的最高价

表达式为:High>High[1]andHigh>High[2]

或者:High>High[1]&&High>High[2]5

序列数据6序列变量序列变量序列变量序列变量序列变量序列变量序列变量序列变量序列变量序列变量序列变量序列变量NN-1…210

非序列变量(简单变量)7

非序列变量

TB公式运行机制从左到右,从上到下

8

盘中和盘后公式运行的差别盘后公式的执行情况分析

K线是确定的,不存在信号消失问题;公式在每根K线上只执行一遍;

符合开仓条件和平仓条件会标出买卖信号(使用Buy、Sell指令),但并不真正发单;盘中公式的执行情况分析K线是变化的,如用最新价或基于最新价计算出的指标来作为入场或出场条件会出现信号消失问题;每当分笔交易数据(tick)传来时,公式都会执行一遍;

符合开仓条件和平仓条件除标出买卖信号,还会真正发单;

有些函数和数据只有盘中才能支持,盘后不支持。

TB公式的结构TB的公式一般由三段组成。Params NumericLength(10);公式参数段 ……Vars

NumericSeriesMA;公式变量段 ……Begin MA=AverageFC(Close,Length);公式脚本段 ……End10例1:HelloWorldSample1:Begin FileAppend("c:\\tb\\sample1.txt","HelloWorld!");End实验1:Sample1实验目标:通过学习,掌握在TB中如何新建公式应用,如何编译和使用公式。实验步骤:TB公式

新建公式应用

输入公式简称

选择适当的模板;在公式编辑器中,输入sample1的代码;点击工具栏中的“校验保存公式”进行代码编译;新建超级图表,鼠标右键

插入公式应用;到指定文件路径,查看文件内容。公式运行结果大家都知道每个HelloWorld!都是怎么产生的吗?例2:输出BAR数据Sample2:Begin FileAppend(“c:\\tb\\sample2.txt","Date="+DateToString(Date) +"Time="+TimeToString(time) +"Close="+Text(Close) +"CurrentBar="+Text(CurrentBar) +"Barstatus="+Text(BarStatus));End例2运行结果

参数的作用

假如我们要写一个均线指标,现在是用10天做周期。代码如下: Begin PlotNumeric("MA",AverageFC(Close,10)); End那如果要改用20天做周期,我们必须改程序,把10改成20,然后编译。下次想用别的周期,还得改,非常麻烦。如果使用参数,就方便多了。程序写好,使用时改参数就好了。代码如下:

Params NumericLength(10); Begin

PlotNumeric("MA",AverageFC(Close,Length)); End数据类型TB公式中有三种基本的数据类型

数值型(Numeric)

字符型(String)

布尔型(Bool)为了对变量、参数进行回溯,又增加了序列类型

数值型序列变量/参数(NumericSeries)

字符型序列变量/参数(StringSeries)

布尔型序列变量/参数(BoolSeries)为了通过用户函数返回多个值,又增加了引用类型

数值型引用(NumericRef)

字符型引用(StringRef)

布尔型引用(BoolRef)

参数的声明和使用参数在使用前必须进行声明,声明方法如下:Params NumericLength(10); StringFilename("D:\\sample2.log");

bool

OutputToFile(false);公式应用和用户函数的参数略有不同:公式应用的参数只支持三种基本类型,用户函数的参数支持全部九种类型;公式应用的参数一定要有初始值,而用户函数的参数可以没有默认值;参数的值在公式的脚本段中只能引用,不能修改;

变量变量的主要用处在于它可以存放计算或比较的结果,以方便在之后的脚本中直接引用运算的值,而无需重现计算过程。变量在使用前必须进行声明,声明方法如下:

Vars

NumericSeriesMA; NumericStopline(30);变量的赋值(变量类型和表达式的类型要一致)

变量名称=表达式;

例如:MA=AverageFC(Close,10);

常用数据类型转换函数(1)数值型转字符型:StringText(Numericvalue)

例如:Text(1.2345)返回值为"1.2345"字符型转数值型:NumericValue(String

str)

例如:Value("1.2345")返回值为1.2345根据布尔型值返回转字符型或数值型:NumericIIF(Bool

Conditon,Numeric

TrueValue,Numeric

FalseValue)

例如:IIF(Close>Open,Close,Open);StringIIFString(Bool

Conditon,String

TrueValue,String

falseValue)

例如:IIFString(Close>Open,"阳线","阴线");

常用数据类型转换函数(2)日期时间值转字符型:

StringDateTimeToString(Numeric

dtDateTime)

例如:

DateTimeToString(20040612.114323)="2004-06-1211:43:23"

日期值转字符型:StringDateToString(Integer

nDate)时间值转字符型:StringTimeToString(Numeric

fTime)将字符串转化为日期时间:

NumericStringToDateTime(String

str)例如:StringToDateTime("2003-02-2312:24:55")=20030223.122455将字符串转化为日期:IntegerStringToDate(String

str)将字符串转化为时间:IntegerStringToTime(String

str)例3:使用参数和变量Sample3:Params StringFilename("c:\\tb\\sample3.txt");Vars Numericchange;Begin change=Close-Close[1];

FileAppend(Filename,"Date="+DateToString(Date) +"Time="+TimeToString(time) +"Close="+Text(Close) +"涨跌:"+text(change));End例3运行结果

变量的存续周期简单变量在每次公式运行时,被赋默认值,公式运行过程中存在,公式运行完后不再存在;序列变量的生存周期V3和V4略有区别:V3:每次公式运行时,序列变量被赋默认值,公式运行完后仍然存在,但下次如果还是同一根Bar运行公式的话,变量值又会被赋成默认值;V4:每次公式运行时,除了第一根BAR会被赋默认值,其他BAR会自动传递上一根BAR的值,公式运行完后仍然存在,但下次如果还是同一根BAR运行公式的话,变量值又会传递上一根BAR的值;只有一根BAR的最后一个Tick公式运行完后,序列变量的值才能保留下来。24例4:变量的存续周期差别Sample4:Vars Numericjdbl;

NumericSeries

xlbl;Begin FileAppend("c:\\tb\\sample4.txt","Bartime=" +DateTimeToString(date+time) +"\tCurrentTime="+TimeToString(Currenttime) +"\t公式运行前Jdbl="+Text(jdbl) +"xlbl="+Text(xlbl));

jdbl=jdbl+1;

xlbl=xlbl+1; FileAppend("c:\\tb\sample4.txt","Bartime=" +DateTimeToString(date+time) +"\tCurrentTime="+TimeToString(Currenttime) +"\t公式运行后Jdbl="+Text(jdbl) +"xlbl="+Text(xlbl));End实验2:Sample4实验目标:通过实验,理解TB中简单变量和序列变量的区别,了解简单变量和序列变量的存续周期;学习如何设置图表的K线样本数。实验步骤:新建公式应用,在公式编辑器中,输入Sample4的代码;新建超级图表,任意选择一个交易品种,

设置时间周期,鼠标右键点击图表,进入“商品设置”,选择商品合约后,点“属性”,修改样本数为“10”后确定返回;插入公式应用Sample4;打开Sample4.txt,分析和思考在盘后K线和实时K线中简单变量和序列变量值的变化过程以及产生的原因。

Sample4运行结果1

Sample4运行结果2(实时)注释语句--CommentaryTB的信息输出,除了可以通过FileAppend输出到文件外,也可以将信息输出显示到图表上;Commentary的用法:

在超级图表的当前BAR添加一行注释信息;参数:String

strTip;//提示的信息例5:改写例2Sample5:Begin

Commentary("Date="+DateToString(Date));

Commentary("Time="+TimeToString(time));

Commentary("Open="+Text(Open));

Commentary("High="+Text(High));

Commentary("Low="+Text(Low));

Commentary("Close="+Text(Close));

Commentary("CurrentBar="+Text(CurrentBar));

Commentary("Barstatus="+Text(BarStatus));End例5运行结果

控制语句条件语句(If-Else)if语句if-else语句if-Elseif语句if-Else嵌套循环语句(For\While)For循环变量=初始值TO结束值For循环变量=初始值Downto

结束值While循环条件语句----IFElse语句语法如下:If(Condition){

TB公式语句1;}Else{

TB公式语句2;}如果TB公式语句是单条,您可以省略{},二条或者二条以上的语句必须使用{}。For语句1For语句是一个循环语句,重复执行某项操作,直到循环结束。语法如下:For循环变量=初始值To结束值{

TradeBlazer公式语句;}For循环的执行是从循环变量从初始值到结束值,按照步长为1递增,依次执行TradeBlazer公式语句,结束值必须大于或等于初始值才有意义。For语句2如果希望For语句从大到小进行循环,可以使用以下的语法:For循环变量=初始值DownTo

结束值

{

TradeBlazer公式语句;}For-DownTo让循环变量从结束值每次递减1直到等于结束值,依次调用TradeBlazer公式语句执行,初始值必须大于或等于结束值才有意义。

例6:For语句求和及均线Sample6:Params NumericLength(10);Vars NumericSumValue(0); NumericMA; Numerici;Begin

SumValue=0; fori=0toLength-1 {

SumValue=SumValue+Close[i]; } MA=SumValue/Length;

Commentary("SumValue="+text(SumValue));

Commentary("MA="+Text(MA));EndWhile循环While语句在条件为真的时候重复执行某一项操作。即,只要条件表达式的值为真(True)时,就重复执行某个动作。直到行情信息改变以致条件为假(False)时,循环才结束。

语法如下:While(Condition){

TradeBlazer公式语句;}Continue和Break

例7:BarsSinceTodaySample7:(求当天第一根Bar到现在的BAR数)Vars NumericTodayBars;Begin

TodayBars=0; While(CurrentBar>TodayBarsand

date[TodayBars]==date[TodayBars+1]) {

TodayBars=TodayBars+1; }

Commentary("TodayBars="+text(TodayBars));End

BarsSinceToday的算法Vars

NumericSeries

ReBars;Begin

If(CurrentBar==0||Date!=Date[1]) {

ReBars=0; }Else {

ReBars=ReBars+1; } ReturnReBars;End40公式基础知识1交易策略实现4技术指标编写2TB编程进阶541技术指标输出函数(1)

PlotNumeric–在当前BAR输出一个数值

参数:StringName-----输出值的名称;

NumericNumber-----输出的数值;

NumericLocator=0-----输出值的定位点;

IntegerColor=-1-----输出值的颜色;

IntegerBarsBack=0-----从当前BAR回溯的BAR数举例: PlotNumeric(“MA”,AverageFC(Close,10));

输出均线指标值

PlotNumeric(“OpenToClose”,open,close);

输出开盘价与收盘价的连线(线型选择柱状图)42技术指标输出函数(2)

PlotString–在当前BAR输出一个字符串

参数:StringName-----输出值的名称

Stringstr-----输出的字符串;

NumericLocator=0-----输出值的定位点;

IntegerColor=-1-----输出值的颜色;

IntegerBarsBack=0-----从当前BAR回溯的BAR数举例:

PlotString("CandleStick","阳线",Low,Red);

在Bar的最低价位置输出字符串“阳线”,并显示为红色43技术指标输出函数(3)

PlotBool–在当前BAR输出一个布尔值

参数:StringName-----输出值的名称

Bool

bPlot-----输出的布尔值;

NumericLocator=0-----输出值的定位点;

IntegerColor=-1-----输出值的颜色;

IntegerBarsBack=0-----从当前BAR回溯的BAR数举例:

PlotString(“con",con,High);

在Bar的最高价位置输出布尔变量con的值,如果con为真,则显示“笑脸”图标,否则显示为“哭脸”图标实验3:Sample8实验目标:通过实验,学习TB中技术指标的编写;掌握PlotNumeric、PlotString和PlotBool函数的用法;掌握正确设置技术指标的属性。实验步骤:新建公式应用,在公式编辑器中,输入Sample8的代码;点击“文件”-》“属性设置”-》在“常规”中选择“主图显示”,在线型中针对不同的线选择适当的线型、粗细和颜色等等,然后“校验保存公式”;新建超级图表,选择交易品种和时间周期,插入公式应用;观察指标的输出结果。45例8:自编指标的输出Sample8:

单均线加通道指标Params NumericLength(10); //均线周期

NumericFilterPercent(20); //通道幅度比例(%%)Vars

NumericSeriesMA;

NumericSeries

UpperBand;

NumericSeries

LowerBand;

Bool

ConBuy(False);

Bool

ConSell(False);Begin MA=AverageFC(Close,Length);

UpperBand=MA*(1+FilterPercent/10000);

LowerBand=MA*(1-FilterPercent/10000);46

PlotNumeric("MA",MA,0,Yellow); PlotNumeric("UpperBand",UpperBand,0,Red); PlotNumeric("LowerBand",LowerBand,0,Green);

ConBuy=CrossOver(Close,UpperBand);

ConSell=CrossUnder(Close,LowerBand); if(ConBuy) {

PlotBool("ConBuy",ConBuy,High+(High-Low)*0.3);

PlotString("BS","多头突破",High+(High-Low)*0.6,red); } if(ConSell) {

PlotBool("ConSell",!ConSell,Low-(High-Low)*0.3);

PlotString("SS","空头突破",Low-(High-Low)*0.6,Green); }End47

Sample8运行结果

48指标编写常见问题指标编写完成后,还要注意在属性设置中进行相应的设置;指标是在主图显示还是在子图显示;指标的线型;从V3转到V4的客户注意参数的位置另外学习的例子可以参考:MACD指标的写法(柱状图)SAR指标(点图)49公式基础知识1交易策略实现4技术指标编写2TB编程进阶5

TB用户函数

用户函数是可以通过名称进行调用的一组语句的集合,实际应用中一般将某些经常需要用到的功能做成用户函数以方便以后编程时调用;用户函数一般有一个返回值,类型可以是三种基本类型之一;用户函数通过参数传入数据,通过返回值或引用型变量返回值;用户函数间可以相互调用,也可以递归调用;用户函数分为内建用户函数和其他用户函数,内建用户函数可以查看和调用,不能修改;

例9:求平均值

Sample9:这是求平均值的内建用户函数,其中就调用了summation函数Params

NumericSeriesPrice(1); NumericLength(10);Vars NumericAvgValue;Begin

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

例10:求极值

Sample10:这是求极值的内建用户函数,其中就用到了引用参数Params

NumericSeriesPrice(1); NumericLength(10);

Bool

bMax(True);

NumericRef

ExtremeBar; Vars

NumericSeries

MyVal;

NumericSeries

MyBar; Numerici;Begin

MyVal=Price;

MyBar=0;

If(CurrentBar<=Length-1||MyBar[1]==Length-1) { fori=1toLength-1 { If(bMax)

{ If(Price[i]>MyVal) {

MyVal=Price[i];

MyBar=i; } }Else { If(Price[i]<MyVal) {

MyVal=Price[i];

MyBar=i; } } } }Else { If(bMax) { If(Price>=MyVal[1]) {

MyVal=Price;

MyBar=0; }Else

{

MyVal=MyVal[1];

MyBar=MyBar[1]+1; } }Else { If(Price<=MyVal[1]) {

MyVal=Price;

MyBar=0; }Else {

MyVal=MyVal[1];

MyBar=MyBar[1]+1; } } }

ExtremeBar=MyBar; ReturnMyVal;End序列函数序列函数是一种特殊的用户函数,当它的参数或变量中使用了序列变量时,我们就称之为序列函数;序列数据作为普通计算机语言和TB语言的重要区别,是进行金融序列数据计算的的核心;为保证序列数据的正确计算,序列函数需要每个BAR都调用,否则序列函数中的序列数据会不正确;除非算法需要,否则建议不要在条件语句内、循环语句内以及包含逻辑运算符的条件表达式中使用序列函数。56公式基础知识1交易策略实现4技术指标编写2TB编程进阶557交易指令–Buy/Sell

Buy--平掉所有空头持仓,开多头仓位;sell--平掉指定多头持仓;

Sellshort--平掉所有多头持仓,开空头仓位;

Buytocover--平掉指定空头持仓。

参数:NumericShare买入数量,默认=0时,使用系统设置参数NumericPrice买入价格,为浮点数,默认=0时为使用现价(非最后Bar为Close)。58交易指令

A_SendOrder针对当前公式应用的帐户、商品发送委托单。该函数直接发单,不经过任何确认,并会在每次公式计算时发送,一般需要配合着仓位头寸进行条件处理,在不清楚运行机制的情况下慎用。不能使用于历史测试,仅适用于实时行情交易。参数:BuyOrSell

:买卖类型,买Enum_Buy/卖Enum_Sell;EntryOrExit:开平仓类型,开仓Enum_Entry/平仓Enum_Exit /平今Enum_ExitToday;fLot

委托单的交易数量;fPrice

委托单的交易价格。

叠加多个商品合约进行交易TB可以在一个图表中插入多个商品合约,支持同时对多个商品合约数据源编写公式应用。具体的方法是在交易指令、BAR数据及系统函数前加上数据源。TB中数据源的命名规则如下:Data0:图表中最开始选择的商品合约Data1:第一个插入的商品合约Data2:第二个插入的商品合约……一个图表最多支持50个数据源;调用方法:

Data1.A_SendOrder(…)Data2.Buy(….) Data3.CloseData4.MarketPosition

59

交易常用系统函数介绍IntegerMarketPosition()---获得当前的持仓状态返回值为整型。返回值定义如下: -1当前位置为持空仓

0当前位置为持平

1当前位置为持多仓

这个函数用来配合Buy/Sell指令工作,对A_SendOrder无效。IntegerBarsSinceEntry()---获得当前持仓的第一个建仓位置到当前位置的Bar计数。只有当MarketPosition!=0时,即有持仓的状况下,该函数才有意义,否则返回0;在开仓Bar上为0。60

Bool

CrossOver(NumericSeriesPrice1,NumericSeriesPrice2)---求Price1是否上穿Price2返回值为布尔型。Price1和Price2必须为数值型序列值。Bool

CrossUnder(NumericSeriesPrice1,NumericSeriesPrice2)---求Price1是否下穿Price2返回值为布尔型。Price1和Price2必须为数值型序列值。61信号消失问题(1)产生原因:使用变化的价格(如Close)或是基于最新价Close计算的技术指标,来作为交易的进场、出场或止损条件时,就会产生信号消失问题。如果编写的公式策略中存在信号闪烁问题,在历史测试中会得出失真的测试结果,在实盘交易时,更会因为重复发单造成严重损失。信号消失问题的一般解决办法:延迟发单或用前一根K线的数据来做为判断条件用能保持得住的价格来做为判断条件信号消失问题(2)用前一根K线做判断举例: condition=交易条件 If(condition[1]) { Buy(1,Open); }用High,Low,Open等做判断If(High>High[1]){ buy(1,High[1]);}

例11:双均线系统交易规则:如果短期均线上穿长期均线,做多,如原来持有空单,则先平空单,再建多仓如果短期均线下穿长期均线,做空,如原来持有多单,则先平多单,再建空单短周期:10长周期:20交易头寸暂为1手64

实现代码Sample11:Params

NumericLength1(10); NumericLength2(20); NumericLots(1);Vars

NumericSeriesMA1;

NumericSeriesMA2;

BoolSeries

condBuy(false);

BoolSeries

condSell(false);Begin MA1=AverageFC(Close,Length1); MA2=AverageFC(Close,Length2);65

PlotNumeric("MA1",MA1); PlotNumeric("MA2",MA2);

condBuy=CrossOver(MA1,MA2);

condSell=CrossUnder(MA1,MA2); If(MarketPosition<>1andcondBuy[1]==true)

Buy(Lots,Open); If(MarKetPosition<>-1andcondSell[1]==true) SellShort(lots,Open);End6667公式基础知识1交易策略实现4技术指标编写2TB编程进阶5

止盈止损策略的实现止盈止损的设置有多种方法,常见的有:固定点数价格百分比进场价的一定比例;平均波动范围的一定比例;形态判断下面以固定点数止损,进场价的一定比例止盈为例,来实现它。68

例12:止盈止损的代码Sample12:Params NumericTakeProfit(1);//百分比NumericStopLoss(20);Vars NumericMinPoint; NumericMyEntryPrice; NumericMyExitPrice;Begin

MinPoint=MinMove*PriceScale;

MyEntryPrice=AvgEntryPrice; if(MarketPosition==1) { if(High>=MyEntryPrice*(1+TakeProfit*0.01)) {

MyExitPrice=MyEntryPrice*(1+TakeProfit*0.01); if(open>MyExitPrice)MyExitPrice=Open; Sell(0,MyExitPrice);69

}Elseif(Low<MyEntryPrice-Stoploss*MinPoint) {

MyExitPrice=MyEntryPrice-Stoploss*MinPoint; if(Open<MyExitPrice)MyExitPrice=Open; Sell(0,MyExitPrice); } }Elseif(MarketPosition==-1) { if(Low<=MyEntryPrice*(1-TakeProfit*0.01)) {

MyExitPrice=MyEntryPrice*(1-TakeProfit*0.01); if(open<MyExitPrice)MyExitPrice=Open; BuyToCover(0,MyExitPrice); }ElseIf(High>MyEntryPrice+Stoploss*MinPoint) { MyExitPrice=MyEntryPrice+Stoploss*MinPoint; if(Open>MyExitPrice)MyExitPrice=Open; BuyToCover(0,MyExitPrice); } }End70

追踪止盈策略的实现追踪止盈的设置也有多种方法,常见的有:峰值价回落固定点数峰值价回落一定的百分比峰值价的一定比例;平均波动范围的一定比例;开盘价的一定比例。是否盈利达到一定幅度才启用追踪止盈;动态的回落点数或比例。下面以峰值价回落一定比例为例,来实现它。71

例13:追踪止盈的代码Sample13:Params

NumericTrailingStop(1);//跟踪止损百分比Vars

NumericMinPoint; NumericMyExitPrice;

NumericSeries

HigherAfterEntry;

NumericSeries

LowerAfterEntry; NumericStopLine(0);Begin if(BarsSinceEntry==1) {

HigherAfterEntry=AvgEntryPrice;

LowerAfterEntry=AvgEntryPrice; }ElseIf(BarsSinceEntry>1) {

HigherAfterEntry=Max(HigherAfterEntry[1],High[1]);

LowerAfterEntry=Min(LowerAfterEntry[1],Low[1]); }72

Else {

HigherAfterEntry=HigherAfterEntry[1];

LowerAfterEntry=LowerAfterEntry[1]; }

MinPoint=MinMove*PriceScale;

If(MarketPosition==1) {

StopLine=HigherAfterEntry*(1-TrailingStop*0.01);

If(Low<=StopLine) {

MyExitPrice=StopLine-MinPoint;

If(Open<MyExitPrice)MyExitPrice=Open; Sell(0,MyExitPrice); } }ElseIf(MarketPosition==-1) {

StopLine=LowerAfterEntry*(1+TrailingStop*0.01);

If(High>=StopLine) {

MyExitPrice=StopLine+MinPoint;

If(Open>MyExitPrice)MyExitPrice=Open; BuyToCover(0,MyExitPrice); } }End7374应注意的问题如果单根K线的最高价和最低价相差很大,有可能出现止盈和止损同时满足的情况,解决办法:切换到更小的时间周期上进行交易;扩大止盈和止损的幅度在开仓BAR,因无法判断开仓价和最高价最低价的先后顺序,因此一般是在开仓BAR的后一根BAR才开始判断是否满足止盈止损或跟踪止盈的的条件。如交易策略需要及时的止损,同样需要切换到更小的时间周期上进行交易。

K线波动太大的问题进场位置和盈利峰值价计算开盘价最低价追踪止损价盈利峰值价止损没被止损

开盘价进场的追踪止损开盘价(进场价)最低价追踪止损价以进场价作为盈利峰值价止损

再进场策略的设计使用止损止盈或追踪止盈出场后,如果趋势没有改变,我们仍然需要再进场的策略以避免错失大的波段趋势;可以考虑的再入场的方法有:价格创出新高或新低,再次入场;出场后一定时间后,大趋势仍未改变则再次入场;出场后大趋势未改变,其他辅助指标出现和大趋势一致的进场信号时再次入场。下面以出场后一定时间后大趋势仍未改变即再次入场的方法来举例。78

跟踪止盈后,我们要设个标志,表示曾经出场过,因此要增加两个布尔型序列变量;

BoolSeries

bLongStoped(false);

BoolSeries

bShortStoped(false);跟踪止盈后,设置这两个变量;//多头跟踪止盈后

If(Low<=StopLine) {

…… Sell(0,MyExitPrice);

bLongStoped=true; }//空头跟踪止盈后

If(High>=StopLine) {

…… BuyToCover(0,MyExitPrice);

bShortStoped=true; }79

这两个序列变量值必须往下传递(V4中可以免写)

if(BarStatus>0) {

bLongStoped=bLongStoped[1];

bShortStoped=bShortStoped[1]; }多头或空头初次进场和再次进场后,都要将这两个变量复位;

bLongStoped=false;

bShortStoped=false;为了配合再进场,我们需要记录当前的趋势方向,以例9的双均线交叉为例,我们需要增加以下代码:

if(condBuy==falseandcondSell==false) {

condBuy=condBuy[1];

condSell=condSell[1]; }80

追踪止盈后的等待时间,我们可用止盈后的K线根数来衡量。因为我们止盈后bLongStoped或bShortStoped会被置为True,因此我们可通过一个函数NthCon来寻找跟踪止盈的那根BAR到现在的BAR数。具体止盈后多少根BAR后趋势还在持续再进场,我们可以设置为一个参数:BarsReEntry。多头再进场部分的代码如下

BarsAfterLongExit=NthCon(!bLongStoped,1);

Commentary("BarsAfterLongExit="+text(BarsAfterLongExit));

If(bLongStopedandMarketPosition==0andcondBuy[1]==true andBarsAfterLongExit>=BarsReEntry) {

Buy(Lots,Open);

bLongStoped=False;

HigherAfterEntry=Open; }81例14:双均线完整策略Sample14:例11加上跟踪止盈和再进场策略Params

NumericLength1(10); NumericLength2(20); NumericLots(1); NumericTrailingStop(1); //跟踪止损百分比

NumericBarsReEntry(5); //出场后趋势维持多少根Bar后再进场Vars

NumericSeriesMA1;

NumericSeriesMA2;

BoolSeries

condBuy(false);

BoolSeries

condSell(false); NumericMinPoint; NumericMyExitPrice;

NumericSeries

HigherAfterEntry;

NumericSeries

LowerAfterEntry; NumericStopLine(0);

BoolSeries

bLongStoped(false);

BoolSeries

bShortStoped(false); NumericBarsAfterLongExit(0); NumericBarsAfterShortExit(0);Begin

/*if(BarStatus>0)//V4中可以省略的序列变量传递部分 {

bLongStoped=bLongStoped[1];

bShortStoped=bShortStoped[1]; }*/

Commentary("bLongStoped="+IIFString(bLongStoped,"true","false"));

Commentary("bShortStoped="+IIFString(bShortStoped,"true","false")); if(BarsSinceEntry==1) {

HigherAfterEntry=AvgEntryPrice;

LowerAfterEntry=AvgEntryPrice; }ElseIf(BarsSinceEntry>1) {

HigherAfterEntry=Max(HigherAfterEntry[1],High[1]);

LowerAfterEntry=Min(LowerAfterEntry[1],Low[1]); } Else {

HigherAfterEntry=HigherAfterEntry[1];

LowerAfterEntry=LowerAfterEntry[1]; }

MA1=AverageFC(Close,Length1); MA2=AverageFC(Close,Length2); PlotNumeric("MA1",MA1); PlotNumeric("MA2",MA2);

condBuy=CrossOver(MA1,MA2);

condSell=CrossUnder(MA1,MA2); if(condBuy==falseandcondSell==false) {

condBuy=condBuy[1];

condSell=condSell[1]; } If(MarketPosition<>1andcondBuy[1]==trueandbLongStoped==false) {

Buy(Lots,Open);

HigherAfterEntry=Open;

bLongStoped=false;

bShortStoped=false; } If(MarKetPosition<>-1andcondSell[1]==trueandbShortStoped==false) {

SellShort(lots,Open);

LowerAfterEntry=Open;

bLongStoped=false;

bShortStoped=false; }

BarsAfterLongExit=NthCon(!bLongStoped,1);

Commentary("BarsAfterLongExit="+text(BarsAfterLongExit));

If(bLongStopedandMarketPosition==0andcondBuy[1]==true andBarsAfterLongExit>=BarsReEntry) {

Buy(Lots,Open);

bLongStoped=False;

HigherAfterEntry=Open; Return; }

BarsAfterShortExit=NthCon(!bShortStoped,1);

Commentary("BarsAfterShortExit="+text(BarsAfterShortExit));

If(bShortStopedandMarketPosition==0andcondSell[1]==true andBarsAfterShortExit>=BarsReEntry) {

SellShort(Lots,Open);

bShortStoped=False;

LowerAfterEntry=Open; Return; }

MinPoint=MinMove*PriceScale;

If(MarketPosition==1) {

StopLine=HigherAfterEntry*(1-TrailingStop*0.01);

If(Low<=StopLine) {

MyExitPrice=StopLine-MinPoint;

If(Open<MyExitPrice)MyExitPrice=Open; Sell(0,MyExitPrice);

bLongStoped=true; } }ElseIf(MarketPosition==-1) {

StopLine=LowerAfterEntry*(1+TrailingStop*0.01);

If(High>=StopLine) {

MyExitPrice=StopLine+MinPoint;

If(Open>MyExitPrice)MyExitPrice=Open; BuyToCover(0,MyExitPrice);

bShortStoped=true; } }End实验4:Sample14实验目标:通过实验,学习TB中交易策略的编写;理解交易策略中具体的进场、出场、再进场、再出场规则的设计思路和代码实现;掌握公式应用的全局设置以及交易品种费率的调整;掌握历史回测和参数优化工具的使用。实验步骤:新建公式应用,输入Sample14的代码,编译通过;打开超级图表,选好品种和时间周期,插入公式应用;右键点击图表-》商品设置-》交易-》修改保证金率和佣金比率;右键点击图表-》公式应用设置-》全局交易设置;点击“工具”-》投资组合性能测试报告,进行历史测试;点击“工具”-》交易策略参数优化报告,进行参数优化。全局变量序列变量的缺陷序列变量在每个BAR只能有一个值,这个值在行情更新时,会不断刷新,直到最后一个Tick才能将值保存下来;因此,序列变量无法记录盘中每个Tick运行公式产生的数据;比如:我们要对每个Tick计数,用序列变量就做不到。全局变量全局变量通过SetGlobalVar和GetGlobalVar函数来设置和读取,TBV4中单个公式应用可以支持500个全局变量;Bool

SetGlobalVar(Integer

nIndex,Numeric

fVal)

参数:nIndex---全局变量的索引值

fVal---要设置的变量的值

如:SetGlobalVar(0,1)将0号全局变量设置为1;NumericGetGlobalVar(Integer

nIndex)获取某个索引的全局变量值

全局变量的初始值为无效值,它的值不会因为当前BAR的变化而变化,而只能由SetGlobalVar函数来设置;全局变量依附在超级图表上,一旦关掉超级图表后,所有与该图表有关的全局变量将不复存在;全局变量值的变化只跟SetGlobalVar的执行顺序有关,因此在图表上进行刷新时,必须考虑因公式重新运行导致的全局变量值的变化。

例15:记录BAR的tick数Sample15:Vars

NumericSeries

SeTickCnt; NumericTickCnt; NumericGlobTickCnt; Numericbartime;Begin

bartime=GetGlobalVar(0); if(CurrentBar==0||bartime==InvalidNumeric) {

bartime=date+time; SetGlobalVar(0,bartime);

TickCnt=1;

SeTickCnt=1;

GlobTickCnt=1; SetGlobalVar(1,GlobTickCnt); FileAppend("c:\\tb\\Sample15.txt","Bartime="+DateTimeToString(date+time) +"计数器初始化,全局变量时间="+DateTimeToString(bartime) +"TickCnt="+Text(tickcnt)+"SeTickCnt="+Text(SeTickCnt) +"GlobTickCnt="+Text(GlobTickCnt)); }elseif(Date+Time>bartime)

{

bartime=Date+Time; SetGlobalVar(0,bartime);

TickCnt=1;

SeTickCnt=1;

GlobTickCnt=1; SetGlobalVar(1,GlobTickCnt); FileAppend("c:\\tb\\Sample15.txt","Bartime="+DateTimeToString(date+time) +"新K线产生,全局变量时间="+DateTimeToString(bartime) +"

TickCnt="+Text(tickcnt)+"SeTickCnt="+Text(SeTickCnt) +"GlobTickCnt="+Text(GlobTickCnt)); }ElseIf(Date+Time==bartime) {

TickCnt=TickCnt+1;

SeTickCnt=SeTickCnt+1;

GlobTickCnt=GetGlobalVar(1)+1; SetGlobalVar(1,GlobTickCnt); FileAppend("c:\\tb\\Sample15.txt","Bartime="+DateTimeToString(date+time) +"原K线增加计数,全局变量时间="+DateTimeToString(bartime) +"TickCnt="+Text(tickcnt)+"SeTickCnt="+Text(SeTickCnt) +"GlobTickCnt="+Text(GlobTickCnt)); }End

Sample15运行结果Sample15运行结果写数据库文件SetTBProfileString

写信息文件

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论