Getting Indicator Values in EA OnInit() functions to be processed.

 

Hi,


I have problems getting indicator values within the OnInit() function.  Same methods have no issue in OnTick() function.

Below is a demo of the issue.

The following is the code used.


//+------------------------------------------------------------------+
//|                                                OnInit_NoData.mq5 |
//|                                                         Nameless |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Nameless"
#property link      "http://www.mql5.com"
#property version   "1.00"

#include <Indicators\TimeSeries.mqh>  
#include <Indicators\Oscilators.mqh>

CiClose  close;
CiATR    atr;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
   atr.Create("EURUSD",PERIOD_D1,14);
   close.Create("EURUSD",PERIOD_D1);
   atr.Refresh();
   close.Refresh();
   
   Print("OnInit ATR - ",atr.Main(0));
   Print("OnInit Close - ",close.GetData(0));
   
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
if(!New_Period(PERIOD_D1)) return;
   atr.Refresh();
   close.Refresh();
   Print("OnTick ATR - ",atr.Main(0));
   Print("OnTick Close - ",close.GetData(0));
   
  }
//+------------------------------------------------------------------+
bool  New_Period(ENUM_TIMEFRAMES period)
  {
   static datetime Old_Time;
   datetime New_Time[1];
   bool new_period=false;

// copying the last bar time to the element New_Time[0]
   int copied=CopyTime("EURUSD",period,0,1,New_Time);
   if(copied>0) // ok, the data has been copied successfully
     {
      if(Old_Time!=New_Time[0]) // if old time isn't equal to new bar time
        {
         new_period=true;   // if it isn't a first call, the new bar has appeared
         if(MQL5InfoInteger(MQL5_DEBUGGING)) Print("We have new bar here ",New_Time[0]," old time was ",Old_Time);
         Old_Time=New_Time[0];            // saving bar time
        }
     }
   else
     {
      Alert("Error in copying historical times data, error =",GetLastError());
      ResetLastError();

      return(new_period);
     }
   return(new_period);
  }



The result is




Note that OnInit, Close returns value, but not ATR.

OnTick, using same methods, both returns value.


In Oninit, close.GetData(x) where x = 0 to 10 has no issues.

Trying to do same with atr.Main(x) or even atr.GetData(0,x)


Can anyone enlighten?  How do i get values from indicators in OnInit??  

I am using ATR as a demo.  The same happens for Custom indicators.

 

OnInit() should be used to retrieve the indicator handles only. Their values should be queried during OnTick() calls.

If you need indicator values during OnInit() you should think about improving your EA design. It may work for some indicators but it's totally unreliable.

 

I know my work around is to put it in OnTick and execute once and turn off the flag so that it wont be executed again.

However, that appears to be a workaround, and does not feel like a good place to put a "initialization" part of the program.

Just wanted to know if there are some other stuff that i have not thought about.

 
Keith Long :

I know my work around is to put it in OnTick and execute once and turn off the flag so that it wont be executed again.

However, that appears to be a workaround, and does not feel like a good place to put a "initialization" part of the program.

Just wanted to know if there are some other stuff that i have not thought about.

The indicator handle is created in OnInit - this is the law. You cannot try to get indicator data in OnInit - this is the law. Preparatory procedures are performed in OnInit, and the OnTick event ensures that the full operation of the program has begun.

 

Don't try to use any price or server related functions in OnInit (or on load,) 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.