//+------------------------------------------------------------------+
//|                           Blessing Martingale_v5-sloptimized.mq4 |
//|                                                            timbo |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "timbo sloptimized"
#property link      ""

//---- input parameters

extern double  levels = 8;
extern double  Multiplier=2;
extern int     PS=20;
extern int     TP=30;
extern int     Level1TP=40;
extern bool    UseStopLoss=true;
extern int     SL=1000;
extern bool    MM=true;
extern int     LotsDigit=2;
extern double  nonMMlot=0.01;
extern int     EF=1000000;
extern double  MaxLot=100;
extern double  MinLot=0.01;
extern int     magiclong=800111;
extern int     magicshort=800222;

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
    
   int cmd = 2; double Lot; double price; int slippage=5; double stoploss; double takeprofit; color colour;
   int BuyTicket = 0; int SellTicket = 0;
   if (MM==true) Lot = NormalizeDouble((AccountEquity()/EF),LotsDigit); else Lot = nonMMlot;
   if (Lot > MaxLot) Lot = MaxLot;
   if (Lot < MinLot) Lot = MinLot;
   
   BuyTicket = FixTakeProfit(magiclong,0);

   if(BuyTicket == 0)
   {
      CleanAllPendings(magiclong,2);
      
      cmd = 0; price = Ask; colour = Green; takeprofit = Ask +PS*Point;
      if(UseStopLoss == true) stoploss = Ask - levels*SL*Point;
      OpenOrder(cmd, Lot, price, slippage, stoploss,Ask + Level1TP*Point, magiclong, colour);
      SetPendingOrders(2,Lot,price,slippage,stoploss,TP,magiclong,levels);
      return(0);
   }

   SellTicket = FixTakeProfit(magicshort,1);

   if(SellTicket == 0)
   {
      CleanAllPendings(magicshort,3);
      
      cmd = 1; price = Bid; colour = Red; takeprofit = Bid - PS*Point; 
      if(UseStopLoss == true) stoploss = Bid + levels*SL*Point; 
      OpenOrder(cmd, Lot, price, slippage, stoploss, Bid - Level1TP*Point, magicshort, colour);
      SetPendingOrders(3,Lot,price,slippage,stoploss,(-TP),magicshort,levels);
      return(0);
   }

//----
   return(0);
  }
//+------------------------------------------------------------------+

int OpenOrder(int cmd, double Lot, double price, int slippage, double stoploss, double takeprofit, int magic, color colour)
{
   RefreshRates();
   while(IsTradeAllowed() == false) Sleep(10000);
   int ticket = OrderSend(Symbol(), cmd, Lot, price, slippage, stoploss, takeprofit, NULL, magic, 0, colour);
   if(ticket < 0)
   {
      Print(price," == ",stoploss);
      //Alert("!!! Error opening order !!! ", GetLastError());
      ticket = 0;
   }
   return(ticket);
}

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

int FixTakeProfit(int magic, int cmd)
{
   int ticket = 0; int i;
   datetime time = 0;
   for(i=0;i<OrdersTotal();i++)
   {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==magic && OrderType() == cmd)
      {
         if(OrderOpenTime() > time) { time = OrderOpenTime();ticket = OrderTicket(); }
      }
   }
   
   if(ticket != 0)
   {
      OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
      double takeprofit = OrderTakeProfit();
   
      for(i=0;i<OrdersTotal();i++)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==magic && OrderType() == cmd)
         {
            if(OrderTakeProfit() != takeprofit) 
            { 
               while(IsTradeAllowed() == false) Sleep(10000);
               OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),takeprofit,0,Yellow); 
            }
         }
      }
   }
   
   return(ticket);
}   
//+------------------------------------------------------

void CleanAllPendings(int magic,int cmd)
{   
      for(int i=OrdersTotal()-1;i>=0;i--)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==magic && OrderType() == cmd)
         {
            int ticket = OrderTicket();
            while(IsTradeAllowed() == false) Sleep(10000);
            OrderDelete(ticket,CLR_NONE);
         }
      }
}

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

void SetPendingOrders(int cmd,double Lot,double price,int slippage,double stoploss,int PS,int magic, int levels)
{
   for(int i=0;i<levels-1;i++)
   {
      while(IsTradeAllowed() == false) Sleep(10000);
      OpenOrder(cmd,Lot*MathPow(Multiplier,i),price-(i+1)*PS*Point,slippage,stoploss,price-i*PS*Point,magic,CLR_NONE);
   }
   return(0);
}

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