这个箱体理论是很有名的那个,我记得以前看过一个交易大神写的《 我如何在股市赚了200万》,他运用的就是箱体理论。这个TB里写的,我看了一下,有区别,但可以说也是一种别致的算法。看它的策略,如下:
策略说明:
本策略基于k线形成的区域设置进出场价格, 通过价格的上下突破来进行交易或取消做单
系统要素:
k线区域按时间顺序从左向右共由4根k线组成, 最左边的k线标号为3
1. 如果1号k线收盘价高于3号k线最高点, 开始设置做多交易区域, 上轨为3号K线高点, 下轨为标号为1起CancelFlagN根K线的低点
如果标号为0的K线收盘价在上下轨之间, 则做多区域设置成功, 如果收盘价低于下轨则区域设置取消
2. 如果1号k线收盘价低于3号k线最低点, 开始设置做空交易区域, 下轨为3号K线低点, 上轨为标号为1起CancelFlagN根K线的高点
如果标号为0的K线收盘价在上下轨之间, 则做空区域设置成功, 如果收盘价高于上轨则区域设置取消
入场条件:
1. 做多区域设置成功时, 当前k线高于标号为0的K线高点时入场做多
2. 做空区域设置成功时, 当前k线低于标号为0的K线低点时入场做空
出场条件:
1. 基于ATR的保护性止损
2. 基于ATR的盈亏平衡止损
3. 基于ATR的盈利止盈
看着这策略说明,想象力好的,凭空想像应该都知道这图像大概是什么样的,要是跟我一样想象力一般的,就对着TB图表,一个个看了,很容易理解的。接下来就直接看它做多的代码及解读了:
Params
Numeric ATRLength(10); //声明数值参数ATRLength,初值10,即ATR的周期参数值。//
Numeric CancelFlagN(5); //声明数值参数CancelFlagN,初值5,用于计算取消区域成功设置标志的上下轨的N值。//
Numeric ProtectStopATRMulti(0.5); //声明数值参数PritectStopATRMulti,初值0.5,用于保护性止损的ATR系数。//
Numeric BreakEvenStopATRMulti(3); //声明数值参数BreakEvenStopATRMulti,初值3,用于盈亏平衡止损的ATR系数。//
Numeric ProfitTargetATRMulti(5); //声明数值参数ProfitTargetATRMulti,初值5,用于盈利止盈的ATR系数。//
Vars
NumericSeries ATR(0); //声明数值序列变量ATR,初值0.//
NumericSeries UpLine(0); //声明数值序列变量UpLine,初值0,即区域设置上轨。//
NumericSeries DownLine(0); //声明数值序列变量DownLine,初值0,区域设置下轨。//
NumericSeries DownLineTemp;//声明数值序列变量DownLineTemp。//
NumericSeries HighAfterEntry; //声明数值序列变量HighAfterEntry,即持仓后的高点记录。//
NumericSeries EntryPriceL(0); //声明数值序列变量EntryPriceL,初值0,即开仓价格线。//
BoolSeries EntryFlag(False); //声明布尔型序列变量EntryFlag,初值假,即入场标志。//
NumericSeries ProtectStopL; //声明数值序列变量ProtectStopL,即基于ATR的保护性止损。//
NumericSeries ProfitTargetStopL; //声明数值序列变量ProfitTargetStopL,即基于ATR的盈利止盈。//
Numeric BreakEvenStopL; //声明数值变量BreakEvenStopL,即基于ATR的盈亏平衡止损。//
Numeric ExitLineL; //声明数值变量ExitLineL,即平仓价格线。//
NumericSeries MP; //声明数值序列变量MP,即MarketPosition的状态记录。//
Begin
If(!CallAuctionFilter()) Return;// 集合竞价和小节休息过滤。//
//系统设置。//
ATR = AvgTrueRange(ATRLength);//抛物线的公式求法了,都写过四五次了。//
DownLineTemp = LowestFC(Low,CancelFlagN);//利用快速求最低函数LowestFC,把收盘价与周期5返回求值,即可算得变量DownLineTemp值了。//
//接下来的就是算法的具体体现了,1、k线区域按时间顺序从左向右共由4根k线组成, 最左边的k线标号为3, 当前K线标号为0;
2、如果1号k线收盘价高于3号k线最高点, 开始设置做多交易区域, 上轨为3号K线高点, 下轨为从标号为1起CancelFlagN根K线的低点;
3、如果标号为0的K线收盘价在上下轨之间, 则做多区域设置成功, 做多触发价为标号为0的K线高点, 如果之后k线收盘价低于下轨则区域设置取消。//
if(MarketPosition <> 1)//假如当前没有持多仓。//
{
If(EntryFlag[1] == False)//假如前一进场标志EntryFlag[1]为假的时候。//
{
If(Close[1] >= High[3])//假如前一k线收盘价Close[1] >=前三k线的高价High[3]。//
{
UpLine = High[3];//则变量UpLine = 前三k线的高价High[3]。//
DownLine = DownLineTemp[1];//变量DownLine = 前一个变量DownLineTemp[1]值。//
if(C[0]<=UpLine and C[0] >=DownLine) //再假如当前收盘价C[0] <=上轨UpLine,并且当前C[0] >=下轨DownLine。//
{
EntryFlag = True;//则布尔型变量EntryFlag为真。//
EntryPriceL = High[0];//进场线EntryPriceL = 当前k线的高价。//
}
}
}
Else If(EntryFlag[1] == True)//假如前一个进场标志EntryFlag[1]为真。//
{
if(C[0] < DownLine) EntryFlag = False;//假如当前k线收盘低于DownLine, 则做多区域设置取消。//
}
}
PlotNumeric("UpLine",UpLine);//画线上轨。//
PlotNumeric("DownLine",DownLine);//画线下轨。//
PlotNumeric("EntryPriceL",EntryPriceL);//画线进场价。//
//系统入场,做多区域设置成功时, 当前k线高于标号为0的K线高点时入场做多。//
If(MarketPosition <> 1 and CurrentBar >= ATRLength)//假如当前没有持多单,并且当前公式应用商品在当前Bar的索引值 >= 10.//
{
If(EntryFlag[1] == True and High >= EntryPriceL[1] And Vol > 0)//假如前一进场标志为真,并且当前高价High >=前一进场价EntryPriceL[1],并且成交量大于0.//
{
Buy(0,Max(Open,EntryPriceL[1]));//开仓买入。//
EntryFlag = False;//买入后,进场标志赋值为假。//
ProtectStopL = Low[1] - ProtectStopATRMulti * ATR[1];//基于ATR的保护性止损具体算法,代入相应数值就行了。//
ProfitTargetStopL = High[1] + ProfitTargetATRMulti * ATR[1];//基于ATR的盈利止盈,同理的,代入相应数值。//
}
}
//系统出场。//
If(BarsSinceEntry == 0)//建仓位置为0.//
HighAfterEntry = High;//最高价记录为建仓位置k线的高价。//
Else
HighAfterEntry = Max(HighAfterEntry[1],High);//就是建仓位置不是0的时候。//
BreakEvenStopL = LastEntryPrice;//基于ATR的盈亏平衡止损,即BreakEvenStopL = 当前持仓的最后一个建仓价格LastEntryPrice值。//
If(MarketPosition == 1 and mp[1] == 1 And Vol > 0)//假如当前持有多单,并且前一个变量mp[1] == 1,并且成交量大于0.//
{
If(HighAfterEntry[1] >= BreakEvenStopL + BreakEvenStopATRMulti * ATR[1])//出场线选择条件,都是代入相应数值计算后比较了。//
{
ExitLineL = BreakEvenStopL;//平仓价格ExitLineL = 平衡止损BreakEvenStopL。//
}
Else//出场线选择条件不成立的。//
{
ExitLineL = ProtectStopL[1];//平仓价格ExitLineL = 前一个保护性止损ProtectStopL[1]。//
}
//出场规则。//
if(Open >= ProfitTargetStopL[1])//假如当前开盘价Open >= 前一个盈利止盈ProfitTargetStopL[1]。//
{
Sell(0,Open);//开盘价平仓卖出。//
}
//基于ATR的保护性止损或盈亏平衡止损。//
Else if(L <= ExitLineL)//假如当前最低价L <= 平仓价ExitLineL。//
{
Sell(0,Min(Open, ExitLineL));//平仓卖出了,价格就是取两者比较的小值。//
}
}
MP = MarketPosition;//记录MarketPosition的状态,赋值给MP。//
End
设置了这么多保护性的条件,但收益一般,当然,有可能是基于ATR指标做的保护条件一般,要是不喜欢,可以自己改成习惯而且熟悉的指标就行。看着这画图,虽然我没有测试过,但可以大胆预测,把这开仓条件与固定止损止盈合在一起,结果都比这个好,不信的自己试试了。
下面是做空的代码及结果了:
Params
Numeric ATRLength(10);
Numeric CancelFlagN(5);
Numeric ProtectStopATRMulti(0.5);
Numeric BreakEvenStopATRMulti(3);
Numeric ProfitTargetATRMulti(5);
Vars
NumericSeries ATR(0);
NumericSeries UpLine(0);
NumericSeries DownLine(0);
NumericSeries UpLineTemp;
NumericSeries LowAfterEntry;
NumericSeries EntryPriceS(0);
BoolSeries EntryFlag(False);
NumericSeries ProtectStopS;
NumericSeries ProfitTargetStopS;
Numeric BreakEvenStopS;
Numeric ExitLineS;
NumericSeries MP;
Begin
If(!CallAuctionFilter()) Return;
ATR = AvgTrueRange(ATRLength);
UpLineTemp = HighestFC(High,CancelFlagN);
if(MarketPosition <> -1)
{
If(EntryFlag[1] == False)
{
If(Close[1] <= Low[3])
{
UpLine = UpLineTemp[1];
DownLine = Low[3];
if(C[0]<=UpLine and C[0] >=DownLine)
{
EntryFlag = True;
EntryPriceS = Low[0];
}
}
}
Else If(EntryFlag[1] == True)
{
if(C[0] > UpLine) EntryFlag = False;
}
}
PlotNumeric("UpLine",UpLine);
PlotNumeric("DownLine",DownLine);
PlotNumeric("EntryPriceS",EntryPriceS);
If(MarketPosition <> -1 and CurrentBar >= ATRLength)
{
If(EntryFlag[1] == True and Low <= EntryPriceS[1] And Vol > 0)
{
SellShort(0,Min(Open,EntryPriceS[1]));
EntryFlag = False;
ProtectStopS = High[1] + ProtectStopATRMulti * ATR[1];
ProfitTargetStopS = Low[1] - ProfitTargetATRMulti * ATR[1];
}
}
If(BarsSinceEntry == 0)
LowAfterEntry = Low;
Else
LowAfterEntry = Min(LowAfterEntry[1],Low);
BreakEvenStopS = LastEntryPrice;
If(MarketPosition == -1 and mp[1] == -1 And Vol > 0)
{
If(LowAfterEntry[1] <= BreakEvenStopS - BreakEvenStopATRMulti * ATR[1])
{
ExitLineS = BreakEvenStopS;
}
Else
{
ExitLineS = ProtectStopS[1];
}
if(Open <= ProfitTargetStopS[1])
{
BuyToCover(0,Open);
}
Else if(H >= ExitLineS)
{
BuyToCover(0,Max(Open, ExitLineS));
}
}
MP = MarketPosition;
End