//+------------------------------------------------------------------+
//|                                             MA Martingale v3.mq4 |
//|                                                    Ramiro Alonso |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, Ramiro Alonso - Version 3.33g2"
#property link      "www.forexfactory.com/forum/Martingale Baggio Method"

//Reformular el tamaño del lote y el take profit cuando una orden entra después de un gap
//muy grande en la cotización. De lo contrario, puede que nunca se cierre con ganancia
//una martingala que si la tuvo, y mucho. Ver caso del 11/01/2007 GBPJPY en reverseband.

#include <stdlib.mqh>
#include <stderror.mqh> //Handles errors.
#include <info.mq4> //Handles information displayed on chart.
#include <log.mq4> //Creates and manages expert log file.
#include <AllOrdersControl.mq4> //Place in memory the array containing orders ejecuted by EA.
                                //It makes faster and secure ejecution of this EA.
#include <OrdersCount.mqh>  //Registers in log file martingale frequency orders statistic.
//#include <GlobalTime.mqh> //Manages start/stop time trading.
#include <ChartWindow.mqh> //Returns chart window background color.
                              
extern int Magic = 9999;//Number used by EA to identify orders placed by itself and manage them.
extern int MagicHedge = 0; //Number used by EA to identify other expert running hedged by this one.

extern int TakeProfit=34; //Fixed pips profit target on each order.
extern int PipsStep=32; //Fixed pips loss until a new order is entered in the same way.
extern int StopLoss=5; //Fixed pips loss when TrailingStop is enabled.

extern int MaxTrades = 9; //Max number of orders in a martingale.
extern int EmergencyClose = 9; //Order number to close martingale at break even.

extern bool TrailingProfit=false; //Change take profit of all orders in martingale to the same
            // price of the last one entered.
extern bool TrailingStop=false; //Change stop loss when last order's TP is hit. The rest of the
         //martingale keeps open with a SL in profit, letting profits run.

extern double FactorLot = 2; //Multiplier of previous lotsize. This is the lot size growth factor of the next order.
extern double FactorPips = 1;//Multiplier of previos PipsStep. This is the pip loss growth factor of the next order.
extern int OrdenSalto = 5;//Number of order to make a jump (Salto) on the FactorLot. It could be negative also (fall).
extern double Salto = 1;//Determine size jump on growth of the lot size.

extern double SecureProfit=0.1;//Profit target of any martingale as balance % for close all.

extern int TradesCriticQtty = 4; //If martingale opened order # TradesCriticQtty, then disables
            // the others EA execution, modifying a global variable flag.
            
extern bool TradeOncePerBar=false; //Trades once per bar.

extern bool TradeBands = true;
extern bool TradeMA = true;

extern bool TradeLong = true;
extern bool TradeShort = true;

extern bool ReverseBands=false; //Read inverse the indicator signals. If buy, then sell and viceversa.
extern bool ReverseMA=false;

extern bool MiniAccount=true; //If EA works on a mini or standar.
extern bool mm=true; //If it is "true" EA manage money management as percentage of balance.

extern double risk=0.15; //Lot size of initial trade as percentage of balance
extern double InitialFixedLots=0.01; //Minimum lot size admitted by broker/trader.
extern double MaxLots=50;//Maximum lot size admitted by broker/trader.

extern string MAMethod_desc="0-Simple/ 1-Exponential/ 2-Smoothed/ 3-Weighted";
extern int MAMethod = MODE_SMMA; //Method of Moving Average Indicator.
extern int MAPeriod = 100;//Period of Moving Average Indicator.
extern string MAPrice_desc="0-Close/ 1-Open/ 2-High/ 3-Low/ 4-8 Others";
extern int MAPrice = MODE_OPEN; //Prices of Moving Avergae Indicator.

extern int MALevel = 120; //Detemines top and bottom bands position from Moving Average.

extern string StopTrading_desc="Stops trading when all opened orders get closed";
extern bool StopTrading = false; //Stops trading if there isn't open orders.

extern int slippage = 40;//Slippage for close orders.

extern string ForceOrderType_desc="Force open trade. 0-Buy/ 1-Sell /6-None";
extern int ForceOrderType = 6;

extern string UpdateVar_Desc="Trader set values when EA lose them by restart";
extern bool UpdateVar = false; //Force variables values update.
extern double NewLastLotSize = 0; //Variable lost
extern int NewMaxTradesAux = 0; //Variable lost
extern int NewPreviousOpenOrders = 0; //variable lost
extern int NewMyOrderType=6; //variable lost

int cnt, cnt2, NumberOfTries = 5, error, leverage=0, LotDecimals=2;
int BandsOrderType = 6, MAOrderType = 6;
double lotsi=0, myLotAux, tp, sl, EnterPrice, SaltoAux;
double PipsStepAux, Margin = 0, StopLossAux = 0;
string text = "";
bool ContinueOpening=true, MarginFlag = true;
datetime TimeBar = 0; //Used for start trade new martingale only once per bar.
color ChartColor = Black; //identifies chart windows background color.
color LabelColor1= Lime, LabelColor2 = Aquamarine;

//Static variable called LastLotSize is stored in permanent memory for later retrieve 
//on EA reloading (i.e. after unnormal computer shut down).
static double LastLotSize = 0;
static int MaxTradesAux = 0;
static int PreviousOpenOrders = 0;
static int myOrderType=6;



//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//-----------  
   
   //This is necessary each time EA needs recognize its opened orders.
   AllOrdersInit(Magic);
   
	if(_ExpertOrdersTotal>0)
   {
     //Si se reinició el EA y no se almacenó el mayor tamaño de lote aseguro este valor.
     //Si bien LastLotSize es una variable static que no se pierde al cerrar el EA
     //aseguro el valor de LastLotSize con _ExpertBiggerLot porque de lo contrario
     //no se van a ingresar las ordenes siguientes necesarias de la martingala.
     //Este valor puede ser erróneo si LastLotSize > 50. _ExpertBiggerLot será igual 50.
     if(LastLotSize <= 0) { LastLotSize = _ExpertBiggerLot; }
     if(PreviousOpenOrders <= 0) { PreviousOpenOrders = _ExpertOrdersTotal; }
     if(myOrderType >= 6) { myOrderType = _ExpertOrdersType; }
   }

//---- Creates a log.txt file to save events information from expert execution.
   string log_file = DoubleToStr(Magic,0);
   log_open( log_file);
   log( "Log file successfully opened at "+TimeToStr(TimeCurrent(),TIME_DATE));
   
   log("STATIC VAR: LastLotSize:"+DoubleToStr(LastLotSize,2)+" MaxTradesAux:"+
   DoubleToStr(MaxTradesAux,0)+" PreviousOpenOrders:"+DoubleToStr(PreviousOpenOrders,0)+
   " myOrderType:"+DoubleToStr(myOrderType,0));
   
//---- Detects critics trades
   CheckCriticTrade(10);
   CheckTradingTime();
      
//---- Creates array for martingales frequency orders.
   if(IsTesting()) init_OrdersCount(MaxTrades);   
   
//---- Creates Labels text for information display.
   info_init(false);
   info_clear();
   
   //Check chart background color for select a contrast label color.
   ChartColor = ChartBackGrdColor();
   if(ChartColor == White)
   {
      LabelColor1 = DarkViolet;
      LabelColor2 = Green;
   }
   else //default
   {
      LabelColor1 = Lime;
      LabelColor2 = Aquamarine;
   }
   
   
   info( 0, "MA Martingale - Version 3.33g2", LabelColor2, 8);
   
   if(StopTrading==false || IsTradeAllowed() || IsExpertEnabled())
   {  
     info( 1, "Expert Advisor is allowed to trade.", LabelColor2);
	  info( 2, "On first tick this message will desapear", LabelColor2 );
	}
	else
	{
	   info( 1, "Expert Advisor is not allowed to trade.", Red, 8 );
	   info( 2, "Set StopTrading to false, Allow Live Trading on Common tab,", Red );
	   info( 3, "and enable Expert Advisors on MT4 Client Terminal.", Red );
	}
  
//----
   return(0);
  }
  
  
  
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   Comment("");
   info_clear();
   info_deinit();
   
   //If is testing update log file with martingales orders count or frequency.
   if(IsTesting())
   {   
      text = "Martingale´s frequency orders |";
      for(int w=0; w<MaxTrades; w++)
      {
         if(groups[w]!=0) 
         {
            text = text+StringConcatenate(" ", DoubleToStr(groups[w],0) )+
            " de "+StringConcatenate(DoubleToStr(w+1,0)," |");
         }
      }
      log(text);    
    }
   
//--------   
   log("LastLotSize:"+DoubleToStr(LastLotSize,2)+" MaxTradesAux:"+
   DoubleToStr(MaxTradesAux,0)+" PreviousOpenOrders:"+DoubleToStr(PreviousOpenOrders,0)+
   " myOrderType:"+DoubleToStr(myOrderType,0));
   
//--------   
   int DeinitReason = UninitializeReason();
   switch(DeinitReason)
   {
        case 0: text="Normal deinit. No forced causes";                          break;
        case 1: text="REASON_REMOVE: Expert removed from chart";                 break;
        case 2: text="REASON_RECOMPILE: Expert recompiled";                      break;
        case 3: text="REASON_CHARTCHANGE: Symbol or timeframe changed on chart"; break;
        case 4: text="REASON_CHARTCLOSE: Chart closed or Test Stopped";          break;
        case 5: text="REASON_PARAMETERS: Input parameters was changed by user";  break;
        case 6: text="REASON_ACCOUNT: Other account activated";                  break;
        default: text="Deinit reason not defined";                               break;
   }

   log("Deinit Reason :"+DeinitReason+" "+text);
   
   log( "Close log file, the expert finishes work at "+TimeToStr(TimeCurrent(),TIME_DATE)+
   " ---------------------------------");
   log_close();
   
