//+------------------------------------------------------------------+
//  To Target Manually, draw an horizontal line and tag it targetBuy or targetSell. Line will be deleted after executed. if
//  active it will turn green for targetBuy and Aqua for targetSell.
//
//  To buy/sell stop, tag a line as buyStop or sellStop, enter lot qty in description. Line will turn Green/Red if activeted.
//| tag a line closeAll and all orders will close   (will be purple)                                                              |
//| tag a line neutralize to .. (will be yellow)     
//  tag a line takeProfit to close all profit (will be blue)    
//  tag a line resetGrid to reset grid levels. No for martingale style (will be blue)                                                     |
//+------------------------------------------------------------------+
#property copyright "Bauta"
#property link      "http://www.forexfactory.com/showthread.php?t=548671"
#property version "103.011"


#include <stdlib.mqh>

//style types diferences:
/*
   sA1p1ExGz:    accumulate 1 level by one lot. Expand qty is the bigest lot qty multiplied by the zone levels plus one lot substracting opened side qty.
   mA0x0Ex2:     (by maurineri post 16: http://www.forexfactory.com/showthread.php?p=8382810#post8382810) 
   mA0x0Ep1:      accomulate 0, expands by one lot.           
*/
 
enum styleType
{
   sA1p1ExGz  = 3
   ,mA0x0Ex2  = 4
   ,mA0x0Ep1  = 9
   ,Manual    = 90
    
}; 
 
 
extern int     MagicNumber       = 301;
extern double  Start_Lot_Qty     = 0.01;
extern int     Grid_Increments   = 0;
extern double  MoneyTakeProfit   = 0;
extern styleType TradeStyle = sA1p1ExGz;
extern double  Max_Money_Loss    = 0;
extern int     alert_Levels_Qty  = 0;
extern bool    Pause_Trading     = false;
bool           FlatOnFriday      = true;    //try getting flat on fridays
extern bool    CONTINUE          = true;

bool Trade=True;
int Slippage             = 3;
double LevelDistance     = 20;
double profitTarget;
double entryPrice  = 0;
double lotQty;
int ticketB0,ticketS0;
double levelB1,levelB2,levelB3,levelS1,levelS2,levelS3;
bool FirstTickOfBar=false, isBarInitialized=false;
bool isNextLong = true, takeProfit=false;
double lowestSell, highestBuy;
int profitLabelSize=8;
double startingPrice;
double Total_Buy_Lots, Total_Sell_Lots, Total_Lots;
double bigestLotSize_Buy, bigestLotPrice_Buy, bigestLotSize_Sell, bigestLotPrice_Sell;
bool isNeutralized = false, isNeutralizedSend=false;
int lastLevelBars=0;
double targetLevelMultiplier = 2.5;
bool alertInsideGridSent = false;
bool onExecutionNow;
string nextSize="";
double zoneSize; 
double zoneLevels;
double PointValue;
bool FirstTime=true;
bool verbose = true;
int colorBit = 0;
double maxMoneyLoss;
double Net_Lots;
double Buy_Average, Sell_Average;
double Total_Buy_Size, Total_Sell_Size;
double currentProfit;
double longProfit, shortProfit;
bool isTradingPaused;
double testingLoss;
double zoneTop, zoneBtn;
double insideLevels, counterLevels=10;
bool isInAccumulateMode, refreshLines;
int gridDirection;
double lastOrderQty=0; //to prevent duplicates
int ATRAvg=0;  //day atr averahe in pips
int gridIncrements=10;

