1、1,TB编程基础和策略实现示例,蔡云华深圳开拓者科技有限公司,内容安排,TB 程序化交易的设置和使用(演示) TB 程序化交易编程基本知识 TB 技术指标和交易策略编写示例,2,TB公式如何使用?,TB公式类型 用户函数 公式应用(包括技术指标、交易指令等) 如何使用一个交易模型?或新建公式应用,粘贴代码,校验保存公式(编译)打开超级图表,选择交易品种,插入公式应用修改公式应用设置投资组合性能测试和参数优化启动自动策略交易系 TB公式的导入导出,3,4,5,6,公式源代码,ParamsNumeric Length(10);Numeric Lots(1); VarsNumericSeries M
2、A; BeginMA = AverageFC(Close,Length);PlotNumeric(“MA“,MA);If (Close1 MA1)Buy(Lots, Open);If (Close1 MA1)SellShort(Lots,Open); End,TB公式的结构,TB的公式一般由三段组成。 ParamsNumeric Length(10); 公式参数段 VarsNumericSeries MA; 公式变量段 BeginMA = AverageFC(Close, Length); 公式脚本段 End,8,Bar数据(K线数据),当前时间周期下所有K线的相关数据,按照时间从先到后的顺序
3、排列而成的序列数据。每根K线中包含的数据如下:,9,序列数据,10,序列变量,序列变量,序列变量,序列变量,序列变量,序列变量,序列变量,序列变量,序列变量,序列变量,序列变量,序列变量,N N-1 2 1 0,非序列变量(简单变量),11,非序列变量,Bar数据的使用,Bar数据是TB公式运行的基础。 Bar数据是序列数据,可以回溯读取。 举例:比较今天的最高价是否突破了昨天的最高价表达式为:High High1比较今天的最高价是否突破了前两天的最高价表达式为:High High1 and HighHigh2或者:High High1 & HighHigh2,12,TB公式运行机制,从左到右
4、,从上到下,13,例1:Hello World,Sample1: BeginFileAppend(“c:tbsample1.txt“,“Hello World!“); End,公式运行结果,大家都知道每个Hello World! 都是怎么产生的吗?,注释语句- Commentary,TB的信息输出,除了可以通过FileAppend输出到文件外,也可以将信息输出显示到图表上; Commentary的用法:在超级图表的当前BAR添加一行注释信息;参数:String strTip; / 提示的信息,信息输出函数的作用,调试和诊断TB公式的代码错误; 检验TB公式的运行结果是否符合设计逻辑; 学习TB
5、的运行机制,熟悉TB内建函数的用法;,例2:输出BAR数据,Sample2: BeginFileAppend(“c:tbsample2.txt“,“Date= “+text(Date)+“ Time= “+text(time)+“ Open= “+Text(Open)+“ High= “+Text(High)+“ Low= “+Text(Low)+“ Close=“+Text(Close)+“ CurrentBar= “+Text(CurrentBar)+“ Barstatus= “+Text(BarStatus); End,例2 运行结果,参数与变量,简单地说,参数和变量都是代号,代表一个某
6、一类型的数据,变量还可以代表一个表达式的运算结果; 参数的作用是给用户一个不需修改代码即可改变公式运行结果的一个外部接口; 参数的值在公式的内部不能够被修改; 变量的作用是保存数据或是计算结果,便于以后调用; 参数和变量都需要声明。,参数的作用,假如我们要写一个均线指标,现在是用10天做周期。代码如下:BeginPlotNumeric(“MA“,AverageFC(Close,10);End 那如果要改用20天做周期,我们必须改程序,把10改成20,然后编译。下次想用别的周期,还得改,非常麻烦。 如果使用参数,就方便多了。程序写好,使用时改参数就好了。代码如下:ParamsNumeric Le
7、ngth(10);BeginPlotNumeric(“MA“,AverageFC(Close,Length);End,数据类型,TB公式中有三种基本的数据类型数值型(Numeric)字符型(String)布尔型(Bool) 为了对变量、参数进行回溯,又增加了序列类型数值型序列变量/参数(NumericSeries)字符型序列变量/参数(StringSeries)布尔型序列变量/参数(BoolSeries) 为了通过用户函数返回多个值,又增加了引用类型NumericRef、StringRef、BoolRef 变量(或参数)申明方法:数据类型 变量名或参数名 (初始值);,控制语句,条件语句(If
8、-Else)if 语句if - else 语句if - Else if 语句if - Else 嵌套 循环语句(ForWhile)For 循环变量 = 初始值 TO 结束值For 循环变量 = 初始值 Downto 结束值While 循环,条件语句-IF Else语句,语法如下: If (Condition) TB公式语句1; Else TB公式语句2; 如果TB公式语句是单条,您可以省略,二条或者二条以上的语句必须使用。,25,技术指标输出函数,PlotNumeric 在当前BAR输出一个数值 参数:String Name - 输出值的名称;Numeric Number - 输出的数值;Nu
9、meric Locator=0 - 输出值的定位点;Integer Color=-1 - 输出值的颜色;Integer BarsBack=0 - 从当前BAR回溯的 BAR数 举例:PlotNumeric(“MA”,AverageFC(Close,10);输出均线指标值PlotNumeric (“OpenToClose”,open,close); 输出开盘价与收盘价的连线(线型选择柱状图),26,技术指标输出函数(2),PlotString 在当前BAR输出一个字符串 参数:String Name - 输出值的名称 String str - 输出的字符串;Numeric Locator=0 -
10、 输出值的定位点;Integer Color=-1 - 输出值的颜色;Integer BarsBack=0 - 从当前BAR回溯的 BAR数 举例:PlotString(“CandleStick“,“阳线“,Low,Red);在Bar的最低价位置输出字符串“阳线”,并显示为红色,27,技术指标输出函数(3),PlotBool 在当前BAR输出一个布尔值 参数:String Name - 输出值的名称 Bool bPlot - 输出的布尔值;Numeric Locator=0 - 输出值的定位点;Integer Color=-1 - 输出值的颜色;Integer BarsBack=0 - 从当前
11、BAR回溯的 BAR数 举例:PlotString(“con“,con,High);在Bar的最高价位置输出布尔变量con的值,如果con为真,则显示“笑脸”图标,否则显示为“哭脸”图标,28,例3:技术指标的编写,Sample3: 单均线加通道指标 ParamsNumeric Length(10); / 均线周期Numeric FilterPercent(20); / 通道幅度比例(%) VarsNumericSeries MA;NumericSeries UpperBand;NumericSeries LowerBand;Bool ConBuy(False);Bool ConSell(Fa
12、lse); BeginMA = AverageFC(Close,Length);UpperBand = MA * ( 1 + FilterPercent / 10000 );LowerBand = MA * ( 1 - FilterPercent / 10000 );,29,PlotNumeric(“MA“,MA,0,Yellow);PlotNumeric(“UpperBand“,UpperBand,0,Red);PlotNumeric(“LowerBand“,LowerBand,0,Green);ConBuy = CrossOver(Close,UpperBand);ConSell = Cr
13、ossUnder(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); End,30,指标编写常见问题,指标编写完成后,还要注意在属性设置中进行相应的设置; 指标是在主图显示还是在子图显示
14、; 指标的线型; 从V3转到V4的客户注意参数的位置 另外学习的例子可以参考: MACD指标的写法(柱状图) SAR指标(点图),31,运行结果,32,交易指令 Buy/Sell,Buy - 平掉所有空头持仓,开多头仓位;sell - 平掉指定多头持仓;Sellshort - 平掉所有多头持仓,开空头仓位;Buytocover - 平掉指定空头持仓。参数: Numeric Share 买入数量,默认=0时,使用系统设置参数 Numeric Price 买入价格,为浮点数,默认=0时为使用现价(非最后Bar为Close)。,33,交易指令 A_SendOrder,针对当前公式应用的帐户、商品发送
15、委托单。 该函数直接发单,不经过任何确认,并会在每次公式计算时发送,一般需要配合着仓位头寸进行条件处理,在不清楚运行机制的情况下慎用。 不能使用于历史测试,仅适用于实时行情交易。 参数: BuyOrSell :买卖类型,买Enum_Buy/卖Enum_Sell; EntryOrExit: 开平仓类型, 开仓 Enum_Entry / 平仓Enum_Exit/ 平今 Enum_ExitToday; fLot 委托单的交易数量; fPrice 委托单的交易价格。,叠加多个商品合约进行交易,TB可以在一个图表中插入多个商品合约,支持同时对多个商品合约数据源编写公式应用。具体的方法是在交易指令、BAR
16、数据及系统函数前加上数据源。TB中数据源的命名规则如下: Data0:图表中最开始选择的商品合约 Data1:第一个插入的商品合约 Data2:第二个插入的商品合约 一个图表最多支持50个数据源; 调用方法:Data1.A_SendOrder() Data2.Buy(.)Data3.Close Data4.MarketPosition,34,盘中和盘后公式运行的差别,盘后公式的执行情况分析K线是确定的,不存在信号消失问题公式在每根K线上只执行一遍符合开仓条件和平仓条件会标出买卖信号(使用Buy、Sell指令),但并不真正发单 盘中公式的执行情况分析 K线是变化的,如用最新价或基于最新价计算出的
17、指标来作为入场或出场条件会出现信号消失问题每当分笔交易数据(tick)传来时,公式都会执行一遍符合开仓条件和平仓条件除标出买卖信号,还会真正发单,信号消失问题(1),产生原因:使用变化的价格(如Close)或是基于最新价Close计算的技术指标,来作为交易的进场、出场或止损条件时,就会产生信号消失问题。 如果编写的公式策略中存在信号闪烁问题,在历史测试中会得出失真的测试结果,在实盘交易时,更会因为重复发单造成严重损失。 信号消失问题的一般解决办法: 延迟发单或用前一根K线的数据来做为判断条件 用能保持得住的价格来做为判断条件,信号消失问题(2),延迟发单举例:condition = 交易条件I
18、f (condition)Buy(1, NextOpen, true); 用前一根K线做判断举例:condition = 交易条件If (condition1)Buy(1, Open); 用High,Low,Open等做判断If (HighHigh1) buy(1,High1);,例4:单均线系统,ParamsNumeric Length(10);Numeric Lots(1); VarsNumericSeries MA; BeginMA = AverageFC(Close,Length);PlotNumeric(“MA“,MA);If (MarketPosition 1 and Close1
19、 MA1)Buy(Lots, Open);If (MarketPosition -1 and Close1 MA1)SellShort(Lots,Open); End,连续建仓的控制,原来的公式中,理论上任何一根收盘高于均线的K线,都会开多仓,形成连续建仓,但实际上交易设置中可控制,如果允许连续建仓,代码中限制连续建仓,持仓函数Marketposition的用法:获得当前持仓状态,返回值为整型。返回值定义如下: 1 当前位置为持多仓-1 当前位置为持空仓 0 当前位置为持平 代码修改如下: If (MarketPosition!=1 and Close1 MA1)Buy(Lots, Open)
20、;If (MarketPosition!=-1 and Close1 MA1)SellShort(Lots,Open);,止盈止损策略的实现,止盈止损的设置有多种方法,常见的有: 固定点数 价格百分比 进场价的一定比例; 平均波动范围的一定比例; 形态判断 下面以固定点数止损,进场价的一定比例止盈为例,分别举个例子。,42,止盈止损的代码,(不包含进场部分) ParamsNumeric TakeProfit(1); / 百分比 Numeric StopLoss(20); VarsNumeric MinPoint;Numeric MyEntryPrice;Numeric MyExitPrice;
21、 BeginMinPoint = 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);,43, Else if ( Low MyEntryPrice + Stoploss * MinP
22、oint) MyExitPrice = MyEntryPrice + Stoploss * MinPoint;if (Open MyExitPrice) MyExitPrice = Open;BuyToCover(0,MyExitPrice); End,44,追踪止盈策略的实现,追踪止盈的设置也有多种方法,常见的有: 峰值价回落固定点数 峰值价回落一定的百分比 峰值价的一定比例; 平均波动范围的一定比例; 开盘价的一定比例。 是否盈利达到一定幅度才启用追踪止盈; 动态的回落点数或比例。 下面以峰值价回落一定比例为例,来实现它。,45,追踪止盈的代码,(不包含进场部分) Params Numer
23、ic TrailingStop(1); / 跟踪止损百分比 Vars Numeric MinPoint;Numeric MyExitPrice;NumericSeries HigherAfterEntry;NumericSeries LowerAfterEntry;Numeric StopLine(0); Beginif (BarsSinceEntry = 1)HigherAfterEntry = AvgEntryPrice;LowerAfterEntry = AvgEntryPrice; Else If(BarsSinceEntry 1)HigherAfterEntry = Max(High
24、erAfterEntry1,High1);LowerAfterEntry = Min(LowerAfterEntry1,Low1);,46,ElseHigherAfterEntry = HigherAfterEntry1;LowerAfterEntry = LowerAfterEntry1;MinPoint = MinMove * PriceScale;If(MarketPosition=1)StopLine = HigherAfterEntry * (1 - TrailingStop * 0.01);If(Low = StopLine)MyExitPrice = StopLine + Min
25、Point;If(Open MyExitPrice) MyExitPrice = Open;BuyToCover(0,MyExitPrice); End,47,48,应注意的问题,如果单根K线的最高价和最低价相差很大,有可能出现止盈和止损同时满足的情况,解决办法: 切换到更小的时间周期上进行交易; 扩大止盈和止损的幅度在开仓BAR,因无法判断开仓价和最高价最低价的先后顺序,因此一般是在开仓BAR的后一根BAR才开始判断是否满足止盈止损或跟踪止盈的的条件。如交易策略需要及时的止损,同样需要切换到更小的时间周期上进行交易。,进场位置和盈利峰值价计算,开盘价,最低价,追踪止损价,盈利峰值价,止损,没
26、 被 止 损,再进场策略的设计,使用止损止盈或追踪止盈出场后,如果趋势没有改变,我们仍然需要再进场的策略以避免错失大的波段趋势; 可以考虑的再入场的方法有: 价格创出新高或新低,再次入场; 出场后一定时间后,大趋势仍未改变则再次入场; 出场后大趋势未改变,其他辅助指标出现和大趋势一致的进场信号时再次入场。 下面以出场后一定时间后大趋势仍未改变即再次入场的方法来举例。,50,跟踪止盈后,我们要设个标志,表示曾经出场过,因此要增加两个布尔型序列变量;BoolSeries bLongStoped(false);BoolSeries bShortStoped(false); 跟踪止盈后,设置这两个变量
27、;/ 多头跟踪止盈后If(Low = StopLine ) BuyToCover(0,MyExitPrice);bShortStoped = true;,51,这两个序列变量值必须往下传递(V4中可以免写)if (BarStatus 0)bLongStoped = bLongStoped1;bShortStoped = bShortStoped1; 多头或空头初次进场和再次进场后,都要将这两个变量复位;bLongStoped = false;bShortStoped = false; 为了配合再进场,我们需要记录当前的趋势方向。,52,追踪止盈后的等待时间,我们可用止盈后的K线根数来衡量。因为
28、我们止盈后bLongStoped或bShortStoped会被置为True,因此我们可通过一个函数NthCon来寻找跟踪止盈的那根BAR到现在的BAR数。 具体止盈后多少根BAR后趋势还在持续再进场,我们可以设置为一个参数:BarsReEntry。多头再进场部分的代码如下BarsAfterLongExit = NthCon(!bLongStoped,1);Commentary(“BarsAfterLongExit=“+text(BarsAfterLongExit);If(bLongStoped and MarketPosition = 0 and condBuy1 = trueand Bars
29、AfterLongExit = BarsReEntry)Buy(Lots,Open);bLongStoped = False;HigherAfterEntry = Open;,53,例6:双均线系统,加上跟踪止盈和再进场策略 Params Numeric Length1(10);Numeric Length2(20); Numeric Lots(1);Numeric TrailingStop(1); / 跟踪止损百分比Numeric BarsReEntry(5); / 出场后趋势维持多少根Bar后再进场 Vars NumericSeries MA1; NumericSeries MA2; Bo
30、olSeries condBuy(false);BoolSeries condSell(false);Numeric MinPoint;Numeric MyExitPrice;NumericSeries HigherAfterEntry;NumericSeries LowerAfterEntry;Numeric StopLine(0);BoolSeries bLongStoped(false);BoolSeries bShortStoped(false);Numeric BarsAfterLongExit(0);Numeric BarsAfterShortExit(0); Begin,/*if
31、 (BarStatus 0) / V4中可以省略的序列变量传递部分bLongStoped = bLongStoped1;bShortStoped = bShortStoped1;*/Commentary(“bLongStoped=“+IIFString(bLongStoped,“true“,“false“);Commentary(“bShortStoped=“+IIFString(bShortStoped,“true“,“false“);if (BarsSinceEntry = 1)HigherAfterEntry = AvgEntryPrice;LowerAfterEntry = AvgEn
32、tryPrice; Else If(BarsSinceEntry 1)HigherAfterEntry = Max(HigherAfterEntry1,High1);LowerAfterEntry = Min(LowerAfterEntry1,Low1);ElseHigherAfterEntry = HigherAfterEntry1;LowerAfterEntry = LowerAfterEntry1;,MA1 = AverageFC(Close,Length1); MA2 = AverageFC(Close,Length2); PlotNumeric(“MA1“,MA1);PlotNume
33、ric(“MA2“,MA2);condBuy = CrossOver(MA1,MA2);condSell = CrossUnder(MA1,MA2);if ( condBuy = false and condSell = false )condBuy = condBuy1;condSell = condSell1;If ( MarketPosition 1 and condBuy1 = true and bLongStoped = false)Buy(Lots,Open);HigherAfterEntry = Open;bLongStoped = false;bShortStoped = fa
34、lse;If ( MarKetPosition -1 and condSell1 = true and bShortStoped = false)SellShort(lots,Open); LowerAfterEntry = Open;bLongStoped = false;bShortStoped = false;,BarsAfterLongExit = NthCon(!bLongStoped,1);Commentary(“BarsAfterLongExit=“+text(BarsAfterLongExit);If(bLongStoped and MarketPosition = 0 and
35、 condBuy1 = true and BarsAfterLongExit = BarsReEntry)Buy(Lots,Open);bLongStoped = False;HigherAfterEntry = Open;Return;BarsAfterShortExit = NthCon(!bShortStoped,1);Commentary(“BarsAfterShortExit=“+text(BarsAfterShortExit);If(bShortStoped and MarketPosition = 0 and condSell1 = true and BarsAfterShort
36、Exit = 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;BuyToCov
37、er(0,MyExitPrice);bShortStoped = true; End,更多的优化,参数优化-交易策略参数优化功能 为防止过度优化及处理优化值处于边界值的问题,将参数取连续数值,观察赢利区域。 若最优化结果处于连续赢利数值区域,便认为该最优化参数是合适的参数。 若最优化结果离散于连续赢利数值区域或为临界值,则考虑在连续区域取最优值。,TB的学习资源和方法,系统自带的交易指令范例 TB公式开发指南 http:/ TB的系统交易论坛 http:/ TB的帮助文件(F1帮助)最好的学习方法就是动手实验。,谢谢大家!,公司网站: 新浪微博: 总部客服: 0755-83410021 上海办事处:021-68366255 我的手机:13501683243,61,