//----
   return(0);
  }
  
  
  
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
   ChartColor = ChartBackGrdColor();
   if(ChartColor == White)
   {
      LabelColor1 = DarkViolet;
      LabelColor2 = Green;
   }
   else //default
   {
      LabelColor1 = Lime;
      LabelColor2 = Aquamarine;
   }


   //Identifica las ordenes abiertas por el EA y las carga en una matriz para manejarlas
   //mas rápido y unívoco.
   AllOrdersInit(Magic);
  
   //Updates array values with Martingale orders quantity statistic. Only in backtests.
   if (PreviousOpenOrders>_ExpertOrdersTotal && IsTesting())
   {   
	  int numeral = _ExpertOrdersTotal-MaxTradesAux;
	  update_OrdersCount(numeral);
	}
 
   //This condition is necessary for reset PreviousOpenOrders value when every thing is closed,
   //and not before it is closed. If not, some orders could remain opened.
   if(_ExpertOrdersTotal<1)
   {
      //Delete next enter price line if there isn't opened orders.
      if(ObjectFind("Next Enter Line")==0)
      {
         ObjectDelete("Next Enter Line");
      }
      
      //If there isn't opened orders of this MagicEA, avoid execution if it is disabled,
      //and show information about this set up.
      if(StopTrading==true || !IsTradeAllowed() || !IsExpertEnabled() ||
         !CheckCriticTrade(10) || !CheckTradingTime() && !IsTesting() && ForceOrderType ==6)
      {
         info_clear();
         text = "Magic :"+DoubleToStr(Magic,0);
         if(!CheckCriticTrade(10)) { text=text+" Critic Trade on other EA";}
         if(!CheckTradingTime()) { text=text+" No Trading Time";}
         info( 0, text,LabelColor1, 8);
         
         if(StopTrading) { text=text+" StopTrading: YES"; }
         else {text="StopTrading: No";}
         
         if(IsTradeAllowed()) { text=text+" / IsTradeAllowed: Yes"; }
         else {text=text+" / IsTradeAllowed(): NO";}
         
         if(IsExpertEnabled()) { text=text+" / IsExpertEnabled: Yes"; }
         else {text=text+" / IsExpertEnabled: NO";}
               
         info( 1, text, LabelColor2 );
         return;
      }          
      else
      {
          //Reset trading variables values, and let the EA check new trading conditions.
          if(PreviousOpenOrders>_ExpertOrdersTotal)
          {
            if(TradeOncePerBar)
            {
               //When full martingale is closed, TimeBar identifies current bar to avoid start
               //a new one in the same bar if parameter is set.
               TimeBar = Time[0];
            }
            
            //If complete martingale was closed, check if CriticTrade variable was updated too.
            if(CheckCriticTrade(10))
            {
               //Restore cero value to semaphore.
               //If there isn't any critic martingale from this MagicEA.
	           CriticTrades(10, 0, Magic);
            }
          }
          Comment("");
          LastLotSize = 0;
          MaxTradesAux = 0;
          PreviousOpenOrders = _ExpertOrdersTotal;
          myOrderType=6;
          StopLossAux = 0;
      }
   }
   
   //Manual variable's update. No matter if there isn't opened orders.
   if(UpdateVar==true)
   {
      LastLotSize = NewLastLotSize;
      MaxTradesAux = NewMaxTradesAux;
      PreviousOpenOrders = NewPreviousOpenOrders;
      myOrderType = NewMyOrderType;
   }

   
   //Si al menos una orden tocó su TP, se modificarán los stop loss o se cerrará todo.
   //Asegurando también que se actualice el semaforo CriticTrades.
   if (PreviousOpenOrders>_ExpertOrdersTotal) 
   {
      //Si todavía quedan ordenes abiertas, ver si se cierran todas o se modifican stop loss.
      if(_ExpertOrdersTotal > 0)
      {
         if(!TrailingStop)
         {
            //To ensure complete martingale close PreviousOpenOrders isn't reseted now.
            //So at next tick _ExperOrdersTotal will be bigger than cero.
            CierraTodo();
      
            //Aseguro que no ingrese nuevas ordenes.
            ContinueOpening=False;
            myOrderType = 6;
      
            //Facilita en conteo de ordenes por martingala en back tests.
            if(IsTesting())
            {
               AllOrdersInit(Magic);
               if(_ExpertOrdersTotal<1) { PreviousOpenOrders = _ExpertOrdersTotal; }
            }
      
            MaxTradesAux = 0;
            
            //Este return es necesario para que no reasigne el valor de PreviousOpenOrders
            //cuando no se cerraron juntas todas las ordenes de una misma martingala.
            return;
       
         }
         else
         //Si una orden tocó su TP, entonces modifica Stop Loss en las restantes de la serie.
         {
            //Calculate Stop Loss price for Buy & Sell orders.
            if(_ExpertOrdersType==OP_BUY)
            {
               StopLossAux = NormalizeDouble(_OrderOpenPrice[0],Digits)-StopLoss*Point;
            }
            if(_ExpertOrdersType==OP_SELL)
            {
               StopLossAux = NormalizeDouble(_OrderOpenPrice[0],Digits)+StopLoss*Point;
            }
            //Execute stop loss modification.
            ChangeSL(StopLossAux);

            //Reset LastLotSize value. This is thought for further coding development when EA
            //closes the last order only, remaining opened the rest ones, and if the maket
            //continues against the position, EA opens again the last order closed.
            //If it retraces the martingales will close at each TP.
            if(LastLotSize == 0) { LastLotSize = _ExpertBiggerLot;}
            else LastLotSize = LastLotSize/FactorLot;
         } //end else !TrailingStop.         
      }
      
      //When stop loss was changed, because last order has been closed, and martingale left
      //opened with orders quantity lower than CriticTrades; or there isn't any opened order
      //because complete martingale was closed on broker's server, by enableing TrailingProfit
      //then must update CriticTrade semaphore.
      if(_ExpertOrdersTotal<TradesCriticQtty)
      {
         //If complete martingale was closed, check if CritiTrade variable was updated too.
         if(CheckCriticTrade(10))
         {
            //Restore cero value to semaphore.
            //If there isn't any critic martingale from this MagicEA.
	         CriticTrades(10, 0, Magic);
         }
      }
      
   } //end if PreviousOpenOrders>_ExpertOrdersTotal.
   
         
   //Evalua si se abrieron el maximo de ordenes admitidas, y permite o no abrir nuevas si
   //fuera necesario.
   PreviousOpenOrders=_ExpertOrdersTotal;
   if (_ExpertOrdersTotal>=(MaxTrades+MaxTradesAux)) 
   {
	  ContinueOpening=False;
   } else {
	  ContinueOpening=True;
   }
   
   //Cierra todo si la martingala alcanza un valor mayor o igual a cero a partir de EmergencyClose.
   //Or close all if martingale has reached profit target (not take profit price).
   if(_ExpertProfitTotal>=0)
   {
      //If martingale has reached SecureProfit amount close all or place a stop loss.
      double ProfitTarget = NormalizeDouble(AccountBalance()*SecureProfit/100,2);
      
      if(_ExpertOrdersTotal>=(EmergencyClose+MaxTradesAux) ||
      (_ExpertProfitTotal>=ProfitTarget && _ExpertOrdersTotal>=(OrdenSalto+MaxTradesAux)))
      {
         CierraTodo();
         ContinueOpening=False;
         myOrderType = 6;
         MaxTradesAux = 0;
      }
      
   }
   
   //Si no hay ninguna orden abierta evalua los indicadores técnicos para ver si se presenta
   //una señal de entrada.
   //No se comienza una nueva martingala en una barra en que se cerró una anterior.
   if (_ExpertOrdersTotal<1 && TimeBar !=Time[0])
   {
      //Reset values before read indicators.
      myOrderType=6;
      BandsOrderType =6;
      MAOrderType = 6; 

     //+------------------------------------------------------+
     //|Check indicators signals for new trading.             |
     //|First check MA bands cross over. Then, check MA cross |
     //|Do not check indicators if manual trading is enabled  |
     //+------------------------------------------------------+
	  if(TradeBands && BandsOrderType == 6)
	  {  
	     //First check bands trading.
	     //Identifica una señal de COMPRA = BUY.
	     if(iClose(0,0,0)>(iMA(0,0,MAPeriod,0,MAMethod,MAPrice,0)+(MALevel*Point)))
	     { BandsOrderType=0; }
	  
   	  //Identifica una señal de VENTA = SELL.
	     if(iClose(0,0,0)<(iMA(0,0,MAPeriod,0,MAMethod,MAPrice,0)-(MALevel*Point)))
	     { BandsOrderType=1; }
	     
	     //Invierte la ejecución de la señal. Si señal Buy, entoces Sell y viceversa.
	     if (ReverseBands && BandsOrderType!=6)
	     {
	        switch(BandsOrderType)
	        {
	           case 0: BandsOrderType=1;  break;
	           case 1: BandsOrderType=0;  break;
	        }
	     }
	  } //Fin TradeBands
	  
	  //+--------------------------------------------+
	  // Second signal: check moving average trading.
	  //+--------------------------------------------+
	  if(TradeMA && MAOrderType == 6)
	  {
	     //Identifica una señal de COMPRA = BUY. 
	     if(iLow(0,0,1)>iMA(0,0,MAPeriod,0,MAMethod,MAPrice,1) &&
	     iLow(0,0,2)>iMA(0,0,MAPeriod,0,MAMethod,MAPrice,2) &&
	     iLow(0,0,3)<iMA(0,0,MAPeriod,0,MAMethod,MAPrice,3) &&
	     iLow(0,0,4)<iMA(0,0,MAPeriod,0,MAMethod,MAPrice,4) &&
	     iOpen(0,0,0)>iMA(0,0,MAPeriod,0,MAMethod,PRICE_HIGH,0))
	     { MAOrderType=0; }
	  
	  
	     //Identifica una señal de VENTA = SELL.
	     if(iHigh(0,0,1)<iMA(0,0,MAPeriod,0,MAMethod,MAPrice,1) &&
	     iHigh(0,0,2)<iMA(0,0,MAPeriod,0,MAMethod,MAPrice,2) &&
	     iHigh(0,0,3)>iMA(0,0,MAPeriod,0,MAMethod,MAPrice,3) &&
	     iHigh(0,0,4)>iMA(0,0,MAPeriod,0,MAMethod,MAPrice,4) &&
	     iOpen(0,0,0)<iMA(0,0,MAPeriod,0,MAMethod,PRICE_LOW,0))
	     { MAOrderType=1; }
	
	     if (ReverseMA && MAOrderType!=6)
	     {
	        switch(MAOrderType)
	        {
	           case 0: MAOrderType=1;  break;
	           case 1: MAOrderType=0;  break;
	        }
	     }   	     
	   } //Fin TradeMA
	   
	   if(MAOrderType!=6) {myOrderType = MAOrderType;}
	   if(BandsOrderType!=6) {myOrderType = BandsOrderType;}
	   
	   
	   //Disable trade long or trade short.
	   if(myOrderType==0 && !TradeLong) { myOrderType=6;}	     
	   if(myOrderType==1 && !TradeShort) { myOrderType=6;}


      //Force enter a new trade.
	   if(ForceOrderType==0 || ForceOrderType==1) { myOrderType=ForceOrderType; }   
	         
	} //Fin señales-----------.
	

	//When opened orders is equal to "OrdenSalto", a jump/fall on the lot size growth
   //in next order will increase/decrease equal to "Salto".
   if(_ExpertOrdersTotal==(OrdenSalto+MaxTradesAux-1))SaltoAux=Salto;
   else SaltoAux = 1;
        
   if (!MiniAccount)
   {
      leverage=100000;
      LotDecimals=1;
   }
   else
   {
      leverage=10000;
      LotDecimals=2;
   }
   
   //Determine lot size as % of balance on first order only.
   if(mm && _ExpertOrdersTotal<1)
   { 
      lotsi=NormalizeDouble(AccountBalance()*risk/leverage,LotDecimals);
   }
   
   //Used when initial lot size is fixed.
   if(mm!=true && _ExpertOrdersTotal<1)
   {
      lotsi=InitialFixedLots;
   }
      
   
   //+--------------------------------------------------------------------------+
   //|If there are opened orders then be carefull of run time variables values, |
   //|and calculate next order lot size.                                        |
   //+--------------------------------------------------------------------------+
   if(_ExpertOrdersTotal>0)
   {
      //Si se reinició el EA y no se almacenó el mayor tamaño de lote aseguro este valor.
      //Si bien LastLotSize es una variable static que no se pierde al cerrar el EA
      //aseguro el valor de LastLotSize con _ExpertBiggerLot porque de lo contrario
      //no se van a ingresar las ordenes siguientes necesarias de la martingala.
      //Este valor puede ser erróneo si LastLotSize > 50. _ExpertBiggerLot será igual 50.
     if(LastLotSize <= 0) { LastLotSize = _ExpertBiggerLot; }
     if(PreviousOpenOrders <= 0) { PreviousOpenOrders = _ExpertOrdersTotal; }
     if(myOrderType >= 6) { myOrderType = _ExpertOrdersType; }
     
     //Si ya hay ordenes abiertas determina el tamaño del lote en función de la última
     //orden abierta en la serie.  
     lotsi=NormalizeDouble(LastLotSize*FactorLot*SaltoAux,LotDecimals);
   }
   
   //Asegura que el tamaño del lote sea igual o mayor al InitialFixedLots.
   if(lotsi<=InitialFixedLots) { lotsi=InitialFixedLots; }
   
   //Determina el aumento en la diferencia de pips entre una orden y otra de la martingala.
   PipsStepAux=PipsStep;
   if(_ExpertOrdersTotal>0)
   {
     PipsStepAux=NormalizeDouble(PipsStep*MathPow((1+FactorPips/100),_ExpertOrdersTotal-1),0);  
   }
   
   //Register in log file each new lower free margin produced during testing.
   //Difference between new lower free margin is take in $20 step.
   if(IsTesting() && myOrderType!=6)
   {
      if(Margin == 0) Margin = AccountFreeMargin();
       
      if( NormalizeDouble(AccountFreeMargin(),0) < Margin-20 )
      {  
         log("New lower Free Margin :"+DoubleToStr(AccountFreeMargin(),0));
         Margin = NormalizeDouble(AccountFreeMargin(),0);
      }
   }
   