//+------------------------------------------------------------------+
int init()
  {
//----
   PointValue = Point;
   if( Digits == 5 || Digits == 3 ) PointValue *= 10;
   isBarInitialized=false;
   lowestSell = 0;
   highestBuy = 0;
   isNeutralized = false;
   Trade=True;
   onExecutionNow = false;
   FirstTime=true;
   isNeutralizedSend=false;
   refreshLines = true;
   if (IsTesting())
   {
      verbose = false;
   }
   //EventSetMillisecondTimer(600);
   EventSetTimer(1);
   
   ticketB0 = 0;
   ticketS0 = 0;
   
   lotQty = Start_Lot_Qty;
   if (lotQty < MarketInfo(Symbol(),MODE_MINLOT))
      lotQty = MarketInfo(Symbol(),MODE_MINLOT);
   Print("Using Lot quantity of: "+lotQty);
   //lotQty = MarketInfo(Symbol(),MODE_MINLOT);
   //Print("Using Minimum Lot quantity of: "+lotQty+" Ignoring Start_Lot_Qty for now...");
      
   maxMoneyLoss = 1000000;
   if (Max_Money_Loss>0)
   {
      maxMoneyLoss = Max_Money_Loss;
      if(verbose) Print("Maximum Money Loss set to "+maxMoneyLoss);
   }
   isTradingPaused = Pause_Trading;
   
   ObjectCreate("Rcvr_Hdg_Alert_"+Symbol(),OBJ_LABEL,0,0,0);   
   ObjectSet("Rcvr_Hdg_Alert_"+Symbol(),OBJPROP_XDISTANCE,0);
   ObjectSet("Rcvr_Hdg_Alert_"+Symbol(),OBJPROP_ANCHOR,ANCHOR_LEFT_UPPER);
   ObjectSetText("Rcvr_Hdg_Alert_"+Symbol(),"*** PLEASE WAIT ***" ,16,NULL,Yellow); 
   
    ObjectCreate("hedgLineB1"+Symbol(),OBJ_HLINE,0,0,levelB1);
    ObjectCreate("hedgLineB2"+Symbol(),OBJ_HLINE,0,0,levelB2);
    ObjectCreate("hedgLineB3"+Symbol(),OBJ_HLINE,0,0,levelB3);
    ObjectCreate("hedgLineS1"+Symbol(),OBJ_HLINE,0,0,levelS1);
    ObjectCreate("hedgLineS2"+Symbol(),OBJ_HLINE,0,0,levelS2);
    ObjectCreate("hedgLineS3"+Symbol(),OBJ_HLINE,0,0,levelS3);
    ObjectSet("hedgLineB1"+Symbol(),OBJPROP_BACK,true);
    ObjectSet("hedgLineB2"+Symbol(),OBJPROP_BACK,true);
    ObjectSet("hedgLineB3"+Symbol(),OBJPROP_BACK,true);
    ObjectSet("hedgLineS1"+Symbol(),OBJPROP_BACK,true);
    ObjectSet("hedgLineS2"+Symbol(),OBJPROP_BACK,true);
    ObjectSet("hedgLineS3"+Symbol(),OBJPROP_BACK,true);
      
    ObjectCreate("hedgEntryLine"+Symbol(),OBJ_HLINE,0,0,0);
    ObjectSet("hedgEntryLine"+Symbol(),OBJPROP_COLOR,clrNONE);   
    ObjectSet("hedgEntryLine"+Symbol(),OBJPROP_BACK,true);
   
   counterLevels = 0;
   if (TradeStyle == sA1p1ExGz)     counterLevels = 1; 
   
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
    EventKillTimer();
    deleteLines(); 
    //ObjectDelete("Rcvr_Hdg_Information_"+Symbol());
    ObjectDelete("rcvHdgBuy_Average_Line_"+Symbol());
    ObjectDelete("rcvHdgSell_Average_Line_"+Symbol());
    ObjectDelete("Rcvr_Hdg_Alert_"+Symbol());
    ObjectDelete("Rcvr_Hdg_Counter_"+Symbol());
    ObjectDelete("Epd_Grid_Pause_"+Symbol());
    ObjectDelete("eGrid_levels_"+Symbol());
    ObjectDelete("rcvHdgBuy_Neutral_Line_"+Symbol());
    ObjectDelete("hedgEntryLine"+Symbol());
    
    //ObjectDelete("targetBuy");
    //ObjectDelete("targetSell");
     
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
   //i do not recomend trading with thise lines. use it for emergencies only.
   gridTradeManualLines();

   //ChartSetInteger
   
   FirstTickOfBar = IsNewBar() || !isBarInitialized;   
   isBarInitialized=true;
   
   currentProfit = subTotalProfit();  //initialize variables
   
   if (FirstTime)
   {
      refreshLines = true;
      gridIncrements = getGridIncrements();
      LevelDistance = gridIncrements*PointValue;
   }
    
   
   LevelDistance = gridIncrements*PointValue;
      
   profitTarget = 0.05;
   //if (TradeStyle == Moderate)
   {
      if( Digits == 5 || Digits == 3 ) 
         profitTarget = gridIncrements*10*MarketInfo(Symbol(),MODE_TICKVALUE)*lotQty; 
      else
         profitTarget = gridIncrements*MarketInfo(Symbol(),MODE_TICKVALUE)*lotQty;
   }
   
   if (TradeStyle==Manual)
      profitTarget *=100;
   
   if (refreshLines)
   {
      updateLines(); 
   }   
   
   //if (isNeutralized)               Trade = false;
   if (-currentProfit>maxMoneyLoss)    Trade = false;
   if (isTradingPaused)                Trade = false;
   if (Total_Lots==0 && !CONTINUE)     Trade = false;
   
   if (Total_Lots==0 && Trade)
   {
      ObjectDelete("targetBuy");
      ObjectDelete("closeAll");
      ObjectDelete("targetSell");
      ObjectDelete("buyStop");
      ObjectDelete("sellStop");
      ObjectDelete("buyLimit");
      ObjectDelete("sellLimit");
      ObjectDelete("neutralize");
      ObjectDelete("takeProfit");
      ObjectDelete("resetGrid");
   }
   
   bool itIsFriday=false;   
   if (FlatOnFriday )
   {
       itIsFriday = DayOfWeek()==5 && Hour()>18; 
   }
      
   if (Trade && !takeProfit && !onExecutionNow && TradeStyle!=Manual)
   {
      if(Total_Lots == 0 && !itIsFriday)
      {
         isInAccumulateMode = counterLevels>0;
         lastOrderQty = 0;
         if (verbose) Print("***STARTING NEW GRID TRADE SET*** ->"+MagicNumber);
         
         if (MagicNumber != 301 /*&& Hour()<2*/ && MagicNumber>300 && MagicNumber<400)
         {
            ObjectSetText("Rcvr_Hdg_Alert_"+Symbol(),"*** PLEASE WAIT ***" ,16,NULL,Yellow); 
            Sleep((MagicNumber-300)*1000*30);
         }   
         
         if (!IsTesting())
         {
            ObjectsDeleteAll(-1, OBJ_ARROW_BUY);
            ObjectsDeleteAll(-1, OBJ_ARROW_SELL);
            ObjectsDeleteAll(-1, OBJ_ARROW);
         }   
         
         gridIncrements = getGridIncrements();
         LevelDistance = gridIncrements*PointValue;
         
         isNeutralizedSend = false;
         
         if (FirstTime)
            isNextLong = iClose(Symbol(),PERIOD_H4,1)> iClose(Symbol(),PERIOD_H4,2);
      
         double allMagicTotal = TotalAllMagicLots();
         if (allMagicTotal!=0)
         {
            isNextLong = allMagicTotal>0;
         }
         
         bool dynamicQty=false;
         if (dynamicQty)
         {
            lotQty = AccountFreeMargin()/80000*0.01;
            lotQty = MathRound(lotQty/MarketInfo(Symbol(),MODE_LOTSTEP))*MarketInfo(Symbol(),MODE_LOTSTEP);
            Print("Grid lot quantity dynamically set to "+lotQty);
         }   
         
         if (isNextLong)
         {
            if(ticketB0==0)
            {
               ticketB0 = gridOpenOrder(OP_BUY, lotQty);
            }   
         }   
         if (!isNextLong)
         {
            if(ticketS0==0)
            {
               ticketS0 = gridOpenOrder(OP_SELL, lotQty);
            }   
         }
         refreshLines = true;
         
      } 
     else  //have position. Accumulate or manage it
     {    
   
      zoneSize     = MathAbs(bigestLotPrice_Buy-bigestLotPrice_Sell);
      zoneLevels   = NormalizeDouble(((zoneSize/LevelDistance)+2),1);
      
      if (!alertInsideGridSent)
      {
         if (alert_Levels_Qty>0 && zoneLevels>=alert_Levels_Qty)
         {
            alertInsideGridSent = true;
            SendMail(Symbol()+" Expand Grid Levels at "+zoneLevels+" Alert. This magic is "+MagicNumber,"");
            Print("***ALERT*** Expand Grid Levels at "+zoneLevels+" Alert. This magic is "+MagicNumber);
         }
      }
      if (FirstTime)
      {
         FirstTime=false;
         int initialPips = zoneSize/PointValue; 
         Print("Initial ZoneSize: "+initialPips+" pips ("+zoneSize+"), ZoneLevels: "+zoneLevels);
      }
      
      
      if (zoneTop <=0 || zoneBtn <=0) insideLevels = 0;
      else
      insideLevels = NormalizeDouble((zoneTop-zoneBtn)/LevelDistance,1);
      
      isInAccumulateMode = insideLevels<counterLevels;
      if (isInAccumulateMode && Total_Buy_Lots>0 && Total_Sell_Lots>0) isInAccumulateMode = false;
      
      double levelBuy=0, levelSell=0;
      
      if(ticketB0==0 && MarketInfo(Symbol(),MODE_BID) >= levelB1 && levelB1>0) 
      {
         //accumulate
         if (isInAccumulateMode && Total_Sell_Lots>0)
         {
            levelBuy = bigestLotSize_Sell+lotQty;
               
         }   
         //reverse
         if (!isInAccumulateMode && Total_Sell_Lots>0)
         {
            
            if (TradeStyle == sA1p1ExGz)
            {
               levelBuy=0;
               if (Total_Buy_Lots<=Total_Sell_Lots)
                  levelBuy = (bigestLotSize_Sell*zoneLevels)+lotQty+lotQty-Total_Buy_Lots;
               if (counterLevels>1)
                  if (levelBuy <= bigestLotSize_Buy+lotQty) levelBuy = bigestLotSize_Buy+lotQty;
            } 
            
         }
         
         if (TradeStyle==mA0x0Ex2) //maurineri
         {
            if (bigestLotSize_Buy>bigestLotSize_Sell)
               levelBuy = bigestLotSize_Buy*2;
            else
               levelBuy = bigestLotSize_Sell*2; 
         }
         
         if (TradeStyle==mA0x0Ep1)
         {
           if (bigestLotSize_Buy>bigestLotSize_Sell)
               levelBuy = bigestLotSize_Buy+lotQty;
            else
               levelBuy = bigestLotSize_Sell+lotQty;  
         }
         
         
         levelB1 = 0;
         isNextLong=true;
         
         ticketB0 = gridOpenOrder(OP_BUY,levelBuy );
         
         refreshLines = true;      
         isBarInitialized=false;
         gridIncrements = getGridIncrements();
         
      }
       
       if(ticketS0==0 && MarketInfo(Symbol(),MODE_ASK) <= levelS1) 
       {
         //accumulate
         if (isInAccumulateMode && Total_Buy_Lots>0)
         {
            levelSell = bigestLotSize_Buy+lotQty;
         }   
         //reverse
         if (!isInAccumulateMode && Total_Buy_Lots>0)
         {
            
            if ( TradeStyle == sA1p1ExGz)
            {
               levelSell=0;
               if (Total_Sell_Lots<=Total_Buy_Lots)
                  levelSell = (bigestLotSize_Buy*zoneLevels)+lotQty+lotQty-Total_Sell_Lots; 
               if (counterLevels>1)
                  if (levelSell <= bigestLotSize_Sell+lotQty) levelSell = bigestLotSize_Sell+lotQty;   
            }
            
         }
         
         
         if (TradeStyle==mA0x0Ex2) //maurineri
         {
            if (bigestLotSize_Buy>bigestLotSize_Sell)
               levelSell = bigestLotSize_Buy*2;
            else
               levelSell = bigestLotSize_Sell*2;    
         }
         
       if (TradeStyle==mA0x0Ep1)
         {
           if (bigestLotSize_Buy>bigestLotSize_Sell)
               levelSell = bigestLotSize_Buy+lotQty;
            else
               levelSell = bigestLotSize_Sell+lotQty;  
         }
         
         
         levelS1 = 0;
         isNextLong=false;
         
         ticketS0 = gridOpenOrder(OP_SELL, levelSell);
               
         refreshLines = true;
         isBarInitialized=false;
         gridIncrements = getGridIncrements();
      }
     }    
   }      
       
                    
   //---TAKE PROFIT
   if(MoneyTakeProfit!=0 && currentProfit>=MoneyTakeProfit) takeProfit = true;
   if (currentProfit>=profitTarget) takeProfit = true;
   if(takeProfit)
   {
      isNextLong = gridDirection==OP_BUY;
      
      if (verbose) Print("Money Take Profit/Reset Reached. --->>>>> CLOSING GRID <<<<<<<--- Balance: ", DoubleToStr(AccountBalance(),0));
      takeProfit = false;
      
      Trade = CONTINUE;
      subCloseOrder();
      subCloseAllOrder();
      subCloseAllOrder();
      subCloseAllPending();
      subCloseAllPending();
      
      ObjectDelete("targetBuy");
      ObjectDelete("closeAll");
      ObjectDelete("targetSell");
      ObjectDelete("buyStop");
      ObjectDelete("sellStop");
      ObjectDelete("buyLimit");
      ObjectDelete("sellLimit");
      ObjectDelete("neutralize");
      ObjectDelete("takeProfit");
      
      Sleep(1000);
      
      bigestLotSize_Buy = 0;
      bigestLotSize_Sell = 0;
      bigestLotPrice_Buy = 0;
      bigestLotPrice_Sell = 0;
      
      lowestSell = 0;
      highestBuy = 0;
      //myQty = 0;
      if (Trade)
      {
         ticketB0 = 0;
         ticketS0 = 0;
      }
      
      
      isBarInitialized = false;
      highestBuy=0;
      lowestSell=0;
      refreshLines = true;
   }
      
   
   return(0);
  }
  
