Calculo Delta consome todo PC

 

Por favor, tem alguma forma de calcular o delta sem consumir tanto o pc?


Sei que delta ja é nativo no profitchart, mas no metatrader5 precisa calcular, sendo que esse calculo simplesmente consome todo o pc (e olha que o meu é um HP I7 16gb) e ainda sim, só funciona bem se nao tiver absolutamente mais nada ligado no pc, sómente o metatrader5 e mais nada. 


Ae gostaria de saber se outras pessoas da comunidade ja teve experiencia e, se possivel/houver, quais soluções encontraram. 


Obrigado.

 
Samuel Cavalcanti Costa:

Por favor, tem alguma forma de calcular o delta sem consumir tanto o pc?


Sei que delta ja é nativo no profitchart, mas no metatrader5 precisa calcular, sendo que esse calculo simplesmente consome todo o pc (e olha que o meu é um HP I7 16gb) e ainda sim, só funciona bem se nao tiver absolutamente mais nada ligado no pc, sómente o metatrader5 e mais nada. 


Ae gostaria de saber se outras pessoas da comunidade ja teve experiencia e, se possivel/houver, quais soluções encontraram. 


Obrigado.

Se está com consumo excessivo possívelmente erro na programação do indicador ou EA que está usando, foi você que desenvolveu ou pegou algo pronto? 

Você tem como usar o Profiler do metatrader para ver qual o método que está consumindo mais recurso
 
Samuel Cavalcanti CostaPor favor, tem alguma forma de calcular o delta sem consumir tanto o pc? Sei que delta ja é nativo no profitchart, mas no metatrader5 precisa calcular, sendo que esse calculo simplesmente consome todo o pc (e olha que o meu é um HP I7 16gb) e ainda sim, só funciona bem se nao tiver absolutamente mais nada ligado no pc, sómente o metatrader5 e mais nada. Ae gostaria de saber se outras pessoas da comunidade ja teve experiencia e, se possivel/houver, quais soluções encontraram. Obrigado.

Segue um exemplo de Delta otimizado focado nesses 3 pontos: carga inicial limitada, cálculo incremental (só processa ticks novos) e agregação direta por barra (sem arrays tick-a-tick) - código totalmente comentado. Fique à vontade para adaptar às suas necessidades e informe se identificar falhas (ver log), por favor.

//+------------------------------------------------------------------+
//|                              Indicador de Volume Delta Otimizado |
//|                                                                  |
//| Características:                                                 |
//|  - Cálculo INCREMENTAL (processa apenas ticks novos)             |
//|  - Agregação POR BARRA (sem arrays tick-a-tick)                  |
//|  - Buffers limitados ao histórico realmente exibido              |
//|  - Classificação agressor por flags da B3 + fallback BID/ASK     |
//+------------------------------------------------------------------+
#property copyright "Comunidade MQL5 - Exemplo educacional"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_plots   2

//--- Plot 1: Delta da barra (histograma colorido)
#property indicator_label1  "Delta"
#property indicator_type1   DRAW_COLOR_HISTOGRAM
#property indicator_color1  clrDodgerBlue, clrCrimson
#property indicator_style1  STYLE_SOLID
#property indicator_width1  3

//--- Plot 2: Delta acumulado (linha) - opcional, ver InpShowCumul
#property indicator_label2  "Delta Acumulado"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrGold
#property indicator_style2  STYLE_SOLID
#property indicator_width2  2

//--- Inputs
input int    InpHistoryBars     = 500;   // Quantas barras manter no histórico
input bool   InpShowCumul       = true;  // Exibir Delta acumulado
input bool   InpResetCumulDaily = true;  // Zerar Delta acumulado a cada novo dia
input bool   InpVerboseLog      = true;  // Imprimir logs de diagnóstico

//--- Buffers
double BufferDelta[];      // Delta de cada barra (histograma)
double BufferDeltaColor[]; // Cor do histograma (0=alta, 1=baixa)
double BufferCumul[];      // Delta acumulado (linha)
double BufferAux[];        // Auxiliar (não plotado)

//--- Estado interno (para processamento incremental)
ulong    g_lastTickTime  = 0;     // Timestamp em ms do último tick processado
datetime g_lastBarTime   = 0;     // Open time da última barra processada
double   g_cumulDelta    = 0;     // Delta acumulado corrente
bool     g_initialLoaded = false; // Carga inicial concluída com sucesso?

//+------------------------------------------------------------------+
//| OnInit                                                           |
//+------------------------------------------------------------------+
int OnInit()
  {
// Vincula buffers
   SetIndexBuffer(0, BufferDelta,      INDICATOR_DATA);
   SetIndexBuffer(1, BufferDeltaColor, INDICATOR_COLOR_INDEX);
   SetIndexBuffer(2, BufferCumul,      INDICATOR_DATA);
   SetIndexBuffer(3, BufferAux,        INDICATOR_CALCULATIONS);

// Configurações de plot
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);

// Esconder o cumulativo se desativado
   if(!InpShowCumul)
      PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_NONE);

   IndicatorSetString(INDICATOR_SHORTNAME, "Volume Delta (Incremental)");
   IndicatorSetInteger(INDICATOR_DIGITS, 0);

// Reset de estado
   g_lastTickTime  = 0;
   g_lastBarTime   = 0;
   g_cumulDelta    = 0;
   g_initialLoaded = false;

   return INIT_SUCCEEDED;
  }

//+------------------------------------------------------------------+
//| Retorna o início do dia (00:00) para um dado timestamp           |
//+------------------------------------------------------------------+
datetime DayStart(datetime t)
  {
   MqlDateTime dt;
   TimeToStruct(t, dt);
   dt.hour = 0;
   dt.min  = 0;
   dt.sec  = 0;
   return StructToTime(dt);
  }

//+------------------------------------------------------------------+
//| Classifica um tick como agressão de compra (+1) ou venda (-1)    |
//| Retorna 0 se indeterminado.                                      |
//+------------------------------------------------------------------+
int ClassifyTick(const MqlTick &tick)
  {
// Estratégia mais confiável: usar a flag oficial quando disponível
   if((tick.flags & TICK_FLAG_BUY) != 0)
      return +1;
   if((tick.flags & TICK_FLAG_SELL) != 0)
      return -1;

// Fallback: comparar last com bid/ask
   if(tick.last > 0 && tick.bid > 0 && tick.ask > 0)
     {
      if(tick.last >= tick.ask)
         return +1; // executou no ASK = comprador agressor
      if(tick.last <= tick.bid)
         return -1; // executou no BID = vendedor agressor
      // Entre bid e ask: usar mid-point como referência
      double mid = (tick.bid + tick.ask) / 2.0;
      if(tick.last > mid)
         return +1;
      if(tick.last < mid)
         return -1;
     }

   return 0;
  }

//+------------------------------------------------------------------+
//| Processa um lote de ticks e distribui o delta nas barras         |
//+------------------------------------------------------------------+
void ProcessTicks(const MqlTick &ticks[], const int rates_total,
                  const datetime &time[])
  {
   int ticksCount = ArraySize(ticks);
   if(ticksCount == 0)
      return;

   int classified = 0;
   int lastBarIdx = rates_total - 1;

   for(int i = 0; i < ticksCount; i++)
     {
      // Pular ticks que NÃO são de negócio
      if((ticks[i].flags & (TICK_FLAG_BUY | TICK_FLAG_SELL)) == 0
         && ticks[i].last <= 0)
         continue;

      long vol = (long)ticks[i].volume;
      if(vol <= 0)
         continue;

      int side = ClassifyTick(ticks[i]);
      if(side == 0)
         continue;

      // Encontrar a barra correspondente ao tick
      datetime tickTime = (datetime)(ticks[i].time_msc / 1000);
      int idx = lastBarIdx;
      while(idx >= 0 && time[idx] > tickTime)
         idx--;
      if(idx < 0)
         continue;

      // Inicializar a barra se ainda for "vazia"
      if(BufferDelta[idx] == EMPTY_VALUE)
         BufferDelta[idx] = 0;

      BufferDelta[idx] += (double)(side * vol);
      lastBarIdx = idx;
      classified++;
     }

   if(InpVerboseLog && ticksCount > 0)
      PrintFormat("ProcessTicks: %d ticks recebidos, %d classificados",
                  ticksCount, classified);
  }

