Olá, pessoal! Hoje vamos falar sobre a Média Móvel Hull (HMA) e como você pode implementá-la no seu MetaTrader 5. Eu não consegui entender as implementações de HMA que encontrei por aí, então decidi desenvolver a minha própria versão. Vamos conferir os parâmetros que você precisa ajustar?
A HMA possui quatro parâmetros de entrada:
- InpHmaPeriod = 20
- InpColorKind = single_color
- InpColorIndex = color_index_3
- InpMaxHistoryBars = 240
Esses parâmetros são bem intuitivos. O parâmetro ENUM_COLOR_KIND alterna entre a cor única e a multi-cor. O padrão é a cor única. Quando você opta pela multi-cor, a HMA apresenta uma cor diferente para os valores em alta e outra para os valores em baixa. No modo de cor única, o parâmetro ENUM_COLOR_INDEX define a cor da HMA. No modo multi-cor, a cor padrão é cinza, enquanto na alta a cor fica verde e na baixa, vermelha. Confira as imagens abaixo para ver como fica:


Abaixo, você pode conferir o código da implementação:
//+------------------------------------------------------------------+ //| MelzHull.mq5 | //| Copyright 2022, wm1@gmx.de | //| https://melz.one | //+------------------------------------------------------------------+ /* === Minha implementação da Média Móvel Hull In meu indicador, você pode escolher entre cor única e multi-cor para a linha do indicador. */ enum ENUM_COLOR_KIND { single_color, multi_color }; enum ENUM_COLOR_INDEX { color_index_0, color_index_1, color_index_2, color_index_3, color_index_4, color_index_5, color_index_6 }; #property copyright "Copyright 2022 by W. Melz, wm1@gmx.de" #property link "https://melz.one" #property version "1.00" #property description "Implementação da minha Média Móvel Hull" #property indicator_chart_window #property indicator_buffers 4 #property indicator_plots 1 #property indicator_type1 DRAW_COLOR_LINE #property indicator_color1 clrGray, clrGreen, clrRed, clrBlue, clrGreenYellow, clrDodgerBlue, clrFireBrick #property indicator_width1 1 #property indicator_label1 "HMA" //--- parâmetros de entrada input int InpHmaPeriod = 20; input ENUM_COLOR_KIND InpColorKind = single_color; input ENUM_COLOR_INDEX InpColorIndex = color_index_3; input int InpMaxHistoryBars = 240; //--- buffers do indicador double valueBuffer[]; double colorBuffer[]; double fullWMABuffer[]; double halfWMABuffer[]; //--- variáveis globais do indicador int hmaPeriod, fullPeriod, halfPeriod, sqrtPeriod, maxHistoryBars; //+------------------------------------------------------------------+ int OnInit() { ENUM_INIT_RETCODE result = checkInput(); SetIndexBuffer(0,valueBuffer,INDICATOR_DATA); SetIndexBuffer(1,colorBuffer,INDICATOR_COLOR_INDEX); SetIndexBuffer(2,fullWMABuffer,INDICATOR_CALCULATIONS); SetIndexBuffer(3,halfWMABuffer,INDICATOR_CALCULATIONS); IndicatorSetInteger(INDICATOR_DIGITS,_Digits); string shortName = StringFormat("HMA(%d)",hmaPeriod); IndicatorSetString(INDICATOR_SHORTNAME,shortName); PlotIndexSetString(0,PLOT_LABEL,shortName); fullPeriod = hmaPeriod; halfPeriod = fullPeriod / 2; sqrtPeriod = (int)round(sqrt((double)fullPeriod)); return(result); } //+------------------------------------------------------------------+ ENUM_INIT_RETCODE checkInput(void) { if(InpHmaPeriod <= 0) { hmaPeriod = 14; PrintFormat("Parâmetro de entrada incorreto InpTestPeriod = %d. O indicador usará o valor %d para cálculos.",InpHmaPeriod,hmaPeriod); } else hmaPeriod = InpHmaPeriod; maxHistoryBars = InpMaxHistoryBars; return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ void OnDeinit(const int reason) { ArrayFree(valueBuffer); ArrayFree(colorBuffer); ArrayFree(fullWMABuffer); ArrayFree(halfWMABuffer); } //+------------------------------------------------------------------+ 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 < maxHistoryBars + hmaPeriod) return(0); int startBar; if(prev_calculated == 0) { startBar = rates_total - maxHistoryBars - hmaPeriod - 1; PlotIndexSetInteger(0,PLOT_DRAW_BEGIN, startBar + hmaPeriod); CalcHma(startBar,rates_total,close); } if(rates_total - prev_calculated == 1) { startBar = rates_total - 1; CalcHma(startBar,rates_total,close); } return(rates_total); } // calcula a Média Móvel de startBar até rates_total na array buf void CalcHma(int startBar, const int rates_total, const double &buf[]) { for(int bar = startBar; bar < rates_total && !IsStopped(); bar++) { double sum = 0.0; double wMA = 0.0; int wf = 1; int sumWf = 0; for(int i = fullPeriod - 1; i >= 0; i--) { sum += buf[(bar - i)] * wf; sumWf += wf; wf += 1; } wMA = sum / sumWf; fullWMABuffer[bar] = wMA; sum = 0.0; wMA = 0.0; wf = 1; sumWf = 0; for(int i = halfPeriod - 1; i >= 0; i--) { sum += buf[(bar - i)] * wf; sumWf += wf; wf += 1; } wMA = sum / sumWf; halfWMABuffer[bar] = wMA; sum = 0.0; wf = 1; sumWf = 0; for(int i = sqrtPeriod - 1; i >= 0; i--) { sum += (2 * halfWMABuffer[bar - i] - fullWMABuffer[bar - i]) * wf; sumWf += wf; wf += 1; } wMA = sum / sumWf; valueBuffer[bar] = wMA; colorBuffer[bar] = getColor(bar); } } double getColor(int bar) { double retval; if(InpColorKind == single_color) retval = InpColorIndex; else { retval = 0; if(valueBuffer[bar - 1] < valueBuffer[bar]) retval = 1; if(valueBuffer[bar - 1] > valueBuffer[bar]) retval = 2; } return(retval); } //+------------------------------------------------------------------+ Agora, é só aproveitar e usar a HMA em suas análises! Se você tiver alguma dúvida ou sugestão, deixa nos comentários. Vamos trocar ideias e ajudar uns aos outros a melhorar nas operações!
Publicações relacionadas
- Buffers Horários para Coleta de Dados no MetaTrader 5
- Calendário Econômico: Monitoramento e Cache para Testes de Estratégia no MetaTrader 5
- Utilitário de Informações de Séries e Taxas para MetaTrader 5: Maximize Seu Trading
- Média Móvel Exponencial Quádrupla: Indicador para MetaTrader 5
- Utilitário de Informações de Barras e Taxas: Como Usar no MetaTrader 5