Download history in MQL4 EA - page 5

 
Fernando Carreiro #:

Putting everything in OnInit() is not the correct way to code an Indicator. You should start there. If you use the OnCalculate() you can more easily know when data is available and when there are updates to that data.

I put everything in OnInit, because I want to make indicator do what it does only once, not on every tick.

 
Botan626 #: My indicator does all its job in OnInit. How can I make indicator wait for MT4 to finish downloading missing history first, or is it impossible in this case?

Don't try to use any price (or indicator) or server related functions in OnInit (or on load or in OnTimer before you've received a tick), as there may be no connection/chart yet:

  1. Terminal starts.
  2. Indicators/EAs are loaded. Static and globally declared variables are initialized. (Do not depend on a specific order.)
  3. OnInit is called.
  4. For indicators OnCalculate is called with any existing history.
  5. Human may have to enter password, connection to server begins.
  6. New history is received, OnCalculate called again.
  7. New tick is received, OnCalculate/OnTick is called. Now TickValue, TimeCurrent, account information and prices are valid.
 
William Roeder, understood, the whole process is clear now, please point me to the right place, where I can see, how to make indicator perform its actions in OnCalculate only once, regardless of new ticks being received. I guess I could combine it with the code, provided in this thread, to make my indicator load missing history first, and then do its job only once.
 
Botan626 #: I put everything in OnInit, because I want to make indicator do what it does only once, not on every tick.

That is not the function of OnInit(). It has a purpose. Don't try to put a square peg into a round hole. Read the post above by William. Follow his advice.

Botan626 #:
William Roeder, understood, the whole process is clear now, please point me to the right place, where I can see, how to make indicator perform its actions in OnCalculate only once, regardless of new ticks being received. I guess I could combine it with the code, provided in this thread, to make my indicator load missing history first, and then do its job only once.

Use OnCalculate() event handler, check the "rates_total" to detect when all the data is loaded, then execute your code once by using a static boolean variable to prevent it running again.

 

Use OnCalculate() event handler, check the "rates_total" to detect when all the data is loaded, then execute your code once by using a static boolean variable to prevent it running again.

Would like to see some actual code, please.

 
Botan626 #: Would like to see some actual code, please.

There are examples in the documentation and much more example code in the CodeBase. How much more do you need?

 

Maybe something like this. You will need to adjust it based on your exact requirements. Code is untested and only an example.

// Define indicator properties
   #property indicator_chart_window
   #property indicator_buffers 0
   #property indicator_plots   0
   
// Initialisation event handler
   int OnInit()
   {
      // Do something ...
      return INIT_SUCCEEDED;  // Successful initialisation of indicator
   };

// OnCalculate event handler
   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[] )
   {
      static bool bOnce = true;
      if( bOnce && rates_total > 0 ) // Check for flag and available data
      {
         // Do some operation just once
         bOnce = false;
      };

      return rates_total;  // Return value for prev_calculated of next call
   };
 
Fernando Carreiro #:

How much more do you need?

What I needed (wanted) was not to search for it. I'm sure I'm not the 1st one who wants it, and I'm sure William Roeder has a bookmark for it, just like he did e.g. in this post.

 
Botan626 #: What I needed (wanted) was not to search for it. I'm sure I'm not the 1st one who wants it, and I'm sure William Roeder has a bookmark for it, just like he did e.g. in this post.

I've given you a code sample in the post above. If it does not serve your purpose, then do your research please. We are not going to do it for you.

 
Fernando Carreiro #:

I've given you a code sample in the post above. If it does not serve your purpose, then do your research please. We are not going to do it for you.

Your post with the code wasn't here, when I posted my previous post. Thanks for the code.

Reason: