From 70b945a196aa904ae1b64f73f061a7cf6835210b Mon Sep 17 00:00:00 2001 From: Toh4iem9 Date: Wed, 1 Oct 2025 08:53:48 +0200 Subject: [PATCH] new files added --- Include/MyIncludes/Supertrend_Calculator.mqh | 194 +++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 Include/MyIncludes/Supertrend_Calculator.mqh diff --git a/Include/MyIncludes/Supertrend_Calculator.mqh b/Include/MyIncludes/Supertrend_Calculator.mqh new file mode 100644 index 0000000..a06cfb2 --- /dev/null +++ b/Include/MyIncludes/Supertrend_Calculator.mqh @@ -0,0 +1,194 @@ +//+------------------------------------------------------------------+ +//| Supertrend_Calculator.mqh| +//| Calculation engine for Standard and Heikin Ashi Supertrend. | +//| Copyright 2025, xxxxxxxx | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2025, xxxxxxxx" + +#include // Re-use our robust ATR calculator + +//--- Enum for ATR Calculation Source --- +enum ENUM_ATR_SOURCE + { + ATR_SOURCE_STANDARD, // Calculate ATR from standard candles + ATR_SOURCE_HEIKIN_ASHI // Calculate ATR from Heikin Ashi candles + }; + +//+==================================================================+ +//| | +//| CLASS 1: CSupertrendCalculator (Base Class) | +//| | +//+==================================================================+ +class CSupertrendCalculator + { +protected: + int m_atr_period; + double m_factor; + + CATRCalculator *m_atr_calculator; + + double m_src_high[], m_src_low[], m_src_close[]; + + virtual bool PrepareSourceData(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[]); + +public: + CSupertrendCalculator(void); + virtual ~CSupertrendCalculator(void); + + bool Init(int atr_p, double factor, ENUM_ATR_SOURCE atr_src); + void Calculate(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[], + double &st_buffer[], double &color_buffer[]); + }; + +//+------------------------------------------------------------------+ +//| CSupertrendCalculator: Constructor | +//+------------------------------------------------------------------+ +CSupertrendCalculator::CSupertrendCalculator(void) + { + m_atr_calculator = NULL; // Initialize pointer to NULL + } + +//+------------------------------------------------------------------+ +//| CSupertrendCalculator: Destructor | +//+------------------------------------------------------------------+ +CSupertrendCalculator::~CSupertrendCalculator(void) + { + if(CheckPointer(m_atr_calculator) != POINTER_INVALID) + delete m_atr_calculator; + } + +//+------------------------------------------------------------------+ +//| CSupertrendCalculator: Initialization | +//+------------------------------------------------------------------+ +bool CSupertrendCalculator::Init(int atr_p, double factor, ENUM_ATR_SOURCE atr_src) + { + m_atr_period = (atr_p < 1) ? 1 : atr_p; + m_factor = (factor <= 0) ? 3.0 : factor; + + if(CheckPointer(m_atr_calculator) != POINTER_INVALID) + delete m_atr_calculator; + + if(atr_src == ATR_SOURCE_HEIKIN_ASHI) + { + m_atr_calculator = new CATRCalculator_HA(); + } + else + { + m_atr_calculator = new CATRCalculator(); + } + + if(CheckPointer(m_atr_calculator) == POINTER_INVALID) + return false; + return m_atr_calculator.Init(m_atr_period); + } + +//+------------------------------------------------------------------+ +//| CSupertrendCalculator: Main Calculation Method (Shared Logic) | +//+------------------------------------------------------------------+ +void CSupertrendCalculator::Calculate(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[], + double &st_buffer[], double &color_buffer[]) + { + if(rates_total <= m_atr_period || CheckPointer(m_atr_calculator) == POINTER_INVALID) + return; + if(!PrepareSourceData(rates_total, open, high, low, close)) + return; + + double atr[], upper[], lower[], trend[]; + ArrayResize(atr, rates_total); + ArrayResize(upper, rates_total); + ArrayResize(lower, rates_total); + ArrayResize(trend, rates_total); + + m_atr_calculator.Calculate(rates_total, open, high, low, close, atr); + + for(int i = 1; i < rates_total; i++) + { + double hl2 = (m_src_high[i] + m_src_low[i]) / 2.0; + double atr_val = m_factor * atr[i]; + + double upper_basic = hl2 + atr_val; + double lower_basic = hl2 - atr_val; + + if(upper_basic < upper[i-1] || m_src_close[i-1] > upper[i-1]) + upper[i] = upper_basic; + else + upper[i] = upper[i-1]; + + if(lower_basic > lower[i-1] || m_src_close[i-1] < lower[i-1]) + lower[i] = lower_basic; + else + lower[i] = lower[i-1]; + + if(i == m_atr_period) + trend[i] = (m_src_close[i] > hl2) ? 1 : -1; + else + if(i > m_atr_period) + { + if(trend[i-1] == 1 && m_src_close[i] < lower[i]) + trend[i] = -1; + else + if(trend[i-1] == -1 && m_src_close[i] > upper[i]) + trend[i] = 1; + else + trend[i] = trend[i-1]; + } + + if(trend[i] == 1) + { + st_buffer[i] = lower[i]; + color_buffer[i] = 0; + if(trend[i-1] == -1) + st_buffer[i-1] = lower[i]; + } + else + { + st_buffer[i] = upper[i]; + color_buffer[i] = 1; + if(trend[i-1] == 1) + st_buffer[i-1] = upper[i]; + } + } + } + +//+------------------------------------------------------------------+ +//| CSupertrendCalculator: Prepares the standard source data. | +//+------------------------------------------------------------------+ +bool CSupertrendCalculator::PrepareSourceData(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[]) + { + ArrayResize(m_src_high, rates_total); + ArrayCopy(m_src_high, high, 0, 0, rates_total); + ArrayResize(m_src_low, rates_total); + ArrayCopy(m_src_low, low, 0, 0, rates_total); + ArrayResize(m_src_close, rates_total); + ArrayCopy(m_src_close, close, 0, 0, rates_total); + return true; + } + +//+==================================================================+ +//| | +//| CLASS 2: CSupertrendCalculator_HA (Heikin Ashi) | +//| | +//+==================================================================+ +class CSupertrendCalculator_HA : public CSupertrendCalculator + { +private: + CHeikinAshi_Calculator m_ha_calculator; +protected: + virtual bool PrepareSourceData(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[]) override; + }; + +//+------------------------------------------------------------------+ +//| CSupertrendCalculator_HA: Prepares the HA source data. | +//+------------------------------------------------------------------+ +bool CSupertrendCalculator_HA::PrepareSourceData(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[]) + { + double ha_open[]; + ArrayResize(ha_open, rates_total); + ArrayResize(m_src_high, rates_total); + ArrayResize(m_src_low, rates_total); + ArrayResize(m_src_close, rates_total); + m_ha_calculator.Calculate(rates_total, open, high, low, close, ha_open, m_src_high, m_src_low, m_src_close); + return true; + } +//+------------------------------------------------------------------+ +//+------------------------------------------------------------------+