//+------------------------------------------------------------------+
//|                                               LadderSystemEA.mq4 |
//|                               Copyright © 2013, Khalil Abokwaik. |
//+------------------------------------------------------------------+

//--- input parameters
 #property strict
input string note1= "*** Ladder System by Khalil Abokwaik ***";//note 1
input int      Magic_Number                = 40001;  // magic number
input int      Ladder_Step_Pips            = 100;    // Ladder Step Size.
input int      Unified_Stop_Pips           = 100;    // Ladder_Step_Pips Multiplier for Stop Loss 
input double   Fixed_Lot_Size              = 0.1;    // Starting Lot Size
input int      Max_Open_Orders             = 5;      // Maximum Orders (Ladder Steps)

int ord_arr[100];

double sell_price = 0,buy_price  = 0,stop_loss=0,profit_target=0;
bool OrderSelected=false,OrderDeleted=false;
int NewOrder=0,j;
int oper_max_tries = 100,tries=0;
//-----------
void delete_pending_order()
{ int k=-1;
   for(int j=0;j<100;j++) ord_arr[j]=0;
   
   int ot = OrdersTotal();
   for(j=0;j<ot;j++)
   {
      if(OrderSelect(j,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic_Number)
      {   
         if(OrderType()==OP_BUYSTOP || OrderType()==OP_SELLSTOP)   
         {  k = k + 1; 
            ord_arr[k]=OrderTicket();
         }
      }     
    }
    for(j=0;j<=k;j++)
    {  OrderDeleted=false;
       tries=0;
       while(!OrderDeleted && tries<oper_max_tries)
            {
               OrderDeleted=OrderDelete(ord_arr[j]);
               tries=tries+1;
            }
    }
}


int open_first_order()
{        if(iClose(NULL,PERIOD_D1,0)>iOpen(NULL,PERIOD_D1,0))
         {
            NewOrder=0;
            tries=0;
            while(NewOrder<=0 && tries< oper_max_tries)
            {
               NewOrder=OrderSend(Symbol(),OP_BUY,Fixed_Lot_Size,Ask,5,
                                  Bid-(Unified_Stop_Pips*Point),
                                  Ask+(Max_Open_Orders*Ladder_Step_Pips*Point),
                                  "LSEA",Magic_Number,0,Blue);            
               tries=tries+1;
            }
            OrderSelected=false; tries=0;
            while(!OrderSelected && tries<oper_max_tries)
            {
               OrderSelected=OrderSelect(NewOrder,SELECT_BY_TICKET,MODE_TRADES);
               tries=tries+1;
            }
            buy_price =OrderOpenPrice();
            stop_loss=OrderStopLoss();
            profit_target=OrderTakeProfit();
            sell_price=0;
         }
         else
         {
            NewOrder=0;
            tries=0;
            while(NewOrder<=0 && tries< oper_max_tries)
            {
               NewOrder=OrderSend(Symbol(),OP_SELL,Fixed_Lot_Size,Bid,5,
                                  Ask+(Unified_Stop_Pips*Point),
                                  Bid-(Max_Open_Orders*Ladder_Step_Pips*Point),
                                  "LSEA",Magic_Number,0,Red);            
               tries=tries+1;
            }
            OrderSelected=false;tries=0;
            while(!OrderSelected && tries< oper_max_tries)
            {
               OrderSelected=OrderSelect(NewOrder,SELECT_BY_TICKET,MODE_TRADES);
               tries=tries+1;
            }
            sell_price =OrderOpenPrice();
            stop_loss=OrderStopLoss();
            profit_target=OrderTakeProfit();
            buy_price=0;

         }
         return(NewOrder);
}

int create_ladder_step(int step_number,double org_buy_price,double org_sell_price)
{
   if(org_buy_price>0)
   {
      NewOrder=0;     tries=0;
      while(NewOrder<=0 && tries< oper_max_tries)
      {
         NewOrder=OrderSend(Symbol(),OP_BUYSTOP,Fixed_Lot_Size,
                            org_buy_price+(step_number*Ladder_Step_Pips*Point),5,
                            org_buy_price+(step_number*Ladder_Step_Pips*Point)-(Unified_Stop_Pips*Point),
                            profit_target,"LSEA",Magic_Number,0,Blue);            
         tries=tries+1;
      }
      OrderSelected=false;
      tries=0;
      while(!OrderSelected && tries<oper_max_tries)
      {
         OrderSelected=OrderSelect(NewOrder,SELECT_BY_TICKET,MODE_TRADES);
         tries=tries+1;
      }
   }
   else
   {
      NewOrder=0;tries=0;
      while(NewOrder<=0 && tries< oper_max_tries)
      {  
         NewOrder=OrderSend(Symbol(),OP_SELLSTOP,Fixed_Lot_Size,
                            org_sell_price-(step_number*Ladder_Step_Pips*Point),5,
                            org_sell_price-(step_number*Ladder_Step_Pips*Point)+(Unified_Stop_Pips*Point),
                            profit_target,"LSEA",Magic_Number,0,Red);          
                    
         tries=tries+1;
      }
      OrderSelected=false;
      tries=0;
      while(!OrderSelected && tries< oper_max_tries)
      {
         OrderSelected=OrderSelect(NewOrder,SELECT_BY_TICKET,MODE_TRADES);
         tries=tries+1;
      }
   }
   return(NewOrder);
}

int total_orders()
{ int tot_orders=0;
   for(int i=0;i<OrdersTotal();i++)
   {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderMagicNumber()==Magic_Number 
         && OrderSymbol()==Symbol()
         && (OrderType()==OP_BUY || OrderType()==OP_SELL)
        ) tot_orders=tot_orders+1;
   }
   return(tot_orders);
}

