forked from animatedread/Warrior_EA
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
|