Not able to stop trading in friday and from 20:00 to 21:00 in ΕΑ

 

Good afternoon,

I'm writing and EA in MQL5 with Bollinger Bands based on example I've found on this site.

I'm trying to say to the EA to stop trading Friday at 21:00 (server time) and during the week to avoid to trade from 20:00 to 21:00.

Unfortunately during the backtesting it doesn't work.

Below the entire code of the EA:

Thanks

#property copyright "Riccardo"
#property link      ""
#property version   "1.001"
#include <Trade\PositionInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>  
#include <Expert\Money\MoneyFixedMargin.mqh>
CPositionInfo  m_position;                   // trade position object
CTrade         m_trade;                      // trading object
CSymbolInfo    m_symbol;                     // symbol info object
CMoneyFixedMargin m_money;
//---
input bool     OpenBUY           = true;     // Buy positions
input bool     OpenSELL          = true;     // Sell positions
input bool     CloseBySignal     = true;     // CloseBySignal
input ushort   InpStopLoss       = 0.0;      // StopLoss
input ushort   InpTakeProfit     = 0.0;      // TakeProfit
input ushort   InpTrailingStop   = 0;        // TrailingStop
input int      BBperiod          = 24;       // Bollinger Bands period
input double   BBstdev           = 0.5;     //Bollinger Bands standard deviation
input int      RSILowerLevel     = 35;       //RSI index lower level
input int      RSIUpperLevel     = 65;       //RSI index upper level
input int      RSIPeriod         = 14;       //RSI Period
input bool     AutoLot           = true;     // AutoLot (percent from a free margin)
input double   Risk              = 10;       // Risk percent from a free margin
input double   ManualLots        = 0.1;      // ManualLots
input ulong    m_magic           = 123;      // Magic number
input string   TradeComment      = "BOLLINGER BAND EA"; // TradeComment
input ulong    InpSlippage       = 1;        // Slippage
input int      MaPeriodEquity    = 20;       //Equity curve moving average period
input int      Backarrayhigh     = 5;        //Number of bars to calculate the maximum of the N array elements
input int      Backarraylow      = 5;        //Number of bars to calculate the minimum of the N array elements
//---
int LotDigits;
//---
double         ExtStopLoss=0.0;
double         ExtTakeProfit=0.0;
double         ExtTrailingStop=0.0;
ulong          ExtSlippage=0;
ENUM_ACCOUNT_MARGIN_MODE m_margin_mode;
double         m_adjusted_point;             // point value adjusted for 3 or 5 points
int            handle_iBB;                  // variable for storing the handle of the Bollinger Bands indicator
int            handle_iRSI;                  // variable for storing the handle of th RSI indicator
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   SetMarginMode();
   if(!IsHedging())
     {
      Print("Hedging only!");
      return(INIT_FAILED);
     }
//---
   m_symbol.Name(Symbol());                  // sets symbol name
   if(!RefreshRates())
     {
      Print("Error RefreshRates. Bid=",DoubleToString(m_symbol.Bid(),Digits()),
            ", Ask=",DoubleToString(m_symbol.Ask(),Digits()));
      return(INIT_FAILED);
     }
   m_symbol.Refresh();
//---
   m_trade.SetExpertMagicNumber(m_magic);    // sets magic number

//--- tuning for 3 or 5 digits
   int digits_adjust=1;
   if(m_symbol.Digits()==3 || m_symbol.Digits()==5)
      digits_adjust=10;
   m_adjusted_point=m_symbol.Point()*digits_adjust;

   ExtStopLoss       = InpStopLoss     * m_adjusted_point;
   ExtTakeProfit     = InpTakeProfit   * m_adjusted_point;
   ExtTrailingStop   = InpTrailingStop * m_adjusted_point;
   ExtSlippage       = InpSlippage     * digits_adjust;

   m_trade.SetDeviationInPoints(ExtSlippage);
//---
   if(!m_money.Init(GetPointer(m_symbol),Period(),m_adjusted_point))
      return(INIT_FAILED);
   m_money.Percent(10); // 10% risk
//--- create handle of the indicator iRSI
   handle_iBB=iBands(Symbol(),Period(),BBperiod,0,BBstdev,PRICE_CLOSE);
