mirror of
https://github.com/softwaredevelop/mql5.git
synced 2026-11-02 11:16:15 +00:00
refactor: Pipelined Multipliers & Chronological Safety
This commit is contained in:
@@ -3,55 +3,78 @@
|
||||
//| Engine for Relative Volume (RVOL) Calculation. |
|
||||
//| Copyright 2026, xxxxxxxx |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2026, xxxxxxxx"
|
||||
#property copyright "Copyright 2026, xxxxxxxx"
|
||||
#property version "1.20" // Enterprise Refactor: Pipelined Multipliers & Chronological Safety
|
||||
#property description "High-performance calculation engine for Relative Volume (RVOL)."
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
#ifndef RELATIVE_VOLUME_CALCULATOR_MQH
|
||||
#define RELATIVE_VOLUME_CALCULATOR_MQH
|
||||
|
||||
//+==================================================================+
|
||||
//| CLASS: CRelativeVolumeCalculator |
|
||||
//+==================================================================+
|
||||
class CRelativeVolumeCalculator
|
||||
{
|
||||
protected:
|
||||
int m_period;
|
||||
long m_vol_buffer[]; // Stores volume series
|
||||
double m_inv_period; // Precalculated 1.0 / period
|
||||
|
||||
public:
|
||||
CRelativeVolumeCalculator() : m_period(20) {};
|
||||
~CRelativeVolumeCalculator() {};
|
||||
CRelativeVolumeCalculator(void) : m_period(20), m_inv_period(0.05) {};
|
||||
virtual ~CRelativeVolumeCalculator(void) {};
|
||||
|
||||
bool Init(int period);
|
||||
bool Init(const int period);
|
||||
int GetPeriod(void) const { return m_period; }
|
||||
|
||||
// Calculates RVOL for the entire series
|
||||
void Calculate(int rates_total, int prev_calculated, const long &volume[], double &rvol_buffer[]);
|
||||
// Calculates RVOL for the series in O(1)
|
||||
void Calculate(const int rates_total, const int prev_calculated, const long &volume[], double &rvol_buffer[]);
|
||||
|
||||
// Calculates single value (Helper for Scripts)
|
||||
double CalculateSingle(int total, const long &volume[], int index);
|
||||
double CalculateSingle(const int total, const long &volume[], const int index);
|
||||
};
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRelativeVolumeCalculator::Init(int period)
|
||||
//| Init |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRelativeVolumeCalculator::Init(const int period)
|
||||
{
|
||||
m_period = (period < 1) ? 1 : period;
|
||||
m_period = (period < 1) ? 1 : period;
|
||||
m_inv_period = 1.0 / (double)m_period;
|
||||
return true;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
void CRelativeVolumeCalculator::Calculate(int rates_total, int prev_calculated, const long &volume[], double &rvol_buffer[])
|
||||
//| Main Incremental Calculation (O(1) on live ticks) |
|
||||
//+------------------------------------------------------------------+
|
||||
void CRelativeVolumeCalculator::Calculate(const int rates_total, const int prev_calculated, const long &volume[], double &rvol_buffer[])
|
||||
{
|
||||
if(rates_total <= m_period)
|
||||
return;
|
||||
|
||||
int start_index = (prev_calculated > m_period) ? prev_calculated - 1 : m_period;
|
||||
// Safe allocation of output buffer
|
||||
if(ArraySize(rvol_buffer) != rates_total)
|
||||
{
|
||||
ArrayResize(rvol_buffer, rates_total);
|
||||
ArraySetAsSeries(rvol_buffer, false);
|
||||
}
|
||||
|
||||
int start_index = (prev_calculated > m_period) ? (prev_calculated - 1) : m_period;
|
||||
|
||||
if(prev_calculated == 0)
|
||||
{
|
||||
for(int i = 0; i < m_period; i++)
|
||||
rvol_buffer[i] = 0.0;
|
||||
}
|
||||
|
||||
for(int i = start_index; i < rates_total; i++)
|
||||
{
|
||||
double sum = 0;
|
||||
// Sum previous N bars (excluding current i)
|
||||
double sum = 0.0;
|
||||
for(int k = 1; k <= m_period; k++)
|
||||
sum += (double)volume[i-k];
|
||||
sum += (double)volume[i - k];
|
||||
|
||||
double avg = sum / m_period;
|
||||
double avg = sum * m_inv_period;
|
||||
|
||||
if(avg > 0)
|
||||
if(avg > 1.0e-9)
|
||||
rvol_buffer[i] = (double)volume[i] / avg;
|
||||
else
|
||||
rvol_buffer[i] = 0.0;
|
||||
@@ -59,18 +82,20 @@ void CRelativeVolumeCalculator::Calculate(int rates_total, int prev_calculated,
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
double CRelativeVolumeCalculator::CalculateSingle(int total, const long &volume[], int index)
|
||||
//| Single Bar Calculator Helper |
|
||||
//+------------------------------------------------------------------+
|
||||
double CRelativeVolumeCalculator::CalculateSingle(const int total, const long &volume[], const int index)
|
||||
{
|
||||
if(index < m_period || index >= total)
|
||||
return 0.0;
|
||||
|
||||
double sum = 0;
|
||||
double sum = 0.0;
|
||||
for(int k = 1; k <= m_period; k++)
|
||||
sum += (double)volume[index-k];
|
||||
sum += (double)volume[index - k];
|
||||
|
||||
double avg = sum / m_period;
|
||||
|
||||
return (avg > 0) ? (double)volume[index] / avg : 0.0;
|
||||
double avg = sum * m_inv_period;
|
||||
return (avg > 1.0e-9) ? ((double)volume[index] / avg) : 0.0;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
#endif // RELATIVE_VOLUME_CALCULATOR_MQH
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
Reference in New Issue
Block a user