//+------------------------------------------------------------------+
//|                                                     Breakout.mq4 |
//|                                                     Michael regle|
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Michael Regle "
#property link      "http://www.metaquotes.net"


//+------------------------------------------------------------------+
//| Initializing Variables                                           |
//| ----------------------                                           |
//| These values may be modified from outside                        |
//| the source via the expert program or indicator API.                               |
//+------------------------------------------------------------------+
extern int TakeProfit = 20;
extern double Lots = 0.01;
extern int TrailingStop = 15;
extern int StopLoss = 35;
extern int Bars2Check = 3; //How many bars back do you want to check for High and Low points? 
extern int Bars2CheckOffset = 0; //Offset to begin the Bar2Check for the High and Low points 
extern int BuyStop = 4; //How many points above breakout to buy
extern int SellStop = 4; //How many points below breakout to sell 
extern int ergodicGrad = 1; //How much does ergodicnow have to be greater than ergodiclast?
extern int TSIseparation = 1; //Separation between ergodic & signal to allow trade 
extern int PendingSafe = 15; //Time that a pending order can be in the pool before 
//  extern int max_movement = 1000; //Maximun range between high and low breakout points
//  extern int OrderDeleteTime = 1440; //Time that a pending order can be in the pool before deleting


//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//---- 
// Things to try:
               //Attach comments to each order to identify them
               //Print all Buy and Sell orders to the long and check the parameters
//----
   ObjectDelete("High");
   ObjectDelete("Low");
   
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
  // Declare our internal variables for the BreakOut Indicator.
  double perClose = 0,newClose = 0,closehalf = 0,durration = 60;
  double perHigh = 0,perLow = 0,adx = 0;
  int cordLow = 0,cordHigh = 0;
  double aBuyStop = 0,aSellStop = 0;
  double Current = 0,halflots = 0,X=0;
  double chart = Period();
  int cnt = 0, bar = 0; 
//  int DeleteThreashHold = OrderDeleteTime;
  int err;
  int barRange;
  //int SL;

   if(!IsConnected())
   {
        Print("Locito Advisor noticed that the connection to the server is broken! This advisor  requires you to be connected in order to monito, place and modify your orders!");
        return(0);
   }

// Delete pending now determined by conditions and new bar, not by time duration below.
//  if (OrdersTotal() >= 1) 
//  {
//      for(cnt=0;cnt<OrdersTotal();cnt++) 
//      {
//      
//       OrderSelect(cnt, SELECT_BY_POS); //Select the current order
//       if (OrderType() == OP_BUYSTOP || OrderType() == OP_SELLSTOP) //this is a waiting order  //with a BuyStop of SellStop
//       {
//         if (CurTime()-OrderOpenTime()>DeleteThreashHold) //check to see how long it has been //in  the pool, if too long then clean up orders which have been in the order pool for longer //than X  time
//         {
//            OrderDelete(OrderTicket());
//             err=GetLastError();
//            Print("Deleted order number ", cnt, ". This completed with the following error //code  (0 = no error occured) : ", err);
//            return(0);
   