////////////////////

              
   //Se informa en observaciones de ordenes pendientes el MagicNumber del EA y el número de
   //orden de la serie de la martingala.
   text="Magic: "+DoubleToStr(Magic,0)+". Order: "+(_ExpertOrdersTotal-MaxTradesAux+1)+" of "+MaxTrades;
   
   //+------------------------------------------------------------------------------------------+
   //|Abre ordenes si se dieron las condiciones de los indicadores y si hay margen en la cuenta.|
   //+------------------------------------------------------------------------------------------+
   if(ContinueOpening==true)
   {
   
      int NewOrder = 0;
      //int TraderSpread = (TakeProfit-PipsStep);
      //if(TraderSpread <0) TraderSpread = 0;
      
      switch(myOrderType)
      {
         //BUY
         case 0:
            //Si no hay ordenes abiertas o la última pierde PipsStep abre nuevas ordenes.
            if(_ExpertOrdersTotal<1 ||
            NormalizeDouble((_OrderOpenPrice[0]-Ask),Digits) >= 
            NormalizeDouble(PipsStepAux*Point,Digits) )
            {
            
               if(!CheckMarginAviable()) { return; }
               
               EnterPrice=NormalizeDouble(Ask,Digits);
               if(_ExpertOrdersTotal>0)
                {
                tp=_OrderOpenPrice[0]+(TakeProfit-PipsStep)*Point;
               
                }
               else
                {
                tp = Ask+TakeProfit*Point;
                sl = Ask-MaxTrades*PipsStep*Point;
                }
               // sl = 0;
               
               //Determina el tamaño del lote inferior a MaxLots.         
               myLotAux = NormalizeDouble(MathMod(lotsi,MaxLots),2);
         
               if(myLotAux!=0)
               {
                  //Reservo el valor del tamaño del lote anterior completo para cuando tenga que
                  //fraccionar una orden en no más de MaxLots ó 50.
                  //Esto tiene que estar dentro del if de "pierde PipsStep". De lo contrario myLotsi
                  //se recalcula con cada pip.
                  NewOrder = AbreOrdenes(myOrderType, PreviousOpenOrders,myLotAux,Blue);

                  if(NewOrder>0) LastLotSize = lotsi; //Si no falló el ingreso de la orden
               }
               
               //If martingale sequence full lot size (lotsi) is bigger than MaxLots, then open
               //so many orders with lot = MaxLots as it is necessary.
               if((lotsi/MaxLots)>=1)
		         {
		             //Determine how many order with lot=MaxLots are necessary
		             cnt2 = NormalizeDouble((lotsi-myLotAux)/MaxLots,0);
		              //If previous calc. is bigger than 0 and less than 1 (i.e. 0.999), then
		              //value is 1.
		             if(cnt2<1) {cnt2=1;}
		             for(cnt=cnt2;cnt>0 ;cnt--)
		             {
		               NewOrder = AbreOrdenes(myOrderType, PreviousOpenOrders,MaxLots,Blue);
		               if(NewOrder>0) MaxTradesAux++;//Si no falló el ingreso de la orden fraccionada
		             }
		         }
		         
		         //Change take profit price if TrailingProfit=true from 2º order to MaxTrades order.
		         if(NewOrder>0 && _ExpertOrdersTotal>0 && TrailingProfit==true)
               {
                  ChangeTP(tp,PreviousOpenOrders);
               }
		         
		         //If lot is exact equal to MaxLots, could be a confusion with MaxTradesAux's
		         //count, because order is placed from second AbreOrdenes. Not from the first
		         //with myLotAux.
		         if(myLotAux==0 && lotsi==MaxLots) { MaxTradesAux--;}
            }
            break;
   
         //SELL
         case 1:
            //Ingresa nuevas ordenes si no hay abiertas o la última pierde PipsStep
            if(_ExpertOrdersTotal<1 ||
            NormalizeDouble((Bid-_OrderOpenPrice[0]),Digits) >= 
            NormalizeDouble(PipsStepAux*Point,Digits) )
            {
               if(!CheckMarginAviable()) { return; }
               
               EnterPrice=NormalizeDouble(Bid,Digits);
               if(_ExpertOrdersTotal>0)
                 {
                 tp=_OrderOpenPrice[0]-(TakeProfit-PipsStep)*Point;
                 
                 }
               else
                 {
                 tp = Bid-TakeProfit*Point;
                 sl = Bid+MaxTrades*PipsStep*Point;                 
                 }

               ///sl = 0;
                        
               myLotAux = NormalizeDouble(MathMod(lotsi,MaxLots),2);
		    
               if(myLotAux!=0)
               {
                  NewOrder = AbreOrdenes(myOrderType, PreviousOpenOrders,myLotAux,Red);
                  if(NewOrder>0) LastLotSize = lotsi; 
               }
       
               if((lotsi/MaxLots)>=1)
		         {
		             cnt2 = NormalizeDouble((lotsi-myLotAux)/MaxLots,0);
		             if(cnt2<1) {cnt2=1;}
		             for(cnt=cnt2;cnt>0 ;cnt--)
		             {
                     NewOrder = AbreOrdenes(myOrderType, PreviousOpenOrders,MaxLots,Red);
                     if(NewOrder>0) MaxTradesAux++; 
                   }
               }
               
               if(NewOrder>0 && _ExpertOrdersTotal>0 && TrailingProfit==true)
               {
                  ChangeTP(tp,PreviousOpenOrders);
               }
         
               //Esto sirve para evitar un conteo erroneo de la cantidad de ordenes ingresadas
               //cuando el tamaño del lote de una orden es exactamente igual a MaxLots ó 50.
               if(myLotAux==0 && lotsi==MaxLots) { MaxTradesAux--;}
       
            }
            break;
      }//Fin switch myOrderType
      
      //Si llegó el puntero hasta acá Margin>0 & ninguna orden tocó TP.
      //Esto hay que asignarlo ni bien se ingresa una orden nueva. Ver caso 04/01/07 EURJPY.
      //En un tic se produjo una entrada buy y al siguiente, dio un salto tan alto que se cerró,
      //pero como el EA actualizaba al inicio de un nuevo tic no tenia actualizado la cantidad
      //de ordenes abiertas.
      AllOrdersInit(Magic);
      
      PreviousOpenOrders=_ExpertOrdersTotal;
      
     
   } //Fin ContinueOpening         

   //+--------------------------------------------+
   //| Text showed on chart's top left corner.    |
   //+--------------------------------------------+
   string text1 = "Magic :"+DoubleToStr(Magic,0)+
   " - Floating P/L: "+DoubleToStr(_ExpertProfitTotal,2);
   
   if(ReverseBands || ReverseMA) {text1=text1+" Reverse Signal Enabled";}
   
   string text2 = "Orders Opened: "+DoubleToStr(_ExpertOrdersTotal,0)+
   " - Sequence :"+DoubleToStr((_ExpertOrdersTotal-MaxTradesAux),0)+"/"+MaxTrades+
   " - PreviousOpenOrders: "+DoubleToStr(PreviousOpenOrders,0);
   
   string text3 =  "LastLotSize : "+DoubleToStr(LastLotSize,2)+
   " - NextLotSize :"+DoubleToStr(lotsi,2);
   
   double NextEnter = 0;
   switch(myOrderType)
   {
      case 0:  //BUY
         NextEnter = _OrderOpenPrice[0]-PipsStepAux*Point;
         text3=text3+" - Next Enter Ask :"+DoubleToStr(NextEnter,Digits);
         NextEnter = NextEnter-MarketInfo(Symbol(),MODE_SPREAD)*Point;
         break;
      case 1: //SELL
         NextEnter = _OrderOpenPrice[0]+PipsStepAux*Point;
         text3=text3+" - Next Enter Bid :"+DoubleToStr(NextEnter,Digits);
         break;
      default:  //Not defined
         text3=text3+" No Type Order";
         break;
   }
   
   
   //Draw a yellow line at next enter price level.
   if(NextEnter !=0)
   {
      //If next enter line doesn't exists, then create it.
      if(ObjectFind("Next Enter Line") != 0)
      {
         ObjectCreate("Next Enter Line", OBJ_HLINE, 0, Time[0], NextEnter);
         ObjectSet("Next Enter Line", OBJPROP_STYLE, STYLE_DASHDOT);
         ObjectSet("Next Enter Line", OBJPROP_WIDTH,1);
         ObjectSet("Next Enter Line", OBJPROP_COLOR, Yellow);
      }
      else //If next enter line already exist, then move it to new next enter price.
      {
         ObjectMove("Next Enter Line", 0, Time[0], NextEnter);
      }
   }
   
   
   
   
   if(ForceOrderType==0) { string text4="FORCE BUY"; }
   else if(ForceOrderType==1) { text4="FORCE SELL"; }
   else text4="Auto Trading";
   
   if(UpdateVar) {text4 = text4+"- Variable´s Update: MANUAL";}
   else {text4 = text4+"- Variable´s Update: Auto";}
   
   //If critic trades quantity is opened, check global variable semaphore CriticTrades
   //updated. In this case value must be cero or Magic. Semaphore is restore to cero
   //when complete martingale is closed.
   //Critic global variable must be delete or modify manually if it is necessary.
   if(_ExpertOrdersTotal>=TradesCriticQtty)
   {
      //Switch on semaphore red light.
      CriticTrades(10,Magic,0);
      if(!CheckCriticTrade(10)) { text4=text4+"- Critic Trade Not Updated"; }
      else { text4=text4+" - CRITIC TRADE ON"; }
      
   }
     
   if(ContinueOpening==true)
   {
      if(StopTrading==true)
      {
         string text5 = "EA will stop at martingale close";
      }
      else text5 = "ContinueOpening - Account Margin: "+DoubleToStr(AccountFreeMargin(),2);
   }
   else text5 = "No signals or Max Trades Entered - Free Margin "+DoubleToStr(AccountFreeMargin(),2);
   
   //Display information on top left corner.   
   info( 0, text1, LabelColor1, 8 );
	info( 1, text2, LabelColor2 );
	info( 2, text3, LabelColor2 );
	info( 3, text4, LabelColor2 );
	info( 4, text5, LabelColor2 );  