//------------------------------------------------------------------
void OnTimer()
{
   if (colorBit==0)
      colorBit = 1;
   else
      colorBit = 0;
      
   ObjectDelete("rcvHdgBuy_Average_Line_"+Symbol());
   ObjectDelete("rcvHdgSell_Average_Line_"+Symbol());
   if (Total_Buy_Size>0)
   {
      ObjectCreate("rcvHdgBuy_Average_Line_"+Symbol(),OBJ_HLINE,0,0,Buy_Average/Total_Buy_Size);
      ObjectSet("rcvHdgBuy_Average_Line_"+Symbol(),OBJPROP_WIDTH,2);
      ObjectSet("rcvHdgBuy_Average_Line_"+Symbol(),OBJPROP_COLOR,Blue);
   }   
   if (Total_Sell_Size>0)
   {
      ObjectCreate("rcvHdgSell_Average_Line_"+Symbol(),OBJ_HLINE,0,0,Sell_Average/Total_Sell_Size);
      ObjectSet("rcvHdgSell_Average_Line_"+Symbol(),OBJPROP_WIDTH,2);
      ObjectSet("rcvHdgSell_Average_Line_"+Symbol(),OBJPROP_COLOR,Red);
   }
   
   
   bool labelBit = insideLevels>counterLevels && colorBit==0 && TradeStyle!=sA1p1ExGz; 
   if (currentProfit < -500 && colorBit==0) labelBit = true;
   if (labelBit)
   {      
      ObjectSet("Rcvr_Hdg_Alert_"+Symbol(),OBJPROP_COLOR,clrNONE);
   }
   else       
   {
      //ObjectSet("Rcvr_Hdg_Alert_"+Symbol(),OBJPROP_XDISTANCE,1);
      //ObjectSet("Rcvr_Hdg_Alert_"+Symbol(),OBJPROP_YDISTANCE,40);
      ObjectSetText("Rcvr_Hdg_Alert_"+Symbol(),DoubleToStr(Total_Buy_Lots,2)+"/"+DoubleToStr(Total_Sell_Lots,2)+
         "("+DoubleToStr(currentProfit,2)+")"+nextSize ,14,NULL,Yellow); 
      
      if (currentProfit>=0 && Net_Lots>=0)
         ObjectSet("Rcvr_Hdg_Alert_"+Symbol(),OBJPROP_COLOR,Green);
      else if (currentProfit<0 && Net_Lots>=0)
         ObjectSet("Rcvr_Hdg_Alert_"+Symbol(),OBJPROP_COLOR,Red);
      else if (currentProfit>=0 && Net_Lots<0)
         ObjectSet("Rcvr_Hdg_Alert_"+Symbol(),OBJPROP_COLOR,Aqua);
      else if (currentProfit<0 && Net_Lots<0)
         ObjectSet("Rcvr_Hdg_Alert_"+Symbol(),OBJPROP_COLOR,Magenta);  
      if (Total_Sell_Lots==Total_Buy_Lots)
         ObjectSet("Rcvr_Hdg_Alert_"+Symbol(),OBJPROP_COLOR,Yellow); 
      if (Total_Lots==0)
      {
         if (!CONTINUE)
            ObjectSetText("Rcvr_Hdg_Alert_"+Symbol(),"** DISABLED **" ,18,NULL,Red); 
         else
            ObjectSetText("Rcvr_Hdg_Alert_"+Symbol(),"** FLAT **" ,18,NULL,Yellow); 
         ObjectSet("Rcvr_Hdg_Alert_"+Symbol(),OBJPROP_COLOR,Magenta);  
      }
      
   }
   
   ObjectDelete("eGrid_levels_"+Symbol());
   if (alert_Levels_Qty>0 && zoneLevels>=alert_Levels_Qty && Total_Sell_Lots!=Total_Buy_Lots)
   {
      ObjectCreate("eGrid_levels_"+Symbol(),OBJ_LABEL,0,0,0); 
      ObjectSet("eGrid_levels_"+Symbol(),OBJPROP_XDISTANCE,0);
      ObjectSet("eGrid_levels_"+Symbol(),OBJPROP_YDISTANCE,65);
      if (colorBit==0)
      {
         ObjectSetText("eGrid_levels_"+Symbol(),"LEVELS ALERT: "+zoneLevels ,16,NULL,Red);
      }   
   }
   
   ObjectDelete("Epd_Grid_Pause_"+Symbol());
   if (isTradingPaused)
   {
      ObjectCreate("Epd_Grid_Pause_"+Symbol(),OBJ_LABEL,0,0,0); 
      ObjectSet("Epd_Grid_Pause_"+Symbol(),OBJPROP_XDISTANCE,0);
      ObjectSet("Epd_Grid_Pause_"+Symbol(),OBJPROP_YDISTANCE,65);
      ObjectSetText("Epd_Grid_Pause_"+Symbol(),"** PAUSED **" ,20,NULL,Red);
   }  
  
}  
  
  
 //------------------------------------------------------------------
 bool IsNewBar()
{
   static datetime lastbar = 0;
   //datetime curbar = Time[0];
   datetime curbar = TimeMinute(TimeCurrent());
   if(lastbar!=curbar)
   {
      lastbar=curbar;
      return (true);
   }
   else
   {
      return(false);
   }
}
 