//         } 
//       }
//      }
//  }




  if (bar < Bars) //if a new candle/bar has been created, then delete any pending orders in pool less than PendingSafe minutes
  {
// Delete pending -- now determined by conditions and new bar, not by time duration below.
  if (OrdersTotal() >= 1) 
  {
      for(cnt=0;cnt<OrdersTotal();cnt++) 
      {
      
       OrderSelect(cnt, SELECT_BY_POS); //Select the current order
    if (OrderSymbol() == Symbol()) //Make sure this order is for the currency of this chart
    {
       if (OrderType() == OP_BUYSTOP || OrderType() == OP_SELLSTOP) //Is this a Pending Order?
       {
         if (CurTime()-OrderOpenTime()>PendingSafe) //Delete Pending order unless it was created < PendingSafe mins ago.
         {
            OrderDelete(OrderTicket());
             err=GetLastError();
            Print("Deleted order number ", cnt, ". This completed with the following error code  (0 = no error occured) : ", err);
            return(0);
   
         } 
       }
      }
    }
  }
 }





   if (bar < Bars) //if a new candle/bar has been created on the chart, then go and redraw the  High and Low points for the last Bars2Check
  {
   cordHigh = Highest(NULL, 0, MODE_HIGH, Bars2Check, Bars2CheckOffset);
   cordLow =  Lowest(NULL, 0, MODE_LOW, Bars2Check, Bars2CheckOffset); 
   perHigh = High[cordHigh];
   perLow = Low[cordLow];
    
   //Update the global variables perHigh and perLow
   GlobalVariableSet(Period()+"perHigh",perHigh);
   GlobalVariableSet(Period()+"perLow",perLow);
   
   //Draw a line showing the Lowest Point in the last number of Bars2Check
   //Style properties: Color = Green, Line Style = Solid
   ObjectDelete("High");
   ObjectCreate("High", OBJ_HLINE, 0, CurTime(), perHigh, 0, 0, 0, 0);
   ObjectSet("High", OBJPROP_COLOR, Green);
   ObjectSet("High", OBJPROP_STYLE, STYLE_SOLID);

   //Draw a line showing the Lowest Point in the last number of Bars2Check
   //Style properties: Color = Yellow, Line Style = Solid   
   ObjectDelete("Low");
   ObjectCreate("Low", OBJ_HLINE, 0, CurTime(), perLow, 0, 0, 0, 0); 
   ObjectSet("Low", OBJPROP_COLOR, Yellow);
   ObjectSet("Low", OBJPROP_STYLE, STYLE_SOLID);   
   
   //Show our Highest and Lowest points on our chart with the Pips margin between the two
   Comment(High[cordHigh],"Last ",Bars2Check," Bars                                                                   High  ",perHigh,"                   Low   ",perLow,"               ",(perHigh-perLow)/Point," Pips");                   

// PRINT ALL THESE VARIABLES
   aBuyStop = perHigh+BuyStop*Point;
   aSellStop = perLow-SellStop*Point;
   barRange = perHigh-perLow;
   //SL=StopLoss;
   StopLoss = MathMax(StopLoss, barRange/2);

   Print("perHigh=",perHigh," perLow=",perLow," Point=",Point," barRange=",barRange," aBuyStop=",aBuyStop," aSellStop=",aSellStop," StopLoss=",StopLoss);



   bar=Bars;

  }

  //  perHigh = GlobalVariableGet(Period()+"perHigh");// To be used in sending orders below
  //  perLow = GlobalVariableGet(Period()+"perLow");// To be used in sending orders below


//+------------------------------------------------------------------+
//| Custom indicator function                              |
//+------------------------------------------------------------------+

   double ergodicnow = 0;// Set all TSI indicator values to 0
   double ergodiclast = 0;// Set all TSI indicator values to 0
   double signalnow = 0;// Set all TSI indicator values to 0
   double signallast = 0;// Set all TSI indicator values to 0

   int time_frame=Period();
//   Print("time_frame=",time_frame);
   ergodicnow=iCustom(NULL,time_frame,"TSI-Osc",8,5,5,0,0,0);
   ergodiclast=iCustom(NULL,time_frame,"TSI-Osc",8,5,5,0,0,1);
   signalnow=iCustom(NULL,time_frame,"TSI-Osc",8,5,5,0,1,0);
   signallast=iCustom(NULL,time_frame,"TSI-Osc",8,5,5,0,1,1);

      Print("ergodicnow=",ergodicnow," ergodiclast=",ergodiclast," signalnow=",signalnow," signallast=",signallast);


//+------------------------------------------------------------------+
//| Put in pending orders if criteria are right           |
//+------------------------------------------------------------------+

//  if (perHigh-perLow < max_movement*Point) //If the different between the Highest and Lowset  points (in Pips) is less than max_movement (default 30 pips) then go and trade
//  {


   //Initialise our count of the number of open tickets under the current currency
   int CurrentBuy = 0;
   int CurrentSell = 0;

   //Count the number of open tickets in this currency pairing
   for(cnt=0;cnt<OrdersTotal();cnt++) 
   {
    OrderSelect(cnt, SELECT_BY_POS); //Select the current order based on count
    if (OrderSymbol() == Symbol()) //Make sure this order is for the currency of this chart
    {
      if (OrderType() == OP_BUYSTOP || OrderType() == OP_BUY) // This 1 open order is in this currency pairing and it's a buy stop pending or live position 
      {
         CurrentBuy = CurrentBuy+1;
    }
      if (OrderType() == OP_SELLSTOP || OrderType() == OP_SELL) // This 1 open order is in this  currency pairing and it's a sell stop pending or live position 
      {
         CurrentSell = CurrentSell+1;
    }

   }
  }

