//------------------------------------------------------------------------ // 简称: 布林轨震荡系统 // 名称: IF--5min // 类别: 公式应用 // 类型: 内建应用 //------------------------------------------------------------------------
Params Numeric Lots(1); Numeric Length(20); Vars NumericSeries mClose(0); NumericSeries mOpen(0); NumericSeries mhigh(0); NumericSeries mlow(0); NumericSeries MidBand; NumericSeries Band; NumericSeries UpBand; NumericSeries DnBand; NumericSeries OpenBar; NumericSeries BB; NumericSeries BandAcc; //衡量当日波动 NumericSeries ATR; NumericSeries StopPoint; NumericSeries ExitLine; Begin
if(CurrentBar == 0) { mopen = open; mclose = (O+H+L+C)/4; mhigh = Max( high, mopen); mhigh = Max( mhigh, mclose); mlow = Min( low, mopen); mlow = Min( mlow,mclose); }else if(CurrentBar > 0) { mclose = (O+H+L+C)/4; mopen = (mopen [1] + mclose [1])/2 ; mhigh = Max(High, mopen) ; mhigh = Max(mhigh, mclose) ; mlow = Min(Low, mopen) ; mlow = Min(mlow, mclose) ; } PlotNumeric("Close",mclose); PlotNumeric("Open",mopen); PlotNumeric("High",mhigh); PlotNumeric("Low",mlow); MidBand=Average(mclose[1],Length); Band=StandardDev(mclose[1],Length); UpBand=MidBand+2*Band; DnBand=MidBand-2*Band; PlotNumeric("MidBand",MidBand); PlotNumeric("UpBand",UpBand); PlotNumeric("DnBand",DnBand); BandAcc=Band-Band[1]; BB=(mclose[1]-DnBand[1])/(UpBand[1]-DnBand[1]); Commentary("BB="+Text(BB)); Commentary("BandAcc="+Text(BandAcc)); if( MarketPosition==0 && BandAcc[1]<BandAcc[2] ) { if( L<L[1] && mclose[1]<mopen[1] && mClose[3]> mopen[3] && BB[4]>1 ) { SellShort(Lots,Min(o,L[1])); OpenBar=CurrentBar; } if( H>H[1] && mclose[1]>mopen[1] && mClose[3]< mopen[3] && BB[4]<0 ) { Buy(Lots,max(o,H[1])); OpenBar=CurrentBar; } } if(MarketPosition==1 && mclose[1]<mopen[1] && L<L[1] ) { Sell(lots,Min(o,L[1])); } if(MarketPosition==-1 && mclose[1]>mopen[1] && H>H[1] ) { BuyToCover(lots,max(o,H[1])); } //防止极端行情平仓 ATR=AvgTrueRange(Length); If(MarketPosition<>0) { StopPoint=IIf(MarketPosition>0,C[1]-2*ATR[1],C[1]+2*ATR[1]); If(Currentbar==OpenBar) { ExitLine=StopPoint; } If(MarketPosition>0 && CurrentBar>OpenBar) { ExitLine=Max(StopPoint,ExitLine[1]); } If(MarketPosition<0 && Currentbar>OpenBar ) { ExitLine=Min(StopPoint,ExitLine[1]); } PlotNumeric("ExitLine",ExitLine); } if(MarketPosition==1 && L<ExitLine ) { Sell(lots,Min(o,ExitLine)); OpenBar=0; } if(MarketPosition==-1 && H>ExitLine ) { BuyToCover(lots,Max(O,ExitLine)); OpenBar=0; } End
//------------------------------------------------------------------------ // 编译版本 GS2010.12.08 // 版权所有 TradeBlazer Software 2003-2010 // 更改声明 TradeBlazer Software保留对TradeBlazer平 // 台每一版本的TradeBlazer公式修改和重写的权利 //------------------------------------------------------------------------ |
****************************
楼主思路很好,代码也很严谨,我抛砖引玉,说点自己的看法:我加了2跳滑点和2%%手续费后,曲线就不那么理想了,回看测试报告,主要是交易次数过多,我设置了较高的交易成本后盈利就打折扣了(倒不是我吹毛求疵,我平时给自己的模型设的更高)。震荡策略不像趋势策略,靠抓大行情来补小亏损,从逻辑上讲,震荡模型既然是抓顶抄底,不会像趋势那样不错过任何一个大行情,而错过任何一个大行情,会给最后的总盈利会打不少折扣,要填补较高的交易成本的话,要么就是提高模型胜率,减少错误的交易比例,要么配合一套趋势模型,做模型组合,给趋势模型削峰填谷
**************************
看了一下,代码里有隐藏偷价格的地方,比如下面这里:
if( L<L[1] && mclose[1]<mopen[1] && mClose[3]> mopen[3] && BB[4]>1 ) { SellShort(Lots,Min(o,L[1])); OpenBar=CurrentBar; }
这里是小于,并不是小于等于,也就是说,满足的时候,价格是比L[1]要小的,在等于L[1]的时候并不满足,
也就是不能用L[1]来发单,后面应该改成:
SellShort(Lots,Min(o,L[1]+MinMove*PriceScale));
又或者是直接把前面L<L[1]改成L<=L[1]
****************************************
superwin 发表于 2013-10-11 08:31  看了一下,代码里有隐藏偷价格的地方,比如下面这里:
if( L1 )
在实盘的时候报价是q_askPrice和Q_BidPrice, 这两个价格本身与close相差了一个跳点以上,因此实盘命令
相应改为Q_AskPrice>=H[1],Q_BidPrice<=L[1],这个与回测的时候H>H[1],和L<L[1]是一样的,因此
上述写法是没问题的。
******************************************
没问题的吗?你可以测试一下因为这一跳而导致整个利润的相差差了多少,很多人就因为这些小细节,导致了测试很完美,实盘很悲惨,如果是实盘是多了一跳,而你做的测试是少了一跳的,那这个测试成绩的水分……
我对楼主的“上述写法是没问题的。”表示很惊讶。
***************************************
superwin 发表于 2013-10-11 08:52  没问题的吗?你可以测试一下因为这一跳而导致整个利润的相差差了多少,很多人就因为这些小细节,导致了测试 ...
只是说H[1],L[1]这个价格速度快是可以吃到的,当q_AskPrice>=H[1]时,H已经大于H[1]了, 我们的目标成交价仍是H[1]。。。跳点问题只能去扣计算机速度问题,不是回测程序问题。。。当然这个程序大概率上是不能赚钱的。。。
****************************************
感谢楼主的思路启发,跟通道系统结合起来用效果更好,1手股指收益160万左右,回撤也比较适中。 |
|
|