//----
   return(0);
  }
//----------------------------  END of ejecution of every market tick.
  

//+------------------------------------------------+
//| Manage martingale closing                      |
//+------------------------------------------------+
bool CierraTodo()
{
//----
   //If expert is enabled try to close all positions opened with its Magic Number.
   if(IsExpertEnabled() && IsTradeAllowed())
   {
      //Check all opened orders on this account.  
      for(int h=OrdersTotal() ; h>=0; h--)
	   {
	      OrderSelect(h, SELECT_BY_POS, MODE_TRADES);
	      //Check if order belongs to this martingale.
	      if (OrderSymbol()==Symbol() && OrderMagicNumber() == Magic) 
	      {
	        //Retry to close order NumberOfTries times before give up.
	        for(int i = 1 ; i <= NumberOfTries; i++)
	        {
	           //Context busy don't take off retries chances. It simply add wait time.
	           if(IsTradeContextBusy())
	           {
	              text = "Trade context busy. Please wait. Retry :"+i+"/"+NumberOfTries;
	              Print(text);
	              log(text);
	              Sleep(3000); //3 seconds.
	              RefreshRates();
	           }
	       
	           //Lets try to close the order.
	           bool TicketClosed = OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(OrderClosePrice(),Digits),slippage,Yellow);
	        
	           //If close order result false, means an error occured. Show information.
	           //Wait 5 seconds and retry.
	           if(!TicketClosed)
   	        {
   	           error = GetLastError(); 
   	           text = "Error :"+error+" "+ErrorDescription(error)+" cerrando orden: "+
   	           DoubleToStr(OrderTicket(),2)+". Reintento :"+DoubleToStr(i,0)+"/"+NumberOfTries;
		           Print(text);
		           log(text);
		           Sleep(3000); //3 segundos
		           RefreshRates();
		        }
		        else  //Retries finished or order could been closed. Look for next order to close.
		        {
		           text="Orden #"+DoubleToStr(OrderTicket(),0)+" cerrada en intento :"+i+
		           "/"+NumberOfTries+" al precio :"+DoubleToStr(OrderClosePrice(),Digits);
		           Print(text);
		           if(!IsTesting()) {log(text);}
		           break;
		        }
	        } //end for i
	        
	         if(!TicketClosed)
   	      {
   	        int error = GetLastError();
   	        text = "Could not be closed order: "+DoubleToStr(OrderTicket(),0)+" Error: "+error+
   	        " "+ErrorDescription(error);
		        Print(text);
		        log(text);
		        return(false);
		      }
	      } //end if MagicNumber = Magic.
	   } //end for h
	
	   CheckMarginAviable();
	
	   //Restore cero value to semaphore. There isn't any critic martingale from this MagicEA.
	   CriticTrades(10, 0, Magic);
	   
	   return(true);
	} //end IsExperEnabled.
	else
	{
	   error = GetLastError();
      
      text="No se pudo ejecutar cierre ordenes.";
	   
	   if(error == 0 && !IsExpertEnabled())
      {
         text = text+" Expert is disabled.";
      }
      else if(error == 0 && !IsTradeAllowed())
      {
         text = text+" Trade is not allowed.";
      }
	   Print(text);
	   log(text);
	   
	   text = "Error :"+error+" "+ErrorDescription(error)+" cerrando orden.";
	   Print(text);
	   log(text);
	   
	   return(false);	
	 }
		
