forked from mnbvc188199/Warrior_EA
- 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.
79 lines
3.1 KiB
MQL5
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
|