// FUTURE CODE TO BE WRITTEN: CREATE OPTION TO CHECK >0 Yes/No on these codes below

// PLACE PENDING BUY TRADE IF CRITERIA ARE MET
   if (CurrentBuy == 0 && ergodicnow > ergodiclast+ergodicGrad && ergodicnow > signalnow+TSIseparation) // there are no BUY trades - live or pending - in this currency AND TSI-OSC criteria are met
   {
      OrderSend( Symbol(), OP_BUYSTOP, Lots, aBuyStop, 3, aBuyStop-StopLoss*Point,  aBuyStop+TakeProfit*Point, "OP_BUYSTOP sent. Order code is : 001.", 0, 0, Blue);
      Print("alert = 3 Placed an order in the buy stop pending position for under the ",  Symbol(), " financial instrument. Order parameters are : Volume = ", Lots, " Price = ", aBuyStop,  " Maximum Price Slippage = 3", " StopLoss = ", aBuyStop-StopLoss*Point, " TakeProfit = ",  aBuyStop+TakeProfit*Point, ". The color of the opening arrow on the chart area will appear in  BLUE.");

// DELETE ANY PENDING SELLS in this currency now that a pending buy has been placed
      for(cnt=0;cnt<OrdersTotal();cnt++) 
     {
      
       OrderSelect(cnt, SELECT_BY_POS); //Select the current order
    if (OrderSymbol() == Symbol()) //Make sure this order is for the currency of this chart
      {
       if (OrderType() == OP_SELLSTOP) //Is this a Pending SELL Order?
       {
            OrderDelete(OrderTicket());
             err=GetLastError();
            Print("Deleted order number ", cnt, " because pending BUY was placed. This completed with the following error code  (0 = no error occured) : ", err);
            return(0);
       }
      }
     }

      return(0);   
   }


// PLACE PENDING SELL TRADE IF CRITERIA ARE MET
   if (CurrentSell == 0 && ergodicnow < ergodiclast-ergodicGrad && ergodicnow < signalnow-TSIseparation)

   if (CurrentSell == 0 && ergodicnow < ergodiclast && signalnow < signallast && ergodicnow < signalnow &&  ergodicnow < -5 && signalnow < -5) // there are no SELL trades - live or pending - in this currency AND TSI-OSC criteria are met

      {
         OrderSend( Symbol(), OP_SELLSTOP, Lots, aSellStop, 3, aSellStop+StopLoss*Point,  aSellStop-TakeProfit*Point, "OP_SELLSTOP sent. Order code is : 002.", 0, 0, Blue) ;            
         Print("alert = 4 Placed an order in the sell stop pending position for under the ",  Symbol(), " financial instrument. Order parameters are : Volume = ", Lots, " Price = ",  aSellStop, " Maximum Price Slippage = 3", " StopLoss = ", aSellStop+StopLoss*Point, " TakeProfit  = ", aSellStop-TakeProfit*Point, ".The color of the opening arrow on the chart area will appear  in BLUE.");


// DELETE ANY PENDING BUYS in this currency now that a pending buy has been placed
      for(cnt=0;cnt<OrdersTotal();cnt++) 
     {
      
       OrderSelect(cnt, SELECT_BY_POS); //Select the current order
    if (OrderSymbol() == Symbol()) //Make sure this order is for the currency of this chart
      {

       if (OrderType() == OP_BUYSTOP) //Is this a Pending BUY Order?
       {
            OrderDelete(OrderTicket());
             err=GetLastError();
            Print("Deleted order number ", cnt, " because pending SELL was placed. This completed with the following error code  (0 = no error occured) : ", err);
            return(0);
       }
      }
     }

     return(0);
   }


//   } //End Of: if (perHigh-perLow < max_movement*Point)
  

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