refactor: Memory-safe pointer lifecycle & bounds protection

This commit is contained in:
Toh4iem9
2026-08-31 13:55:57 +02:00
parent 1dca7b9ef9
commit cfebf66b1f
+108 -29
View File
@@ -3,8 +3,7 @@
//| Copyright 2026, xxxxxxxx|
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, xxxxxxxx"
#property version "1.31" // Upgraded for compatibility with dynamic chronological safeguards
#property description "Adapter for the John Ehlers' Laguerre Filter indicator."
#property version "3.20" // Memory-safe pointer lifecycle & bounds protection
#ifndef LAGUERRE_FILTER_CALCULATOR_MQH
#define LAGUERRE_FILTER_CALCULATOR_MQH
@@ -12,72 +11,152 @@
#include <MyIncludes\Laguerre_Engine.mqh>
//+==================================================================+
//| CLASS: CLaguerreFilterCalculator |
//| CLASS 1: CLaguerreFilterCalculator |
//+==================================================================+
class CLaguerreFilterCalculator
{
protected:
CLaguerreEngine *m_engine;
virtual void CreateEngine(void);
public:
CLaguerreFilterCalculator(void) { m_engine = new CLaguerreEngine(); };
virtual ~CLaguerreFilterCalculator(void) { if(CheckPointer(m_engine) != POINTER_INVALID) delete m_engine; };
CLaguerreFilterCalculator(void);
virtual ~CLaguerreFilterCalculator(void);
bool Init(double gamma, ENUM_INPUT_SOURCE source_type);
//--- Enhanced Pro Init
bool Init(const double gamma, const ENUM_INPUT_SOURCE source_type, const ENUM_APPLIED_PRICE_HA_ALL price_source);
//--- Updated: Accepts prev_calculated
void Calculate(int rates_total, int prev_calculated, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[],
//--- Legacy Compatible Init
bool Init(const double gamma, const ENUM_INPUT_SOURCE source_type)
{
return Init(gamma, source_type, PRICE_CLOSE_STD);
}
//--- Modern Unified Calculation Method
void Calculate(const int rates_total, const int prev_calculated,
const double &open[], const double &high[],
const double &low[], const double &close[],
double &filter_buffer[], double &fir_buffer[]);
//--- Legacy Overload with price_type parameter
void Calculate(const int rates_total, const int prev_calculated, const ENUM_APPLIED_PRICE price_type,
const double &open[], const double &high[],
const double &low[], const double &close[],
double &filter_buffer[], double &fir_buffer[])
{
Calculate(rates_total, prev_calculated, open, high, low, close, filter_buffer, fir_buffer);
}
};
//+------------------------------------------------------------------+
//| Init |
//| Constructor |
//+------------------------------------------------------------------+
bool CLaguerreFilterCalculator::Init(double gamma, ENUM_INPUT_SOURCE source_type)
CLaguerreFilterCalculator::CLaguerreFilterCalculator(void) : m_engine(NULL)
{
if(CheckPointer(m_engine) == POINTER_INVALID)
return false;
return m_engine.Init(gamma, source_type);
}
//+------------------------------------------------------------------+
//| Calculate (Optimized) |
//| Destructor |
//+------------------------------------------------------------------+
void CLaguerreFilterCalculator::Calculate(int rates_total, int prev_calculated, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[],
CLaguerreFilterCalculator::~CLaguerreFilterCalculator(void)
{
if(CheckPointer(m_engine) != POINTER_INVALID)
{
delete m_engine;
m_engine = NULL;
}
}
//+------------------------------------------------------------------+
//| Factory Method |
//+------------------------------------------------------------------+
void CLaguerreFilterCalculator::CreateEngine(void)
{
if(CheckPointer(m_engine) != POINTER_INVALID)
{
delete m_engine;
m_engine = NULL;
}
m_engine = new CLaguerreEngine();
}
//+------------------------------------------------------------------+
//| Initialization |
//+------------------------------------------------------------------+
bool CLaguerreFilterCalculator::Init(const double gamma, const ENUM_INPUT_SOURCE source_type, const ENUM_APPLIED_PRICE_HA_ALL price_source)
{
CreateEngine();
if(CheckPointer(m_engine) == POINTER_INVALID)
return false;
return m_engine.Init(gamma, source_type, price_source);
}
//+------------------------------------------------------------------+
//| Main Incremental Calculation Loop |
//+------------------------------------------------------------------+
void CLaguerreFilterCalculator::Calculate(const int rates_total, const int prev_calculated,
const double &open[], const double &high[],
const double &low[], const double &close[],
double &filter_buffer[], double &fir_buffer[])
{
if(CheckPointer(m_engine) == POINTER_INVALID)
if(rates_total < 2 || CheckPointer(m_engine) == POINTER_INVALID)
return;
m_engine.CalculateFilter(rates_total, prev_calculated, price_type, open, high, low, close, filter_buffer);
// Safe allocation of destination arrays
if(ArraySize(filter_buffer) != rates_total)
{
ArrayResize(filter_buffer, rates_total);
ArraySetAsSeries(filter_buffer, false);
ArrayInitialize(filter_buffer, EMPTY_VALUE);
}
if(ArraySize(fir_buffer) != rates_total)
{
ArrayResize(fir_buffer, rates_total);
ArraySetAsSeries(fir_buffer, false);
ArrayInitialize(fir_buffer, EMPTY_VALUE);
}
// FIR Filter Calculation (Optimized using the dynamic inline GetPrice getter)
int start_index = (prev_calculated > 0) ? prev_calculated - 1 : 0;
// 1. Calculate Core Laguerre Filter
m_engine.CalculateFilter(rates_total, prev_calculated, open, high, low, close, filter_buffer);
// 2. Calculate 4-Point FIR Comparison Filter
int start_index = (prev_calculated > 0) ? (prev_calculated - 1) : 0;
if(start_index < 3)
start_index = 3;
if(rates_total > 3)
if(prev_calculated == 0)
{
// FIXED: Uses direct m_engine.GetPrice() to prevent massive memory copy overhead per tick!
for(int i = start_index; i < rates_total; i++)
{
fir_buffer[i] = (m_engine.GetPrice(i) + 2.0 * m_engine.GetPrice(i-1) + 2.0 * m_engine.GetPrice(i-2) + m_engine.GetPrice(i-3)) / 6.0;
}
fir_buffer[0] = filter_buffer[0];
fir_buffer[1] = filter_buffer[1];
fir_buffer[2] = filter_buffer[2];
}
for(int i = start_index; i < rates_total; i++)
{
fir_buffer[i] = (m_engine.GetPrice(i) +
2.0 * m_engine.GetPrice(i - 1) +
2.0 * m_engine.GetPrice(i - 2) +
m_engine.GetPrice(i - 3)) / 6.0;
}
}
//+==================================================================+
//| CLASS 2: CLaguerreFilterCalculator_HA |
//| CLASS 2: CLaguerreFilterCalculator_HA (Legacy Wrapp) |
//+==================================================================+
class CLaguerreFilterCalculator_HA : public CLaguerreFilterCalculator
{
public:
CLaguerreFilterCalculator_HA(void)
protected:
virtual void CreateEngine(void) override
{
if(CheckPointer(m_engine) != POINTER_INVALID)
{
delete m_engine;
m_engine = NULL;
}
m_engine = new CLaguerreEngine_HA();
};
}
};
#endif // LAGUERRE_FILTER_CALCULATOR_MQH