//+------------------------------------------------------------------+
void updateLines()
{
   levelB1 = 0;
   levelB2 = 0; 
   levelB3 = 0;
   levelS1 = 0;
   levelS2 = 0;
   levelS3 = 0;
   
   ticketB0 = 0;
   ticketS0 = 0;
   refreshLines = false;
   
   double gridTop, gridBtn;
   
   gridTop = bigestLotPrice_Buy;
      
   levelB1 = gridTop+(1*LevelDistance);    
   levelB2 = gridTop+(2*LevelDistance);    
   levelB3 = gridTop+(3*LevelDistance);  
   
   gridBtn = bigestLotPrice_Sell;
      
   levelS1 = gridBtn-(1*LevelDistance);    
   levelS2 = gridBtn-(2*LevelDistance);    
   levelS3 = gridBtn-(3*LevelDistance);
   
   
   if (levelB1>0 ) {
       ObjectSet("hedgLineB1"+Symbol(),OBJPROP_COLOR,Blue); 
       ObjectSet("hedgLineB1"+Symbol(),OBJPROP_BACK,true);
       ObjectMove(0,"hedgLineB1"+Symbol(),0,0,levelB1);}
   if (levelB2>0) {
       ObjectSet("hedgLineB2"+Symbol(),OBJPROP_COLOR,Blue);
       ObjectSet("hedgLineB2"+Symbol(),OBJPROP_BACK,true); 
       ObjectMove(0,"hedgLineB2"+Symbol(),0,0,levelB2);}
   if (!IsTesting())
   {
      if (levelB3>0 ) {
         ObjectSet("hedgLineB3"+Symbol(),OBJPROP_COLOR,Blue);
         ObjectSet("hedgLineB3"+Symbol(),OBJPROP_BACK,true); 
         ObjectMove(0,"hedgLineB3"+Symbol(),0,0,levelB3);}
   }
         
   if (levelS1>0 ) {
       ObjectSet("hedgLineS1"+Symbol(),OBJPROP_COLOR,Red);
       ObjectSet("hedgLineS1"+Symbol(),OBJPROP_BACK,true);
       ObjectMove(0,"hedgLineS1"+Symbol(),0,0,levelS1);}
   if (levelS2>0 ) {
       ObjectSet("hedgLineS2"+Symbol(),OBJPROP_COLOR,Red);
       ObjectSet("hedgLineS2"+Symbol(),OBJPROP_BACK,true); 
       ObjectMove(0,"hedgLineS2"+Symbol(),0,0,levelS2);}
   if (!IsTesting())
   {
      if (levelS3>0 ) {
         ObjectSet("hedgLineS3"+Symbol(),OBJPROP_COLOR,Red);
         ObjectSet("hedgLineS3"+Symbol(),OBJPROP_BACK,true); 
         ObjectMove(0,"hedgLineS3"+Symbol(),0,0,levelS3);}
   }  
   
   if (Total_Lots>0)
   {
      ObjectSet("hedgEntryLine"+Symbol(),OBJPROP_COLOR,Yellow); 
      ObjectSet("hedgEntryLine"+Symbol(),OBJPROP_BACK,true);
      ObjectMove(0,"hedgEntryLine"+Symbol(),0,0,startingPrice);
   }
   else
       ObjectSet("hedgEntryLine"+Symbol(),OBJPROP_COLOR,clrNONE);                             
      
}

void deleteLines()
{
   ObjectDelete("hedgLineB1"+Symbol());
   ObjectDelete("hedgLineB2"+Symbol());
   ObjectDelete("hedgLineB3"+Symbol());
   
   
   ObjectDelete("hedgLineS1"+Symbol());
   ObjectDelete("hedgLineS2"+Symbol());
   ObjectDelete("hedgLineS3"+Symbol());
   
}


//---
int getGridIncrements()
{
   int R1=0, R5=0, R10=0, R20=0;
   int gIncrements=10;
   
   if (!Trade) return 10;
   
   if (Grid_Increments>0)
   {
      return(Grid_Increments);
   }
   
   // Get the average daily range in pips
   R1  = iATR(NULL,PERIOD_D1, 1,1) / PointValue;
   R5  = iATR(NULL,PERIOD_D1, 5,1) / PointValue;
   R10 = iATR(NULL,PERIOD_D1,10,1) / PointValue;
   R20 = iATR(NULL,PERIOD_D1,20,1) / PointValue;
   ATRAvg  =  (3*R1+2*R5+R10+R20) / 7;
   
   
   gIncrements =  ATRAvg/6; 
   
   if (TradeStyle==sA1p1ExGz)    gIncrements =  ATRAvg/8;    
   if (TradeStyle==Manual)       gIncrements =  ATRAvg/2;
   
   //if (gIncrements<8) gIncrements=8;  
   if (gIncrements<5) gIncrements=5;  
   
   if (Trade && TradeStyle!=Manual)
      if (verbose) Print("Daily ATR Average is "+ATRAvg+" Pips. Changing Grid Increments to "+gIncrements);
   
   return(gIncrements);
}
 
