diff --git a/Indicators/MyIndicators/Holt_MA.mq5 b/Indicators/MyIndicators/Holt_MA.mq5 index 43d49d4..c346738 100644 --- a/Indicators/MyIndicators/Holt_MA.mq5 +++ b/Indicators/MyIndicators/Holt_MA.mq5 @@ -1,17 +1,17 @@ //+------------------------------------------------------------------+ //| Holt_MA.mq5 | //| Copyright 2025, xxxxxxxx| -//| | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, xxxxxxxx" -#property version "1.00" +#property version "2.00" #property description "Holt's Linear Trend Method (Double Exponential Smoothing)." -#property description "Provides a smoothed line with a 1-bar forecast." #property indicator_chart_window #property indicator_buffers 1 #property indicator_plots 1 +#include + //--- Plot 1: Holt MA Forecast Line #property indicator_label1 "Holt MA" #property indicator_type1 DRAW_LINE @@ -20,138 +20,14 @@ #property indicator_width1 2 //--- Input Parameters --- -input int InpPeriod = 20; // Period for initialization -input double InpAlpha = 0.1; // Alpha (Level smoothing factor, 0 < a < 1) -input double InpBeta = 0.05; // Beta (Trend smoothing factor, 0 < b < 1) -input ENUM_APPLIED_PRICE InpSourcePrice = PRICE_CLOSE; // Source Price +input int InpPeriod = 20; +input double InpAlpha = 0.1; +input double InpBeta = 0.05; +input ENUM_APPLIED_PRICE InpSourcePrice = PRICE_CLOSE; //--- Indicator Buffers --- double BufferHoltMA[]; -//+------------------------------------------------------------------+ -//| CLASS: CHoltMACalculator | -//| Encapsulates the Double Exponential Smoothing logic. | -//+------------------------------------------------------------------+ -class CHoltMACalculator - { -private: - //--- Parameters - int m_period; - double m_alpha; - double m_beta; - - //--- Internal calculation buffers - double m_price[]; - double m_level[]; - double m_trend[]; - double m_forecast[]; - -public: - CHoltMACalculator(void); - ~CHoltMACalculator(void) {}; - - bool Init(int period, double alpha, double beta); - void Calculate(int rates_total, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[], - double &holt_ma_out[]); - }; - -//+------------------------------------------------------------------+ -//| CHoltMACalculator: Constructor | -//+------------------------------------------------------------------+ -CHoltMACalculator::CHoltMACalculator(void) : m_period(0), m_alpha(0.1), m_beta(0.05) - { - } - -//+------------------------------------------------------------------+ -//| CHoltMACalculator: Initialization | -//+------------------------------------------------------------------+ -bool CHoltMACalculator::Init(int period, double alpha, double beta) - { - m_period = (period < 2) ? 2 : period; - -//--- Constrain alpha and beta to be between 0 and 1 - m_alpha = (alpha <= 0) ? 0.0001 : (alpha >= 1) ? 0.9999 : alpha; - m_beta = (beta <= 0) ? 0.0001 : (beta >= 1) ? 0.9999 : beta; - - return true; - } - -//+------------------------------------------------------------------+ -//| CHoltMACalculator: Main Calculation Method | -//+------------------------------------------------------------------+ -void CHoltMACalculator::Calculate(int rates_total, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[], - double &holt_ma_out[]) - { - if(rates_total < m_period) - return; - -//--- Resize internal buffers - ArrayResize(m_price, rates_total); - ArrayResize(m_level, rates_total); - ArrayResize(m_trend, rates_total); - ArrayResize(m_forecast, rates_total); - -//--- Step 1: Prepare the source price series - PriceSeries(price_type, rates_total, open, high, low, close, m_price); - -//--- Step 2: Robust Initialization of the first Level and Trend - m_level[0] = m_price[0]; - m_trend[0] = m_price[1] - m_price[0]; // Initial trend estimate - m_forecast[0] = m_level[0] + m_trend[0]; - m_forecast[1] = m_forecast[0]; // To avoid zero value at the start - -//--- Step 3: Recursive calculation for the rest of the series - for(int i = 2; i < rates_total; i++) - { - //--- Calculate Level - m_level[i] = m_alpha * m_price[i] + (1 - m_alpha) * (m_level[i-1] + m_trend[i-1]); - - //--- Calculate Trend - m_trend[i] = m_beta * (m_level[i] - m_level[i-1]) + (1 - m_beta) * m_trend[i-1]; - - //--- Calculate 1-bar ahead Forecast (this is the plotted line) - m_forecast[i] = m_level[i] + m_trend[i]; - } - -//--- Copy final results to the output buffer - ArrayCopy(holt_ma_out, m_forecast, 0, 0, rates_total); - } - -//+------------------------------------------------------------------+ -//| Helper function to get the selected price series. | -//+------------------------------------------------------------------+ -void PriceSeries(ENUM_APPLIED_PRICE type, int rates_total, const double &open[], const double &high[], const double &low[], const double &close[], double &dest_buffer[]) - { - switch(type) - { - case PRICE_CLOSE: - ArrayCopy(dest_buffer, close, 0, 0, rates_total); - break; - case PRICE_OPEN: - ArrayCopy(dest_buffer, open, 0, 0, rates_total); - break; - case PRICE_HIGH: - ArrayCopy(dest_buffer, high, 0, 0, rates_total); - break; - case PRICE_LOW: - ArrayCopy(dest_buffer, low, 0, 0, rates_total); - break; - case PRICE_MEDIAN: - for(int i=0; i