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