//+------------------------------------------------------------------+
void subCloseAllPending()
{
   int
         NumberOfTries=10,
         cnt, 
         total       = 0,
         ticket      = 0,
         err         = 0,
         c           = 0;
 
   if (verbose) Print("Closing ALL Pending Orders. Magic is :"+MagicNumber);
   
   total = OrdersTotal();
   for(cnt=total-1;cnt>=0;cnt--)
   {
      if (OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderMagicNumber()==MagicNumber)
         {
            if(OrderSymbol() == Symbol() )
            {
               switch(OrderType())
               {               
                  case OP_BUYLIMIT :
                  case OP_BUYSTOP  :
                  case OP_SELLLIMIT:
                  case OP_SELLSTOP :
                     OrderDelete(OrderTicket());
               }
            }
            }
         }   
   }      
}
int subTotalOrders()
{
   int
      cnt, 
      total = 0;
 
   for(cnt=0;cnt<OrdersTotal();cnt++)
   {
      OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
      if(OrderMagicNumber()==MagicNumber)
      {
         if(OrderSymbol()==Symbol())
         total++;
      }   
   }
   return(total);
}

int subTotalOpen()
{
   int
      cnt, 
      total = 0;
 
   for(cnt=0;cnt<OrdersTotal();cnt++)
   {
      OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
      if(OrderMagicNumber()==MagicNumber)
      {
         if(OrderType()<=OP_SELL&&OrderSymbol()==Symbol())
            total++;
      }      
   }
   
   return(total);
}


void resetGrid(int orderType)
{
   string thisComent = "egRbuy";
   if (orderType==OP_SELL) thisComent = "egRsell";
   for(int i=OrdersTotal()-1; i>=0; i--)
   {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      if(OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol())
      {
         if (OrderComment()==thisComent)
            OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),3);
      }
   }
   
   if (orderType==OP_BUY)
      OrderSend(Symbol(),OP_BUY,MarketInfo(Symbol(),MODE_MINLOT),MarketInfo(Symbol(),MODE_ASK),3,0,0,thisComent,MagicNumber,0,Yellow);
   if (orderType==OP_SELL)
      OrderSend(Symbol(),OP_SELL,MarketInfo(Symbol(),MODE_MINLOT),MarketInfo(Symbol(),MODE_BID),3,0,0,thisComent,MagicNumber,0,Yellow);
   Print("Grid levels have been reseted.");
      
}

void removeReset(int orderType)
{
   string thisComent = "egRbuy";
   if (orderType==OP_SELL) thisComent = "egRsell";
   for(int i=OrdersTotal()-1; i>=0; i--)
   {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      if(OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()==orderType)
      {
         if (OrderComment()==thisComent)
            OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),3);
      }
   }
}   


double subTotalProfit()
{
   int
      cnt, 
      total = 0;
   int err       = 0;   
   double Profit = 0;
   Net_Lots = 0;
   highestBuy = 0;
   lowestSell = 0;
   Total_Lots = 0;
   bigestLotSize_Buy  = 0;
   bigestLotPrice_Buy = 0;
   bigestLotSize_Sell  = 0;
   bigestLotPrice_Sell = 0;
   Buy_Average =0; Sell_Average = 0;
   Total_Buy_Size =0; Total_Sell_Size =0;
   longProfit=0; shortProfit=0; 
   zoneTop = 0; zoneBtn = 0;
   startingPrice = Ask;
   datetime startTime=TimeCurrent();
   double buyResetValue=0,sellResetValue=0;
   double thisProfit = 0;
   
   for(cnt=0;cnt<OrdersTotal();cnt++)
   {
      OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
      if(OrderMagicNumber()==MagicNumber)
      {
         if(OrderType()==OP_BUY && OrderSymbol()==Symbol())
         {
             if(highestBuy<OrderOpenPrice()) highestBuy = OrderOpenPrice();
             if (OrderLots()>bigestLotSize_Buy) {bigestLotSize_Buy = OrderLots(); bigestLotPrice_Buy = OrderOpenPrice();}
             Net_Lots+=OrderLots();
             Buy_Average+= OrderOpenPrice()*OrderLots();
             Total_Buy_Size+=OrderLots();
             if (zoneTop < OrderOpenPrice())             zoneTop = OrderOpenPrice();
             if (zoneBtn==0 || zoneBtn>OrderOpenPrice()) zoneBtn = OrderOpenPrice();
             if (OrderOpenTime() < startTime) {startTime=OrderOpenTime(); gridDirection = OP_BUY; startingPrice = OrderOpenPrice();}
             if (OrderComment()=="egRbuy") buyResetValue =  OrderOpenPrice();
             thisProfit = OrderProfit()+OrderSwap()+OrderCommission();
             Profit = Profit + thisProfit;
             longProfit = longProfit + thisProfit;
         }    
         if(OrderType()==OP_SELL && OrderSymbol()==Symbol())
         {
             if(lowestSell==0 || lowestSell>OrderOpenPrice()) lowestSell = OrderOpenPrice();
             if (OrderLots()>bigestLotSize_Sell)  {bigestLotSize_Sell = OrderLots(); bigestLotPrice_Sell = OrderOpenPrice();}
             Net_Lots-=OrderLots();
             Sell_Average+= OrderOpenPrice()*OrderLots();
             Total_Sell_Size+=OrderLots();
             if (zoneTop < OrderOpenPrice())             zoneTop = OrderOpenPrice();
             if (zoneBtn==0 || zoneBtn>OrderOpenPrice()) zoneBtn = OrderOpenPrice();
             if (OrderOpenTime() < startTime) {startTime=OrderOpenTime(); gridDirection = OP_SELL; startingPrice = OrderOpenPrice();}
             if (OrderComment()=="egRsell") sellResetValue =  OrderOpenPrice();
             thisProfit = OrderProfit()+OrderSwap()+OrderCommission();
             Profit = Profit + thisProfit;
             shortProfit = shortProfit + thisProfit;
         }
         
      }   
   }
   
   if (bigestLotPrice_Buy==0)  bigestLotPrice_Buy = bigestLotPrice_Sell;
   if (bigestLotPrice_Sell==0) bigestLotPrice_Sell = bigestLotPrice_Buy;
   
   if (bigestLotPrice_Buy==0)  bigestLotPrice_Buy = Ask;
   if (bigestLotPrice_Sell==0) bigestLotPrice_Sell = Bid;
   
   if (buyResetValue>0)  bigestLotPrice_Buy  = buyResetValue+LevelDistance;
   if (sellResetValue>0) bigestLotPrice_Sell = sellResetValue-LevelDistance;
   
   Total_Buy_Lots = NormalizeDouble(Total_Buy_Size,2);
   Total_Sell_Lots = NormalizeDouble(Total_Sell_Size,2);
   Total_Lots = NormalizeDouble(Total_Buy_Lots+Total_Sell_Lots,2);
   
   string profitLabel = "P/L: "+DoubleToStr(Profit,2)+"/"+Net_Lots;
   string profitLabel2 = profitLabel;
   
   
   
   double  contractsLabel = Total_Buy_Size+Total_Sell_Size;
   string thisDirection = "LONG"; if (gridDirection==OP_SELL) thisDirection = "SHORT";
   if (!IsTesting())
      Comment(profitLabel+ " ("+contractsLabel+") -> "+MagicNumber
         +"\nZone Levels: "+DoubleToStr(zoneLevels,1) +" Inside: "+DoubleToStr(insideLevels,1)
         +"\n"+thisDirection+" Target: "+DoubleToString(profitTarget,2)
      );
      
   if (IsTesting())
   {
      
      if (testingLoss>Profit)             testingLoss   = Profit;
      Comment(profitLabel+ " ("+contractsLabel+") -> "+MagicNumber
         +"\nZone Levels:  "+DoubleToStr(zoneLevels,1)
         +"\nInside Levels: "+ insideLevels
         +"\nLog Lots:     "+ DoubleToStr(Total_Buy_Lots,2)
         +"\nShort Lots:   "+ DoubleToStr(Total_Sell_Lots,2)
         +"\nNet_Lots:     "+Net_Lots
         +"\nGridDirection: "+thisDirection
         +"\nAcummulating: "+ isInAccumulateMode
         +"\nProfit Target: "+profitTarget
         +"\nMaximun Loss: "+DoubleToStr(testingLoss,2)
      
      );
      
      ObjectDelete("Rcvr_Hdg_Alert_"+Symbol());
      
   }
   
   
   //LOSS
   if (-Profit>maxMoneyLoss)
   {
     Print("TRADE MAXIMUN MONEY LOSS. ***NEUTRALIZED*** "+Profit);
     neutralizeGrid();
     isTradingPaused = true;
     return -1; 
   }
   
    
   return(Profit);
}

