Discussion of article "Implementing indicator calculations into an Expert Advisor code" - page 3

 

I decided to share Indicator.mqh, which was modified for myself, maybe it will save time for someone when translating the indicator into a class.

Files:
 
MetaQuotes:

New article Implementing indicator calculations into an Expert Advisor code has been published:

Author: Dmitriy Gizlyk

Blast from the past here.

Very interesting article indeed! Sound and nice concept... but I fear there is a mistake in the distributed software, and it is not good to leave errors around.


Method GetData. Distributed code is:

double CIndicator::GetData(const uint buffer_num,const uint shift)
  {
   if(!Calculate())
      return EMPTY_VALUE;
//---
   if((int)buffer_num>=m_buffers)
      return EMPTY_VALUE;
//---
   return ar_IndBuffers[buffer_num].At(m_data_len-shift);
  }

Corrected code should be:

double CIndicator::GetData(const uint buffer_num,const uint shift)
  {
   if(!Calculate())
      return EMPTY_VALUE;
//---
   if((int)buffer_num>=m_buffers)
      return EMPTY_VALUE;
//---
   return ar_IndBuffers[buffer_num].At(m_data_len-shift - 1);
  }

Array index starts from 0 and last element has index (m_data_len - 1) instead of m_data_len, isn't it?

 

rf, section Working with custom indicators of https://www.mql5.com/en/articles/261

Use of Resources in MQL5
Use of Resources in MQL5
  • www.mql5.com
MQL5 programs not only automate routine calculations, but also can create a full-featured graphical environment. The functions for creating truly interactive controls are now virtually the same rich, as those in classical programming languages. If you want to write a full-fledged stand-alone program in MQL5, use resources in them. Programs with resources are easier to maintain and distribute.
 
Hi thanks u somuch
 

Thanks for the article! I am studying it to get away from unstable conventional indicators.

But it is important for me to be able to visualise indicators on a chart. Has anyone implemented it?

 

Why do you need to transfer calculations from an indicator to an Expert Advisor at all?

Many people use indicators without EA at all.

You can simply break the calculations into stages.

For example, like this:

//+------------------------------------------------------------------+
//|FutData.mq5 |
//|Copyright 2020 - 2021, prostotrader |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020-2021, prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.001"
//---
#property indicator_separate_window
#property indicator_plots   1
#property indicator_buffers 1
//---
enum IND_STAGE
{
  LOAD_TICKS = 0,
  READ_TICKS = 1,
  READ_DEALS = 2,
  FILL_DATA = 3
} stage;
//+------------------------------------------------------------------+
//| Custom indicator OnInit function|
//+------------------------------------------------------------------+
int OnInit()
{
  stage = LOAD_TICKS;  
//---
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator Load ticks function |
//+------------------------------------------------------------------+
bool LoadTicks(const datetime &a_times[])
{
  return(false);
}
//+------------------------------------------------------------------+
//| Custom indicator Read primary ticks function |
//+------------------------------------------------------------------+
bool ReadTicks()
{
  return(false);
}
//+------------------------------------------------------------------+
//| Custom indicator Read secondary ticks function |
//+------------------------------------------------------------------+
bool ReadDeals()
{
  return(false);
}
//+------------------------------------------------------------------+
//| Custom indicator Fill data function |
//+------------------------------------------------------------------+
void FillData()
{
//---
}
//+------------------------------------------------------------------+
//| Custom indicator On Calculate function |
//+------------------------------------------------------------------+
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[]  
)
{
    
  if(prev_calculated == 0)
  {
      switch (stage)
      {
        case LOAD_TICKS:
          if(LoadTicks(time) == true)
          {
            stage = READ_TICKS;
          }
          return(0);
        break;
        case READ_TICKS:
          if(ReadTicks() == true)
          {
            stage = READ_DEALS;
          }  
          return(0);
        break;
        case READ_DEALS:
          if(ReadDeals() == true)
          {
            stage = FILL_DATA;
          }  
          return(0);
        break;
        case FILL_DATA:
          stage = LOAD_TICKS;
        break;
      }
  }
  else
  {
    //
  }    
  //---
  return(rates_total);
}
//+------------------------------------------------------------------+
 