//----

} 


//+-----------------------------------------------------------------------------------------+
// Modifies take profit of opened orders to ensure exact and simultaneous close of all the
// martingale. It also avoids problems on internet connection, because take profit is placed
// on broker server.
//+-----------------------------------------------------------------------------------------+
bool ChangeTP(double TP, int OrderOnThisMartingale)
{    
   for(int h=0; h<OrdersTotal()-1; h++)
   {
      OrderSelect(h, SELECT_BY_POS, MODE_TRADES);
      
      if (OrderSymbol()==Symbol() && OrderMagicNumber() == Magic) 
	   {
	        //This avoid change TP on the martingale's last/s order/s when its lot size
	        //is bigger than MaxLotSize.
	        if(OrderOnThisMartingale <= 0)
	        { break; }
	    
	        OrderOnThisMartingale--;
	           
	        for(int i = 1 ; i <= NumberOfTries; i++)
	        {
	           bool TicketModify = OrderModify(OrderTicket(),0,sl,TP,0,Aquamarine);
	        
	           if(!TicketModify)
   	        {
   	           error = GetLastError(); 
   	           text = "Error :"+error+" "+ErrorDescription(error)+" modificando TP orden: "+
   	           DoubleToStr(OrderTicket(),0)+". Reintento :"+i+"/"+NumberOfTries;
		           Print(text);
		           log(text);
		           Sleep(5000); //5 segundos
		           RefreshRates();
		        }
		        else
		        {
		           text="TP Orden #"+DoubleToStr(OrderTicket(),0)+" modificado en intento :"+i+
		           "/"+NumberOfTries+" al precio aprox.:"+DoubleToStr(TP,Digits);
		           Print(text);
		           if(!IsTesting()) {log(text);}
		           break;
		        }
	        } //end for i
	        
	        if(!TicketModify)
	        {
	           text="No se pudo modificar TP orden :"+OrderTicket();
	           Print(text);
	           log(text);
	           return(false);
	        }
	    }   
   } //end for h

//----
   return(true);
} //End ChangeTP() -----------