//-------------------------------------------------------------------
 
//+------------------------------------------------------------------+
int gridOpenOrder(int orderType, double Lotz)
{
   int NumberOfTries = 5;
   //string TicketComment = MagicNumber+"-ExG";
   string TicketComment = MagicNumber; 
   int
         ticket      = 0,
         err         = 0,
         c           = 0;
         
   double         
         aStopLoss   = 0,
         aTakeProfit = 0,
         bStopLoss   = 0,
         bTakeProfit = 0;
   int type = orderType;      
         
         
   if (isInAccumulateMode)
   {
      if (type==OP_BUY)  type = OP_SELL;
      else if (type==OP_SELL) type = OP_BUY;
      //CloseAllProfitAtLevel();
   }   
   
   string typeStr = "BUY";
   if (type==1)  typeStr = "SELL";      
         
   if (verbose) Print("Price is Crosing Grid "+typeStr+" at "+Close[0]+", Inside Levels: "+insideLevels);
         
   //Close Positions if profit
   if (takeProfit)
      return 0;
      
   int zonePips = zoneSize/PointValue;
   if (verbose) Print("ZoneSize: "+zonePips+" pips ("+zoneSize+"), ZoneLevels: "+zoneLevels);
   
   //if (currentProfit>0.05) 
   if (currentProfit>= profitTarget)
   {
      if (verbose) Print("Taking profit at grid level "+Ask);
      takeProfit = true;
      //just in case
      subCloseOrder();
      //Sleep(1000);
      return -1;
   } 
   
   if (Lotz<=0)
   {
      if (verbose) Print("Checking for profit at Grid Line "+typeStr+", grid level "+Ask+" Profit: "+DoubleToStr(currentProfit,2));
      
      //if (!isInAccumulateMode && Total_Buy_Lots>0 && Total_Sell_Lots>0 && MathAbs(Total_Buy_Lots-Total_Sell_Lots) < Total_Lots/2)
      //{
      //   if (type==OP_BUY) Lotz = Total_Sell_Lots*zoneLevels;
      //   if (type==OP_SELL) Lotz = Total_Buy_Lots*zoneLevels;
      //}
      //else
         return -2;
   }
      
   //close all in profit.
   //CloseSideProfit(type);  //close all side if profit.
   //if (TradeStyle==sA1x1Exz)
   //   CloseAllProfitAtLevel(); //close all orders at level profit
   
   isNeutralizedSend = false;
   
   double thisLotz = NormalizeDouble(Lotz,2);
   if (thisLotz>MarketInfo(Symbol(),MODE_MAXLOT))
      thisLotz = MarketInfo(Symbol(),MODE_MAXLOT);
   
   if (thisLotz<MarketInfo(Symbol(),MODE_MINLOT))
      return -2;
   
   thisLotz = MathRound(thisLotz/MarketInfo(Symbol(),MODE_LOTSTEP))*MarketInfo(Symbol(),MODE_LOTSTEP);
   
   //if (lastOrderQty == thisLotz)
   //  if (lastOrderQty>0) return -2;
   //else
   //  lastOrderQty = thisLotz;
   
   if (verbose) Print("Order to "+typeStr+" with lot "+thisLotz+" of "+Lotz+" at grid level "+Ask);   
   
   if (!onExecutionNow)
   {
      onExecutionNow = true;
      if(type==OP_BUY)
      {
         removeReset(OP_BUY);
         for(c=0;c<NumberOfTries;c++)
         {
            entryPrice = NormalizeDouble(MarketInfo(Symbol(),MODE_ASK),Digits);
            ticket=OrderSend(Symbol(),OP_BUY,thisLotz,entryPrice,Slippage,aStopLoss,aTakeProfit,TicketComment,MagicNumber,0,Green);
            err=GetLastError();
            if (verbose) Print("OrderSend #",OrderTicket()," Code: ",err,"-",ErrorDescription(err));
            if(err==0)
            { 
               if(ticket>0) break;
            }
            else
            {
               if(err==0 || err==4 || err==136 || err==137 || err==138 || err==146) //Busy errors
               {
                  Sleep(5000);
                  continue;
               }
               else //normal error
               {
                  if(ticket>0) break;
               }  
            }
         }   
      }
      if(type==OP_SELL)
      {   
         removeReset(OP_SELL);
         for(c=0;c<NumberOfTries;c++)
         {
            entryPrice = NormalizeDouble(MarketInfo(Symbol(),MODE_BID),Digits);
            ticket=OrderSend(Symbol(),OP_SELL,thisLotz,entryPrice,Slippage,bStopLoss,bTakeProfit,TicketComment,MagicNumber,0,Red);
            err=GetLastError();
            if (verbose) Print("OrderSend #",OrderTicket()," Code: ",err,"-",ErrorDescription(err));
            if(err==0)
            { 
               if(ticket>0) break;
            }
            else
            {
               if(err==0 || err==4 || err==136 || err==137 || err==138 || err==146) //Busy errors
               {
                  Sleep(5000);
                  continue;
               }
               else //normal error
               {
                  if(ticket>0) break;
               }  
            }
         }   
      }
      onExecutionNow = false;
   }     
   
   updateLines();
   return(ticket);
}


void CloseAllProfit()
{
   for(int i=OrdersTotal()-1; i>=0; i--)
   {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      
      if(OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol())
      {
         if(OrderProfit()+OrderSwap()+OrderCommission()>0)
         {
            if(!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage))
               if (verbose) Print("OrderClose #",OrderTicket()," not closed, Code: ",GetLastError(),"-",ErrorDescription(GetLastError()));
         }      
      }
   }
}

void CloseAllProfitAtLevel()
{
   for(int i=OrdersTotal()-1; i>=0; i--)
   {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      
      if(OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol())
      {
         if(OrderProfit()+OrderSwap()+OrderCommission()>0.01)
         {
            if(!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage))
               if (verbose) Print("OrderClose #",OrderTicket()," not closed, Code: ",GetLastError(),"-",ErrorDescription(GetLastError()));
         }      
      }
   }
}



