MelBar EuSwiss 1.85

Author: Copyright 2020, © Hakimi Abdul Jabar and The Software Suite
11 Views
0 Downloads
0 Favorites
MelBar EuSwiss 1.85
ÿþ//

// MelBar MetaStudio Expert Advisor

//

// Created with: MelBar Expert Advisor MetaStudio

// Website: https://www.facebook.com/TheSoftwareSuite/

//

// Copyright 2020, © Hakimi Abdul Jabar and The Software Suite

//



#property copyright "Copyright 2020, © Hakimi Abdul Jabar and The Software Suite"

#property link      "https://352422.e-junkie.com/"

#property version   "2.88"

#property description "MelBar EuroSwiss M30 500 1.85x 2Y Expert Advisor"

#property strict



static input string StrategyProperties__ = "------------"; // ------ Expert Properties ------

static input double Entry_Amount = 0.20; // Entry lots

input int Stop_Loss   = 13; // Stop Loss (pips)

input int Take_Profit = 61; // Take Profit (pips)

static input string Ind0 = "------------";// ----- Bollinger Bands -----

input int Ind0Param0 = 18; // Period

input double Ind0Param1 = 2.75; // Deviation

static input string Ind1 = "------------";// ----- RVI -----

input int Ind1Param0 = 15; // Period

input double Ind1Param1 = 0.30; // Level



static input string ExpertSettings__ = "------------"; // ------ Expert Settings ------

static input int Magic_Number = 04336930; // Magic Number



#define TRADE_RETRY_COUNT 4

#define TRADE_RETRY_WAIT  100

#define OP_FLAT           -1

#define OP_BUY            ORDER_TYPE_BUY

#define OP_SELL           ORDER_TYPE_SELL



// Session time is set in seconds from 00:00

int sessionSundayOpen           = 0;     // 00:00

int sessionSundayClose          = 86400; // 24:00

int sessionMondayThursdayOpen   = 0;     // 00:00

int sessionMondayThursdayClose  = 86400; // 24:00

int sessionFridayOpen           = 0;     // 00:00

int sessionFridayClose          = 86400; // 24:00

bool sessionIgnoreSunday        = false;

bool sessionCloseAtSessionClose = false;

bool sessionCloseAtFridayClose  = false;



const double sigma=0.000001;



double posType       = OP_FLAT;

ulong  posTicket     = 0;

double posLots       = 0;

double posStopLoss   = 0;

double posTakeProfit = 0;



datetime barTime;

int      digits;

double   pip;

double   stopLevel;

bool     isTrailingStop=false;



ENUM_ORDER_TYPE_FILLING orderFillingType;



int ind0handler;

int ind1handler;



//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

int OnInit()

  {

   barTime          = Time(0);

   digits           = (int) SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);

   pip              = GetPipValue(digits);

   stopLevel        = (int) SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL);

   orderFillingType = GetOrderFillingType();

   isTrailingStop   = isTrailingStop && Stop_Loss > 0;



   ind0handler = iBands(NULL,0,Ind0Param0,0,Ind0Param1,PRICE_CLOSE);

   ind1handler = iRVI(NULL,0,Ind1Param0);



   const ENUM_INIT_RETCODE initRetcode = ValidateInit();



   return (initRetcode);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

