Discussão do artigo "Como transferir a parte de cálculo de qualquer indicador para o código do EA" - página 3

 

Decidi compartilhar o Indicator.mqh, que foi modificado por mim mesmo, talvez economize o tempo de alguém ao traduzir o indicador para uma classe.

Arquivos anexados:
 

Uma explosão do passado aqui.

De fato, um artigo muito interessante! Conceito sólido e agradável... mas temo que haja um erro no software distribuído, e não é bom deixar erros por aí.


Método GetData. O código distribuído é:

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);
  }

O código corrigido deve ser:

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);
  }

O índice da matriz começa em 0 e o último elemento tem o índice (m_data_len - 1) em vez de m_data_len, não é?

 

rf, seção Trabalhando com indicadores personalizados de https://www.mql5.com/pt/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.
 
Oi, muito obrigado
 

Obrigado pelo artigo! Estou estudando-o para me afastar dos indicadores convencionais instáveis.

Mas é importante para mim poder visualizar os indicadores em um gráfico. Alguém já o implementou?

 

Por que você precisa transferir cálculos de um indicador para um Expert Advisor?

Muitas pessoas usam indicadores sem EA.

Você pode simplesmente dividir os cálculos em etapas.

Por exemplo, assim:

//+------------------------------------------------------------------+
//|FutData.mq5
//|Direitos autorais 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;
//+------------------------------------------------------------------+
//| Função OnInit do indicador personalizado|
//+------------------------------------------------------------------+
int OnInit()
{
  stage = LOAD_TICKS;  
//---
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Indicador personalizado Função Load ticks
//+------------------------------------------------------------------+
bool LoadTicks(const datetime &a_times[])
{
  return(false);
}
//+------------------------------------------------------------------+
//| Indicador personalizado Função de leitura de ticks primários
//+------------------------------------------------------------------+
bool ReadTicks()
{
  return(false);
}
//+------------------------------------------------------------------+
//| Indicador personalizado Função de leitura de ticks secundários
//+------------------------------------------------------------------+
bool ReadDeals()
{
  return(false);
}
//+------------------------------------------------------------------+
//| Indicador personalizado Função de preenchimento de dados
//+------------------------------------------------------------------+
void FillData()
{
//---
}
//+------------------------------------------------------------------+
//| Indicador personalizado na função Calcular
//+------------------------------------------------------------------+
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 #:

Por que preciso transferir cálculos de um indicador para um Expert Advisor?

Muitas pessoas usam indicadores sem um Expert Advisor.

Você pode simplesmente dividir os cálculos em etapas.

Por exemplo, assim:

Devido ao fato de que o mecanismo regular dos indicadores funciona por meio de um toco, por exemplo: https://www.mql5.com/ru/forum/372612 e isso se deve à sua implementação.

Com o aumento da complexidade dos indicadores, meu Expert Advisor ficou "atolado". No testador, encontrei muitos outros bugs no trabalho dos indicadores, mas não os descrevi, porque é inútil.

Não entendi sua ideia.

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

Devido ao fato de que o mecanismo regular de indicadores funciona por meio do toco, por exemplo: https://www.mql5.com/ru/forum/372612 e isso se deve à sua implementação.

Com o aumento da complexidade dos indicadores, meu Expert Advisor ficou "atolado". No testador, encontrei muitos outros bugs no trabalho dos indicadores, mas não os descrevi, porque é inútil.

Não entendi sua ideia.

Para começar, seu código não está totalmente correto.

Eu o escreveria assim:

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()   { //se(!InitComplite)
 // { // IndicatorInitialisation();
 // }   } //+------------------------------------------------------------------+
bool IndicatorInitialization()
   { //---Obter o identificador do indicador TicksTesterIndicator
    TicksTesterIndicatorHandle=iCustom(NULL, _Period, "OnInit_TestIndicator");
 //--- Necessidade de verificar se foram retornados valores de alça inválidos 
  if(TicksTesterIndicatorHandle == INVALID_HANDLE)
      {       Print("Erro ao criar o indicador TicksTesterIndicator - número do erro: ",GetLastError(),"!!!");
      
   }
    else
      { 
      Print("TicksTesterIndicator inicializado, identificador: ", TicksTesterIndicatorHandle);
       ArraySetAsSeries(Buf, true);
     InitComplite=true;
     return(true);
   }
    return(false);  
 }

Além disso, como as funções nos indicadores devem ser executadas com atrasos mínimos, os processos complexos (carregamento de histórico, cálculos complexos etc.)

são divididos em várias partes, retornando ao

OnCalculate

valor zero (return(0) ), ou seja, o indicador está no estágio inicial até executarmos todas as ações necessárias com atrasos mínimos em cada estágio.

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

Então você está dizendo que será mais rápido na vida real? -Porque na realidade será assim. Especialista em uma trilha, indicador em outra (e talvez até em núcleos diferentes). Somente se você o colocar em processamento serial, ele se tornará mais lento - mas essa é apenas uma limitação artificial devido ao testador de estratégia.

 
Não entendi no artigo se o indicador de classe tem proteção contra barras perdidas. Por exemplo, se houve uma interrupção de conexão por 5 barras e, em seguida, o histórico foi carregado, o indicador de classe preencherá novamente apenas o último valor na simulação ou fará um recálculo completo?