Warrior_EA/Mind/VolumeFeed.mqh
AnimateDread e9c562b39f Add Feature Scaling and Regime Math Classes; Implement Mind Trading Logic
- Introduced `FeatureScale.mqh` with `FeatSquash` function for stateless feature scaling.
- Added `RegimeMath.mqh` class for regime arithmetic, including efficiency and variance calculations.
- Documented the Mind trading logic in `MIND.md`, detailing the trading process and modes.
- Created `VOLNORM_PLAN.md` and `VOLNORM_RESULTS.md` for tick-volume normalization testing.
- Implemented `read_book.py` for analyzing trade book data and correlations.
- Developed `volnorm.py` for testing tick-volume normalization with new and old methods.
2026-09-30 18:36:33 -04:00

79 lines
3.1 KiB
MQL5

//+------------------------------------------------------------------+
//| VolumeFeed.mqh |
//| AnimateDread |
//| |
//| ONE PLACE THAT ANSWERS "HOW BUSY WAS THIS BAR, FOR ITS HOUR". |
//| |
//| The neural module and the management net each used to compute |
//| their own bar-over-recent-mean volume ratio, and both carried the |
//| same defect (see Mind\VolumeProfile.mqh: the ratio mostly encoded |
//| the hour of day). They now ask this feed instead, so there is one |
//| definition of relative volume in the codebase and one place to fix |
//| it. The Mind's own volume modality reads the same profile. |
//| |
//| One feed per chart, guarded by the symbol/period it was built for, |
//| like g_wyckoffFeed. It owns a bar cache of the whole history - the |
//| stdlib series stop at shift 1023 and the neural module trains far |
//| deeper than that. |
//+------------------------------------------------------------------+
#ifndef WARRIOR_VOLUMEFEED_MQH
#define WARRIOR_VOLUMEFEED_MQH
#include "VolumeProfile.mqh"
class CVolumeFeed
{
protected:
CBarCache m_cache;
CVolumeProfile m_profile;
string m_for;
public:
CVolumeFeed(void) : m_for("") {}
bool Ensure(const string symbol, const ENUM_TIMEFRAMES tf)
{
const string want = symbol + "/" + IntegerToString((int)tf);
if(m_for == want)
return true;
m_cache.Init(symbol, tf, 14, 30);
m_profile.Init(GetPointer(m_cache));
m_for = want;
return true;
}
//--- Bring the cache up to the newest closed bar and fold it into the profile.
bool Sync(void)
{
if(m_for == "" || !m_cache.Sync())
return false;
m_profile.Update();
return true;
}
//--- The bar that OPENED at `barTime`: its level-detrended log volume against the hour's norm,
//--- that reading's mean over the last five bars, and its change from the previous bar.
//--- False when any of them is not yet defined - the caller drops the row, as it does for any
//--- other feature it cannot compute.
bool Reading(const datetime barTime, double &now, double &mean5, double &change) const
{
const int i = m_cache.IndexOf(barTime);
if(i < 5)
return false;
now = m_profile.Detrended(i);
const double prev = m_profile.Detrended(i - 1);
if(now == VOLPROF_NA || prev == VOLPROF_NA)
return false;
double s = now;
for(int k = 1; k < 5; k++)
{
const double d = m_profile.Detrended(i - k);
if(d == VOLPROF_NA)
return false;
s += d;
}
mean5 = s / 5.0;
change = now - prev;
return true;
}
};
CVolumeFeed g_volFeed;
#endif // WARRIOR_VOLUMEFEED_MQH