Files
mql5/Include/MyIncludes/MurreyMath_Calculator.mqh
T
2025-11-28 10:19:41 +01:00

180 lines
6.0 KiB
Plaintext

//+------------------------------------------------------------------+
//| MurreyMath_Calculator.mqh |
//| Calculation engine for Murrey Math. |
//| Copyright 2025, xxxxxxxx |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, xxxxxxxx"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CMurreyMathCalculator
{
private:
string m_symbol;
ENUM_TIMEFRAMES m_timeframe;
int m_period;
int m_step_back;
public:
CMurreyMathCalculator(void);
~CMurreyMathCalculator(void) {};
bool Init(string symbol, ENUM_TIMEFRAMES timeframe, int period, int step_back);
bool Calculate(double &levels[]);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CMurreyMathCalculator::CMurreyMathCalculator(void) : m_period(64), m_step_back(0)
{
}
//+------------------------------------------------------------------+
//| Initialization |
//+------------------------------------------------------------------+
bool CMurreyMathCalculator::Init(string symbol, ENUM_TIMEFRAMES timeframe, int period, int step_back)
{
m_symbol = symbol;
m_timeframe = timeframe;
m_period = period;
m_step_back = step_back;
return true;
}
//+------------------------------------------------------------------+
//| Main Calculation Method (Original Logic Preserved) |
//+------------------------------------------------------------------+
bool CMurreyMathCalculator::Calculate(double &levels[])
{
if(ArraySize(levels) < 13)
ArrayResize(levels, 13);
int bars_to_copy = m_period + m_step_back;
if(bars_to_copy <= 0)
bars_to_copy = 1;
//--- 1. Check available bars (Safety check)
int bars_available = (int)SeriesInfoInteger(m_symbol, m_timeframe, SERIES_BARS_COUNT);
if(bars_available < bars_to_copy)
return false; // Not enough data yet
double htf_high[], htf_low[];
//--- 2. Copy Data
int copied_high = CopyHigh(m_symbol, m_timeframe, 0, bars_to_copy, htf_high);
int copied_low = CopyLow(m_symbol, m_timeframe, 0, bars_to_copy, htf_low);
if(copied_high < bars_to_copy || copied_low < bars_to_copy)
return false; // Copy failed
//--- 3. Set as non-series for calculation
ArraySetAsSeries(htf_high, false);
ArraySetAsSeries(htf_low, false);
int rates_total = ArraySize(htf_high);
int start_pos = rates_total - 1 - m_step_back;
//--- 4. Find High/Low in range
int min_idx = ArrayMinimum(htf_low, start_pos - m_period + 1, m_period);
int max_idx = ArrayMaximum(htf_high, start_pos - m_period + 1, m_period);
if(min_idx < 0 || max_idx < 0)
return false;
double v1 = htf_low[min_idx];
double v2 = htf_high[max_idx];
//--- 5. Murrey Math Algorithm (Original)
double fractal = 0;
if((v2 <= 250000) && (v2 > 25000))
fractal = 100000;
else
if((v2 <= 25000) && (v2 > 2500))
fractal = 10000;
else
if((v2 <= 2500) && (v2 > 250))
fractal = 1000;
else
if((v2 <= 250) && (v2 > 25))
fractal = 100;
else
if((v2 <= 25) && (v2 > 12.5))
fractal = 12.5;
else
if((v2 <= 12.5) && (v2 > 6.25))
fractal = 12.5;
else
if((v2 <= 6.25) && (v2 > 3.125))
fractal = 6.25;
else
if((v2 <= 3.125) && (v2 > 1.5625))
fractal = 3.125;
else
if((v2 <= 1.5625) && (v2 > 0.390625))
fractal = 1.5625;
else
if((v2 <= 0.390625) && (v2 > 0))
fractal = 0.1953125;
if(fractal == 0)
return false;
double range = v2 - v1;
if(range <= 0)
return false;
double sum = MathFloor(MathLog(fractal / range) / MathLog(2));
double octave = fractal * (MathPow(0.5, sum));
double mn = MathFloor(v1 / octave) * octave;
double mx;
if(mn + octave > v2)
mx = mn + octave;
else
mx = mn + (2 * octave);
double x1=0, x2=0, x3=0, x4=0, x5=0, x6=0;
if((v1 >= (3 * (mx - mn) / 16 + mn)) && (v2 <= (9 * (mx - mn) / 16 + mn)))
x2 = mn + (mx - mn) / 2;
if((v1 >= (mn - (mx - mn) / 8)) && (v2 <= (5 * (mx - mn) / 8 + mn)) && (x2 == 0))
x1 = mn + (mx - mn) / 2;
if((v1 >= (mn + 7 * (mx - mn) / 16)) && (v2 <= (13 * (mx - mn) / 16 + mn)))
x4 = mn + 3 * (mx - mn) / 4;
if((v1 >= (mn + 3 * (mx - mn) / 8)) && (v2 <= (9 * (mx - mn) / 8 + mn)) && (x4 == 0))
x5 = mx;
if((v1 >= (mn + (mx - mn) / 8)) && (v2 <= (7 * (mx - mn) / 8 + mn)) && (x1 == 0) && (x2 == 0) && (x4 == 0) && (x5 == 0))
x3 = mn + 3 * (mx - mn) / 4;
if((x1 + x2 + x3 + x4 + x5) == 0)
x6 = mx;
double finalH = x1 + x2 + x3 + x4 + x5 + x6;
double y1=0, y2=0, y3=0, y4=0, y5=0, y6=0;
if(x1 > 0)
y1 = mn;
if(x2 > 0)
y2 = mn + (mx - mn) / 4;
if(x3 > 0)
y3 = mn + (mx - mn) / 4;
if(x4 > 0)
y4 = mn + (mx - mn) / 2;
if(x5 > 0)
y5 = mn + (mx - mn) / 2;
if((finalH > 0) && ((y1 + y2 + y3 + y4 + y5) == 0))
y6 = mn;
double finalL = y1 + y2 + y3 + y4 + y5 + y6;
double dmml = (finalH - finalL) / 8;
if(dmml <= 0)
return false;
levels[0] = (finalL - dmml * 2);
for(int i = 1; i < 13; i++)
levels[i] = levels[i - 1] + dmml;
return true;
}
//+------------------------------------------------------------------+