1、TB公式入门,唐帆,深圳市拓瑞邦泽科技有限公司,Bar数据:公式在进行计算时,都是建立在基本数据源(Bar数据)之上,我们这里所谓的Bar数据,是指商品在不同周期下形成的序列数据,在单独的每个Bar上面包含开盘价、收盘价、最高价、最低价、成交量及时间。期货等品种还有持仓量等数据。所有的Bar按照不同周期组合,并按照时间从先到后进行排列,由此形成为序列数据,整个序列称之为Bar数据。 公式如何执行:TradeBlazer公式在计算时按照Bar数据的Bar数目,从第一个Bar到最后一个Bar,依次进行计算,如果公式中出现了调用Bar数据函数的,则取出当前Bar的相应值,进行运算。公式执行从上至下,
2、Bar从左到右执行。,交易开拓者公式基础,公式执行顺序,公式执行顺序,TradeBlazer公式的HelloWorld! FileAppend(“c:Formula.log“,“hello world“); End,公式的种类,指标 K线形态 特征走势 交易指令函数,公式环境的组织层次(1),BAR数据,指标,K线形态,特征走势,交易指令,公式环境的组织层次(2),BAR数据,指标,K线形态,特征走势,交易指令,函数,建立一个最简单的指标:画零线,BeginPlotNumeric(“Line1”,0); End Begin和End宣告公式正文的开始和结束,公式语句应该放到Begin和End之
3、间。 PlotNumeric表示输出一个数值型组成的数组。 技术指标属性的设置,再画一条线,BeginPlotNumeric(“Line1”,5); End,参数,一根线 ParamsNumeric Length(0); BeginPlotNumeric(“Line1”,length); End N根线 ParamsNumeric Length1(0);Numeric Length2(5); BeginPlotNumeric(“Line1”,length1);PlotNumeric(“Line2”,length2); End,取较大值,ParamsNumeric Length1(0);Nume
4、ric Length2(5); Beginif(Length1 = Length2)PlotNumeric(“Line1”,length1);elsePlotNumeric(“Line1”,length1); End PlotNumeric由输出的名字来区分是否为同一条线。,关于IF语句,If语句是一个条件语句,当特定的条件满足后执行一部分操作。 语法如下: If (Condition) TradeBlazer公式语句; TradeBlazer公式语句是一些语句的组合,如果TradeBlazer公式语句是单条,您可以省略,二条或者二条以上的语句必须使用。,关于条件表达式,逻辑操作符 :AND(
5、&),OR(|),NOT(!) 表达式1 AND 表达式2 表达式1 OR 表达式2 NOT表达式1 注意:浮点数字的等于详细介绍参见帮助文件公式系统操作符 注意:条件表达式括号后面不要加分号。,IF-Else,If-Else语句是对指定条件进行判断,如果条件满足执行If后的语句。否则执行Else后面的语句。 语法如下: If (Condition) TradeBlazer公式语句1; Else TradeBlazer公式语句2; ,If-Else-If,If-Else-If是在If-Else的基础上进行扩展,支持条件的多重分支。 语法如下: If (Condition1) TradeBlaz
6、er公式语句1; Else If(Condition2) TradeBlazer公式语句2; Else TradeBlazer公式语句3; If-Else-If的语句可以根据需要一直扩展,在最后的Else之后再加If(Condition)和新的执行代码即可。当然您也可以省略最后的Else分支,,If-Else的嵌套,If-Else的嵌套是在If-Else的执行语句中包含新的条件语句,即一个条件被包含在另一个条件中。 If (Condition1) If (Condition2) TradeBlazer公式语句1; Else TradeBlazer公式语句2; Else If (Conditio
7、n3) TradeBlazer公式语句3; Else TradeBlazer公式语句4; ,回到指标,赋值语句 用变量使流程清晰 ParamsNumeric Length1(0);Numeric Length2(5); VarsNumeric biger; Beginif(Length1 = Length2)biger = Length1;elsebiger = Length2;PlotNumeric(“Line1”, biger );End,公式的三段论,函数(1),用函数使流程更加简洁 ParamsNumeric Length1(0);Numeric Length2(5); VarsNum
8、eric biger; Beginbiger = GetBiger(Length1,Length2);PlotNumeric(“Line1”, biger ); End,函数(1),GetBiger的内容 Return 语句 ParamsNumeric Length1(0);Numeric Length2(5); Beginif(Length1 = Length2)return Length1;elsereturn Length2; End,指标模板,Params VarsNumeric line1;Numeric line2; Beginline1 = GetLine1(.);line2 =
9、 GetLine2(.);PlotNumeric(“Line1”, line1 );PlotNumeric(“Line2”, line2 ); End 参考MA指标的模板写法,函数(2),假设要写这样一个指标:两个数字型参数,比较其大小,并输出两条线 ParamsNumeric Length1(0);Numeric Length2(5); VarsNumeric biger;Numeric smaller; Beginbiger = GetBiger(Length1,Length2);smaller = GetSmaller(Length1,Length2);PlotNumeric(“bigg
10、er”, biger );PlotNumeric(“smaller”, smaller); End 然而,函数(2),引用型参数 函数compare的内容 ParamsNumeric param1(0);Numeric param2(5);NumericRef samller; Beginif(param1 = param2)smaller = param2;return param1;elsesmaller = param1;return Length2; End,函数(2),调用compare ParamsNumeric param1(0);Numeric param2(5); VarsN
11、umeric biger;Numeric smaller; Beginbiger = compare(param1,param2,smaller);PlotNumeric(“bigger”, biger );PlotNumeric(“smaller”, smaller); End,一个新需求,用函数计算最近三根BAR的最低点 Beginif(low = low1 End,一个新需求(另一种写法:冒泡),Varsnumeric smallest(999999); / 初始值很重要! Beginif(low2 samllest) smallest = low2;if(low1 samllest)
12、smallest = low1;if(low samllest) smallest = low;return smallest; End,最近N个BAR的最低值(循环语句),Paramsnumeric Length(5); Varsnumeric smallest(999999); / 初始值很重要!numeric i; Beginfor i=1 to Length-1if(lowi = smallest)smallest = lowi;return smallest; End,最近N个BAR的最低值,Paramsnumeric Length(5); Varsnumeric smallest(
13、999999); / 初始值很重要!numeric i; Beginif(CurrentBar Length -1)return InvalidNumeric;for i=1 to Length-1if(lowi = smallest)smallest = lowi;return smallest; End,数据回溯,如何使用回溯表达? XXXnOffset nOffset是要回溯引用的Bar相对于当前Bar的偏移值,该值必须大于等于0,当nOffset = 0时,即为获取当前Bar的参数值。并且nOffset不能大于当时的CurrentBar,这样会导致数据访问越界。造成不可预知的计算结果。
14、 变量回溯,参数回溯,函数回溯(系统函数),序列参数,ParamsnumericSeries Price(1);numeric Length(5); Varsnumeric smallest(999999); / 初始值很重要!numeric i; Beginif(CurrentBar Length -1)return InvalidNumeric;for i=1 to Length-1if(Pricei = smallest)smallest =Pricei;return smallest; End,没完没了的新需求,得到最低值与最低值的位置,没完没了的新需求,ParamsnumericSe
15、ries Price(1);numericRef Position; VarsnumericSeries smallest(999999); numericSeries i; Beginif(CurrentBar = 0)smallest = Price;I = 0;Position = i;return smallest;elsesmallest = smallest1;I = i1;if(price = smallest)samllest = price;I = currentBar;return smallest; End,关于常量和变量的定义,常量是用来代替一个数或字符串的名称 。在公
16、式整个执行过程中不发生改变。 变量是一个存储值的地址,当变量被声明之后,就可以在脚本中使用变量,可以对其赋值,也可以在其他地方引用变量的值进行计算,要对变量进行操作,直接使用变量名称即可。 变量的主要用处在于它可以存放计算或比较的结果,以方便在之后的脚本中直接引用运算的值,而无需重现计算过程。,关于变量的类型,TradeBlazer公式支持有三种基本数据类型:数值型(Numeric)、字符串(String)、布尔型(Bool)。 为了通过用户函数返回多个值,我们对三种数据类型进行了扩展,增加了引用数据类型。另外,为了对变量,参数进行回溯,我们增加了序列数据类型。因此,我们的数据类型共有九种,9
17、种数据类型,Bool布尔型。 BoolRef布尔型引用。 BoolSeries和周期长度一致的Bool型序列值。 Numeric数值型。 NumericRef数值型引用。 NumericSeries和周期长度一致的Numeric型序列值。 String字符串。 StringRef字符串引用。 StringSeries和周期长度一致的String型序列值。,关于参数,参数是一个预先声明的地址,用来存放输入参数的值,在声明之后,您就可以在接下来的公式中使用该参数的名称来引用其值。 参数的值在公式的内部是不能够被修改,在整个程序中一直保持不变,不能对参数进行赋值操作(引用参数是个特例)。参数的好处在
18、于您可以在调用执行技术分析,交易指令的时候才指定相应的参数,而不需要重新编译。 详细使用参见帮助文件公式系统参数,交易策略-完整的交易系统,通常单个交易指令只完成建仓或平仓的单个动作,而一个完整的交易策略应该至少包含建仓、平仓交易指令,并且根据需要加上止损,获利等锁定风险和收益的交易指令。多个交易指令的组合才能更加有效的帮助我们完整的进行交易,因此,我们将多个交易指令的有效组合称之为交易策略。,交易策略的运行机制(1),假定我们创建一个交易策略,该交易策略由以下交易指令组成,并按照如下顺序应用到超级图表中。,交易策略的运行机制(2),当我们将该交易策略应用到超级图表上时,TradeBlazer
19、公式将会从图表的第一个Bar开始执行交易策略,在第一个Bar上首先执行多头建仓指令A,可能会产生交易委托(开仓),该委托可能被设置为在当前Bar执行,也可以被设置为延迟到下一个Bar执行。当多头建仓指令A执行完成之后,将按顺序调用多头平仓指令B,同时该指令会判断当前的持仓状态,仓位等信息,当条件满足的时候会产生交易委托(平仓)。,交易策略的运行机制(3),接下来依次执行止损平仓指令C和获利平仓指令D,当四个交易指令在第一个Bar上都执行完之后,将会移到第二个Bar执行,这时候,系统会首先读取上一个Bar是否有延迟的交易委托,如果有延迟的交易委托,对这些委托先进行处理,然后像第一个Bar一样,依
20、次调用各个交易指令。以此类推,从图表的第一个Bar到最后一个Bar,全部执行完成之后,整个交易策略执行完毕。在整个执行过程产生的所有交易委托被保存下来供超级图表模块显示或进行性能测试分析。,历史数据测试和实际交易的关系,MarketPosition与A_TotalPosition,普通型函数 状态型函数,Q函数和A函数,Q函数,指以Q_开头的系统函数,主要是获取实时行情信息。 A函数,指以A_开头的系统函数,获取自动交易关联帐户的帐户信息,只有在启动自动交易的情况下才能取值。Q函数和A函数都是反映最新的实时状态,不能取历史上的值,所以只能在当前有效,在公式中表现为只能在最后Bar上取值。,交易
21、设置的作用,Buy,SellShort等,Buy:多头开仓; Sell:多头平仓 SellShort:空头开仓;BuyToCover:空头平仓Bool Buy(Numeric Share=0,Numeric Price=0,Bool Delay=False) Share 买入数量,为整型值,默认为使用系统设置参数; Price 买入价格,为浮点数,默认=0时为使用现价(非最后Bar为Close); Delay 买入动作是否延迟,默认为当前Bar发送委托,当Delay=True,在下一个Bar执行。,关于Delay,默认情况下,4个交易函数产生的委托单即时发送;当参数Delay=True时,委托
22、单将延迟到下一个Bar发送,这样设计的原因在于:延迟的委托单才会保证发送的交易指令的正确性。 假定在某商品A的周期为5分钟的数据上应用交易指令,A商品每1秒钟会产生一个Tick数据,因此一段时间内(5分钟)A商品最后一个Bar的数据的收盘价,最高价,最低价以及成交量等数据,会随着Tick的变化和累计而产生相应的变化。在某种情况下,上一个Tick更新时,Buy的预设条件可能为False,下一个Tick更新时,Buy的预设条件为True。如果不延迟,将会马上发送该委托单到交易所。但是,当更多的Tick累计,产生一个新的Bar时,Buy的预设条件可能会变成False。在这种情况,前面产生的委托单将会
23、丢失,不会在测试和优化报表中出现。该委托单实际上是由于噪音数据产生的错误讯号导致,为了避免这种情况的出现,一定要等最后Bar数据更新结束之后,新Bar产生第一个Tick时,才会发送上一个Bar产生的委托单。 当交易函数的延迟设置为False。将会实时发送产生的委托单,按Tick进行更新。在使用该参数时,需要确认自己所编写的公式不会用到这些无效的中间数据,从而影响交易结果。,信号消失,基于前面的描述,如果用Close变化的数据来计算开平仓条件,就可能出现信号消失。 为了解决信号消失,可以使用前面所讲的Delay,或者使用另外一种方式,特别是我们经常用的突破系统。 使用High,Low,Open这
24、样能够保持住的价格来进行条件判断。是价格往上的突破形成的交易操作用High来判断。是价格下上的突破形成的交易操作用Low来判断。其他不确定方向的情况最好用Open来判断。,交易策略的性能测试及报表,交易汇总:按照多头交易、空头交易和全部交易列出当前交易策略的交易统计信息。 交易分析:对当前策略的交易情况进行分析,包括交易分析、盈亏分析和连续盈亏分析。 交易记录:按开仓平仓对所有交易进行配对组合,并计算盈亏及累计盈亏。 平仓分析:按平仓记录对交易情况进行分析和汇总。 阶段总结:按年、月对交易盈亏及次数进行统计。 资产变化:列出资产的变化记录及统计信息。 图表分析:按资产图表和盈亏图表两大类共十三小类对帐户进行图表分析。 系统设置:显示交易策略的参数,设置以及数据等内容。,交易策略的参数优化及报表,参数优化目标有以下七种选项 : 净利润最大,交易次数最大,平均净利润最大,盈利因子最大,收益率最大,盈亏比率最大,回报率最大。 寻找最优的参数。 需防止过度优化。 寻找最稳定的系统。而不是最大化的系统。,实例讲解-夹板,规定一个上轨,上穿就空;一个下轨,下穿就多;一个最大偏离范围,突破上下轨后再继续偏离出最大范围,就剁。,夹板扩展1,赢够就走 输了也走 收盘前平仓,夹板扩展2,把原来的状态当作参数输入 加减仓,夹板扩展3,动态的基点,谢谢!,