MT5, mql5 bugs to be fixed.

 

As suggested by James Cater, I am opening this thread to centralize bugs reported on MT5 and mql5. 

You can report what you found, ask for confirmation of the community, and report it to ServiceDesk. The goal of this topic is to effectively have bugs fixed, if you want to ask for improvements, please use this topic instead.

BugsStatus
 OnDeinit reason code is sometimes corrupted when changing timeframes. (Occasionally the reason code is set as 1 rather than 3) Ticket open. Not recognized by MQ.
 OnDeinit / OnInit are not always synchronous Ticket open. Not recognized by MQ.
 

Ok, lets get started with this one....

MQL5 reason code corrupted

Open, Start: 2016.06.13 13:46, #1492194

Problem description

OnDeInit reason code is sometimes corrupted when changing timeframes. (Occasionally the reason code is set as 1 rather than 3)

...

Sequence of action

Create new chart (a chart with some missing history is necessary for recreating this issue rather than an up to date terminal)

Attach supplied script (below)

Change timeframes 5-10 times

...

Obtained result

Log normally shows reason code 3 - REASON_CHARTCHANGE.

Log occasionally shows reason code 1  -REASON_REMOVE

RE 0 00:16:12.008 blah2 (USDZAR,H1) OnDeinit_Deinitalization reason code =3
IQ 0 00:16:12.008 blah2 (USDZAR,H1) OnDeinit_UninitReason =Symbol or timeframe was changed
HQ 0 00:16:14.435 blah2 (USDZAR,W1) ReasonCodes: 111
KP 0 00:16:14.435 blah2 (USDZAR,W1) OnDeinit_Deinitalization reason code =1

KR 0 00:16:14.435 blah2 (USDZAR,W1) OnDeinit_UninitReason =Program blah2.mq5 was removed from chart
LF 0 00:16:40.031 blah2 (USDZAR,M15) ReasonCodes: 333
EQ 0 00:16:40.031 blah2 (USDZAR,M15) OnDeinit_Deinitalization reason code =3
HH 0 00:16:40.031 blah2 (USDZAR,M15) OnDeinit_UninitReason =Symbol or timeframe was changed

...

Expected result

reason code should ALWAYS be 3 REASON_CHARTCHANGE when changing timeframes

(the indicator was never removed from chart during this test so Reason code 111 should not be possible)


//+------------------------------------------------------------------+
//|                                                  testdeinint.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_plots 0


int OnInit()
{
   return INIT_SUCCEEDED;
}

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime& time[],
                const double& open[],
                const double& high[],
                const double& low[],
                const double& close[],
                const long& tick_volume[],
                const long& volume[],
                const int& spread[])
{
   return rates_total;
}

void OnDeinit(const int reason)
{
   Print("ReasonCodes: ", UninitializeReason(), reason, _UninitReason);
   //--- The first way to get the deinitalization reason code
   Print(__FUNCTION__, "_Deinitalization reason code =", reason);
   //--- The second way to get the deinitalization reason code
   Print(__FUNCTION__, "_UninitReason =", ReasonText(_UninitReason));
}

string ReasonText(int reasonCode)
{
   string text="";

   switch(reasonCode)
   {
      case REASON_ACCOUNT:       text="Account was changed";break;
      case REASON_CHARTCHANGE:   text="Symbol or timeframe was changed";break;
      case REASON_CHARTCLOSE:    text="Chart was closed";break;
      case REASON_PARAMETERS:    text="Input-parameter was changed";break;
      case REASON_RECOMPILE:     text="Program "+__FILE__+" was recompiled";break;
      case REASON_REMOVE:        text="Program "+__FILE__+" was removed from chart";break;
      case REASON_TEMPLATE:      text="New template was applied to chart";break;
      default:                   text="Another reason";break;
   }
   return text;
}
 
James Cater:

Create new chart (a fresh chart with some missing history is necessary for recreating this issue than an up to date terminal)


Not sure how to do that as history is loaded automatically ?

When a ticket is already open, could you please say what is its "status" : no answer, will be fixed, no agreement it's a bug... ?

 
Alain Verleyen:

Not sure how to do that as history is loaded automatically ?

When a ticket is already open, could you please say what is its "status" : no answer, will be fixed, no agreement it's a bug... ?

Anyway, I confirm the issue :

2017.01.17 11:03:19.483    OnDeinit_Deinitalization reason code =1
2017.01.17 11:03:19.483    OnDeinit_UninitReason =Program 167049.mq5 was removed from chart

Got it once. The indicator was of course not removed from chart.
 
Alain Verleyen:

