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.
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); } //+------------------------------------------------------------------+
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso
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.