iCustom don't work

 

Hello every one.

I'm iniciant in mql5, I have a indicator that I do and now I want create a EA for work with indicator. This is very simple because I am a iniciant

I'm testing this EA, but I think that the values of buffers are not actualized when I am using the EA. 
If you try ut just the indicator on a graph, you will see tha indicator works fine, but if you try use the EA, the values of buffers will be 0 ever.


this the code to indicator:

//+------------------------------------------------------------------+
//|                                                          DOM.mq5 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
#property indicator_type1   DRAW_LINE
#property indicator_type2   DRAW_LINE
#property indicator_color1  Green
#property indicator_color2  Red
#property indicator_width1  2
#property indicator_width2  2
#property indicator_label1  "Volume Vendas (Média)"
#property indicator_label2  "Volume Compras (Média)"

double ComprasBuffer[];
double VendasBuffer[];


// Variáveis para calcular médias
double VolCompraAcumulado = 0;
double VolVendaAcumulado = 0;
double ContadorAtualizacoes = 0;

int j = 0;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   MarketBookAdd(_Symbol);
   Print("Adicionando Ativo");
   SetIndexBuffer(0, ComprasBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, VendasBuffer, INDICATOR_DATA);

   
   // Configurar um temporizador para calcular a média a cada 30 segundos
   EventSetTimer(30);
   
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator iteration 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[])
{
   j = rates_total - 1;
   return(rates_total);
   Print("OnCalculate acontecendo");
}

//+------------------------------------------------------------------+
//| Função chamada em mudanças no DOM                                |
//+------------------------------------------------------------------+
MqlBookInfo DadosDOM[];

void OnBookEvent(const string &symbol)
{
   Print("EVENTOS NO BOOK OK");
   bool getBook = MarketBookGet(NULL, DadosDOM);
   if (getBook)
   {
      long VolCompra = 0;
      long VolVenda = 0;
      int size = ArraySize(DadosDOM);
      
      for (int i = 0; i < size; i++)
      {
         if (DadosDOM[i].type == BOOK_TYPE_BUY)
            VolCompra += DadosDOM[i].volume;
         else if (DadosDOM[i].type == BOOK_TYPE_SELL)
            VolVenda += DadosDOM[i].volume;
      }
      
      // Acumular valores para calcular média
      VolCompraAcumulado += VolCompra;
      VolVendaAcumulado += VolVenda;
      ContadorAtualizacoes++;
   }
   else
   {
      Print("Não foi possível obter dados do DOM ", Symbol());
   }
}

//+------------------------------------------------------------------+
//| Função chamada a cada 30 segundos para calcular médias           |
//+------------------------------------------------------------------+
void OnTimer()
{
   if (ContadorAtualizacoes > 0)
   {
      // Calcular médias
      double MediaCompra = VolCompraAcumulado / ContadorAtualizacoes;
      double MediaVenda = VolVendaAcumulado / ContadorAtualizacoes;

      // Atualizar buffers
      ComprasBuffer[j] = MediaCompra;
      VendasBuffer[j] = MediaVenda;
      Print("COMPRAS", ComprasBuffer[j]);
      Print("VENDAS", VendasBuffer[j]);
      Print("J: ", j);
      // Debugging
      //Print("Média de Compras: ", MediaCompra, " | Média de Vendas: ", MediaVenda);

      // Resetar acumuladores
      VolCompraAcumulado = 0;
      VolVendaAcumulado = 0;
      ContadorAtualizacoes = 0;

      // Incrementar índice do buffer

   }
}

//+------------------------------------------------------------------+
//| Destruir temporizador na desinicialização                        |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Print("Tchau Abner, Espero que tenha Lucrado!!!");
   MarketBookRelease(_Symbol);
   EventKillTimer();
}



and this is the code of EA:

//+------------------------------------------------------------------+
//|                                                        ABNER.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#include <Trade\Trade.mqh>
//+------------------------------------------------------------------+
//| Variáveis Globais                                                |
//+------------------------------------------------------------------+
input double RiscoPercentual = 1.0;  // Percentual de risco por operação
input int StopLossPontos = 100;     // Stop Loss em pontos
input int TakeProfitPontos = 200;   // Take Profit em pontos
input string IndicadorNome = "DOM"; // Nome do indicador customizado
CTrade trade;

double IndicatorValue1[];             // Volume de intenção de compra
double IndicatorValue2[];             // Volume de intenção de venda
int indicadorHandle;
int index=0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   Print("EA Iniciado");
   Print("Iniciando Indicador");
   indicadorHandle = iCustom(NULL, Period(), "DOM");
   
   if (indicadorHandle == INVALID_HANDLE) {
        Print("Erro ao carregar o indicador: ", GetLastError());
        return(INIT_FAILED);  // Falha ao inicializar
    }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
  Print(" Estamos de Saída, E.A. foi desativado");
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(){
   // Obter os valores mais recentes dos buffers do indicador
    CopyBuffer(indicadorHandle, 0, 0, 1, IndicatorValue1);
    CopyBuffer(indicadorHandle, 1, 0, 1, IndicatorValue2);

    Print("COMPRAS", IndicatorValue1[0]);
    Print("VENDAS", IndicatorValue2[0]);
//---
   // Validar valores do indicador
   if (IndicatorValue1[0] == EMPTY_VALUE || IndicatorValue2[0] == EMPTY_VALUE) {
      Print("Valores inválidos do indicador. Ignorando tick.");
      return;
   }
   
   // Verificar condições de compra ou venda
   if (IndicatorValue1[index] > IndicatorValue2[0]) {
      Print("Volume de Compra maior", IndicatorValue1[0]);
   } 
   else if (IndicatorValue1[0] < IndicatorValue2[0]) {
      Print("Volume de Venda maior", IndicatorValue2[0]);
      }
}

  
//+------------------------------------------------------------------+
//| Função de Compra                                                 |
//+------------------------------------------------------------------+
void Comprar() {
   if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL){
   trade.PositionClose(Symbol());
   };
   if (ContarPosicoesAbertas("BUY") == 0) {
      double lotes = 1; //CalcularLotes();
      double precoAtual = SymbolInfoDouble(Symbol(), SYMBOL_ASK);

      if (!trade.Buy(lotes, Symbol(), precoAtual, precoAtual - StopLossPontos * _Point, precoAtual + TakeProfitPontos * _Point)) {
         Print("Erro ao abrir ordem de compra: ", GetLastError());
      } else {
         Print("Ordem de compra aberta com sucesso!");
         }
   } else{
      Print("Já existe uma ordem de compra aberta");
      }
     }


//+------------------------------------------------------------------+
//| Função de Venda                                                  |
//+------------------------------------------------------------------+
void Vender() {
   if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY){
   trade.PositionClose(Symbol());
   };
   if (ContarPosicoesAbertas("SELL") == 0) {
      double lotes = 1; //CalcularLotes();
      double precoAtual = SymbolInfoDouble(Symbol(), SYMBOL_BID);

      if (!trade.Sell(lotes, Symbol(), precoAtual, precoAtual + StopLossPontos * _Point, precoAtual - TakeProfitPontos * _Point)) {
         Print("Erro ao abrir ordem de venda: ", GetLastError());
      } else {
         Print("Ordem de venda aberta com sucesso!");
      }
   }
}

//+------------------------------------------------------------------+
//| Função para Calcular o Lote com Base no Risco                   |
//+------------------------------------------------------------------+
//double CalcularLotes() {
//   double saldo = AccountBalance();
//   double riscoEmDinheiro = saldo * (RiscoPercentual / 100.0);
//   double valorPorPonto = SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE);
//   double pontosStop = StopLossPontos * SymbolInfoDouble(Symbol(), SYMBOL_POINT);
//   double lotes = riscoEmDinheiro / (pontosStop * valorPorPonto);
//   return NormalizeDouble(lotes, 2); // Retorna lotes arredondados para 2 casas decimais
//}

//+------------------------------------------------------------------+
//| Função para Contar Ordens Abertas                               |
//+------------------------------------------------------------------+
int ContarPosicoesAbertas(string tipo) {
   int total = 0;
   
   if (PositionSelect(Symbol())) { 
      if ((tipo == "BUY" && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) ||
          (tipo == "SELL" && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)) {
         total++;
      }
   } 
   return total;  // A chave de fechamento do método também precisa estar aqui.
}
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
  
  }
  //---------------
//+------------------------------------------------------------------+
//| Trade function                                                   |
//+------------------------------------------------------------------+
void OnTrade()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Tester function                                                  |
//+------------------------------------------------------------------+
double OnTester()
  {
//---
   double ret=0.0;
//---

//---
   return(ret);
  }
//+------------------------------------------------------------------+
//| TesterInit function                                              |
//+------------------------------------------------------------------+
void OnTesterInit()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| TesterDeinit function                                            |
//+------------------------------------------------------------------+
void OnTesterDeinit()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
   
  }
[Deleted]  
Your topic has been moved to the section: Expert Advisors and Automated Trading
Please consider which section is most appropriate — https://www.mql5.com/en/forum/172166/page6#comment_49114893
 
Is your broker offering Depth Of Market ?
 
Daniel Cioca #:
Is your broker offering Depth Of Market ?
Yes, I am using the indicator all days, my indicator has acess to Depth Of Market, but with EA, I guess that it don't work, but I don't know what is wrong
 

Maybe if you try to get the value of last closed candle ? Like 


void OnTick(){
   // Obter os valores mais recentes dos buffers do indicador
    CopyBuffer(indicadorHandle, 0, 0, 2, IndicatorValue1);
    CopyBuffer(indicadorHandle, 1, 0, 2, IndicatorValue2);

    Print("COMPRAS", IndicatorValue1[1]);
    Print("VENDAS", IndicatorValue2[1]);
 
Daniel Cioca #:

Maybe if you try to get the value of last closed candle ? Like 


The same answer, I got 0 for both Buffers.
O don't know, but, if you observe, there are some Prints in "Ontimer", and "OnCalculate". In the experts tab, these prints don't occour. But if I select my indicator to graph, the prints appears normaly
 
abnercta #:
The same answer, I got 0 for both Buffers.
O don't know, but, if you observe, there are some Prints in "Ontimer", and "OnCalculate". In the experts tab, these prints don't occour. But if I select my indicator to graph, the prints appears normaly

maybe 0 means it hasnt changed?

 
Michael Charles Schefe #: maybe 0 means it hasnt changed?

This is unlikely. There are sell and buy orders all the time. In fact, using the operator, you can check this, as the line graphs will form curves

 
abnercta #:

This is unlikely. There are sell and buy orders all the time. In fact, using the operator, you can check this, as the line graphs will form curves

i meant unchanged from the previous tick. Try adding the copybuffer(s) to a loop of 5. If output is less than or equal to 0, then continue the loop.

The indicator may not be responding fast enuf also. all my ea I include such a loop now, when sourcing indicator info for this same reason of 0 reply from the indicator. I am unsure if the indicators are too slow to respond, or it happens for some other reason.
 
Michael Charles Schefe #:

i meant unchanged from the previous tick. Try adding the copybuffer(s) to a loop of 5. If output is less than or equal to 0, then continue the loop.

The indicator may not be responding fast enuf also. all my ea I include such a loop now, when sourcing indicator info for this same reason of 0 reply from the indicator. I am unsure if the indicators are too slow to respond, or it happens for some other reason.

ok, let me get this straight

for(i=0;i,6;i++){
        CopyBuffer(indicadorHandle, 0, 0, 1, IndicatorValue1);
        CopyBuffer(indicadorHandle, 1, 0, 1, IndicatorValue2);
}
I just need add this code? 
 
abnercta #:

ok, let me get this straight

I just need add this code? 

close. I think i would do somthing like this. maybe a moderator can "pipe in".

where you have the copy buffer, i would add a function call of the following function load_Buffers();

bool load_Buffers()
  {
   ArraySetAsSeries(IndicatorValue1,true);
   ArraySetAsSeries(IndicatorValue2,true);
   int i = 1, j = i - 1;
   for(i = 1; i <6; ++i)
     {
      ArrayResize(IndicatorValue1, 5, 5);
      ArrayResize(IndicatorValue2, 5, 5);
      if(!(CopyBuffer(indicadorHandle, 0, 0, 5, IndicatorValue1) > j))
         continue;
      else
         if(!(CopyBuffer(indicadorHandle, 0, 0, 5, IndicatorValue2) > j))
            continue;
         else
            return true;
     }
   return false;
  }