Files
2026-05-28 19:06:07 +03:00

79 lines
2.6 KiB
Plaintext

//+------------------------------------------------------------------+
//| Data/VWAP_Engine.mqh |
//+------------------------------------------------------------------+
#ifndef __VWAP_ENGINE_MQH__
#define __VWAP_ENGINE_MQH__
#include "../Core/Config.mqh"
#include "../Core/State.mqh"
class CVWAPEngine
{
private:
AssetProfile m_profile;
datetime m_lastSessionStart;
double m_cachedVWAP;
double m_cachedSlope;
public:
bool Init(const AssetProfile &profile)
{
m_profile = profile;
m_lastSessionStart = 0;
m_cachedVWAP = 0;
m_cachedSlope = 0;
return true;
}
void Release() {}
void Calculate(VWAPState &state)
{
datetime sessionStart = g_session.GetSessionStart(m_profile);
if(sessionStart != m_lastSessionStart)
{
m_lastSessionStart = sessionStart;
state.sumPV = 0; state.sumV = 0; state.sessionStart = sessionStart;
m_cachedVWAP = 0; m_cachedSlope = 0;
}
MqlTick ticks[];
int copied = CopyTicksRange(_Symbol, ticks, COPY_TICKS_TRADE, sessionStart, TimeCurrent());
if(copied <= 0) { state.isValid = false; return; }
double sumPV = 0; long sumV = 0;
for(int i = 0; i < copied; i++)
{
double price = (ticks[i].bid + ticks[i].ask) / 2.0;
long volume = (long)ticks[i].volume;
if(volume > 0 && price > 0) { sumPV += price * (double)volume; sumV += volume; }
}
if(sumV > 0)
{
state.vwapValue = sumPV / (double)sumV;
state.sumPV = sumPV; state.sumV = (double)sumV; state.isValid = true;
m_cachedVWAP = state.vwapValue;
CalculateSlope(state);
}
else { state.isValid = false; state.vwapValue = m_cachedVWAP; }
}
private:
void CalculateSlope(VWAPState &state)
{
MqlRates rates[];
ArraySetAsSeries(rates, true);
int copied = CopyRates(_Symbol, PERIOD_M15, 0, VWAP_SLOPE_BARS + 2, rates);
if(copied < VWAP_SLOPE_BARS + 2) { state.vwapSlope = m_cachedSlope; return; }
double sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;
int n = VWAP_SLOPE_BARS;
for(int i = 1; i <= n; i++)
{
double x = (double)i;
double y = rates[i].close - state.vwapValue;
sumX += x; sumY += y; sumXY += x * y; sumX2 += x * x;
}
double denominator = (n * sumX2 - sumX * sumX);
if(denominator != 0) { state.vwapSlope = (n * sumXY - sumX * sumY) / denominator; m_cachedSlope = state.vwapSlope; }
else { state.vwapSlope = m_cachedSlope; }
}
};
#endif // __VWAP_ENGINE_MQH__