//--- if the handle is not created 
   if(handle_iBB==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code 
      PrintFormat("Failed to create handle of the iRSI indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early 
      return(INIT_FAILED);
     }
//---
//--- create handle of the indicator iRSI
   handle_iRSI=iRSI(Symbol(),Period(),RSIPeriod,PRICE_OPEN);
//--- if the handle is not created 
   if(handle_iRSI==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code 
      PrintFormat("Failed to create handle of the iRSI indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early 
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
  double Equity=AccountInfoDouble(ACCOUNT_EQUITY);
  //Check the equity
  if(Equity<7000)
  {
  Print("The account equity is below 7000 euros");
  return;
  }
  //--- Do we have enough bars to work with?
   if(Bars(_Symbol,_Period)<60) // if total bars is less than 60 bars
     {
      Alert("We have less than 60 bars, EA will now exit!!");
      return;
     }  
//--- Define some MQL5 Structures we will use for our trade
   MqlTick latest_price;      // To be used for getting recent/latest price quotes
   MqlDateTime now_time;
// We will use the static Old_Time variable to serve the bar time.
// At each OnTick execution we will check the current bar time with the saved one.
// If the bar time isn't equal to the saved time, it indicates that we have a new tick.

   static datetime Old_Time;
   datetime New_Time[1];
   bool IsNewBar=false;
   bool we=false;
   bool twenty=false;
   
   TimeCurrent(now_time);
   we=now_time.day_of_week==5 && now_time.hour>=21;
   
   twenty=now_time.hour<21 && now_time.hour>20;

// copying the last bar time to the element New_Time[0]
   int copied=CopyTime(_Symbol,_Period,0,1,New_Time);
   if(copied>0) // ok, the data has been copied successfully
     {
      if(Old_Time!=New_Time[0]) // if old time isn't equal to new bar time
        {
         IsNewBar=true;   // if it isn't a first call, the new bar has appeared
         if(MQL5InfoInteger(MQL5_DEBUGGING)) Print("We have new bar here ",New_Time[0]," old time was ",Old_Time);
         Old_Time=New_Time[0];            // saving bar time
        }
     }
   else
     {
      Alert("Error in copying historical times data, error =",GetLastError());
      ResetLastError();
      return;
     }

//--- EA should only check for new trade if we have a new bar
   if(IsNewBar==false)
     {
      return;
     }
 
//--- Do we have enough bars to work with
   int Mybars=Bars(_Symbol,_Period);
   if(Mybars<60) // if total bars is less than 60 bars
     {
      Alert("We have less than 60 bars, EA will now exit!!");
      return;
     }
  
   
   
   if(!SymbolInfoTick(_Symbol,latest_price))
     {
      Alert("Error getting the latest price quote - error:",GetLastError(),"!!");
      return;
     }


     

  
//---
   int total_buy=0;
   int total_sell=0;
//-count Buy and Sell positions, and also modify (if specified in the input parameters)
   for(int i=PositionsTotal()-1;i>=0;i--)
      if(m_position.SelectByIndex(i))
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==m_magic)
           {
            if(m_position.PositionType()==POSITION_TYPE_BUY)
              {
               total_buy++;
               if(ExtTrailingStop>0)
                 {
                  if(m_position.PriceCurrent()>m_position.PriceOpen())
                     if(m_position.PriceCurrent()-2*ExtTrailingStop>m_position.StopLoss())
                       {
                        double sl=NormalizeDouble(m_position.PriceCurrent()-ExtTrailingStop,m_symbol.Digits());
                        m_trade.PositionModify(m_position.Ticket(),sl,m_position.TakeProfit());
                       }
                 }
              }

            if(m_position.PositionType()==POSITION_TYPE_SELL)
              {
               total_sell++;
               if(ExtTrailingStop>0)
                 {
                  if(m_position.PriceCurrent()<m_position.PriceOpen())
                     if(m_position.PriceCurrent()+2*ExtTrailingStop<m_position.StopLoss())
                       {
                        double sl=NormalizeDouble(m_position.PriceCurrent()+ExtTrailingStop,m_symbol.Digits());
                        m_trade.PositionModify(m_position.Ticket(),sl,m_position.TakeProfit());
                       }
                 }
              }
           }
           
     
//---
   double BBUpper_0=iBBGetUpper(0);
   double BBUpper_1=iBBGetUpper(1);
   double BBUpper_2=iBBGetUpper(2);
   double BBLower_0=iBBGetLower(0);
   double BBLower_1=iBBGetLower(1);
   double BBLower_2=iBBGetLower(2);
   double BBMiddle_0=iBBGetMiddle(0);
   double BBMiddle_1=iBBGetMiddle(1);
   double BBMiddle_2=iBBGetMiddle(2);
   double RSI_0 =iRSIGet(0);
   double RSI_1 =iRSIGet(1);
   double Rate_1close=ratesGetClose(1);
   double Rate_2close=ratesGetClose(2);
   double Rate_1open=ratesGetOpen(1);
   double Rate_2open=ratesGetOpen(2);
  
   


   //--- Declare bool type variables to hold our Buy Conditions & Sell Conditions
   
   bool Buy_Condition_2=(Rate_1close>BBUpper_1);
   bool Buy_Condition_3=(Rate_2close>BBUpper_2);
   bool Buy_Condition_4=(Rate_1open<BBUpper_1);
   bool Buy_Condition_5=(Rate_2open<BBUpper_2);
   bool Sell_Condition_2=(Rate_1close<BBLower_1);
   bool Sell_Condition_3=(Rate_2close<BBLower_2);
   bool Sell_Condition_4=(Rate_1open>BBLower_1);
   bool Sell_Condition_5=(Rate_2open>BBLower_2);
   
    if((MathAbs(Rate_1open-Rate_1close)>0.0045)||(MathAbs(Rate_2open-Rate_2close)>0.0045))
          {
          return;
          }
//--- close position if it's Friday
   if(we)
   {
   Alert("Friday H21 close trade and don't open new positions");
    if(total_buy>0 )
         ClosePositions(POSITION_TYPE_BUY);
    if(total_sell>0 )
         ClosePositions(POSITION_TYPE_SELL);
    return;     
   }
   
//---close position if it's 20:00 of evening
   if(twenty)
   {
   Alert("Between 20:00 and 21:00 close trade and don't open new positions");
    if(total_buy>0 )
         {
         ClosePositions(POSITION_TYPE_BUY);
         }
      if(total_sell>0 )
      {
      ClosePositions(POSITION_TYPE_SELL);
      }
       return;  
         
   }
   
//--- close position by signal
   if(CloseBySignal)
     {
      if(total_buy>0 && m_position.PriceCurrent()<BBLower_0 )
         ClosePositions(POSITION_TYPE_BUY);
      if(total_sell>0 && m_position.PriceCurrent()>BBUpper_0)
         ClosePositions(POSITION_TYPE_SELL);
     }
     
//--- open position
   if(OpenSELL && total_sell<1 && ((Sell_Condition_2||Sell_Condition_3)&&(Sell_Condition_4||Sell_Condition_5)))
      OPSELL();
   if(OpenBUY && total_buy<1 && ((Buy_Condition_2||Buy_Condition_3)&&(Buy_Condition_4||Buy_Condition_5)))
      OPBUY();
      
   
//---
   return;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OPBUY()
  {
   if(!RefreshRates())
      return;

  double StopLossLevel=0.0;
  double TakeProfitLevel=0.0;
  double arraylow[];
  ArrayInitialize(arraylow,EMPTY_VALUE);
  ArrayResize(arraylow,Backarraylow,0);
  for(int i=0;i<=Backarraylow-1;i++)
   // Copy the bar low prices of the last N bars 
   arraylow[i]=NormalizeDouble(ratesGetLow(i+1),_Digits);
   
   double min = arraylow[ArrayMinimum(arraylow)];

  
   if(ExtStopLoss>0)
      StopLossLevel=m_symbol.NormalizePrice(m_symbol.Ask()-ExtStopLoss);
       {
   if(StopLossLevel<min)
   StopLossLevel=StopLossLevel;
   else StopLossLevel=min;
   }
   if(ExtTakeProfit>0)
      TakeProfitLevel=m_symbol.NormalizePrice(m_symbol.Ask()+ExtTakeProfit);

   double volume=LOT();
   if(volume!=0.0)
      m_trade.Buy(volume,NULL,m_symbol.Ask(),StopLossLevel,TakeProfitLevel,TradeComment);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OPSELL()
  {
   if(!RefreshRates())
      return;

   double StopLossLevel=0.0;
  double TakeProfitLevel=0.0;
  double arrayhigh[];
  ArrayInitialize(arrayhigh,EMPTY_VALUE);
  ArrayResize(arrayhigh,Backarrayhigh,0);
  for(int i=0;i<=Backarrayhigh-1;i++)
   // Copy the bar low prices of the last four bars 
   arrayhigh[i]=NormalizeDouble(ratesGetHigh(i+1),_Digits);
   double max = arrayhigh[ArrayMaximum(arrayhigh)];


   if(ExtStopLoss>0)
   StopLossLevel=m_symbol.NormalizePrice(m_symbol.Bid()+ExtStopLoss);
   {
   if(StopLossLevel>max)
   StopLossLevel=StopLossLevel;
   else StopLossLevel=max;
   }
   
   
      
   if(ExtTakeProfit>0)
      TakeProfitLevel=m_symbol.NormalizePrice(m_symbol.Bid()-ExtTakeProfit);
//---
   double volume=LOT();
   if(volume!=0.0)
      m_trade.Sell(volume,NULL,m_symbol.Bid(),StopLossLevel,TakeProfitLevel,TradeComment);
  }
//+------------------------------------------------------------------+
//| Close Positions                                                  |
//+------------------------------------------------------------------+
void ClosePositions(ENUM_POSITION_TYPE pos_type)
  {
   for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of current orders
      if(m_position.SelectByIndex(i))
         if(m_position.Symbol()==Symbol() && m_position.Magic()==m_magic)
            if(m_position.PositionType()==pos_type)
               m_trade.PositionClose(m_position.Ticket());
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double LOT()
  {
   double lots=0.0;
//---
   if(AutoLot)
     {
      lots=0.0;
      //--- getting lot size for open long position (CMoneyFixedMargin)
      double sl=0.0;
      double check_open_long_lot=m_money.CheckOpenLong(m_symbol.Ask(),sl);
      

      if(check_open_long_lot==0.0)
         return(0.0);

      //--- check volume before OrderSend to avoid "not enough money" error (CTrade)
      double chek_volime_lot=m_trade.CheckVolume(m_symbol.Name(),check_open_long_lot,m_symbol.Ask(),ORDER_TYPE_BUY);

      if(chek_volime_lot!=0.0)
         if(chek_volime_lot>=check_open_long_lot)
            lots=check_open_long_lot;
     }
   else
      lots=ManualLots;
//---
   return(LotCheck(lots));
  }
//+------------------------------------------------------------------+
//| Lot Check                                                        |
//+------------------------------------------------------------------+
double LotCheck(double lots)
  {
//--- calculate maximum volume
   double volume=NormalizeDouble(lots,2);
   double stepvol=m_symbol.LotsStep();
   if(stepvol>0.0)
      volume=stepvol*MathFloor(volume/stepvol);
//---
   double minvol=m_symbol.LotsMin();
   if(volume<minvol)
      volume=0.0;
//---
   double maxvol=m_symbol.LotsMax();
   if(volume>maxvol)
      volume=maxvol;
   return(volume);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void SetMarginMode(void)
  {
   m_margin_mode=(ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool IsHedging(void)
  {
   return(m_margin_mode==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING);
  }
//+------------------------------------------------------------------+
//| Refreshes the symbol quotes data                                 |
//+------------------------------------------------------------------+
bool RefreshRates()
  {
//--- refresh rates
   if(!m_symbol.RefreshRates())
      return(false);
//--- protection against the return value of "zero"
   if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
      return(false);
//---
   return(true);
  }
//+------------------------------------------------------------------+
//| Get value of buffers for the iBands                               |
//+------------------------------------------------------------------+
double iBBGetUpper(const int index)
  {
   double BBUpper[1];
//--- reset error code 
   ResetLastError();
//--- fill a part of the iRSI array with values from the indicator buffer that has 0 index 
   if(CopyBuffer(handle_iBB,1,index,1,BBUpper)<0)
     {
      //--- if the copying fails, tell the error code 
      PrintFormat("Failed to copy data from the iRSI indicator, error code %d",GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated 
      return(0.0);
     }
   return(BBUpper[0]);
  }
//+------------------------------------------------------------------+
double iBBGetLower(const int index)
  {
   double BBLower[1];
//--- reset error code 
   ResetLastError();
//--- fill a part of the iRSI array with values from the indicator buffer that has 0 index 
   if(CopyBuffer(handle_iBB,2,index,1,BBLower)<0)
     {
      //--- if the copying fails, tell the error code 
      PrintFormat("Failed to copy data from the Lower BB indicator, error code %d",GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated 
      return(0.0);
     }
   return(BBLower[0]);
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
double iBBGetMiddle(const int index)
  {
   double BBMiddle[1];
//--- reset error code 
   ResetLastError();
//--- fill a part of the iRSI array with values from the indicator buffer that has 0 index 
   if(CopyBuffer(handle_iBB,0,index,1,BBMiddle)<0)
     {
      //--- if the copying fails, tell the error code 
      PrintFormat("Failed to copy data from the Middle BB indicator, error code %d",GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated 
      return(0.0);
     }
   return(BBMiddle[0]);
  }
//+------------------------------------------------------------------+
double iRSIGet(const int index)
  {
   double RSI[1];
//--- reset error code 
   ResetLastError();
//--- fill a part of the iRSI array with values from the indicator buffer that has 0 index 
   if(CopyBuffer(handle_iRSI,0,index,1,RSI)<0)
     {
      //--- if the copying fails, tell the error code 
      PrintFormat("Failed to copy data from the RSI indicator, error code %d",GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated 
      return(0.0);
     }
   return(RSI[0]);
  }
//+------------------------------------------------------------------+
//Function to get rates close
double ratesGetClose(const int index)
{
MqlRates mrate[];          // To be used to store the prices, volumes and spread of each bar

   //--- Get the details 
   if(CopyRates(_Symbol,_Period,index,1,mrate)<0)
     {
      Alert("Error copying rates/history data - error:",GetLastError(),"!!");
      ResetLastError();
      return(0.0);
     }
     return (mrate[0].close);
}

//Function to get rates close
double ratesGetOpen(const int index)
{
MqlRates mrate[];          // To be used to store the prices, volumes and spread of each bar
   //--- Get the details 
   if(CopyRates(_Symbol,_Period,index,1,mrate)<0)
     {
      Alert("Error copying rates/history data - error:",GetLastError(),"!!");
      ResetLastError();
      return(0.0);
     }
     return (mrate[0].open);
}
//Function to get rates high
double ratesGetHigh(const int index)
{
MqlRates mrate[];          // To be used to store the prices, volumes and spread of each bar
   //--- Get the details 
   if(CopyRates(_Symbol,_Period,index,1,mrate)<0)
     {
      Alert("Error copying rates/history data - error:",GetLastError(),"!!");
      ResetLastError();
      return(0.0);
     }
     return (mrate[0].high);
}
//Function to get rates high
double ratesGetLow(const int index)
{
MqlRates mrate[];          // To be used to store the prices, volumes and spread of each bar
   //--- Get the details 
   if(CopyRates(_Symbol,_Period,index,1,mrate)<0)
     {
      Alert("Error copying rates/history data - error:",GetLastError(),"!!");
      ResetLastError();
      return(0.0);
     }
     return (mrate[0].low);
}
Bollinger Bands ®
Bollinger Bands ®
  • www.mql5.com
Bollinger Bands ® technical indicator (BB) is similar to Envelopes. The only difference is that the bands of Envelopes are plotted a fixed distance (%) away from the moving average, while the Bollinger Bands are plotted a certain number of standard deviations away from it. Standard deviation is a measure of volatility, therefore Bollinger Bands...
 
 twenty=now_time.hour<21 && now_time.hour>20;

Hour is an integer — if it is greater than 20 it can never be less than 21.

 
William Roeder:

Hour is an integer — if it is greater than 20 it can never be less than 21.

Thanks, you're right.

Anyway I've changed the value as below but the situation doesn't change.

TimeCurrent(now_time);
   we=now_time.day_of_week==5 && now_time.hour>=19;
   
   twenty=now_time.hour<=21.5 && now_time.hour>=19.8;


Moreover it doesn't seem to stop and close positions during the weekend and I'don't understand why....

Thanks in advance

 
Riccardo_1983: Moreover it doesn't seem to stop and close positions during the weekend and I'don't understand why....

Because the market is closed during the weekend.