mirror of
https://github.com/softwaredevelop/mql5.git
synced 2026-08-21 16:28:06 +00:00
refactor:
This commit is contained in:
@@ -1,17 +1,17 @@
|
|||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
//| Holt_MA.mq5 |
|
//| Holt_MA.mq5 |
|
||||||
//| Copyright 2025, xxxxxxxx|
|
//| Copyright 2025, xxxxxxxx|
|
||||||
//| |
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
#property copyright "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 "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_chart_window
|
||||||
#property indicator_buffers 1
|
#property indicator_buffers 1
|
||||||
#property indicator_plots 1
|
#property indicator_plots 1
|
||||||
|
|
||||||
|
#include <MyIncludes\Holt_Calculator.mqh>
|
||||||
|
|
||||||
//--- Plot 1: Holt MA Forecast Line
|
//--- Plot 1: Holt MA Forecast Line
|
||||||
#property indicator_label1 "Holt MA"
|
#property indicator_label1 "Holt MA"
|
||||||
#property indicator_type1 DRAW_LINE
|
#property indicator_type1 DRAW_LINE
|
||||||
@@ -20,138 +20,14 @@
|
|||||||
#property indicator_width1 2
|
#property indicator_width1 2
|
||||||
|
|
||||||
//--- Input Parameters ---
|
//--- Input Parameters ---
|
||||||
input int InpPeriod = 20; // Period for initialization
|
input int InpPeriod = 20;
|
||||||
input double InpAlpha = 0.1; // Alpha (Level smoothing factor, 0 < a < 1)
|
input double InpAlpha = 0.1;
|
||||||
input double InpBeta = 0.05; // Beta (Trend smoothing factor, 0 < b < 1)
|
input double InpBeta = 0.05;
|
||||||
input ENUM_APPLIED_PRICE InpSourcePrice = PRICE_CLOSE; // Source Price
|
input ENUM_APPLIED_PRICE InpSourcePrice = PRICE_CLOSE;
|
||||||
|
|
||||||
//--- Indicator Buffers ---
|
//--- Indicator Buffers ---
|
||||||
double BufferHoltMA[];
|
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<rates_total; i++)
|
|
||||||
dest_buffer[i] = (high[i]+low[i])/2.0;
|
|
||||||
break;
|
|
||||||
case PRICE_TYPICAL:
|
|
||||||
for(int i=0; i<rates_total; i++)
|
|
||||||
dest_buffer[i] = (high[i]+low[i]+close[i])/3.0;
|
|
||||||
break;
|
|
||||||
case PRICE_WEIGHTED:
|
|
||||||
for(int i=0; i<rates_total; i++)
|
|
||||||
dest_buffer[i] = (high[i]+low[i]+close[i]+close[i])/4.0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//--- Global calculator object ---
|
//--- Global calculator object ---
|
||||||
CHoltMACalculator *g_calculator;
|
CHoltMACalculator *g_calculator;
|
||||||
|
|
||||||
@@ -163,7 +39,7 @@ int OnInit()
|
|||||||
SetIndexBuffer(0, BufferHoltMA, INDICATOR_DATA);
|
SetIndexBuffer(0, BufferHoltMA, INDICATOR_DATA);
|
||||||
ArraySetAsSeries(BufferHoltMA, false);
|
ArraySetAsSeries(BufferHoltMA, false);
|
||||||
|
|
||||||
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 2); // Start drawing from the 3rd bar
|
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 2);
|
||||||
IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("Holt MA(%d, %.2f, %.2f)", InpPeriod, InpAlpha, InpBeta));
|
IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("Holt MA(%d, %.2f, %.2f)", InpPeriod, InpAlpha, InpBeta));
|
||||||
|
|
||||||
g_calculator = new CHoltMACalculator();
|
g_calculator = new CHoltMACalculator();
|
||||||
@@ -200,7 +76,8 @@ int OnCalculate(const int rates_total,
|
|||||||
{
|
{
|
||||||
if(CheckPointer(g_calculator) != POINTER_INVALID)
|
if(CheckPointer(g_calculator) != POINTER_INVALID)
|
||||||
{
|
{
|
||||||
g_calculator.Calculate(rates_total, InpSourcePrice, open, high, low, close, BufferHoltMA);
|
double dummy_trend[];
|
||||||
|
g_calculator.Calculate(rates_total, InpSourcePrice, open, high, low, close, BufferHoltMA, dummy_trend);
|
||||||
}
|
}
|
||||||
return(rates_total);
|
return(rates_total);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user