void modify_stop_loss()
{  double max_buy_SL=0,min_sell_SL=99999999;
   OrderSelected=false;
   int i;
   if(buy_price>0)
   {
      for( i=0;i<OrdersTotal();i++)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
            if(OrderMagicNumber()==Magic_Number 
            && OrderSymbol()==Symbol()
            && OrderType()==OP_BUY  ) 
            {
               if(OrderStopLoss()>max_buy_SL) max_buy_SL=OrderStopLoss();
            }

      }
      for( i=0;i<OrdersTotal();i++)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
            if(OrderMagicNumber()==Magic_Number 
            && OrderSymbol()==Symbol()
            && OrderType()==OP_BUY  )       
            {
               if(OrderStopLoss()<max_buy_SL)
               OrderSelected=false; tries=0;
               while(!OrderSelected && tries< oper_max_tries)
               {
                  OrderSelected=OrderModify(OrderTicket(),OrderOpenPrice(),max_buy_SL,profit_target,0,Yellow);
                  tries=tries+1;
               }
               
            }
       }
   }
   if(sell_price>0)
   {
      for( i=0;i<OrdersTotal();i++)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
            if(OrderMagicNumber()==Magic_Number 
            && OrderSymbol()==Symbol()
            && OrderType()==OP_SELL  ) 
            {
               if(OrderStopLoss()<min_sell_SL) min_sell_SL=OrderStopLoss();
               
            }

      }
      for( i=0;i<OrdersTotal();i++)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
            if(OrderMagicNumber()==Magic_Number 
            && OrderSymbol()==Symbol()
            && OrderType()==OP_SELL  )       
            {
               if(OrderStopLoss()>min_sell_SL)
               OrderSelected=false; tries=0;
               while(!OrderSelected && tries< oper_max_tries)
               {
                  OrderSelected=OrderModify(OrderTicket(),OrderOpenPrice(),min_sell_SL,profit_target,0,Yellow);
                  tries=tries+1;
               }
               
            }
       }

   }

}

void init()
{
/*   spread=MarketInfo(Symbol(),MODE_SPREAD);
   min_lot_div=1/MarketInfo(Symbol(),MODE_MINLOT);
   tick_value=MarketInfo(Symbol(),MODE_TICKVALUE);
   last_oper=get_last_oper();
  
   Comment("Spread ",spread," Tick Value ",tick_value," last_vol=",last_vol ); 
 */
}
int start()
{  int first_order=0,next_order=0;
   if(total_orders()==0) 
   { 
      delete_pending_order();
      first_order=open_first_order();
      if(first_order<=0) 
      {
         Alert("Error : Can Not Open First Order.");
         Print("Error : Can Not Open First Order.");
         return(-1);
      }
      for(int i=1;i<Max_Open_Orders;i++)
      {
         next_order=create_ladder_step(i,buy_price,sell_price);
         if(next_order<=0) 
         {
            Alert("Error : Can Not Create Next Order.");
            Print("Error : Can Not Create Next Order.");
            return(-1);
         }
         
      }
   }
   else
   {
      modify_stop_loss();
   }
   return(1);
}

