//+------------------------------------------------------------------+ //| Stochastic_Roofing_Calculator.mqh | //| Calculation engine for a Stochastic (Fast or Slow) on an | //| Ehlers' Roofing Filter. | //| Copyright 2025, xxxxxxxx | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, xxxxxxxx" #include enum ENUM_STOCH_TYPE { STOCH_FAST, STOCH_SLOW }; //+==================================================================+ //| | //| CLASS 1: CStochasticRoofingCalculator (Base) | //| | //+==================================================================+ class CStochasticRoofingCalculator { protected: int m_hp_period, m_ss_period; // Roofing int m_k_period, m_d_period, m_slowing; // Stochastic ENUM_STOCH_TYPE m_stoch_type; double m_price[]; virtual bool PreparePriceSeries(int rates_total, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[]); public: CStochasticRoofingCalculator(void) {}; virtual ~CStochasticRoofingCalculator(void) {}; bool Init(int hp_p, int ss_p, int k_p, int d_p, int slowing, ENUM_STOCH_TYPE stoch_type); void Calculate(int rates_total, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[], double &k_buffer[], double &d_buffer[]); }; //+------------------------------------------------------------------+ bool CStochasticRoofingCalculator::Init(int hp_p, int ss_p, int k_p, int d_p, int slowing, ENUM_STOCH_TYPE stoch_type) { m_hp_period = (hp_p < 10) ? 10 : hp_p; m_ss_period = (ss_p < 2) ? 2 : ss_p; m_k_period = (k_p < 1) ? 1 : k_p; m_d_period = (d_p < 1) ? 1 : d_p; m_slowing = (slowing < 1) ? 1 : slowing; m_stoch_type = stoch_type; return true; } //+------------------------------------------------------------------+ void CStochasticRoofingCalculator::Calculate(int rates_total, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[], double &k_buffer[], double &d_buffer[]) { int warmup = m_hp_period + m_k_period + m_slowing + m_d_period; if(rates_total < warmup) return; if(!PreparePriceSeries(rates_total, price_type, open, high, low, close)) return; // --- Step 1: Calculate Roofing Filter --- double roofing_buffer[]; ArrayResize(roofing_buffer, rates_total); double hp_buffer[]; ArrayResize(hp_buffer, rates_total); double arg_hp = 0.707 * 2 * M_PI / m_hp_period; double alpha1_hp = (cos(arg_hp) + sin(arg_hp) - 1.0) / cos(arg_hp); double hp1=0, hp2=0; for(int i=2; i