Ok, lets get started with this one....
MQL5 reason code corrupted
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;
}
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... ?
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
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
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
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;
}
Another test case showing a very similar issue.. arguably more horrifying...
OnDeinit being called after OnInit (yes really!)
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 ?
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 ?
Just read that thread. I too find this very odd:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
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.