Specifiche
Таймфрейм: любой
Используемые инструменты:
Bollinger bands : период 20
отклонения 2
применено к close
ADX: период 14
применено к close
есть уровень 25
Сигнал на покупку : во время флэта (когда уровень ADX ниже уровня 25) ждем когда цена закроется у нижней полосы болинджера.с параметром o (параметр o определяет , точку открытия ордера,расстояние от средней полосы боллинджера до нижней определяется как 100 % ; 0 % это точка на нижней полосе боллинджера,10 % выше и т.д.) дальше ждем закрытия подтверждающей свечи в сторону увеличения цены. Открываем покупку . Стоплосс задается в пунктах в настройках .Закрытие ордера зависит от опций в советнике, параметры опций будут разъяснены далее. .Ордер закрывается с параметром n когда задевает среднюю полосу боллинджера(параметр n задается в процентах, определяет какая часть объема закрывается, в лотах эта величина округляется в меньшую сторону, 0% это значит что ничего не закрывается ) . Ставится стоплосс на цену открытия ордера, далее ордер закрывается полностью с параметром f ( расстояние от средней полосы боллинджера до верхней полосы принимается за 100 %, параметр f определяемый в процентах задает точку где закроется ордер, если цена до нее дойдет, 0 % это точка на верхней полосе боллинджера 10 % ниже и т.д. )/
Сигнал на продажу : во время флэта (когда уровень ADX ниже уровня 25) ждем когда цена закроется у верхней полосы болинджера. с параметром o (параметр o определяет , точку открытия ордера,расстояние от средней полосы боллинджера до верхней определяется как 100 % ; 0 % это точка на верхней полосе боллинджера,10 % ниже и т.д.), дальше ждем закрытия подтверждающей свечи в сторону уменьшения цены. Открываем продажу . Стоплосс задается в пунктах в настройках .Закрытие ордера зависит от опций в советнике, параметры опций будут разъяснены далее. .Ордер закрывается с параметром n когда задевает среднюю полосу боллинджера. (параметр n задается в процентах, определяет какая часть объема закрывается, в лотах эта величина округляется в меньшую сторону, 0% это значит что ничего не закрывается ).Ставится стоплосс на цену открытия ордера, далее ордер закрывается полностью с параметром f . (расстояние от средней полосы боллинджера до нижней полосы принимается за 100 %, параметр f определяемый в процентах задает точку где закроется ордер, если цена до нее дойдет, 0 % точка на нижней поосе боллинждера , 10% выше и т.д)/
Опции :
В опциях советника ставятся стоп лоссы или не ставятся совсем . Стоплоссы подразделяются на два вида : обыкновенный,который указывается в пунктах и стоп лосс , который зависит от потенциальной ожидаемой прибыли, т.е , когда открывается ордер, от цены ордера до противоположной полосы боллинджера(именно верхней или нижней)подсчитывается расстояние в пунктах. В опциях ставится коэффициент S ( от 0 до 1). который умножается на потенциальную прибыль. Эта величина и есть стоплосс, т.е если коэффициент 0,5, то стоплосс будет величина равная половине потенциальной прибыли . Коэффициент M определяет область закрытия у среденей полосы боллинджерера(расстояние от полосы где открыта сделка до средней полосы определяется как 100 %:полоса где открыта сделка 0%, средняя полоса 100 %.
PS: в итоговом ТЗ нужно будет обсудить как отфильтровать слишком большие подтверждающие свечи,которые закрываются у средней полосы слишком долгое движение между крайней и среденей полосой боллинджера
Исходный код:
property copyright "Copyright 2015, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property strict //--- input parameters input int BBPeriod=20; input double BBdeviation=2.0; input int ADX=14; input double AdxLevel=25; input double SL=2000; input double TP=0; input int Obuy=5; input int Osell=5; input double Lot=0.1; input bool CloseMiddle=true; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ bool buyOpen=false; bool sellOpen=false; double _Obuy; double _OSell; int TryShots= 3; int Slippage=50; // Slippage //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit() { _Obuy=Obuy/100; _OSell=Osell/100; if(!IsTradeAllowed()) { string message="You must allow trading!"; Print(message); Comment(message); return INIT_FAILED; } return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { static datetime prevTime; datetime currentTime=iTime(Symbol(),0,0); if(prevTime==currentTime) { return; } else { prevTime=currentTime; } double adx=iADX(NULL,0,ADX,PRICE_CLOSE,0,2); if(adx<AdxLevel) { double bbMain1=iBands(NULL,0,BBPeriod,BBdeviation,0,PRICE_CLOSE,0,2); double close=iClose(NULL,0,2); if(!buyOpen) { double bbDown1=iBands(NULL,0,BBPeriod,BBdeviation,0,PRICE_CLOSE,2,2); BuyPosition(bbDown1,bbMain1,close); } else { double currentClose=iClose(NULL,0,0); double currentBB=iBands(NULL,0,BBPeriod,BBdeviation,0,PRICE_CLOSE,0,0); if(CloseMiddle && currentClose>currentBB) { CloseOpenPos(OP_BUY); buyOpen=false; } } if(!sellOpen) { double bbUp1=iBands(NULL,0,BBPeriod,BBdeviation,0,PRICE_CLOSE,1,2); SellPosition(bbUp1,bbMain1,close); } else { double currentClose=iClose(NULL,0,0); double currentBB=iBands(NULL,0,BBPeriod,BBdeviation,0,PRICE_CLOSE,0,0); if(CloseMiddle && currentClose<currentBB) { CloseOpenPos(OP_SELL); sellOpen=false; } } } } //+------------------------------------------------------------------+ void BuyPosition(double bbDown,double bbMain,double close) { double dif=bbMain-bbDown; double proc=dif *_Obuy; double DownProc=bbDown+proc; if(close<DownProc) { double openCurrent=iOpen(NULL,0,1); double closeCurrent=iClose(NULL,0,1); if(closeCurrent>openCurrent) { for(int it=0; it<TryShots; it++) { ResetLastError(); RefreshRates(); double sl,tp; if(SL!=0) sl=NormalizeDouble(Bid-SL*Point,Digits); if(TP!=0) tp=NormalizeDouble(Bid+TP*Point,Digits); Print(Ask+" sl"+sl+" tp"+tp); if(!OrderSend(Symbol(),OP_BUY,Lot,NormalizeDouble(Ask,Digits),Slippage,sl,tp)) { if(it>=TryShots) { Print("Failed OP_BUY !"); break; } int err=GetLastError(); if(err==4 || err==6 || err==8 || err==128 || err==137 || err==141 || err==146) Sleep(1000*it); else { Print("Failed OP_BUY !"); break; } } else { buyOpen=true; break; } } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void SellPosition(double bbUp,double bbMain,double close) { double dif=bbUp-bbMain; double proc=dif*_OSell; double UpProc=bbUp-proc; if(close>UpProc) { double openCurrent=iOpen(NULL,0,1); double closeCurrent=iClose(NULL,0,1); if(closeCurrent<openCurrent) { for(int it=0; it<TryShots; it++) { ResetLastError(); RefreshRates(); double sl,tp; if(SL!=0) sl=NormalizeDouble(Ask+SL*Point,Digits); if(TP!=0) tp=NormalizeDouble(Ask-TP*Point,Digits); Print(Bid+" sl"+sl+" tp"+tp); if(!OrderSend(Symbol(),OP_SELL,Lot,NormalizeDouble(Bid,Digits),Slippage,sl,tp)) { if(it>=TryShots) { Print("Failed OP_SELL !"); break; } int err=GetLastError(); if(err==4 || err==6 || err==8 || err==128 || err==137 || err==141 || err==146) Sleep(1000*it); else { Print("Failed OP_SELL !"); break; } } else { sellOpen=true; break; } } } } } //+------------------------------------------------------------------+ //| Close open position | //+------------------------------------------------------------------+ void CloseOpenPos(int or_tp) { int i,err,k=OrdersTotal(); //--- for(i=k-1; i>=0; i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderSymbol()==Symbol()) { if(or_tp==OrderType()) { for(int it=0; it<TryShots; it++) { ResetLastError(); RefreshRates(); double _price=Ask; if(or_tp==OP_BUY) _price=Bid; //--- if(!OrderClose(OrderTicket(),OrderLots(),_price,Slippage)) { if(it>=TryShots) { Print("Failed to close the order ",OrderTicket(),"!"); break; } err=GetLastError(); if(err==4 || err==6 || err==8 || err==128 || err==137 || err==141 || err==146) Sleep(1000*100); else { Print("Failed to close the order ",OrderTicket(),"!"); break; } } else break; } } } } } } //+------------------------------------------------------------------+