//+-------------------------------------------------------+
//|Function for change stop loss on each martingale order |
//+-------------------------------------------------------+
bool ChangeSL(double SL)
{
   //Don't try to modify orders if expert is disabled, it looks like hunged.
   if(IsExpertEnabled() && IsTradeAllowed())
   {
      for(int h=0; h<OrdersTotal(); h++)
      {
         OrderSelect(h, SELECT_BY_POS, MODE_TRADES);
      
         if (OrderSymbol()==Symbol() && OrderMagicNumber() == Magic) 
	      {
	        for(int i = 1 ; i <= NumberOfTries; i++)
	        {
	           bool TicketModify = OrderModify(OrderTicket(),tp,SL,OrderTakeProfit(),0,Pink);
	        
	           if(!TicketModify)
   	        {
   	           error = GetLastError(); 
   	           text = "Error :"+error+" "+ErrorDescription(error)+" modificando SL orden: "+
   	           DoubleToStr(OrderTicket(),0)+". Reintento :"+i+"/"+NumberOfTries;
		           Print(text);
		           log(text);
		           Sleep(5000); //5 segundos
		           RefreshRates();
		           }
		        else
		        {
		           text="SL Orden #"+DoubleToStr(OrderTicket(),0)+" modificado en intento :"+i+
		           "/"+NumberOfTries+" al precio aprox.:"+DoubleToStr(SL,Digits);
		           Print(text);
		           if(!IsTesting()) {log(text);}
		           break;
		        }
	        } //end for i
	        
	        if(!TicketModify)
	        {
	           text="No se pudo modificar SL orden :"+OrderTicket()+" SL Price: "+
	           DoubleToStr(SL,Digits);
	          	           
	           Print(text);
	           log(text);
	           return(false);
	        }
	      }  //end if Symbol & Magic. 
      } //end for h
      
      return(true);
   }//end if enabled
   else
   {
      error = GetLastError();
      
      text="No se pudo modificar SL de ordenes(SL Price: "+DoubleToStr(SL,Digits)+").";
	   
	   if(error == 0 && !IsExpertEnabled())
      {
         text = text+" Expert is disabled.";
      }
      else if(error == 0 && !IsTradeAllowed())
      {
         text = text+" Trade is not allowed.";
      }
	   Print(text);
	   log(text);
	   
	   text = "Error :"+error+" "+ErrorDescription(error)+" modificando Stop Loss.";
	   Print(text);
	   log(text);
	   
	   return(false);
	}   
} //End ChangeSL() ---------------------------------

//+--------------------------------------------------------+
//  Open new orders and mange errors
//+--------------------------------------------------------+  
int AbreOrdenes(int OrdenTipo, int OrderOnThisMartingale, double Lote, color Color )
{
//----
   string AOText = "";
   //If expert is enabled try to open a new order.
   if(IsExpertEnabled() && IsTradeAllowed())
   {
      //Retry open new order NumberOfTries times.
	   for(int i = 1 ; i <= NumberOfTries; i++)
	   {
	     //If context trade is busy wait 3 seconds for try enter order.
	     if(IsTradeContextBusy())
	     {
	        AOText = "Trade context busy. Please wait. Retry :"+i+"/"+NumberOfTries;
	        Print(AOText);
	        log(AOText);
	        Sleep(3000); //3 seconds.
	        RefreshRates();
	     }
	     
	     //If context trade is not busy, or 3 seconds has been passed, send new order.
	     int TicketOpened = OrderSend(Symbol(),OrdenTipo,Lote,EnterPrice,slippage,sl,tp,text,Magic,0,Color);
	   
	     //If ticket is not a positive number, means an error occured. Show information.
	     //Wait 4 seconds and retry NumberOfTries times.	        
	     if(TicketOpened>0)
	     {
		     //If ticket has a positive number, it means order has been opened.
		     //Show information and quit this function.
		     //Selecting the ticket is a better way to confirm the opening result.
		     if(OrderSelect(TicketOpened,SELECT_BY_TICKET,MODE_TRADES))
		     {
		       AOText = "Ticket Opened by EA :"+OrderTicket()+" "+text;
		     }
		     else
		     {
		       AOText = "Trader must check opening of Ticket :"+TicketOpened+" "+text+". Could not select it.";
		     }
		     Print(AOText);
		     if(!IsTesting()) {log(AOText);} //Do not save this information on log file at test mode.
		     return(TicketOpened);
		     break;
		  }
	     else
        {
           error = GetLastError(); 
           AOText= "Error :"+error+" "+ErrorDescription(error)+", opening orden #"+
           (OrderOnThisMartingale+1)+"/"+MaxTrades+". Retry :"+i+"/"+NumberOfTries;
		     Print(AOText);
		     log(AOText);
		     Sleep(4000); //4 segundos
		     RefreshRates();
	     } 	
		  
	   } //end for i

      //If number or retries finished, and there isn't a ticket opened, show information about
      //the reasons.	        
	   if(TicketOpened<1)
      {
          error = GetLastError();
          AOText = "Could not open order: "+DoubleToStr(myLotAux,2)+" lots of "+
          Symbol()+" at EnterPrice "+DoubleToStr(EnterPrice,Digits)+
          " & TP: "+DoubleToStr(tp,Digits);
          
          Print(AOText);
	       log(AOText);
	       
	       //Inform wich was the exact error.
	       AOText= "Error :"+error+" - "+ErrorDescription(error);
	       Print(AOText);
	       log(AOText);
	       return(error);
	   }
	 
//----
   } //end if IsExpertEnabled()
   else
   {
      error = GetLastError();
      AOText = "Could not open order: "+DoubleToStr(myLotAux,2)+" lots of "+
          Symbol()+" at EnterPrice "+DoubleToStr(EnterPrice,Digits)+
          " & TP: "+DoubleToStr(tp,Digits);
          
      if(error == 0 && !IsExpertEnabled())
      {
         AOText = AOText+". Expert is disabled.";
      }
      else if(error == 0 && !IsTradeAllowed())
      {
         AOText = AOText+" Trade is not allowed.";
      }
      Print(AOText);
	   log(AOText);
      
      //Inform wich was the exact error.
	   AOText= "Error :"+error+" - "+ErrorDescription(error);
	   Print(AOText);
	   log(AOText);
	   return(error);
	   
	 }//end else if enable.
  
} //End AbreOrdenes()-------------------