prostotrader #:

Why do I need to transfer calculations from an indicator to an Expert Advisor?

Many people use indicators without an Expert Advisor at all.

You can simply divide the calculations into stages.

For example, like this:

Due to the fact that the regular mechanism of indicators works through a stump, for example: https://www.mql5.com/ru/forum/372612 and this is due to their implementation.

With the increasing complexity of indicators, my Expert Advisor "bogged down". In the tester I caught many other bugs in the work of indicators, but I did not describe them, because it is useless.

I did not understand your idea.

Некорректная инициализация индикаторов в визуальном тестере
Некорректная инициализация индикаторов в визуальном тестере
  • 2021.07.04
  • www.mql5.com
Если делаю инициализацию индикаторов в OnInit() { } эксперта, то в визуальном тестере индикатор обычно не появляется и не отрисовывается...
 
Sunriser #:

Due to the fact that the regular indicator mechanism works through the stump , e.g.: https://www.mql5.com/ru/forum/372612 and this is due to their implementation.

With the increasing complexity of indicators, my Expert Advisor "got bogged down". In the tester, I caught many other bugs in the work of indicators, but I did not describe them, because it is useless.

I did not understand your idea.

To begin with, your code is not quite correct.

I would write it like this:

int OnInit()
  {int  TicksTesterIndicatorHandle = INVALID_HANDLE;
   bool InitComplite=false;
   if(IndicatorInitialization() == false) return(INIT_FAILED);
    return(INIT_SUCCEEDED);
 }
void OnDeinit(const int reason)
{
     if(TicksTesterIndicatorHandle != INVALID_HANDLE) IndicatorRelease(TicksTesterIndicatorHandle);
}
void OnTick()   { //if(!InitComplite)
 // { // IndicatorInitialisation();
 // }   } //+------------------------------------------------------------------+
bool IndicatorInitialization()
   { //---Get TicksTesterIndicator indicator handle
    TicksTesterIndicatorHandle=iCustom(NULL, _Period, "OnInit_TestIndicator");
 //--- Need to check if Invalid Handle values were returned 
  if(TicksTesterIndicatorHandle == INVALID_HANDLE)
      {       Print("Error while creating TicksTesterIndicator indicator - error number: ",GetLastError(),"!!!");
      
   }
    else
      { 
      Print("TicksTesterIndicator initialised, handle: ", TicksTesterIndicatorHandle);
       ArraySetAsSeries(Buf, true);
     InitComplite=true;
     return(true);
   }
    return(false);  
 }

Further, since the functions in indicators should be executed with minimal delays, complex processes (history loading, complex calculations, etc.)

are broken into several parts, returning to

OnCalculate

zero value (return(0) ), i.e. the indicator is in the initial stage until we perform all the necessary actions with minimal delays in each stage.

 
В архитектуре MetaTrader 5 организован асинхронный доступ к значениям индикаторов. Иными словами, при получении хэндла индикатора он прикрепляется к графику. Далее этот индикатор производит свои расчеты вне потока советника. Они взаимодействуют лишь на этапе передачи данных, аналогично получению данных тайм-серий. Поэтому и время на выполнение этих операций сопоставимо.

So you're saying it's gonna be faster in real life?! -Because in reality it will be so. Expert in one track, indicator in another (and maybe even on different cores). This is only if you put it into serial processing, it turns out slower - but this is only an artificial limitation due to the strategy tester.

 
I didn't understand from the article, does the class-indicator have protection against missing bars? For example, there was a connection break for 5 bars, and then the history was loaded, will the class-indicator refill only the last value in the drill or will it do a full recalculation?