MultiAgentTest v7: zero magic constants, neural orchestrator, multi-position, agent interaction fixes
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
#ifndef REGIME_ADX_MQH
|
||||
#define REGIME_ADX_MQH
|
||||
#include "AgentBase.mqh"
|
||||
#include "../Core/PeriodCalculator.mqh"
|
||||
|
||||
class RegimeADX : public IAgent {
|
||||
private:
|
||||
int adxPeriod;
|
||||
int userPeriod;
|
||||
int adxHandle;
|
||||
int lastADXPeriod;
|
||||
int adxMinP, adxMaxP;
|
||||
double prevZ;
|
||||
|
||||
void Recreate(int p) {
|
||||
if(adxHandle != INVALID_HANDLE) IndicatorRelease(adxHandle);
|
||||
adxHandle = iADX(symbol, timeframe, p);
|
||||
lastADXPeriod = p;
|
||||
}
|
||||
|
||||
double GetADX() {
|
||||
if(adxHandle == INVALID_HANDLE) Recreate(adxPeriod);
|
||||
double buf[];
|
||||
ArraySetAsSeries(buf, true);
|
||||
if(CopyBuffer(adxHandle, 0, 0, 1, buf) < 1) return 0;
|
||||
return buf[0];
|
||||
}
|
||||
|
||||
double GetDI(int plusMinus=1, int shift=0) {
|
||||
if(adxHandle == INVALID_HANDLE) Recreate(adxPeriod);
|
||||
double buf[];
|
||||
ArraySetAsSeries(buf, true);
|
||||
if(CopyBuffer(adxHandle, plusMinus, shift, 1, buf) < 1) return 0;
|
||||
return buf[0];
|
||||
}
|
||||
|
||||
public:
|
||||
RegimeADX(string n="ADX", double w=1.0, int period=0)
|
||||
: IAgent(n, w), userPeriod(period), adxPeriod(0), adxHandle(INVALID_HANDLE),
|
||||
lastADXPeriod(0), adxMinP(7), adxMaxP(30), prevZ(0) { signalStats.SetR(50.0); }
|
||||
|
||||
void Init(string sym, ENUM_TIMEFRAMES tf) override {
|
||||
IAgent::Init(sym, tf);
|
||||
adxHandle = INVALID_HANDLE;
|
||||
lastADXPeriod = 0;
|
||||
}
|
||||
|
||||
void Release() override {
|
||||
if(adxHandle != INVALID_HANDLE) IndicatorRelease(adxHandle);
|
||||
adxHandle = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
double Analyze(const MarketData &data) override {
|
||||
// Periodo: fisso se utente lo specifica, altrimenti data-driven + EWMA
|
||||
if(userPeriod > 0) {
|
||||
adxPeriod = userPeriod;
|
||||
} else {
|
||||
int newP = PeriodCalculator::AutoPeriod(data, adxMinP, adxMaxP);
|
||||
if(adxPeriod <= 0) adxPeriod = newP;
|
||||
else {
|
||||
double pAlpha = 1.0 / (1.0 + signalStats.Count() * 0.05);
|
||||
pAlpha = MathMax(0.05, pAlpha); // solo floor
|
||||
adxPeriod = (int)MathRound(pAlpha * newP + (1.0 - pAlpha) * adxPeriod);
|
||||
}
|
||||
if(adxPeriod < adxMinP) adxPeriod = adxMinP;
|
||||
if(adxPeriod > adxMaxP) adxPeriod = adxMaxP;
|
||||
}
|
||||
if(adxPeriod <= 0) { lastZScore = 0; return 0; }
|
||||
|
||||
if(adxHandle == INVALID_HANDLE || adxPeriod != lastADXPeriod)
|
||||
Recreate(adxPeriod);
|
||||
|
||||
double adx = GetADX();
|
||||
double epsAdx = DATA_EPS(adx);
|
||||
if(MathAbs(adx) < epsAdx) { lastZScore = 0; return 0; }
|
||||
|
||||
// Normalizza ADX via EWMA
|
||||
signalStats.Update(adx);
|
||||
double zRaw = signalStats.ZScore(adx);
|
||||
|
||||
// EWMA alpha: scala con conteggio campioni, solo floor data-driven
|
||||
double alpha = 1.0 / (1.0 + signalStats.Count() * 0.1);
|
||||
double minAlpha = 1.0 / MathMax(2.0, (double)MathMax(1, adxPeriod));
|
||||
alpha = MathMax(minAlpha, alpha); // solo floor, niente max clamp
|
||||
prevZ = (1.0 - alpha) * prevZ + alpha * zRaw;
|
||||
double calibrated = CalibrateZ(prevZ);
|
||||
lastZScore = MathTanh(calibrated);
|
||||
lastRawSignal = adx;
|
||||
|
||||
// Pubblica nel contesto condiviso
|
||||
SHARED_adxZ = lastZScore;
|
||||
SHARED_adxRaw = adx;
|
||||
|
||||
return lastZScore;
|
||||
}
|
||||
|
||||
void Interact(IAgent *&allAgents[], int count) override {}
|
||||
|
||||
void Learn(double predictedZ, double actualReturnZ) override {}
|
||||
|
||||
void Save(int fh) const override {
|
||||
IAgent::Save(fh);
|
||||
FileWriteDouble(fh, prevZ);
|
||||
}
|
||||
void Load(int fh) override {
|
||||
IAgent::Load(fh);
|
||||
prevZ = FileReadDouble(fh);
|
||||
}
|
||||
|
||||
void Reset() override {
|
||||
IAgent::Reset();
|
||||
prevZ = 0;
|
||||
}
|
||||
|
||||
string SignalInfo() const override {
|
||||
return name + " z=" + StringFormat("%+.3f", lastZScore)
|
||||
+ " ADX=" + StringFormat("%.1f", SHARED_adxRaw)
|
||||
+ " p=" + (string)adxPeriod
|
||||
+ " " + signalStats.ToString();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
Reference in New Issue
Block a user