OnDeinit() race condition and recalculation issues - page 2

 
Stanislav Korotky:
I tried ObjectsDeleteAll() just after the moment it has been added to the platform, and it was buggy, so I still prefer to use explicit loop through the objects as you did. Probably this all is related to asynchronous nature of event processing in the terminal: so calling the functions does not mean the objects will be deleted immediately during its execution. Instead the deletion is queued and processed after a while. I think this is bad, because may lead to problems you've encountered, this is why I suggested to write to the service desk, just to get some feedback from MQ. BTW, you could probably wait for actual object deletion in OnDeinit, that is call the function ObjectDelete and then loop until your objects can not be found anymore. The script have approx 3 seconds before it will be unloaded forcedly, but I think the objects should be wiped out in a second or so, so terminal situation will not occur.

You are right, it would be interesting to have an answer from Metaquotes.

I don't understand how this can happen :

2016.11.10 21:38:20.967    160715 (EURUSD,M15)    OnCalculate start
2016.11.10 21:38:20.993    160715 (EURUSD,M15)    OnCalculate end
2016.11.10 21:38:21.318    160715 (EURUSD,H1)    OnInit start
2016.11.10 21:38:21.318    160715 (EURUSD,H1)    OnInit end
2016.11.10 21:38:21.318    160715 (EURUSD,H1)    OnCalculate start
2016.11.10 21:38:21.349    160715 (EURUSD,H1)    OnCalculate end
2016.11.10 21:38:21.350    160715 (EURUSD,M15)    OnDeinit start
2016.11.10 21:38:21.768    160715 (EURUSD,M15)    OnDeinit end
2016.11.10 21:38:21.768    160715 (EURUSD,H1)    OnCalculate start
2016.11.10 21:38:21.788    160715 (EURUSD,H1)    OnCalculate end

While events are asynchronous at the terminal scale, an EA is supposed to be mono-threaded and EA events are SYNCHRONOUS (or should be). So how is it possible that the OnDeinit() comes AFTER OnInit() and even OnCalculate() ? While OnDeinit() comes after, when it seems it takes too long, it should not be known that it takes too long before executing it.

That's a queue issue and there is clearly a bug here (or the documentation is wrong). Anyway, it requires a clarification.

P.S: My reasoning above is partially wrong as we are talking about an indicator and not an EA. But still it's not clear.

 
Marco vd Heijden:

Care to explain why you would need 5000 trendlines?

Drawing, as well as running mass printing will take some time to process.

Of course you can always increase the number until it crashes but do you really need that many ?

No I don't need that many in the indicator, but a couple of hundred, in addition to text labels and triangles. It was more to increase the odds of the race condition appearing, as it has a tendency to happen the longer one sees "Waiting for update" after changing chart period.

Stanislav Korotky:

... this is why I suggested to write to the service desk, just to get some feedback from MQ. ...

I don't think I will do that, as it is not a bug in itself but a nuisance and just not documented. Allowing for the malicious ordering of OnDeinit() calls for more workaround indicator code, and can perhaps be confusing for novice programmers. In fact I don't think enforcing a strict ordering of those events could bring anything but positive changes for the platform, but I don't know if it should be a priority either.

 
Alain Verleyen:

You are right, it would be interesting to have an answer from Metaquotes.

I don't understand how this can happen :

P.S: My reasoning above is partially wrong as we are talking about an indicator and not an EA. But still it's not clear.

IMHO, this is perfectly clear. The race condition happens between different instances of the same script. Each instance in its own thread. Previous one is not yet unloaded completely, but new is already popping up. This seems strange to me, but probably this is a side effect of some optimization, MQ intentionally made to increase the platform performance.
 
Stanislav Korotky:
IMHO, this is perfectly clear. The race condition happens between different instances of the same script. Each instance in its own thread. Previous one is not yet unloaded completely, but new is already popping up. This seems strange to me, but probably this is a side effect of some optimization, MQ intentionally made to increase the platform performance.

I noticed you find something strange perfectly clear

For me it's not clear the exact reason. But anyway a Deinit() which happens AFTER Init() and OnCalculate() running with new timeframe/settings is clearly a bug.

 
Alain Verleyen:

For me it's not clear the exact reason. But anyway a Deinit() which happens AFTER Init() and OnCalculate() running with new timeframe/settings is clearly a bug.

Well, then somebody should probably write to the service desk, and it will not be me ;-), because I see the point (logic). OnDeinit and OnInit in different programs are not bound to any time sequence relations. New timeframe starts another instance. I'm sure MQ finds this a feature, not a bug.
 
Stanislav Korotky:
Well, then somebody should probably write to the service desk, and it will not be me ;-), because I see the point (logic). OnDeinit and OnInit in different programs are not bound to any time sequence relations. New timeframe starts another instance. I'm sure MQ finds this a feature, not a bug.
Yeah...
 

Searching the documentation, I think this is a bug indeed.

On the documentation https://www.mql5.com/en/docs/basis/function/events#ondeinit it says:

The Deinit event is generated for Expert Advisors and indicators in the following cases:

  • before reinitialization due to the change of a symbol or chart period, to which the mql5 program is attached;
  • before reinitialization due to the change of input parameters;
  • before unloading the mql5 program.

So if reinitialization is supposed to mean a new call to the OnInit(), the OnDeinit() is supposed to be called first.

I'm opening a support ticket.

Documentation on MQL5: Language Basics / Functions / Event Handling Functions
Documentation on MQL5: Language Basics / Functions / Event Handling Functions
  • www.mql5.com
Language Basics / Functions / Event Handling Functions - Reference on algorithmic/automated trading language for MetaTrader 5
 
Andre Enger:

Searching the documentation, I think this is a bug indeed.

On the documentation https://www.mql5.com/en/docs/basis/function/events#ondeinit it says:

So if reinitialization is supposed to mean a new call to the OnInit(), the OnDeinit() is supposed to be called first.

I'm opening a support ticket.

I said you it's bug, but I am afraid Stanislav could be right about MQ finding it a feature ;-)

Thanks, and please keep us posted.

 

MQ's response is that that the "old" and "new" indicator instances are different indicators. From their point of view an indicator is determined by membership in a history cache defined by both a symbol and a timeframe.

There are historyl caches by timeframes. If you open chart then history cache symbol-timeframe created (if it is new, if not then add ref) with generic data - datetime, open, high, low, close, spread,volumes. If you create some indicator its calculated buffers added to the appropriate history cache. In other words indicator become a member of history cache

I've informed them that it is possible to define an indicator as an entry in the indicator list, or that the indicator on the "new" timeframe can be viewed as a reinitialization of the indicator on the "old" timeframe, but the current working is:

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

I don't know if they plan to do anything about it, so for now at least we'll have to handle the issue ourselves when its necessary.

 
Andre Enger:

MQ's response is that that the "old" and "new" indicator instances are different indicators. From their point of view an indicator is determined by membership in a history cache defined by both a symbol and a timeframe.

I've informed them that it is possible to define an indicator as an entry in the indicator list, or that the indicator on the "new" timeframe can be viewed as a reinitialization of the indicator on the "old" timeframe, but the current working is:

I don't know if they plan to do anything about it, so for now at least we'll have to handle the issue ourselves when its necessary.

Thanks for these informations. Always good to know.

As Stanilaw was stating : it's a feature not a bug. Sometimes Metaquotes is really hard to follow.