nullTB编程从入门到进阶
*TB编程从入门到进阶
蔡云华
深圳开拓者科技有限公司null* TB公式基本概念 TB公式基本概念什么是TB公式?
TB公式类型
用户函数
公式应用(包括技术指标、交易指令等)
如何创建和应用公式?
公式导入(*.fbk)
或新建公式应用,粘贴代码,校验保存公式(编译)
打开超级图表,选择交易品种,插入公式应用
修改公式应用设置
启动自动策略交易系统
* Bar数据(K线数据) Bar数据(K线数据)当前时间周期下所有K线的相关数据,按照时间从先到后的顺序排列而成的序列数据。每根K线中包含的数据如下:* Bar数据的使用 Bar数据的使用Bar数据是TB公式运行的基础。
Bar数据是序列数据,可以回溯读取(图示)。
举例:
比较今天的最高价是否突破了昨天的最高价
表达式为:High > High[1]
比较今天的最高价是否突破了前两天的最高价
表达式为:High > High[1] and High>High[2]
或者:High > High[1] && High>High[2]
* 序列数据 序列数据*序列变量序列变量序列变量序列变量序列变量序列变量序列变量序列变量序列变量序列变量序列变量序列变量N N-1 … … … … … … … 2 1 0 非序列变量(简单变量) 非序列变量(简单变量)* 非序列变量 TB公式运行机制 TB公式运行机制从左到右,从上到下
* 盘中和盘后公式运行的差别 盘中和盘后公式运行的差别盘后公式的执行情况分析
K线是确定的,不存在信号消失问题;
公式在每根K线上只执行一遍;
符合开仓条件和平仓条件会标出买卖信号(使用Buy、Sell指令),但并不真正发单;
盘中公式的执行情况分析
K线是变化的,如用最新价或基于最新价计算出的指标来作为入场或出场条件会出现信号消失问题;
每当分笔交易数据(tick)传来时,公式都会执行一遍;
符合开仓条件和平仓条件除标出买卖信号,还会真正发单;
有些函数和数据只有盘中才能支持,盘后不支持。
TB公式的结构 TB公式的结构TB的公式一般由三段组成。
Params
Numeric Length(10); 公式参数段
… …
Vars
NumericSeries MA; 公式变量段
… …
Begin
MA = AverageFC(Close, Length); 公式脚本段
… …
End* 例1:Hello World 例1:Hello WorldSample1:
Begin
FileAppend("c:\\tb\\sample1.txt","Hello World!");
End
实验1:Sample1 实验1:Sample1实验目标:
通过学习,掌握在TB中如何新建公式应用,如何编译和使用公式。
实验步骤:
TB公式 新建公式应用 输入公式简称 选择适当的
模板
个人简介word模板免费下载关于员工迟到处罚通告模板康奈尔office模板下载康奈尔 笔记本 模板 下载软件方案模板免费下载
;
在公式编辑器中,输入sample1的代码;
点击工具栏中的“校验保存公式”进行代码编译;
新建超级图表,鼠标右键 插入公式应用;
到指定文件路径,查看文件内容。
公式运行结果 公式运行结果
大家都知道每个Hello World!
都是怎么产生的吗?
例2:输出BAR数据 例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 运行结果 例2 运行结果 参数的作用 参数的作用 假如我们要写一个均线指标,现在是用10天做周期。代码如下:
Begin
PlotNumeric("MA",AverageFC(Close,10));
End
那如果要改用20天做周期,我们必须改程序,把10改成20,然后编译。下次想用别的周期,还得改,非常麻烦。
如果使用参数,就方便多了。程序写好,使用时改参数就好了。代码如下:
Params
Numeric Length(10);
Begin
PlotNumeric("MA",AverageFC(Close,Length));
End
数据类型 数据类型TB公式中有三种基本的数据类型
数值型(Numeric)
字符型(String)
布尔型(Bool)
为了对变量、参数进行回溯,又增加了序列类型
数值型序列变量/参数(NumericSeries)
字符型序列变量/参数(StringSeries)
布尔型序列变量/参数(BoolSeries)
为了通过用户函数返回多个值,又增加了引用类型
数值型引用(NumericRef)
字符型引用(StringRef)
布尔型引用(BoolRef)
参数的声明和使用 参数的声明和使用参数在使用前必须进行声明,声明方法如下:
Params
Numeric Length(10);
String Filename("D:\\sample2.log");
bool OutputToFile(false);
公式应用和用户函数的参数略有不同:
公式应用的参数只支持三种基本类型,用户函数的参数支持全部九种类型;
公式应用的参数一定要有初始值,而用户函数的参数可以没有默认值;
参数的值在公式的脚本段中只能引用,不能修改; 变量 变量变量的主要用处在于它可以存放计算或比较的结果,以方便在之后的脚本中直接引用运算的值,而无需重现计算过程。
变量在使用前必须进行声明,声明方法如下:
Vars
NumericSeries MA;
Numeric Stopline(30);
变量的赋值(变量类型和表达式的类型要一致)
变量名称 = 表达式;
例如:MA = AverageFC(Close,10); 常用数据类型转换函数(1) 常用数据类型转换函数(1)数值型转字符型:String Text(Numeric value)
例如:Text(1.2345) 返回值为 "1.2345 "
字符型转数值型:Numeric Value(String str)
例如:Value(" 1.2345 ")返回值为1.2345
根据布尔型值返回转字符型或数值型:
Numeric IIF(Bool Conditon,Numeric TrueValue,Numeric FalseValue)
例如:IIF(Close>Open,Close,Open);
String IIFString(Bool Conditon,String TrueValue,String falseValue)
例如:IIFString (Close>Open, "阳线", "阴线"); 常用数据类型转换函数(2) 常用数据类型转换函数(2)日期时间值转字符型:
String DateTimeToString(Numeric dtDateTime)
例如: DateTimeToString (20040612.114323) = "2004-06-12 11:43:23"
日期值转字符型:String DateToString(Integer nDate)
时间值转字符型:String TimeToString(Numeric fTime)
将字符串转化为日期时间: Numeric StringToDateTime(String str)
例如:StringToDateTime ("2003-02-23 12:24:55") = 20030223.122455
将字符串转化为日期:Integer StringToDate(String str)
将字符串转化为时间: Integer StringToTime(String str)例3:使用参数和变量例3:使用参数和变量Sample3:
Params
String Filename("c:\\tb\\sample3.txt");
Vars
Numeric change;
Begin
change = Close - Close[1];
FileAppend(Filename,"Date="+DateToString(Date)
+" Time="+TimeToString(time)
+" Close="+Text(Close)
+" 涨跌:"+text(change));
End
例3 运行结果 例3 运行结果 变量的存续周期 变量的存续周期简单变量在每次公式运行时,被赋默认值,公式运行过程中存在,公式运行完后不再存在;
序列变量的生存周期V3和V4略有区别:
V3: 每次公式运行时,序列变量被赋默认值,公式运行完后仍然存在,但下次如果还是同一根Bar运行公式的话,变量值又会被赋成默认值;
V4:每次公式运行时,除了第一根BAR会被赋默认值,其他BAR会自动传递上一根BAR的值,公式运行完后仍然存在,但下次如果还是同一根BAR运行公式的话,变量值又会传递上一根BAR的 值;
只有一根BAR的最后一个Tick公式运行完后,序列变量的值才能保留下来。
* 例4:变量的存续周期差别 例4:变量的存续周期差别Sample4:
Vars
Numeric jdbl;
NumericSeries xlbl;
Begin
FileAppend("c:\\tb\\sample4.txt","Bartime = "
+DateTimeToString(date+time)
+"\t CurrentTime = "+TimeToString(Currenttime)
+"\t 公式运行前 Jdbl = "+Text(jdbl)
+" xlbl = "+Text(xlbl));
jdbl = jdbl + 1;
xlbl = xlbl + 1;
FileAppend("c:\\tb\sample4.txt","Bartime = "
+DateTimeToString(date+time)
+"\t CurrentTime = "+TimeToString(Currenttime)
+"\t 公式运行后 Jdbl = "+Text(jdbl)
+" xlbl = "+Text(xlbl));
End
实验2:Sample4 实验2:Sample4实验目标:
通过实验,理解TB中简单变量和序列变量的区别,了解简单变量和序列变量的存续周期;
学习如何设置图表的K线样本数。
实验步骤:
新建公式应用,在公式编辑器中,输入Sample4的代码;
新建超级图表,任意选择一个交易品种, 设置时间周期,鼠标右键点击图表,进入“商品设置”,选择商品合约后,点“属性”,修改样本数为“10”后确定返回;
插入公式应用Sample4;
打开Sample4.txt,分析和思考在盘后K线和实时K线中简单变量和序列变量值的变化过程以及产生的原因。
Sample4运行结果1 Sample4运行结果1
Sample4运行结果2(实时) Sample4运行结果2(实时)
注释语句-- Commentary 注释语句-- CommentaryTB的信息输出,除了可以通过FileAppend输出到文件外,也可以将信息输出显示到图表上;
Commentary的用法:
在超级图表的当前BAR添加一行注释信息;
参数:String strTip; // 提示的信息
例5:改写例2 例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 运行结果 例5 运行结果 控制语句 控制语句条件语句(If-Else)
if 语句
if - else 语句
if - Else if 语句
if - Else 嵌套
循环语句(For\While)
For 循环变量 = 初始值 TO 结束值
For 循环变量 = 初始值 Downto 结束值
While 循环 条件语句----IF Else语句 条件语句----IF Else语句语法如下:
If (Condition)
{
TB公式语句1;
}
Else
{
TB公式语句2;
}
如果TB公式语句是单条,您可以省略{},二条或者二条以上的语句必须使用{}。 For 语句 1For 语句 1For语句是一个循环语句,重复执行某项操作,直到循环结束。语法如下:
For 循环变量 = 初始值 To 结束值
{
TradeBlazer公式语句;
}
For循环的执行是从循环变量从初始值到结束值,按照步长为1递增,依次执行TradeBlazer公式语句,结束值必须大于或等于初始值才有意义。For 语句 2For 语句 2如果希望For语句从大到小进行循环,可以使用以下的语法:
For 循环变量 = 初始值 DownTo 结束值
{
TradeBlazer公式语句;
}
For-DownTo让循环变量从结束值每次递减1直到等于结束值,依次调用TradeBlazer公式语句执行,初始值必须大于或等于结束值才有意义。 例6:For语句求和及均线 例6:For语句求和及均线Sample6:
Params
Numeric Length(10);
Vars
Numeric SumValue(0);
Numeric MA;
Numeric i;
Begin
SumValue = 0;
for i = 0 to Length - 1
{
SumValue = SumValue + Close[i];
}
MA = SumValue/Length;
Commentary("SumValue="+text(SumValue));
Commentary("MA="+Text(MA));
End
While循环While循环While语句在条件为真的时候重复执行某一项操作。即,只要条件表达式的值为真(True)时,就重复执行某个动作。直到行情信息改变以致条件为假 (False)时,循环才结束。
语法如下:
While (Condition)
{
TradeBlazer公式语句;
}
Continue 和 Break 例7:BarsSinceToday 例7:BarsSinceTodaySample7:(求当天第一根Bar到现在的BAR数)
Vars
Numeric TodayBars;
Begin
TodayBars = 0;
While ( CurrentBar > TodayBars and
date[TodayBars] == date[TodayBars+1] )
{
TodayBars = TodayBars + 1;
}
Commentary("TodayBars = " + text(TodayBars));
End BarsSinceToday的算法 BarsSinceToday的算法Vars
NumericSeries ReBars;
Begin
If(CurrentBar == 0 || Date != Date[1])
{
ReBars = 0;
}Else
{
ReBars = ReBars + 1;
}
Return ReBars;
Endnull* 技术指标输出函数(1)* 技术指标输出函数(1) PlotNumeric – 在当前BAR输出一个数值
参数:String Name ----- 输出值的名称;
Numeric Number ----- 输出的数值;
Numeric Locator=0 ----- 输出值的定位点;
Integer Color=-1 ----- 输出值的颜色;
Integer BarsBack=0 ----- 从当前BAR回溯的 BAR数
举例:
PlotNumeric(“MA”,AverageFC(Close,10));
输出均线指标值
PlotNumeric (“OpenToClose”,open,close); 输出开盘价与收盘价的连线(线型选择柱状图)
技术指标输出函数(2)* 技术指标输出函数(2) PlotString – 在当前BAR输出一个字符串
参数:String Name ----- 输出值的名称
String str ----- 输出的字符串;
Numeric Locator=0 ----- 输出值的定位点;
Integer Color=-1 ----- 输出值的颜色;
Integer BarsBack=0 ----- 从当前BAR回溯的 BAR数
举例:
PlotString("CandleStick","阳线",Low,Red);
在Bar的最低价位置输出字符串“阳线”,并显示为红色
技术指标输出函数(3)* 技术指标输出函数(3) PlotBool – 在当前BAR输出一个布尔值
参数:String Name ----- 输出值的名称
Bool bPlot ----- 输出的布尔值;
Numeric Locator=0 ----- 输出值的定位点;
Integer Color=-1 ----- 输出值的颜色;
Integer BarsBack=0 ----- 从当前BAR回溯的 BAR数
举例:
PlotString(“con",con,High);
在Bar的最高价位置输出布尔变量con的值,如果con为真,
则显示“笑脸”图标,否则显示为“哭脸”图标
实验3:Sample8 实验3:Sample8实验目标:
通过实验,学习TB中技术指标的编写;
掌握PlotNumeric、PlotString和PlotBool函数的用法;
掌握正确设置技术指标的属性。
实验步骤:
新建公式应用,在公式编辑器中,输入Sample8的代码;
点击“文件”-》“属性设置”-》在“常规”中选择“主图显示”,在线型中针对不同的线选择适当的线型、粗细和颜色等等,然后“校验保存公式”;
新建超级图表,选择交易品种和时间周期,插入公式应用;
观察指标的输出结果。
例8:自编指标的输出* 例8:自编指标的输出Sample8: 单均线加通道指标
Params
Numeric Length(10); // 均线周期
Numeric FilterPercent(20); // 通道幅度比例(%%)
Vars
NumericSeries MA;
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 ); * 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);
}
End Sample8运行结果* Sample8运行结果 指标编写常见问题* 指标编写常见问题指标编写完成后,还要注意在属性设置中进行相应的设置;
指标是在主图显示还是在子图显示;
指标的线型;
从V3转到V4的客户注意参数的位置
另外学习的
例子
48个音标大全附带例子子程序调用编程序例子方差分析的例子空间拓扑关系例子方差不存在的例子
可以参考:
MACD指标的写法(柱状图)
SAR指标(点图)null* TB用户函数 TB用户函数 用户函数是可以通过名称进行调用的一组语句的集合,实际应用中一般将某些经常需要用到的功能做成用户函数以方便以后编程时调用;
用户函数一般有一个返回值,类型可以是三种基本类型之一;
用户函数通过参数传入数据,通过返回值或引用型变量返回值;
用户函数间可以相互调用,也可以递归调用;
用户函数分为内建用户函数和其他用户函数,内建用户函数可以查看和调用,不能修改;
例9:求平均值 例9:求平均值 Sample9:这是求平均值的内建用户函数,其中就调用了summation函数
Params
NumericSeries Price(1);
Numeric Length(10);
Vars
Numeric AvgValue;
Begin
AvgValue = Summation(Price, Length) / Length;
Return AvgValue;
End
例10:求极值 例10:求极值 Sample10:这是求极值的内建用户函数,其中就用到了引用参数
Params
NumericSeries Price(1);
Numeric Length(10);
Bool bMax(True);
NumericRef ExtremeBar;
Vars
NumericSeries MyVal;
NumericSeries MyBar;
Numeric i;
Begin
MyVal = Price;
MyBar = 0;
If ( CurrentBar <= Length - 1 || MyBar[1] == Length - 1)
{
for i = 1 to Length - 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;
Return MyVal;
End
序列函数 序列函数序列函数是一种特殊的用户函数,当它的参数或变量中使用了序列变量时,我们就称之为序列函数;
序列数据作为普通计算机语言和TB语言的重要区别,是进行金融序列数据计算的的核心;
为保证序列数据的正确计算,序列函数需要每个BAR都调用,否则序列函数中的序列数据会不正确;
除非算法需要,否则建议不要在条件语句内、循环语句内以及包含逻辑运算符的条件表达式中使用序列函数。
null* 交易指令 – Buy/Sell* 交易指令 – Buy/Sell Buy -- 平掉所有空头持仓,开多头仓位;
sell -- 平掉指定多头持仓;
Sellshort -- 平掉所有多头持仓,开空头仓位;
Buytocover -- 平掉指定空头持仓。
参数:
Numeric Share 买入数量,默认=0时,使用系统设置参数
Numeric Price 买入价格,为浮点数,默认=0时为使用现价(非最后Bar为Close)。
交易指令 A_SendOrder* 交易指令 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.Close Data4.MarketPosition
* 交易常用系统函数介绍 交易常用系统函数介绍Integer MarketPosition() --- 获得当前的持仓状态
返回值为整型。返回值定义如下:
-1 当前位置为持空仓 0 当前位置为持平 1 当前位置为持多仓
这个函数用来配合Buy/Sell指令工作,对A_SendOrder无效。
Integer BarsSinceEntry() --- 获得当前持仓的第一个建仓位置到当前位置的Bar计数。
只有当MarketPosition != 0时,即有持仓的状况下,该函数才有意义,否则返回0;
在开仓Bar上为0。
* Bool CrossOver
(NumericSeries Price1,NumericSeries Price2)
--- 求Price1是否上穿Price2
返回值为布尔型。
Price1和Price2必须为数值型序列值。
Bool CrossUnder
(NumericSeries Price1,NumericSeries Price2)
--- 求Price1是否下穿Price2
返回值为布尔型。
Price1和Price2必须为数值型序列值。
* 信号消失问题(1) 信号消失问题(1)产生原因:使用变化的价格(如Close)或是基于最新价Close计算的技术指标,来作为交易的进场、出场或止损条件时,就会产生信号消失问题。
如果编写的公式策略中存在信号闪烁问题,在历史测试中会得出失真的测试结果,在实盘交易时,更会因为重复发单造成严重损失。
信号消失问题的一般解决
办法
鲁班奖评选办法下载鲁班奖评选办法下载鲁班奖评选办法下载企业年金办法下载企业年金办法下载
:
延迟发单或用前一根K线的数据来做为判断条件
用能保持得住的价格来做为判断条件 信号消失问题(2) 信号消失问题(2)用前一根K线做判断举例:
condition = 交易条件
If (condition[1])
{
Buy(1, Open);
}
用High,Low,Open等做判断
If (High>High[1])
{
buy(1,High[1]);
}
例11:双均线系统 例11:双均线系统交易规则:
如果短期均线上穿长期均线,做多,如原来持有空单,则先平空单,再建多仓
如果短期均线下穿长期均线,做空,如原来持有多单,则先平多单,再建空单
短周期:10
长周期:20
交易头寸暂为1手
* 实现代码 实现代码Sample11:
Params
Numeric Length1(10);
Numeric Length2(20);
Numeric Lots(1);
Vars
NumericSeries MA1;
NumericSeries MA2;
BoolSeries condBuy(false);
BoolSeries condSell(false);
Begin
MA1 = AverageFC(Close,Length1);
MA2 = AverageFC(Close,Length2); * PlotNumeric("MA1",MA1);
PlotNumeric("MA2",MA2);
condBuy = CrossOver(MA1,MA2);
condSell = CrossUnder(MA1,MA2);
If ( MarketPosition <> 1 and condBuy[1] == true )
Buy(Lots,Open);
If ( MarKetPosition <>-1 and condSell[1] == true) SellShort(lots,Open);
End *null* 止盈止损策略的实现 止盈止损策略的实现止盈止损的设置有多种方法,常见的有:
固定点数
价格百分比
进场价的一定比例;
平均波动范围的一定比例;
形态判断
下面以固定点数止损,进场价的一定比例止盈为例,来实现它。
* 例12:止盈止损的代码 例12:止盈止损的代码Sample12:
Params
Numeric TakeProfit(1); // 百分比
Numeric StopLoss(20);
Vars
Numeric MinPoint;
Numeric MyEntryPrice;
Numeric MyExitPrice;
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);
* } Else if ( Low < MyEntryPrice-Stoploss * MinPoint)
{
MyExitPrice = MyEntryPrice-Stoploss * MinPoint;
if (Open < MyExitPrice) MyExitPrice = Open;
Sell(0,MyExitPrice);
}
} Else if (MarketPosition == -1)
{
if (Low <= MyEntryPrice * (1 - TakeProfit * 0.01))
{
MyExitPrice = MyEntryPrice * (1 - TakeProfit * 0.01);
if (open < MyExitPrice) MyExitPrice = Open;
BuyToCover(0,MyExitPrice);
} Else If (High > MyEntryPrice + Stoploss * MinPoint)
{ MyExitPrice = MyEntryPrice + Stoploss * MinPoint;
if (Open > MyExitPrice) MyExitPrice = Open;
BuyToCover(0,MyExitPrice);
}
}
End
* 追踪止盈策略的实现 追踪止盈策略的实现追踪止盈的设置也有多种方法,常见的有:
峰值价回落固定点数
峰值价回落一定的百分比
峰值价的一定比例;
平均波动范围的一定比例;
开盘价的一定比例。
是否盈利达到一定幅度才启用追踪止盈;
动态的回落点数或比例。
下面以峰值价回落一定比例为例,来实现它。
* 例13:追踪止盈的代码 例13:追踪止盈的代码Sample13:
Params
Numeric TrailingStop(1); // 跟踪止损百分比
Vars
Numeric MinPoint;
Numeric MyExitPrice;
NumericSeries HigherAfterEntry;
NumericSeries LowerAfterEntry;
Numeric StopLine(0);
Begin
if (BarsSinceEntry == 1)
{
HigherAfterEntry = AvgEntryPrice;
LowerAfterEntry = AvgEntryPrice;
} Else If(BarsSinceEntry > 1)
{
HigherAfterEntry = Max(HigherAfterEntry[1],High[1]);
LowerAfterEntry = Min(LowerAfterEntry[1],Low[1]);
}
* 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);
}
}Else If(MarketPosition==-1)
{
StopLine = LowerAfterEntry * ( 1 + TrailingStop * 0.01);
If(High >= StopLine)
{
MyExitPrice = StopLine + MinPoint;
If(Open > MyExitPrice) MyExitPrice = Open;
BuyToCover(0,MyExitPrice);
}
}
End
* 应注意的问题* 应注意的问题如果单根K线的最高价和最低价相差很大,有可能出现止盈和止损同时满足的情况,解决办法:
切换到更小的时间周期上进行交易;
扩大止盈和止损的幅度
在开仓BAR,因无法判断开仓价和最高价最低价的先后顺序,因此一般是在开仓BAR的后一根BAR才开始判断是否满足止盈止损或跟踪止盈的的条件。如交易策略需要及时的止损,同样需要切换到更小的时间周期上进行交易。 K线波动太大的问题 K线波动太大的问题 进场位置和盈利峰值价计算 进场位置和盈利峰值价计算 开盘价
最低价追踪止损价盈利峰值价止损没
被
止
损 开盘价进场的追踪止损 开盘价进场的追踪止损 开盘价
(进场价)最低价追踪止损价以进场价作为盈利峰值价止损 再进场策略的
设计
领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计
再进场策略的设计使用止损止盈或追踪止盈出场后,如果趋势没有改变,我们仍然需要再进场的策略以避免错失大的波段趋势;
可以考虑的再入场的方法有:
价格创出新高或新低,再次入场;
出场后一定时间后,大趋势仍未改变则再次入场;
出场后大趋势未改变,其他辅助指标出现和大趋势一致的进场信号时再次入场。
下面以出场后一定时间后大趋势仍未改变即再次入场的方法来举例。
* 跟踪止盈后,我们要设个标志,表示曾经出场过,因此要增加两个布尔型序列变量;
BoolSeries bLongStoped(false);
BoolSeries bShortStoped(false);
跟踪止盈后,设置这两个变量;
// 多头跟踪止盈后
If(Low <= StopLine )
{
… …
Sell(0,MyExitPrice);
bLongStoped = true;
}
// 空头跟踪止盈后
If(High >= StopLine )
{
… …
BuyToCover(0,MyExitPrice);
bShortStoped = true;
}
* 这两个序列变量值必须往下传递(V4中可以免写)
if (BarStatus > 0)
{
bLongStoped = bLongStoped[1];
bShortStoped = bShortStoped[1];
}
多头或空头初次进场和再次进