Search code examples
mql4metatrader4

Sporadically opens trades when EA should be preventing this


Morning all,

I'm currently testing out a segment of my EA which is supposed to only open a trade (providing other conditions are met) on the opening of the candle bar, which in MQL4 language is LastActiontime=Time[0];.

It's working really well: it is only opening trades on the LastActiontime=Time[0]; time, and not opening any trades part way through the candlestick bar should the EA need to be reinitialised.

However, on some occasions (though not every occasion), when I close the trade party way through the current candlestick bar, it sporadically opens another trade and thus defying the "only opening a trade on the opening time of the candlestick bar" rule.

I have the the snippet, below. Does anyone know where I'm going wrong?

Notes:

  • The best way is to test this on a 1M chart so you're not waiting any longer to confirm the EA works.
  • The EA will only allow one trade to be open, if there are any trades open when the EA is reinitialised, it won't open a new trade - this is by design so as to avoid overtrading.

Suggestions / thinking points

  • The EA may not be initialising fast enough to comply with the oninit parameters, so does not recognise that the conditions before another trade is initialised.

//+------------------------------------------------------------------+
//|                                          initialization_test.mq4 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+

datetime LastActiontime;
bool totalOrders = OrdersTotal();
double currencyConversion;

int OnInit()
  {
//---

  LastActiontime=Time[0];
  
  if (totalOrders == 0){
      totalOrders = true;
  }
   

//---
   return(INIT_SUCCEEDED);
  }

void OnTick()
  {
//---
   int LotSize = 30;
   int RewardFactor = 3;
   int stopLossPoints = 200;
   double entryPriceBid = MarketInfo(Symbol(),MODE_BID);
   double spread = MarketInfo(Symbol(), MODE_SPREAD);
   double tickvalue = MarketInfo(Symbol(), MODE_TICKVALUE);
   color sellcolor = clrGreen;
   bool Newbar = true;
   
   if(LastActiontime!=Time[0])
   if(OrdersTotal() == 0)
   if(totalOrders == true){
   
      bool OpenShort = OrderSend(Symbol(),OP_SELL,LotSize,MarketInfo(Symbol(),MODE_BID),100,((entryPriceBid/Point)+(stopLossPoints))*Point,((entryPriceBid/Point)-(stopLossPoints*RewardFactor))*Point,"Spread Charge £"+DoubleToStr((spread * tickvalue)*LotSize,2),Period(),0,sellcolor);
LastActiontime=Time[0];    
       
   }
  }
//+------------------------------------------------------------------+

All the best,


Solution

  • Your code is not really best practice for what you are trying to achieve. The best method to only carry out operations at the start of a bar would be as follows:

    void OnTick()
    {
        if(TimeBar==Time[0])
        {
            //Carry out any operations on each tick here
        return;
        }
    
       if(TimeBar==0)
       {
           // Operations carried out on First Run only here
           TimeBar=Time[0];
       return;
       }
    
       // Operations at the start of a new bar here
    
       TimeBar=Time[0];
    return;
    }