bool CloseSideProfit(int orderType)
{
   double sideProfit = 0;
   int i;
   bool closedOrders = false;
   
   for(i=0; i<OrdersTotal(); i++)
   {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      
      if(OrderType()==orderType && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol())
         sideProfit = sideProfit + OrderProfit()+OrderSwap()+OrderCommission();
   }
   
   if (sideProfit>0.05)
   {      
      if (orderType==OP_BUY)
      {
         CloseAllBuys();
         Sleep(1000);
         CloseAllBuys(); //go again just in case
         closedOrders = true;
      }
      if (orderType==OP_SELL)
      {
         CloseAllSells();
         Sleep(1000);
         CloseAllSells(); //go again just in case
         closedOrders = true;
      }
   } 
   return(closedOrders);  
}

void CloseAllBuys()
{
   if (verbose) Print("Closing All BUY's orders at "+Bid);   
   for(int i=OrdersTotal()-1; i>=0; i--)
   {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      
      if(OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol())
      {
         if(OrderType()==OP_BUY || OrderType()==OP_BUYLIMIT || OrderType()==OP_BUYSTOP)
         {
            if(!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage))
               if (verbose) Print("OrderClose#",OrderTicket()," not closed. Error Code: ",GetLastError());
            
         }      
      }
   }
}

void CloseAllSells()
{
   if (verbose) Print("Closing All SELL's orders at "+Ask); 
   for(int i=OrdersTotal()-1; i>=0; i--)
   {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      
      if(OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol())
      {
         if(OrderType()==OP_SELL || OrderType()==OP_SELLLIMIT || OrderType()==OP_SELLSTOP)
         {
            if(!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage))
               if (verbose) Print("Block: CloseOnlyProfits. Order #",OrderTicket()," not closed. Error Code: ",GetLastError());
               
         }      
      }
   }
}


void subCloseAllOrder()
{
   int
         NumberOfTries=10,
         cnt, 
         total       = 0,
         ticket      = 0,
         err         = 0,
         c           = 0;
 
   if (verbose) Print("Closing All BUY's and SELL's orders at "+Bid); 
   total = OrdersTotal();
   for(cnt=total-1;cnt>=0;cnt--)
   {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if(OrderMagicNumber()==MagicNumber)
      {
       if(OrderSymbol() == Symbol())
       {
         switch(OrderType())
         {
            case OP_BUY      :
               for(c=0;c<NumberOfTries;c++)
               {
                  entryPrice = NormalizeDouble(MarketInfo(Symbol(),MODE_BID),Digits);
                  ticket=OrderClose(OrderTicket(),OrderLots(),entryPrice,Slippage,Violet);
                  err=GetLastError();
                  if (verbose) Print("OrderClose #",OrderTicket()," Code: ",err,"-",ErrorDescription(err));
                  if(err==0)
                  { 
                     if(ticket>0) break;
                  }
                  else
                  {
                     if(err==0 || err==4 || err==136 || err==137 || err==138 || err==146) //Busy errors
                     {
                        Sleep(5000);
                        continue;
                     }
                     else //normal error
                     {
                        if(ticket>0) break;
                     }  
                  }
               }   
               break;
               
            case OP_SELL     :
               for(c=0;c<NumberOfTries;c++)
               {
                  entryPrice = NormalizeDouble(MarketInfo(Symbol(),MODE_ASK),Digits);
                  ticket=OrderClose(OrderTicket(),OrderLots(),entryPrice,Slippage,Violet);
                  err=GetLastError();
                  if (verbose) Print("OrderClose #",OrderTicket()," Code: ",err,"-",ErrorDescription(err));
                  if(err==0)
                  { 
                     if(ticket>0) break;
                  }
                  else
                  {
                     if(err==0 || err==4 || err==136 || err==137 || err==138 || err==146) //Busy errors
                     {
                        Sleep(5000);
                        continue;
                     }
                     else //normal error
                     {
                        if(ticket>0) break;
                     }  
                  }
               }   
               break;
               
            case OP_BUYLIMIT :
            case OP_BUYSTOP  :
            case OP_SELLLIMIT:
            case OP_SELLSTOP :
               OrderDelete(OrderTicket());
         }
      
      }
     }      
   }      
}
void subCloseOrder()
{
   int
         NumberOfTries=10,
         cnt, 
         total       = 0,
         ticket      = 0,
         err         = 0,
         c           = 0;
 
   total = OrdersTotal();
   for(cnt=total-1;cnt>=0;cnt--)
   {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if(OrderMagicNumber()==MagicNumber)
      {
        if(OrderSymbol() == Symbol() )
        {
         switch(OrderType())
         {
            case OP_BUY      :
               for(c=0;c<NumberOfTries;c++)
               {
                  entryPrice = NormalizeDouble(MarketInfo(Symbol(),MODE_BID),Digits);
                  ticket=OrderClose(OrderTicket(),OrderLots(),entryPrice,Slippage,Violet);
                  err=GetLastError();
                  if (verbose) Print("OrderClose #",OrderTicket()," Code: ",err,"-",ErrorDescription(err));
                  if(err==0)
                  { 
                     if(ticket>0) break;
                  }
                  else
                  {
                     if(err==0 || err==4 || err==136 || err==137 || err==138 || err==146) //Busy errors
                     {
                        Sleep(5000);
                        continue;
                     }
                     else //normal error
                     {
                        if(ticket>0) break;
                     }  
                  }
               }   
               break;
               
            case OP_SELL     :
               for(c=0;c<NumberOfTries;c++)
               {
                  entryPrice = NormalizeDouble(MarketInfo(Symbol(),MODE_ASK),Digits);
                  ticket=OrderClose(OrderTicket(),OrderLots(),entryPrice,Slippage,Violet);
                  err=GetLastError();
                  if (verbose) Print("OrderClose #",OrderTicket()," Code: ",err,"-",ErrorDescription(err));
                  if(err==0)
                  { 
                     if(ticket>0) break;
                  }
                  else
                  {
                     if(err==0 || err==4 || err==136 || err==137 || err==138 || err==146) //Busy errors
                     {
                        Sleep(5000);
                        continue;
                     }
                     else //normal error
                     {
                        if(ticket>0) break;
                     }  
                  }
               }   
               break;
               
         }
         
      
      }
     }
   }      
}