When a ticket is already open, could you please say what is its "status" : no answer, will be fixed, no agreement it's a bug... ?

Support Team 2016.06.13 14:57                

Status: Unapproved Open
Your request has been accepted for processing.
               


The support team initially tried to claim this was the expected behaviour, however I replied back to them countering their claim and asked them to escalate this to the development team.

The issue is still open, but I have not heard back since Jun 2016

 
Alain Verleyen:

Not sure how to do that as history is loaded automatically ?

Yes, but when you switch timeframes the history for that new timeframe may not be loaded and it can take a some time for the history to sync on the new timeframe.

I believe the bug happens in these circumstances and then stops happening once the history is fully synced. Hence the bug appears to be "intermittent", but I think it is actually quite easy to recreate (as you have found in a few minutes)

 

Another test case showing a very similar issue.. arguably more horrifying...

OnDeinit being called after OnInit (yes really!)


2017.01.17 10:59:48.979 TestInitGlobalsMT5 (GBPJPY,M15) OnDeinit - This should be printed before the OnInit call
2017.01.17 10:59:48.990 TestInitGlobalsMT5 (GBPJPY,M1) OnInit  - Found global variable 3736772_TEST_GLOBAL = 123.456
2017.01.17 10:59:51.305 TestInitGlobalsMT5 (GBPJPY,MN1) OnInit  - Cannot find global variable 3736772_TEST_GLOBAL
2017.01.17 10:59:51.306 TestInitGlobalsMT5 (GBPJPY,M1) OnDeinit - This should be printed before the OnInit call
2017.01.17 10:59:52.306 TestInitGlobalsMT5 (GBPJPY,MN1) OnTimer - Oh look, it turned up after the OnInit call. 123.456 DOH!



#property indicator_chart_window
#property indicator_plots 0


string ExtGlobalVarName = IntegerToString(ChartGetInteger(0, CHART_WINDOW_HANDLE)) + "_TEST_GLOBAL";


int OnInit()
{
   double testVal;
  
   if (GlobalVariableGet(ExtGlobalVarName, testVal))
   {
      Print("OnInit  - Found global variable ", ExtGlobalVarName, " = ", testVal);
      GlobalVariableDel(ExtGlobalVarName);   // Delete the global variable
   }
   else
   {
      Print("OnInit  - Cannot find global variable ", ExtGlobalVarName);
      EventSetTimer(1); // Setup the event time to see if we can get it later
   }
   return INIT_SUCCEEDED;
}


void OnDeinit(const int reason)
{
   Print("OnDeinit - This should always be printed before the OnInit Call");
   GlobalVariableSet(ExtGlobalVarName, 123.456);   // Set the global variable as we exit
   EventKillTimer();
}


void OnTimer()
{
   double testVal;
  
   if (GlobalVariableGet(ExtGlobalVarName, testVal))
   {
      Print("OnTimer - Oh look, it turned up after the OnInit call. ", testVal, " DOH!");
      GlobalVariableDel(ExtGlobalVarName);   // Delete the global variable
      EventKillTimer();
   }
}


int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime& time[],
                const double& open[],
                const double& high[],
                const double& low[],
                const double& close[],
                const long& tick_volume[],
                const long& volume[],
                const int& spread[])
{
   return rates_total;
}
 
James Cater:

Another test case showing a very similar issue.. arguably more horrifying...

OnDeinit being called after OnInit (yes really!)

Yes it has already been reported on the forum. It's not a bug, it's a feature !
 
Alain Verleyen:
Yes it has already been reported on the forum. It's not a bug, it's a feature !

Its definitely a bug, because you must be able to rely on the OnInit being called after the OnDeInit.

It never happens in MQL4 and I suspect it's the same cause of the reason code is being corrupted.

If MQ are saying it's a feature I would cry utter BS.

How are you supposed to sensibly unload and then load an indicator, passing global variables or writing files between the previous and next instance if the Deinit /Init methods are not synchronous ?

 
James Cater:

Its definitely a bug, because you must be able to rely on the OnInit being called after the OnDeInit.

It never happens in MQL4 and I suspect it's the same cause of the reason code is being corrupted.

If MQ are saying it's a feature I would cry utter BS.

How are you supposed to sensibly unload and then load an indicator, passing global variables or writing files between the previous and next instance if the processes are not synchronous ?

I do agree of course, it's not me who said it's not a bug.
 
Alain Verleyen:
Yes it has already been reported on the forum. It's not a bug, it's a feature !

Just read that thread. I too find this very odd:

At the moment of timeframe change 2 copies of the same indicator exist. One of them initialized, other - deinitialized. Sequence of processing for 2 indicators is undefined
Reason: