73 lines
2.8 KiB
Plaintext
73 lines
2.8 KiB
Plaintext
//+------------------------------------------------------------------+
|
|
//| Logic/MacroAudit.mqh |
|
|
//+------------------------------------------------------------------+
|
|
#ifndef __MACRO_AUDIT_MQH__
|
|
#define __MACRO_AUDIT_MQH__
|
|
|
|
#include "../Core/Config.mqh"
|
|
#include "../Core/State.mqh"
|
|
#include "../Core/Logger.mqh"
|
|
#include "../Data/VWAP_Engine.mqh"
|
|
#include "../Data/PriceEngine.mqh"
|
|
|
|
extern CLogger g_logger;
|
|
extern CPriceEngine g_priceEngine;
|
|
|
|
class CMacroAudit
|
|
{
|
|
private:
|
|
ENUM_TIMEFRAMES m_htf;
|
|
CVWAPEngine *m_vwap;
|
|
|
|
public:
|
|
bool Init(ENUM_TIMEFRAMES htf, CVWAPEngine &vwap)
|
|
{
|
|
m_htf = htf; m_vwap = GetPointer(vwap);
|
|
Print("[MacroAudit] HTF analysis initialized on ", EnumToString(htf));
|
|
return true;
|
|
}
|
|
void Release() {}
|
|
void Analyze(EAState &state)
|
|
{
|
|
if(!state.vwapState.isValid) { state.currentBias = BIAS_NEUTRAL; return; }
|
|
MqlRates currentBar;
|
|
if(!g_priceEngine.GetClosedBar(m_htf, 1, currentBar)) { state.currentBias = BIAS_NEUTRAL; return; }
|
|
double price = currentBar.close;
|
|
double vwap = state.vwapState.vwapValue;
|
|
double slope = state.vwapState.vwapSlope;
|
|
bool aboveVWAP = (price > vwap * 1.005);
|
|
bool belowVWAP = (price < vwap * 0.995);
|
|
bool risingVWAP = (slope > 0);
|
|
bool fallingVWAP = (slope < 0);
|
|
int highestIdx = iHighest(_Symbol, m_htf, MODE_HIGH, SWING_LOOKBACK, 1);
|
|
int lowestIdx = iLowest(_Symbol, m_htf, MODE_LOW, SWING_LOOKBACK, 1);
|
|
if(highestIdx < 0 || lowestIdx < 0) { state.currentBias = BIAS_NEUTRAL; return; }
|
|
double swingHigh = iHigh(_Symbol, m_htf, highestIdx);
|
|
double swingLow = iLow(_Symbol, m_htf, lowestIdx);
|
|
state.swingHigh = swingHigh; state.swingLow = swingLow;
|
|
bool bullBOS = (currentBar.close > swingHigh);
|
|
bool bearBOS = (currentBar.close < swingLow);
|
|
bool volConfirmed = false;
|
|
int volHandle = iMA(_Symbol, m_htf, 20, 0, MODE_SMA, VOLUME_TICK);
|
|
if(volHandle != INVALID_HANDLE)
|
|
{
|
|
double volMABuf[]; ArraySetAsSeries(volMABuf, true);
|
|
if(CopyBuffer(volHandle, 0, 1, 1, volMABuf) > 0)
|
|
{
|
|
double avgVol = volMABuf[0];
|
|
if(avgVol > 0) volConfirmed = (currentBar.tick_volume >= avgVol * VOLUME_CONFIRM);
|
|
}
|
|
IndicatorRelease(volHandle);
|
|
}
|
|
state.bosBullish = bullBOS && volConfirmed;
|
|
state.bosBearish = bearBOS && volConfirmed;
|
|
if(aboveVWAP && risingVWAP && state.bosBullish) state.currentBias = BIAS_BULL;
|
|
else if(belowVWAP && fallingVWAP && state.bosBearish) state.currentBias = BIAS_BEAR;
|
|
else if((aboveVWAP && risingVWAP) || state.bosBullish) state.currentBias = BIAS_BULL;
|
|
else if((belowVWAP && fallingVWAP) || state.bosBearish) state.currentBias = BIAS_BEAR;
|
|
else state.currentBias = BIAS_NEUTRAL;
|
|
}
|
|
};
|
|
|
|
#endif // __MACRO_AUDIT_MQH__
|