//+----------------------------------------------------+
//| Avoid enter new order if there isn't enough margin.|
//+----------------------------------------------------+
bool CheckMarginAviable()
{
   string texto;
   //Si no hay margen no hace nada, y la primera vez cambia el estado de MarginFlag
   //para registrar en el log file cada nuevo free margin.
   if(AccountFreeMarginCheck(Symbol(),myOrderType,lotsi)<=0)
   {
      texto = "Free Margin :"+DoubleToStr(AccountFreeMargin(),2)+
      " Not enough for next order." ;
      Print(texto);
         
      if(MarginFlag)
      {
         log(texto);
         info( 4, texto, Red );
      }
      MarginFlag = false;
      return(false);
   }
   else if(!MarginFlag)  //If there is enough margin again, it shows the information.
   {
      texto="Free Margin :"+DoubleToStr(AccountFreeMargin(),2)+
      " avaible, enough for new order." ;
      Print(texto);
      log(texto);
      MarginFlag = true;   
   }
   return(true);
}
// End CheckMarginAviable().


//+-----------------------------------------------------------------------------------+
//| Used to avoid start new martingales if current opened has reached x orders or more|
//| Initialize a global variable identifying the Magic Number with a critic trade.    |
//| This function informs wich Magic Number has a critic trade.                       |
//+-----------------------------------------------------------------------------------+
bool CheckCriticTrade(int Retries)
{
   int _error = 0;
   
   //This function is disabled on testing mode.
   if(!IsTesting())
   {
      
      for(int i = 1 ; i <= Retries; i++)
      {
         //First check if CriticTrade global variable exists.
         if(GlobalVariableCheck("CriticTrade"))
         {
            //If CriticTrade is set to cero or equal to Magic numbers, return true and leave
            //this for/next loop.
            if(GlobalVariableGet("CriticTrade") ==0 ||
               GlobalVariableGet("CriticTrade") ==Magic ||
               GlobalVariableGet("CriticTrade") ==MagicHedge)
               { return(true); }
            else {return(false);}
         } //end if GlobalVariableCheck.
         else
         // if the GlobalVariableCheck returns FALSE, it means that it does not exist or  
         // an error has occurred during checking.
         {
            _error = GetLastError();
            // if it is still an error, display information, wait for 0.1 second, and 
            // restart checking.
            if(_error != 0)
            {
               log("CheckCriticTrade()-GlobalVariableCheck(\"CriticTrade\")-Error # "+_error);
               Sleep(100); //0.1 segundo
            }
         } // end else
       
         // if there is no error, it means that there is just no global variable.
         // try to create it. If the GlobalVariableSet > 0, it means that the global variable
         // has been successfully created. Leave the function, returning true.
        if(GlobalVariableSet( "CriticTrade", 0.0 ) > 0 ) 
        {
            return(true);
        }
        else
        // if the GlobalVariableSet has returned a value <= 0, it means that an error 
        // occurred at creation of the variable.
        {
          _error = GetLastError();
          // display information, wait for 0.1 second, and try again.
          if(_error != 0)
            {
              log("CheckCriticTrade()-GlobalVariableSet(\"CriticTrade\")-Error # "+_error );
              Sleep(100);
            }
         }
       
      }//end for.
      
      //If loop for/next is finished it is because an error ocurred, and no solution after
      //retries of GlobalVariableCheck() or GlobalVariableSet().
      return(false);
      
  } //end if !IsTesting().
  
} //end init_CriticTrade


//+-------------------------------------------------------------------------+
//| Before this function is called global variable must exists. EA needs to |
//| change its value, putting on alert the other EAs.                       |
//| Magic Number is used to indentify the EA in problems.                   |
//+-------------------------------------------------------------------------+
bool CriticTrades(int Retries, double NewStatus, double OldStatus)
{
   int _error = 0;
   
   //This function is disabled on testing mode.
   if(!IsTesting())
   {
      for(int i = 1 ; i <= Retries; i++)
      {
         // Try to change value of the CriticTrade from OldStatus to NewStatus
         // if succeed, leave the function returning TRUE ("successfully completed")
         if(GlobalVariableSetOnCondition( "CriticTrade", NewStatus, OldStatus ))
         {
            log("CriticTrade() set condition OK. NewStatus: "+DoubleToStr(NewStatus,0)+
            ". OldStatus: "+DoubleToStr(OldStatus,0));
            return(true);
         }
         else
         // if not, 2 reasons for it are possible: CriticTrade not equal to OldStatus, 
         // or an error occurred (this is what we will check).
         {
            _error = GetLastError();
            // if it is still an error, display information and try again.
            if(_error != 0)
            {
               log("CriticTrade()-GlobalVariableSetOnCondition(\"CriticTrade\,"+
               DoubleToStr(NewStatus,0)+" "+DoubleToStr(OldStatus,0)+" -Error # "+_error );
               continue;
            }
         }
         // if there is no error, it means that CriticTrade not equal to NewStatus
         // or another expert is executing a trading, then display information and wait...
         Sleep(100); //0.1 segundo.
            
       }//end for.
       
       //Loop "for i+" completed retries times means that error couldn't been solved,
       //and variable was not updated.
       return(false);
       
   } //end if !IsTesting().
   
} //end CriticTrade
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


bool CheckTradingTime()
  {
  bool Chk;

// stop Friday at 11:00 pm GMT+1
// start Monday at 3:00 pm GMT+1
// stop on holidyas

  Chk = True;
  if (DayOfWeek()==0 || DayOfWeek()==6) Chk = False;
  if (DayOfWeek()==5 && Hour() > 11) Chk = False;
  if (DayOfWeek()==1 && Hour() < 1) Chk = False;
  
  if (Month()==12 && Day()>22) Chk=False;
  if (Month()==1 &&Day()<2) Chk=False;

 
  return(Chk);
} // end CheckTradingTime