mirror of
https://github.com/softwaredevelop/mql5.git
synced 2026-08-14 04:48:05 +00:00
refactor: Optimized for incremental calculation & Consolidated Engine
This commit is contained in:
@@ -1,17 +1,151 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| MovingAverage_Ribbon_MTF_Calculator.mqh|
|
||||
//| Engine for the fully customizable MTF MA Ribbon. |
|
||||
//| Contains both the Line Helper and the Ribbon Manager. |
|
||||
//| Copyright 2025, xxxxxxxx |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2025, xxxxxxxx"
|
||||
|
||||
#include <MyIncludes\Single_MA_MTF_Calculator.mqh>
|
||||
#include <MyIncludes\MovingAverage_Engine.mqh>
|
||||
|
||||
//+==================================================================+
|
||||
//| HELPER CLASS: CSingleMAMTFCalculator |
|
||||
//| Handles the logic, state, and buffers for ONE MTF line. |
|
||||
//+==================================================================+
|
||||
class CSingleMAMTFCalculator
|
||||
{
|
||||
private:
|
||||
CMovingAverageCalculator *m_calculator;
|
||||
|
||||
//--- MTF Settings
|
||||
ENUM_TIMEFRAMES m_timeframe;
|
||||
bool m_is_mtf;
|
||||
|
||||
//--- Persistent State for MTF Calculation
|
||||
double m_htf_buffer[]; // Stores HTF MA values between ticks
|
||||
int m_htf_prev_calc; // Tracks how many HTF bars are already calculated
|
||||
|
||||
public:
|
||||
CSingleMAMTFCalculator(void);
|
||||
~CSingleMAMTFCalculator(void);
|
||||
|
||||
bool Init(ENUM_TIMEFRAMES tf, int period, ENUM_MA_TYPE type, bool is_ha);
|
||||
|
||||
void Calculate(int rates_total, int prev_calculated, const datetime &time[], ENUM_APPLIED_PRICE price_type,
|
||||
const double &open[], const double &high[], const double &low[], const double &close[],
|
||||
double &output_buffer[]);
|
||||
};
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| CSingleMAMTFCalculator Implementation |
|
||||
//+------------------------------------------------------------------+
|
||||
CSingleMAMTFCalculator::CSingleMAMTFCalculator(void) : m_calculator(NULL), m_htf_prev_calc(0) {}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
CSingleMAMTFCalculator::~CSingleMAMTFCalculator(void)
|
||||
{
|
||||
if(CheckPointer(m_calculator) != POINTER_INVALID)
|
||||
delete m_calculator;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSingleMAMTFCalculator::Init(ENUM_TIMEFRAMES tf, int period, ENUM_MA_TYPE type, bool is_ha)
|
||||
{
|
||||
m_timeframe = (tf == PERIOD_CURRENT) ? (ENUM_TIMEFRAMES)Period() : tf;
|
||||
m_is_mtf = (m_timeframe > Period());
|
||||
|
||||
if(m_timeframe < Period())
|
||||
return false;
|
||||
|
||||
if(is_ha)
|
||||
m_calculator = new CMovingAverageCalculator_HA();
|
||||
else
|
||||
m_calculator = new CMovingAverageCalculator();
|
||||
|
||||
if(CheckPointer(m_calculator) == POINTER_INVALID || !m_calculator.Init(period, type))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
void CSingleMAMTFCalculator::Calculate(int rates_total, int prev_calculated, const datetime &time[], ENUM_APPLIED_PRICE price_type,
|
||||
const double &open[], const double &high[], const double &low[], const double &close[],
|
||||
double &output_buffer[])
|
||||
{
|
||||
if(CheckPointer(m_calculator) == POINTER_INVALID)
|
||||
return;
|
||||
|
||||
if(prev_calculated == 0)
|
||||
m_htf_prev_calc = 0;
|
||||
|
||||
//--- MTF MODE ---
|
||||
if(m_is_mtf)
|
||||
{
|
||||
int htf_rates = (int)SeriesInfoInteger(_Symbol, m_timeframe, SERIES_BARS_COUNT);
|
||||
if(htf_rates < m_calculator.GetPeriod())
|
||||
return;
|
||||
|
||||
datetime htf_time[];
|
||||
double htf_open[], htf_high[], htf_low[], htf_close[];
|
||||
|
||||
if(CopyTime(_Symbol, m_timeframe, 0, htf_rates, htf_time) <= 0 ||
|
||||
CopyOpen(_Symbol, m_timeframe, 0, htf_rates, htf_open) <= 0 ||
|
||||
CopyHigh(_Symbol, m_timeframe, 0, htf_rates, htf_high) <= 0 ||
|
||||
CopyLow(_Symbol, m_timeframe, 0, htf_rates, htf_low) <= 0 ||
|
||||
CopyClose(_Symbol, m_timeframe, 0, htf_rates, htf_close) <= 0)
|
||||
return;
|
||||
|
||||
if(ArraySize(m_htf_buffer) != htf_rates)
|
||||
ArrayResize(m_htf_buffer, htf_rates);
|
||||
|
||||
// Incremental HTF Calculation
|
||||
m_calculator.Calculate(htf_rates, m_htf_prev_calc, price_type, htf_open, htf_high, htf_low, htf_close, m_htf_buffer);
|
||||
m_htf_prev_calc = htf_rates;
|
||||
|
||||
// Mapping
|
||||
ArraySetAsSeries(htf_time, true);
|
||||
ArraySetAsSeries(m_htf_buffer, true);
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(output_buffer, true);
|
||||
|
||||
int limit = (prev_calculated > 0) ? rates_total - prev_calculated : rates_total;
|
||||
|
||||
for(int i = 0; i < limit; i++)
|
||||
{
|
||||
int htf_shift = iBarShift(_Symbol, m_timeframe, time[i], false);
|
||||
if(htf_shift >= 0 && htf_shift < htf_rates)
|
||||
output_buffer[i] = m_htf_buffer[htf_shift];
|
||||
else
|
||||
output_buffer[i] = EMPTY_VALUE;
|
||||
}
|
||||
|
||||
ArraySetAsSeries(m_htf_buffer, false);
|
||||
ArraySetAsSeries(time, false);
|
||||
ArraySetAsSeries(output_buffer, false);
|
||||
}
|
||||
//--- CURRENT TF MODE ---
|
||||
else
|
||||
{
|
||||
m_calculator.Calculate(rates_total, prev_calculated, price_type, open, high, low, close, output_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//+==================================================================+
|
||||
//| MAIN CLASS: CMovingAverageRibbonMTFCalculator |
|
||||
//| Manages the 4 instances of the helper class. |
|
||||
//+==================================================================+
|
||||
class CMovingAverageRibbonMTFCalculator
|
||||
{
|
||||
protected:
|
||||
//--- Composition: The Ribbon HAS four single MTF MA calculators
|
||||
// Composition: 4 independent instances
|
||||
CSingleMAMTFCalculator *m_ma1, *m_ma2, *m_ma3, *m_ma4;
|
||||
|
||||
public:
|
||||
@@ -24,17 +158,13 @@ public:
|
||||
ENUM_TIMEFRAMES tf4, int p4, ENUM_MA_TYPE t4,
|
||||
bool is_ha);
|
||||
|
||||
void Calculate(int rates_total, const datetime &time[], ENUM_APPLIED_PRICE price_type,
|
||||
void Calculate(int rates_total, int prev_calculated, const datetime &time[], ENUM_APPLIED_PRICE price_type,
|
||||
const double &open[], const double &high[], const double &low[], const double &close[],
|
||||
double &ma1_buffer[], double &ma2_buffer[], double &ma3_buffer[], double &ma4_buffer[]);
|
||||
};
|
||||
|
||||
//+==================================================================+
|
||||
//| METHOD IMPLEMENTATIONS |
|
||||
//+==================================================================+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//| CMovingAverageRibbonMTFCalculator Implementation |
|
||||
//+------------------------------------------------------------------+
|
||||
CMovingAverageRibbonMTFCalculator::CMovingAverageRibbonMTFCalculator(void)
|
||||
{
|
||||
@@ -85,18 +215,17 @@ bool CMovingAverageRibbonMTFCalculator::Init(ENUM_TIMEFRAMES tf1, int p1, ENUM_M
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
void CMovingAverageRibbonMTFCalculator::Calculate(int rates_total, const datetime &time[], ENUM_APPLIED_PRICE price_type,
|
||||
void CMovingAverageRibbonMTFCalculator::Calculate(int rates_total, int prev_calculated, const datetime &time[], ENUM_APPLIED_PRICE price_type,
|
||||
const double &open[], const double &high[], const double &low[], const double &close[],
|
||||
double &ma1_buffer[], double &ma2_buffer[], double &ma3_buffer[], double &ma4_buffer[])
|
||||
{
|
||||
if(CheckPointer(m_ma1) == POINTER_INVALID || CheckPointer(m_ma2) == POINTER_INVALID ||
|
||||
CheckPointer(m_ma3) == POINTER_INVALID || CheckPointer(m_ma4) == POINTER_INVALID)
|
||||
if(CheckPointer(m_ma1) == POINTER_INVALID)
|
||||
return;
|
||||
|
||||
m_ma1.Calculate(rates_total, time, price_type, open, high, low, close, ma1_buffer);
|
||||
m_ma2.Calculate(rates_total, time, price_type, open, high, low, close, ma2_buffer);
|
||||
m_ma3.Calculate(rates_total, time, price_type, open, high, low, close, ma3_buffer);
|
||||
m_ma4.Calculate(rates_total, time, price_type, open, high, low, close, ma4_buffer);
|
||||
// Delegate with prev_calculated
|
||||
m_ma1.Calculate(rates_total, prev_calculated, time, price_type, open, high, low, close, ma1_buffer);
|
||||
m_ma2.Calculate(rates_total, prev_calculated, time, price_type, open, high, low, close, ma2_buffer);
|
||||
m_ma3.Calculate(rates_total, prev_calculated, time, price_type, open, high, low, close, ma3_buffer);
|
||||
m_ma4.Calculate(rates_total, prev_calculated, time, price_type, open, high, low, close, ma4_buffer);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
Reference in New Issue
Block a user