void OnTick()

  {

   datetime time=Time(0);

   if(time>barTime)

     {

      barTime=time;

      OnBar();

     }

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

void OnBar()

  {

   UpdatePosition();



   if(posType!=OP_FLAT && IsForceSessionClose())

     {

      ClosePosition();

      return;

     }



   if(IsOutOfSession())

      return;



   if(posType!=OP_FLAT)

     {

      ManageClose();

      UpdatePosition();

     }



   if(posType!=OP_FLAT && isTrailingStop)

     {

      double trailingStop=GetTrailingStop();

      ManageTrailingStop(trailingStop);

      UpdatePosition();

     }



   if(posType==OP_FLAT)

     {

      ManageOpen();

      UpdatePosition();

     }

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

void UpdatePosition()

  {

   posType   = OP_FLAT;

   posTicket = 0;

   posLots   = 0;

   int posTotal=PositionsTotal();

   for(int posIndex=0;posIndex<posTotal;posIndex++)

     {

      const ulong ticket=PositionGetTicket(posIndex);

      if(PositionSelectByTicket(ticket) &&

         PositionGetString(POSITION_SYMBOL)==_Symbol &&

         PositionGetInteger(POSITION_MAGIC)==Magic_Number)

        {

         posType       = (int) PositionGetInteger(POSITION_TYPE);

         posLots       = NormalizeDouble(PositionGetDouble(POSITION_VOLUME), 2);

         posTicket     = ticket;

         posStopLoss   = NormalizeDouble(PositionGetDouble(POSITION_SL), digits);

         posTakeProfit = NormalizeDouble(PositionGetDouble(POSITION_TP), digits);

         break;

        }

     }

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

void ManageOpen()

  {

   double ind0buffer0[]; CopyBuffer(ind0handler,1,1,2,ind0buffer0);

   double ind0buffer1[]; CopyBuffer(ind0handler,2,1,2,ind0buffer1);

   double ind0upBand1 = ind0buffer0[1];

   double ind0dnBand1 = ind0buffer1[1];

   double ind0upBand2 = ind0buffer0[0];

   double ind0dnBand2 = ind0buffer1[0];

   bool ind0long  = Open(0) < ind0dnBand1 - sigma && Open(1) > ind0dnBand2 + sigma;

   bool ind0short = Open(0) > ind0upBand1 + sigma && Open(1) < ind0upBand2 - sigma;



   const bool canOpenLong  = ind0long;

   const bool canOpenShort = ind0short;



   if(canOpenLong && canOpenShort) return;



   if(canOpenLong)

      OpenPosition(OP_BUY);

   else if(canOpenShort)

      OpenPosition(OP_SELL);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

void ManageClose()

  {

   double ind1buffer[]; CopyBuffer(ind1handler,0,1,3,ind1buffer);

   double ind1val1 = ind1buffer[2];

   bool ind1long  = ind1val1 > Ind1Param1 + sigma;

   bool ind1short = ind1val1 < -Ind1Param1 - sigma;



   if(posType==OP_BUY && ind1long)

      ClosePosition();

   else if(posType==OP_SELL && ind1short)

      ClosePosition();

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

void OpenPosition(int command)

  {

   const double stopLoss   = GetStopLossPrice(command);

   const double takeProfit = GetTakeProfitPrice(command);

   ManageOrderSend(command,Entry_Amount,stopLoss,takeProfit,0);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

void ClosePosition()

  {

   const int command=posType==OP_BUY ? OP_SELL : OP_BUY;

   ManageOrderSend(command,posLots,0,0,posTicket);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

void ManageOrderSend(int command,double lots,double stopLoss,double takeProfit,ulong ticket)

  {

   for(int attempt=0; attempt<TRADE_RETRY_COUNT; attempt++)

     {

      if(IsTradeContextFree())

        {

         ResetLastError();

         MqlTick         tick;    SymbolInfoTick(_Symbol,tick);

         MqlTradeRequest request; ZeroMemory(request);

         MqlTradeResult  result;  ZeroMemory(result);



         request.action       = TRADE_ACTION_DEAL;

         request.symbol       = _Symbol;

         request.volume       = lots;

         request.type         = command==OP_BUY ? ORDER_TYPE_BUY : ORDER_TYPE_SELL;

         request.price        = command==OP_BUY ? tick.ask : tick.bid;

         request.type_filling = orderFillingType;

         request.deviation    = 10;

         request.sl           = stopLoss;

         request.tp           = takeProfit;

         request.magic        = Magic_Number;

         request.position     = ticket;

         request.comment      = IntegerToString(Magic_Number);



         bool isOrderCheck = CheckOrder(request);

         bool isOrderSend  = false;



         if(isOrderCheck)

           {

            isOrderSend=OrderSend(request,result);

           }



         if(isOrderCheck && isOrderSend && result.retcode==TRADE_RETCODE_DONE)

            return;

        }

      Sleep(TRADE_RETRY_WAIT);

      Print("Order Send retry no: "+IntegerToString(attempt+2));

     }

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

void ModifyPosition(double stopLoss,double takeProfit,ulong ticket)

  {

   for(int attempt=0; attempt<TRADE_RETRY_COUNT; attempt++)

     {

      if(IsTradeContextFree())

        {

         ResetLastError();

         MqlTick         tick;    SymbolInfoTick(_Symbol,tick);

         MqlTradeRequest request; ZeroMemory(request);

         MqlTradeResult  result;  ZeroMemory(result);



         request.action   = TRADE_ACTION_SLTP;

         request.symbol   = _Symbol;

         request.sl       = stopLoss;

         request.tp       = takeProfit;

         request.magic    = Magic_Number;

         request.position = ticket;

         request.comment  = IntegerToString(Magic_Number);



         bool isOrderCheck = CheckOrder(request);

         bool isOrderSend  = false;



         if(isOrderCheck)

           {

            isOrderSend=OrderSend(request,result);

           }



         if(isOrderCheck && isOrderSend && result.retcode==TRADE_RETCODE_DONE)

            return;

        }

      Sleep(TRADE_RETRY_WAIT);

      Print("Order Send retry no: "+IntegerToString(attempt+2));

     }

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

bool CheckOrder(MqlTradeRequest &request)

  {

   MqlTradeCheckResult check; ZeroMemory(check);

   const bool isOrderCheck=OrderCheck(request,check);

   if(isOrderCheck) return (true);





   if(check.retcode==TRADE_RETCODE_INVALID_FILL)

     {

      switch(orderFillingType)

        {

         case  ORDER_FILLING_FOK:

            orderFillingType=ORDER_FILLING_IOC;

            break;

         case  ORDER_FILLING_IOC:

            orderFillingType=ORDER_FILLING_RETURN;

            break;

         case  ORDER_FILLING_RETURN:

            orderFillingType=ORDER_FILLING_FOK;

            break;

        }



      request.type_filling=orderFillingType;



      const bool isNewCheck=CheckOrder(request);



      return (isNewCheck);

     }



   Print("Error with OrderCheck: "+check.comment);

   return (false);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

double GetStopLossPrice(int command)

  {

   if(Stop_Loss==0) return (0);



   MqlTick tick; SymbolInfoTick(_Symbol,tick);

   const double delta    = MathMax(pip*Stop_Loss, _Point*stopLevel);

   const double price    = command==OP_BUY ? tick.bid : tick.ask;

   const double stopLoss = command==OP_BUY ? price-delta : price+delta;

   const double normalizedStopLoss = NormalizeDouble(stopLoss, _Digits);



   return (normalizedStopLoss);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

double GetTrailingStop()

  {

   MqlTick tick; SymbolInfoTick(_Symbol,tick);

   const double stopLevelPoints = _Point*stopLevel;

   const double stopLossPoints  = pip*Stop_Loss;



   if(posType==OP_BUY)

     {

      const double stopLossPrice=High(1)-stopLossPoints;

      if(posStopLoss<stopLossPrice-pip)

        {

         if(stopLossPrice<tick.bid)

           {

            const double fixedStopLossPrice = (stopLossPrice>=tick.bid-stopLevelPoints)

                                              ? tick.bid - stopLevelPoints

                                              : stopLossPrice;



            return (fixedStopLossPrice);

           }

         else

           {

            return (tick.bid);

           }

        }

     }



   else if(posType==OP_SELL)

     {

      const double stopLossPrice=Low(1)+stopLossPoints;

      if(posStopLoss>stopLossPrice+pip)

        {

         if(stopLossPrice>tick.ask)

           {

            if(stopLossPrice<=tick.ask+stopLevelPoints)

               return (tick.ask + stopLevelPoints);

            else

               return (stopLossPrice);

           }

         else

           {

            return (tick.ask);

           }

        }

     }



   return (posStopLoss);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

void ManageTrailingStop(double trailingStop)

  {

   MqlTick tick; SymbolInfoTick(_Symbol,tick);



   if(posType==OP_BUY && MathAbs(trailingStop-tick.bid)<_Point)

     {

      ClosePosition();

     }



   else if(posType==OP_SELL && MathAbs(trailingStop-tick.ask)<_Point)

     {

      ClosePosition();

     }



   else if(MathAbs(trailingStop-posStopLoss)>_Point)

     {

      posStopLoss=NormalizeDouble(trailingStop,digits);

      ModifyPosition(posStopLoss,posTakeProfit,posTicket);

     }

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

double GetTakeProfitPrice(int command)

  {

   if(Take_Profit==0) return (0);



   MqlTick tick; SymbolInfoTick(_Symbol,tick);

   const double delta      = MathMax(pip*Take_Profit, _Point*stopLevel);

   const double price      = command==OP_BUY ? tick.bid : tick.ask;

   const double takeProfit = command==OP_BUY ? price+delta : price-delta;

   const double normalizedTakeProfit = NormalizeDouble(takeProfit, _Digits);



   return (normalizedTakeProfit);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

datetime Time(int bar)

  {

   datetime buffer[]; ArrayResize(buffer,1);

   const int result=CopyTime(_Symbol,_Period,bar,1,buffer);

   return (result==1 ? buffer[0] : 0);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

double Open(int bar)

  {

   double buffer[]; ArrayResize(buffer,1);

   const int result=CopyOpen(_Symbol,_Period,bar,1,buffer);

   return (result==1 ? buffer[0] : 0);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

double High(int bar)

  {

   double buffer[]; ArrayResize(buffer,1);

   const int result=CopyHigh(_Symbol,_Period,bar,1,buffer);

   return (result==1 ? buffer[0] : 0);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

double Low(int bar)

  {

   double buffer[]; ArrayResize(buffer,1);

   const int result=CopyLow(_Symbol,_Period,bar,1,buffer);

   return (result==1 ? buffer[0] : 0);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

double Close(int bar)

  {

   double buffer[]; ArrayResize(buffer,1);

   const int result=CopyClose(_Symbol,_Period,bar,1,buffer);

   return (result==1 ? buffer[0] : 0);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

double GetPipValue(int digit)

  {

   if(digit==4 || digit==5)

      return (0.0001);

   if(digit==2 || digit==3)

      return (0.01);

   if(digit==1)

      return (0.1);

   return (1);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

bool IsTradeContextFree()

  {

   if(MQL5InfoInteger(MQL5_TRADE_ALLOWED)) return (true);



   uint startWait=GetTickCount();

   Print("Trade context is busy! Waiting...");



   while(true)

     {

      if(IsStopped()) return (false);



      uint diff=GetTickCount()-startWait;

      if(diff>30*1000)

        {

         Print("The waiting limit exceeded!");

         return (false);

        }



      if(MQL5InfoInteger(MQL5_TRADE_ALLOWED)) return (true);



      Sleep(TRADE_RETRY_WAIT);

     }



   return (true);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

bool IsOutOfSession()

  {

   MqlDateTime time0; TimeToStruct(Time(0),time0);

   const int weekDay           = time0.day_of_week;

   const long timeFromMidnight = Time(0)%86400;

   const int periodLength      = PeriodSeconds(_Period);



   if(weekDay==0)

     {

      if(sessionIgnoreSunday) return (true);



      const int lastBarFix = sessionCloseAtSessionClose ? periodLength : 0;

      const bool skipTrade = timeFromMidnight<sessionSundayOpen ||

                             timeFromMidnight+lastBarFix>sessionSundayClose;



      return (skipTrade);

     }



   if(weekDay<5)

     {

      const int lastBarFix = sessionCloseAtSessionClose ? periodLength : 0;

      const bool skipTrade = timeFromMidnight<sessionMondayThursdayOpen ||

                             timeFromMidnight+lastBarFix>sessionMondayThursdayClose;



      return (skipTrade);

     }



   const int lastBarFix=sessionCloseAtFridayClose || sessionCloseAtSessionClose ? periodLength : 0;

   const bool skipTrade=timeFromMidnight<sessionFridayOpen || timeFromMidnight+lastBarFix>sessionFridayClose;



   return (skipTrade);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

bool IsForceSessionClose()

  {

   if(!sessionCloseAtFridayClose && !sessionCloseAtSessionClose) return (false);



   MqlDateTime time0; TimeToStruct(Time(0),time0);

   const int weekDay           = time0.day_of_week;

   const long timeFromMidnight = Time(0)%86400;

   const int periodLength      = PeriodSeconds(_Period);



   bool forceExit=false;

   if(weekDay==0 && sessionCloseAtSessionClose)

     {

      forceExit=timeFromMidnight+periodLength>sessionSundayClose;

     }

   else if(weekDay<5 && sessionCloseAtSessionClose)

     {

      forceExit=timeFromMidnight+periodLength>sessionMondayThursdayClose;

     }

   else if(weekDay==5)

     {

      forceExit=timeFromMidnight+periodLength>sessionFridayClose;

     }



   return (forceExit);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

ENUM_ORDER_TYPE_FILLING GetOrderFillingType()

  {

   const int oftIndex=(int) SymbolInfoInteger(_Symbol,SYMBOL_FILLING_MODE);

   const ENUM_ORDER_TYPE_FILLING fillType=(ENUM_ORDER_TYPE_FILLING)(oftIndex>0 ? oftIndex-1 : oftIndex);



   return (fillType);

  }

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

ENUM_INIT_RETCODE ValidateInit()

  {

   return (INIT_SUCCEEDED);

  }

//+------------------------------------------------------------------+

/*STRATEGY MARKET MetaTrader-Demo; EURCHF; M30 */

/*STRATEGY CODE {"properties":{"entryLots":0.2,"stopLoss":13,"takeProfit":61,"useStopLoss":true,"useTakeProfit":true,"isTrailingStop":false},"openFilters":[{"name":"Bollinger Bands","listIndexes":[4,3,0,0,0],"numValues":[18,2.75,0,0,0,0]}],"closeFilters":[{"name":"RVI","listIndexes":[2,0,0,0,0],"numValues":[15,0.3,0,0,0,0]}]} */

Comments