Discussion about OnCalculate returning 0. - page 2

 
Conor Mcnamara #:
And can you explain why the indicator always seems to work correctly if return rates_total is used instead of return 0?  😏

You can find out by looking at the logs. Make the indicator work incorrectly and look at the logs.

How did you understand that the indicator was not working correctly? Has the indicator become detached from the chart? The log will most likely contain an error that occurred during runtime due to which the indicator was detached.
 
Vladislav Boyko #:

You can find out by looking at the logs. Make the indicator work incorrectly and look at the logs.

I did look at the logs and this is how I found how that the indicator was deinitialized seconds after being initialized. I'm not talking from my imagination.

 
Conor Mcnamara #:

I did look at the logs and this is how I found how that the indicator was deinitialized seconds after being initialized. I'm not talking from my imagination.

What else was in the logs? Runtime errors?

What is the reason for deinitialization? Add deinitialization reason logging:

void OnDeinit(const int reason)
  {
   Print("Deinitialization reason code = ",reason); 
   ObjectDelete(ChartID(),"Average_Price_Line_"+Symbol());
   ObjectDelete(ChartID(),"Information_"+Symbol());
   ObjectDelete(ChartID(),"Information_2"+Symbol());
  }

And wait for the following situation to occur once again:

Conor Mcnamara #:
that the indicator was deinitialized seconds after being initialized

Aren't you curious to know what really happened?

 
Vladislav Boyko #:

What else was in the logs? Runtime errors?

What is the reason for deinitialization? Add deinitialization reason logging:

And wait for the following situation to occur once again:

Aren't you curious to know what really happened?

this is what I got

2024.06.30 15:30:03.961 average_price_1 (XAUUSD,M1)     The reason indicator deinitialized: 1

I couldn't find error num 1 here: https://www.mql5.com/en/docs/constants/errorswarnings  (I guess because 1 means it is a "successful call of OnDeInit" and is not seen as an error)


and it does not print this when returning rates_total instead of 0


You're not wrong to be skeptical due to the fact that a "return 0" scenario is not explained in the documentation for OnCalculate, so it seems to be undisclosed information 

Documentation on MQL5: Constants, Enumerations and Structures / Codes of Errors and Warnings
Documentation on MQL5: Constants, Enumerations and Structures / Codes of Errors and Warnings
  • www.mql5.com
This section contains the following descriptions: Return codes of the trade server – analyzing results of the trade request sent by function...
 
Conor Mcnamara #:
I couldn't find error num 1 here strangely enough

This is not an error, but a deinitialization reason code.

https://www.mql5.com/en/docs/event_handlers/ondeinit

The reason parameter may have the following values:

Constant

Value

Description

REASON_PROGRAM

0

The EA has stopped working calling the ExpertRemove() function

REASON_REMOVE

1

Program removed from a chart

REASON_RECOMPILE

2

Program recompiled

REASON_CHARTCHANGE

3

A symbol or a chart period is changed

REASON_CHARTCLOSE

4

Chart closed

REASON_PARAMETERS

5

Inputs changed by a user

REASON_ACCOUNT

6

Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings

REASON_TEMPLATE

7

Another chart template applied

REASON_INITFAILED

8

The OnInit() handler returned a non-zero value

REASON_CLOSE

9

Terminal closed

 

Yeah that's what I thought. 

This is what return 0 does in OnCalculate, it tells the program to successfully complete its operation and it calls OnDeInit gracefully. This isn't explained in the docs, however "return 0" was always known to indicate completion of a program in C programming. You would expect it to keep calculating, but this will end the program. They could flesh out the docs a bit more for OnCalculate explanation.

 
Conor Mcnamara #:
this is what I got

This suggests that most likely you simply manually removed the indicator from the chart.

Here is an indicator that definitely crashes in runtime.

#property indicator_chart_window

void OnDeinit(const int reason)
  {
   Print("Deinitialization reason code = ",reason);
  }

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[])
  {
   int a[];
   a[1]++;
   return(rates_total);
  }

So, after the crash, OnDeinit was not called (the deinitialization code was not printed in the log).

If I comment out the line that causes the indicator to crash, OnDeinit will be called and the deinitialization code will be printed.

 
Conor Mcnamara #:
this is what I got

Considering the following

Vladislav Boyko #:

So, after the crash, OnDeinit was not called (the deinitialization code was not printed in the log).

If I comment out the line that causes the indicator to crash, OnDeinit will be called and the deinitialization code will be printed.

I can assume that your indicator did not crash and shut down normally.

 

@Conor Mcnamara, it looks like you are right. I took the standard ATR and made it always return 0. In the strategy tester, the indicator subwindow remains empty in this case. Additionally, the buffer is also not shown in the data window. All this despite the fact that, judging by the performance, the buffer values ​​are calculated for all bars with each tick.


 

Hi

Here you don’t use any buffers just display some objects on the chart, so you can try to add ChartRedraw(ChartID()) at the end of your code to force to redraw th chart.
I tried your code and the objects are displayed normally even without this function, but maybe you have some slower version. Besides that your cod eis not the best solution here, instead of „deleting” and „creating” lines every tick. You can try create the line once and then only move the price of the line on every tick. Also for the label you used wrong function to set the text – you need to specify the parameters of the font in separate functions like this:

ObjectSetInteger(ChartID(),"Information_"+Symbol(),OBJPROP_COLOR,font_color);
   ObjectSetInteger(ChartID(),"Information_"+Symbol(),OBJPROP_FONTSIZE, font_size);
   ObjectSetString(ChartID(),"Information_"+Symbol(),OBJPROP_TEXT, "Avrg= "+DoubleToString(Average_Price,NrOfDigits)+"  "+DoubleToString(distance/(point),1)+" pips ("+Net_Result+" "+AccountInfoString(ACCOUNT_CURRENCY)+")  Lots= "+Net_Lots+"  Orders= "+Net_Trades);

Best Regards