//+------------------------------------------------------------------+
//| Recalcula buffer de cores e Delta acumulado a partir de um       |
//| índice                                                           |
//+------------------------------------------------------------------+
void RebuildCumulAndColors(const int rates_total, const datetime &time[],
                           int startIdx)
  {
   if(startIdx < 0)
      startIdx = 0;
   if(startIdx >= rates_total)
      return;

   double cumul = (startIdx > 0 && BufferCumul[startIdx - 1] != EMPTY_VALUE)
                  ? BufferCumul[startIdx - 1] : 0.0;
   datetime lastDay = (startIdx > 0) ? DayStart(time[startIdx - 1]) : 0;

   for(int i = startIdx; i < rates_total; i++)
     {
      if(InpResetCumulDaily)
        {
         datetime curDay = DayStart(time[i]);
         if(curDay != lastDay)
           {
            cumul = 0;
            lastDay = curDay;
           }
        }

      // Tratar EMPTY_VALUE como 0 para a soma cumulativa
      double bd = (BufferDelta[i] == EMPTY_VALUE) ? 0.0 : BufferDelta[i];
      cumul += bd;
      BufferCumul[i] = cumul;

      // Cor do histograma (apenas para barras com valor)
      if(BufferDelta[i] != EMPTY_VALUE)
         BufferDeltaColor[i] = (BufferDelta[i] >= 0) ? 0 : 1;
     }

   g_cumulDelta = cumul;
  }

//+------------------------------------------------------------------+
//| OnCalculate                                                      |
//+------------------------------------------------------------------+
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(rates_total < 2)
      return 0;

// ----------------------------------------------------------------
// CARGA INICIAL - feita uma única vez COM SUCESSO
// ----------------------------------------------------------------
   if(!g_initialLoaded)
     {
      // Inicializar buffers como "vazios"
      ArrayInitialize(BufferDelta,      EMPTY_VALUE);
      ArrayInitialize(BufferDeltaColor, 0);
      ArrayInitialize(BufferCumul,      EMPTY_VALUE);
      ArrayInitialize(BufferAux,        0);

      int startBar = MathMax(0, rates_total - InpHistoryBars);
      datetime startTime = time[startBar];
      ulong startMsc = (ulong)startTime * 1000;

      MqlTick ticks[];
      int copied = CopyTicksRange(_Symbol, ticks, COPY_TICKS_TRADE,
                                  startMsc, 0);

      if(copied <= 0)
        {
         // Histórico de ticks ainda não disponível - tentar de novo no próximo tick
         int err = GetLastError();
         if(InpVerboseLog)
            PrintFormat("Carga inicial: nenhum tick disponível ainda (erro=%d). "
                        "Tentando novamente no próximo OnCalculate...", err);
         ResetLastError();
         return 0; // <-- IMPORTANTE: retornar 0 força nova tentativa
        }

      if(InpVerboseLog)
         PrintFormat("Carga inicial OK: %d ticks a partir de %s",
                     copied, TimeToString(startTime, TIME_DATE | TIME_MINUTES));

      ProcessTicks(ticks, rates_total, time);
      RebuildCumulAndColors(rates_total, time, startBar);

      g_lastTickTime  = ticks[copied - 1].time_msc;
      g_lastBarTime   = time[rates_total - 1];
      g_initialLoaded = true;

      return rates_total;
     }

// ----------------------------------------------------------------
// CHAMADAS SUBSEQUENTES - processar APENAS ticks novos
// ----------------------------------------------------------------
   bool newBar = (time[rates_total - 1] != g_lastBarTime);
   int recalcFromIdx = rates_total - 1;

   if(newBar)
     {
      BufferDelta[rates_total - 1] = EMPTY_VALUE;
      g_lastBarTime = time[rates_total - 1];
     }

   MqlTick ticks[];
   ulong fromMsc = g_lastTickTime + 1;
   int copied = CopyTicksRange(_Symbol, ticks, COPY_TICKS_TRADE, fromMsc, 0);

   if(copied > 0)
     {
      datetime firstTickTime = (datetime)(ticks[0].time_msc / 1000);
      int idx = rates_total - 1;
      while(idx >= 0 && time[idx] > firstTickTime)
         idx--;
      if(idx >= 0 && idx < recalcFromIdx)
         recalcFromIdx = idx;

      ProcessTicks(ticks, rates_total, time);
      g_lastTickTime = ticks[copied - 1].time_msc;
     }

   RebuildCumulAndColors(rates_total, time, recalcFromIdx);

   return rates_total;
  }

//+------------------------------------------------------------------+
//| OnDeinit                                                         |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   if(InpVerboseLog)
      Print("Volume Delta encerrado. Motivo=", reason);
  }
//+------------------------------------------------------------------+