Hull Moving Average - MetaTrader 5 Script - MQL5 #39735 - MT4/MT5 Resource




I didn't understand where other Hull MA implementations came from, so I decided to implement it myself. It has four input parameters:
These parameters are self-explanatory. The enumeration ENUM_COLOR_KIND switches between single color and multicolor, defaulting to single color. In multicolor, the Hull MA has another color for rising values and another color for falling values. In monochrome mode, ENUM_COLOR_INDEX sets the monochrome color of the Hull MA. In multicolor mode, the default color is gray. The color is green when going uphill and red when going downhill. You can see it in the two pictures below.
//+------------------------------------------------------------------+ //| MelzHull.mq5 | //| Copyright 2022, wm1@gmx.de | //| https://melz.one | //+------------------------------------------------------------------+ /* === My Hull Moving Average Implementation In My Indicator you can choose between single color and multi color indicator lines. */ Enumeration ENUM_COLOR_KIND { // Single color or alternating color Single color, Multicolor}; enumeration ENUM_COLOR_INDEX { // Indicator_color1 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, W. Melz, wm1@gmx.de" #property associated with "https://melz.one" # Property version "1.00" # Property description "My implementation of Hull Moving Average" //--- indicator settings #Property Indicator Chart Window // Draw in chart window #Property indicator buffer 4 // Buffer: fullWMA, halfWMA, vHull, cHull #Property Indicator Chart 1 // Draw only one line #Property indicator type 1 draw_color_line // draw color line // Color index to choose from: 0 1 2 3 4 5 6, feel free to expand the list to 64 colors #Property Indicator Color 1 Grey , Clear Green , Red Cell , Clear Blue , clr Green Yellow , clr Dodge Blue , clr FireBrick #PropertyIndicatorWidth1 1 // Line width #Property Indicator Tag 1 "HMA" //Indicator Name //--- input parameters Input integer InpHmaPeriod = 20 ; // Indicator period, default 20 Input ENUM_COLOR_KIND InpColorKind = single_color; // Type of indicator color, single color or multi-color Input ENUM_COLOR_INDEX InpColorIndex = color_index_3; // Set the color of the single color indicator Input integer InpMaxHistoryBars = 240 ; // Calculate the number of historical bars, the default is 240, no more //--- indicator buffer Double value buffer[]; //Storage hull index value Double color buffer[]; // Store the hull indicator color on the bar Double fullWMABuffer[]; //Storage calculation of WMA full cycle Double halfWMABuffer[]; // Store the calculated WMA half cycle //--- indicator global variables Integer hmaPeriod, fullPeriod, halfPeriod, sqrtPeriod, maxHistoryBars; // Store input value or default value //+------------------------------------------------------------------+ //|Custom indicator initialization function | //+------------------------------------------------------------------+ Integer initialization () { ENUM_INIT_RETCODE result = check input(); // Check whether the input parameters are correctly set index buffer ( 0 , value buffer, INDICATOR_DATA ); // Store indicator buffer mapping set index buffer ( 1 , color buffer, INDICATOR_COLOR_INDEX ); // Store indicator candle color set index buffer ( 2 , complete WMA buffer, indicator calculation ); // Store the results of fullWMA calculation set index buffer ( 3 , halfWMABuffer, indicator calculation ); // Store the halfWMA calculation result indicator set integer ( INDICATOR_DIGITS , _number ); // Set the indicator bit string abbreviation = string format ( "HMA(%d)" , hma period); // The name of the data window and indicator sub-window label indicator set string ( INDICATOR_SHORTNAME , abbreviation); the drawing index setting string ( 0 , drawing label , abbreviation); // Calculate the global value of the indicator fullPeriod = hmaPeriod; // Period starting from input half period = full period / 2 ; // Compute half period sqrt period = ( integer ) circular ( square root (( double )fullPeriod)); // Compute square root of period return (result); // Success or failure, init complete } //+--------------------------------------------------------------------------------+ //| | //+--------------------------------------------------------------------------------+ ENUM_INIT_RETCODE Check input ( blank ) { // Change this function to your own indicator parameters if (InpHmaPeriod <= 0 ) { // Check if the input value range is correct hmaPeriod = 14 ; // If the input is invalid, set the period to 14 print format ( "The input parameter InpTestPeriod = %d is incorrect. The indicator will be calculated using the value %d." ,InpHmaPeriod,hmaPeriod); } else hmaPeriod = InpHmaPeriod; // Set the input period maxHistoryBars = InpMaxHistoryBars; // Otherwise use the input value to return ( initialization successful ); // or INIT_FAILED } //------------------------------------------------------------------ // Custom indicator de-initialization function //----------------------------------------------------------------------------- Blank solution initialization ( constant integer reason) { Array free (value buffer); Array free (color buffer); Array free (full WMA buffer); Array free (half WMA buffer); } //+------------------------------------------------------------------+ //|Customized indicator iteration function | //+------------------------------------------------------------------+ when calculated with integers ( const integer rate_total, const integer previously calculated, const datetime &time[], const double &open[], const double& high [], const double &low[], const double & off [], const"keyword">long &tick_volume[], constant long &volume[], constant integer &spread[]) { if (rates_total < maxHistoryBars + hmaPeriod) // Test available bars, adjust period when calculating other indicators return ( 0 ); // When there are no available bars, no operation is performed on this tick. Integer start bar; // Store index value if (previously calculated == 0 ) { // If no historical bars were calculated before //Print("--- Calculate historical bars"); // For the first price movement, calculate all historical bars, the earliest index 0, plus rates_total - InpMaxHistoryBars - 1 (start from index) startBar = rates_total - maxHistoryBars - hmaPeriod - 1 ; Plotting index set integer ( 0 , drawing_draw_start , startBar + hmaPeriod); // Set the drawing to start from the bar with index startBar + hmaPeriod // Calculate CalcHma(startBar,rates_total,close); // Calculate the Ma value on the volume and compare it with the bar size } if (rates_total - prev_calculated == 1 ) { //Print("-- calculate new bar"); start bar = rates_total - 1 ; // Calculate actual new opening bar // Calculate CalcHma(startBar,rates_total,close); // Calculate Ma value on volume and compare with bar size } // Calculate //Print("- calculate each tick"); Return (rate_total); // Return value of prev_calculated for next call } // Calculate from startBar to rates_total on array buf Ma blank calorific value( integer startbar, const integer rates_total, const double &buf[]) { for ( integer column = startbar; columns < rates_total && ! stopped (); bar++) { // Loop through the bar chart // (1) Indicator calculation, WMA sum of full period doubles = 0.0 ; // Store period sum value for later use in division double wMA = 0.0 ; // Store the calculated value of the bar integer wf = 1 ; // Set the starting weight factor to 1 and the sum of the integers Wf = 0 ; // Set the sum of the weight factors to 0 for ( integer i = complete period - 1 ; i >= 0 ; i - ) { // Loop through the entire period of the actual bar // sum += getPrice(open, high, low, close, (bar - i)) * wf; // Get the applied price and add the prices of n bars, starting from the oldest bar, the lowest index sum += buf[(bar - i)] * wf; // Get the applied prices and add the prices of n bars, starting from the oldest bar, the lowest index sumWf += wf; // Add all the weighting factors of the division wf += 1 ; // Add the weighting factor of the linear weight of the next newer bar } wMA=sum/sumWf; // Calculate the linear weighted average of the entire MA period fullWMABuffer[bar] = wMA; // Save the value to the buffer for later use // (2) Indicator calculation, WMA half-period sum = 0.0 ; // Store the period sum value for later division wMA= 0.0 ; // Store the calculated value of the bar wf= 1 ; // Set the starting weight factor to 1 sum Wf = 0 ; // Set the sum of the weight factors to 0ss="keyword">for ( integer i = half period - 1 ; i >= 0 ; i - ) { // Loop over half a period of the actual bar // sum += getPrice(opening price, highest price, lowest price, closing price, (bar - i)) * wf; // Get the applied price and add the prices of n bars, starting from the oldest bar, the lowest index sum += buf[(bar - i)] * wf; // Get the applied price and add the prices of n bars, starting from the oldest bar, the lowest index sumWf += wf; // Add all weighting factors of the division wf += 1 ; // Add weighting factor of the linear weight of the next newer bar } wMA=sum/sumWf; // Calculate the linear weighted average of half MA periods halfWMABuffer[bar] = wMA; // Save the value to the buffer for later use // (3) Indicator calculation, calculation of Hull sum = 0.0 ; // Store period sum value for later division wf = 1 ; // Set starting weight factor to 1 sum Wf = 0 ; // Set sum of weight factors to 0 for ( integer i = sqrtPeriod - 1 ; i >= 0 ; i - ) { // Loop half period sum of the actual bar += ( 2 * halfWMABuffer[bar - i] - fullWMABuffer[bar - i]) * wf; // Calculate the sum of sqrt(period) and multiply by the weighting factor sumWf += wf; // Add all weighting factors of the division wf += 1 ; // Add the weighting factor of the linear weight of the next newer bar } wMA=sum/sumWf; // Calculate the linear weighted average of half MA periods valueBuffer[bar] = wMA; // Store the HMA for display // (4) Indicator color calculation, adjust as needed colorBuffer[bar] = getColor(bar); } } // Calculate color for each bar, adjust as needed double getcolor( integer bar) { double reval; // Store return value if (InpColorKind == single_color) // Set single color retval = InpColorIndex; // blue // retval = InpHullColor; else { // Set multi-color, default is gray retrieval value = 0 ; // gray if (valueBuffer[bar - 1 ] < valueBuffer[column]) // green if indicator is up retrieval value = 1; // green if (valueBuffer[column - 1 ] > valueBuffer[column]) // red if indicator is down retrieval value = 2 ; // red } return (retrieval); // return calculated color } //+--------------------------------------------------------------------------------+
Enjoy using it.
Attachment download
📎 melzhull.mq5 (11.73 KB)
Source: MQL5 #39735
💡 Featured Recommendations
✍️ Latest by the author
- •
- •
- •
- •
- •
- •
📌 Popular topics
- •
- •
- •
- •
- •
- •
- •
- •
🔗 You May Be Interested In
- •
- •
- •
- •
- •
- •