"shutdown by timeout" when switching timeframes -- solved: MT4 bug + workaround!

 

0.01% of you might be interested in the following:


I had strange timeout problems one out of 10 times when switching between timeframes when one of my EAs was attached to the chart. This included every EA that makes use of the ofline_charts library to plot equity curves and is relevant to all EAs that produce and update offline charts in general.


When the timeframe is switched metatrader will wait for the current call of start() to return and then call deinit(). If start wont return within 2 seconds it will forcefully kill the execution of start() and log "shutdown by timeout". IsStopped() can be used to determine whether mt4 wants to deinit the EA and is waiting for start to finish. Long running loops should test for this condition.


I had no long running loops in any of my EAs but still I got this error from time to time. The cause is a bug in the function WindowHandle(). I had the following code called somewhere from within my start() function on every tick to update a separate offline chart window containing the equity curve:

      // refresh the chart window
      // this won't work in backtesting mode
      if (!IsTesting()){
         int hwnd=WindowHandle(symbol, period);
         if (hwnd != 0){
            PostMessageA(hwnd, WM_COMMAND, 33324, 0);
         }
      }

I had to change this to additionally check for IsStopped(). Whenever MT4 wants to shutdown the EA the WindowHande() function will run into some kind of deadlock and block and never return. Check for IsStopped() before you attempt to send messages to another chart window. The following code will not block anymore:

      // refresh the chart window
      // this won't work in backtesting mode
      // and also don't do it while deinitializing or the
      // WindowHandle() function will run into a deadlock
      // for unknown reasons. (this took me a while to debug)
      if (!IsStopped() && !IsTesting()){
         int hwnd=WindowHandle(symbol, period);
         if (hwnd != 0){
            PostMessageA(hwnd, WM_COMMAND, 33324, 0);
         }
      }

The next release of offline_charts.mqh will include this fix.

 
Thanks for the info.