void gridTradeManualLines()
{
   //find resetGrid line:
   if (ObjectFind(0,"resetGrid")>=0)
   {
      ObjectSet("resetGrid",OBJPROP_WIDTH,2);
      ObjectSet("resetGrid",OBJPROP_COLOR,Blue);
      double resetGridLine = ObjectGetDouble(0,"resetGrid",OBJPROP_PRICE,0);
      if (High[0]>resetGridLine && Low[0]<resetGridLine) //line crossed
      {
         resetGrid(OP_BUY);
         ObjectDelete("resetGrid");
         isBarInitialized = false;
         SendMail(Symbol()+" Line resetGrid executed. "+MagicNumber,"");
         Print("Line resetGrid executed. "+MagicNumber);
      }
   }
   
   //find takeProfit line:
   if (ObjectFind(0,"takeProfit")>=0)
   {
      ObjectSet("takeProfit",OBJPROP_WIDTH,2);
      ObjectSet("takeProfit",OBJPROP_COLOR,Blue);
      double takeProfitLine = ObjectGetDouble(0,"takeProfit",OBJPROP_PRICE,0);
      if (High[0]>takeProfitLine && Low[0]<takeProfitLine) //line crossed
      {
        CloseAllProfit();
         ObjectDelete("takeProfit");
         isBarInitialized = false;
         SendMail(Symbol()+" Line takeProfit executed. "+MagicNumber,"");
         Print("Line takeProfit executed. "+MagicNumber);
      }
   }
   
   //find closeAll lines:
   if (ObjectFind(0,"closeAll")>=0)
   {
      ObjectSet("closeAll",OBJPROP_WIDTH,4);
      ObjectSet("closeAll",OBJPROP_COLOR,Purple);
      double closeAllLine = ObjectGetDouble(0,"closeAll",OBJPROP_PRICE,0);
      if (High[0]>closeAllLine && Low[0]<closeAllLine) //line crossed
      {
         subCloseOrder();
         subCloseAllOrder();
         subCloseAllOrder();
         subCloseAllPending();
         subCloseAllPending();
         Sleep(1000);
         ObjectDelete("closeAll");
         isBarInitialized = false;
         SendMail(Symbol()+" All orders closed by line closeAll. "+MagicNumber,"");
         Print("All orders closed by line closeAll. "+MagicNumber);
      }
   }
   
   //find neutralize line:
   if (ObjectFind(0,"neutralize")>=0)
   {
      ObjectSet("neutralize",OBJPROP_WIDTH,4);
      ObjectSet("neutralize",OBJPROP_COLOR,Yellow);
      double neutralizeLine = ObjectGetDouble(0,"neutralize",OBJPROP_PRICE,0);
      if (High[0]>neutralizeLine && Low[0]<neutralizeLine) //line crossed
      {
         neutralizeGrid();
         
         ObjectDelete("neutralize");
         isBarInitialized = false;
         SendMail(Symbol()+" Set neutralized by line neutralize. "+MagicNumber,"");
         Print("Set neutralized by line neutralize. "+MagicNumber);
      }
   }
   
   //find target lines:
   if (ObjectFind(0,"targetBuy")>=0)
   {
      ObjectSet("targetBuy",OBJPROP_WIDTH,3);
      ObjectSet("targetBuy",OBJPROP_COLOR,Green);
      if (Close[0] > ObjectGetDouble(0,"targetBuy",OBJPROP_PRICE,0))
      {
         CloseAllBuys();
         ObjectDelete("targetBuy");
         isBarInitialized = false;
         SendMail(Symbol()+" Buy Target Line Executed. "+MagicNumber,"");
      }
   }
   
   if (ObjectFind(0,"targetSell")>=0)
   {
      ObjectSet("targetSell",OBJPROP_WIDTH,3);
      ObjectSet("targetSell",OBJPROP_COLOR,Aqua);
      if (Close[0] < ObjectGetDouble(0,"targetSell",OBJPROP_PRICE,0))
      {
         CloseAllSells();
         ObjectDelete("targetSell");
         isBarInitialized = false;
         SendMail(Symbol()+" Sell Target Line Executed. "+MagicNumber,"");
      }
   }
   
   //Find BUY SELL stop lines
   if (ObjectFind(0,"buyStop")>=0)
   {
      ObjectSet("buyStop",OBJPROP_WIDTH,4);
      ObjectSet("buyStop",OBJPROP_COLOR,Green);
      if (Close[0] >= ObjectGetDouble(0,"buyStop",OBJPROP_PRICE,0))
      {
         gridOpenOrder(OP_BUY, NormalizeDouble(ObjectDescription("buyStop"),2)); 
         ObjectDelete("buyStop");
         isBarInitialized = false;
         Trade = true;
         SendMail(Symbol()+" Buy Stop Line Executed. "+MagicNumber,"");
      }
   }
   if (ObjectFind(0,"sellStop")>=0)
   {
      ObjectSet("sellStop",OBJPROP_WIDTH,4);
      ObjectSet("sellStop",OBJPROP_COLOR,Red);
      if (Close[0] <= ObjectGetDouble(0,"sellStop",OBJPROP_PRICE,0))
      {
         gridOpenOrder(OP_SELL, NormalizeDouble(ObjectDescription("sellStop"),2)); 
         ObjectDelete("sellStop");
         isBarInitialized = false;
         Trade = true;
         SendMail(Symbol()+" Sell Stop Line Executed. "+MagicNumber,"");
      }
   }
   
    //Find BUY SELL limut lines
   if (ObjectFind(0,"buyLimit")>=0)
   {
      ObjectSet("buyLimit",OBJPROP_WIDTH,4);
      ObjectSet("buyLimit",OBJPROP_COLOR,Green);
      if (Close[0] <= ObjectGetDouble(0,"buyLimit",OBJPROP_PRICE,0))
      {
         gridOpenOrder(OP_BUY, NormalizeDouble(ObjectDescription("buyLimit"),2)); 
         ObjectDelete("buyLimit");
         isBarInitialized = false;
         Trade = true;
         SendMail(Symbol()+" Buy Limit Line Executed. "+MagicNumber,"");
      }
   }
   if (ObjectFind(0,"sellLimit")>=0)
   {
      ObjectSet("sellLimit",OBJPROP_WIDTH,4);
      ObjectSet("sellLimit",OBJPROP_COLOR,Red);
      if (Close[0] >= ObjectGetDouble(0,"sellLimit",OBJPROP_PRICE,0))
      {
         gridOpenOrder(OP_SELL, NormalizeDouble(ObjectDescription("sellLimit"),2)); 
         ObjectDelete("sellLimit");
         isBarInitialized = false;
         Trade = true;
         SendMail(Symbol()+" Sell Limit Line Executed. "+MagicNumber,"");
      }
   }
}



void neutralizeGrid()
{
   if (Total_Buy_Lots > Total_Sell_Lots)
   {
      entryPrice = NormalizeDouble(MarketInfo(Symbol(),MODE_BID),Digits);
      OrderSend(Symbol(),OP_SELL,Total_Buy_Lots - Total_Sell_Lots,entryPrice,Slippage,0,0,"NTZ",MagicNumber,0,Green);
      if (verbose) Print("OrderSend #",OrderTicket()," Code: ",GetLastError(),"-",ErrorDescription(GetLastError()));
   } 
   if (Total_Buy_Lots < Total_Sell_Lots)
   {
      entryPrice = NormalizeDouble(MarketInfo(Symbol(),MODE_ASK),Digits);
      OrderSend(Symbol(),OP_BUY,Total_Sell_Lots-Total_Buy_Lots,entryPrice,Slippage,0,0,"NTZ",MagicNumber,0,Green);
      if (verbose) Print("OrderSend #",OrderTicket()," Code: ",GetLastError(),"-",ErrorDescription(GetLastError()));
   }  
}


double TotalAllMagicLots()
{
   int cnt;
   double  total = 0;
 
   for(cnt=0;cnt<OrdersTotal();cnt++)
   {
      OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
      if(OrderSymbol()==Symbol())
      {
         if(OrderType()==OP_BUY)
            total += OrderLots();
         if(OrderType()==OP_SELL)
            total -= OrderLots();
      }      
   }
   
   return(total);
}

