class GAE_Context
Возвращает конфигурацию по умолчанию со всеми рекомендуемыми значениями параметров для расчётов.
Сообщите нам, если считаете, что материал размещён без разрешения.
Обращение по товару «gammaaccelerationenginemulti.mqh» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
Библиотека Gamma Acceleration Engine (GAE) — это детектор состояния рынка на основе ценовых данных для советников MetaTrader 4. Она вычисляет производные цены (Delta, Gamma, Jerk) на основе EMA-сглаженных закрытий, нормализует их по ATR и классифицирует рыночные условия в шесть состояний. Библиотека предназначена для использования как лёгкий слой фильтрации входов и определения состояния рынка в существующих советниках.
Расчёты включают несколько стадий: сглаживание цены, вычисление производных, нормализацию, фильтрацию направления, проверку устойчивости сигнала, детекцию всплесков и фильтрацию тренда. Результат содержит оценку уверенности и флаги разрешения входа в лонг и шорт. Поддерживается работа с несколькими символами через систему кэширования, что делает библиотеку независимой от текущего графика.
Классов: 4 · методов: 0 · конструкторов: 0 · деструкторов: 0 · отдельных функций: 13
class GAE_Context
Возвращает конфигурацию по умолчанию со всеми рекомендуемыми значениями параметров для расчётов.
class GAE_Config
Ограничивает числовое значение заданным диапазоном между минимальным и максимальным значением.
class GAE_Outputs
Преобразует перечисление состояния рынка в читаемую строку.
class GAE_Cache
Преобразует перечисление направления рынка в читаемую строку.
GAE_Config GAE_DefaultConfig()
Вычисляет процентильное значение из массива методом линейной интерполяции по отсортированным данным.
double Clamp(double value, double minVal, double maxVal)
Ищет слот кэша по символу, таймфрейму, сдвигу и времени бара; возвращает индекс или -1.
string GAE_StateToString(GAE_MARKET_STATE s)
Находит или создаёт слот кэша для заданного символа и таймфрейма с автоматическим вытеснением при заполнении.
string GAE_DirectionToString(GAE_DIRECTION d)
Очищает все слоты кэша, сбрасывая их состояние.
double GAE_Percentile(const double &arr[], int size, double pct)
Выполняет полный анализ рынка для указанного сдвига на текущем графике и возвращает результаты в структуру выходных данных.
int GAE_CacheFind(string symbol, ENUM_TIMEFRAMES tf, int shift, datetime barTime)
Выполняет анализ рынка для текущего бара на текущем графике.
int GAE_CacheGetSlot(string symbol, ENUM_TIMEFRAMES tf)
Выполняет анализ рынка для последнего закрытого бара на текущем графике.
void GAE_CacheClear()
Формирует читаемую строковую сводку результатов анализа.
bool GAE_Process(const GAE_Config &cfg, int shift, GAE_Outputs &out)
Формирует читаемую строковую сводку результатов анализа для указанного символа.
bool GAE_ProcessCurrent(const GAE_Config &cfg, GAE_Outputs &out)
Выполняет полный анализ рынка для указанного символа, таймфрейма и сдвига с использованием кэширования.
bool GAE_ProcessLastClosed(const GAE_Config &cfg, GAE_Outputs &out)
Выполняет анализ рынка для текущего бара заданного символа и таймфрейма.
string GAE_Dump(const GAE_Outputs &out)
Выполняет анализ рынка для последнего закрытого бара заданного символа и таймфрейма.
string GAE_DumpSymbol(string symbol, const GAE_Outputs &out)
Выполняет анализ рынка для указанного символа, таймфрейма и сдвига с использованием кэширования.
#property strict
enum GAE_MARKET_STATE
{
GAE_STATE_IDLE = 0, // Idle - no trade
GAE_STATE_BUILDING = 1, // Building - trend beginning
GAE_STATE_TRENDING = 2, // Trending - strong trend
GAE_STATE_EXPLOSIVE = 3, // Explosive - breakout
GAE_STATE_EXHAUSTION = 4, // Exhaustion - momentum fading
GAE_STATE_REVERSAL = 5 // Reversal - potential reversal
};
enum GAE_DIRECTION
{
GAE_DIR_NEUTRAL = 0,
GAE_DIR_BULLISH = 1,
GAE_DIR_BEARISH = -1
};
struct GAE_Context
{
string symbol;
ENUM_TIMEFRAMES tf;
int bars;
datetime currentBarTime;
int spread;
};
struct GAE_Config
{
int PriceEMA_Period; // EMA period on Close (8-20)
int GammaEMA_Period; // EMA period on raw Gamma
int ATR_Period; // ATR period
double StrengthThreshold; // Fixed baseline threshold (e.g. 0.35)
double StrengthEnable; // Enable threshold (hysteresis)
double StrengthDisable; // Disable threshold (hysteresis)
bool UseAdaptiveThreshold; // Use adaptive percentile threshold
int AdaptiveLookback; // Bars for adaptive calc
double AdaptivePercentile; // Percentile (0-100)
int PersistenceBars; // Consecutive same-sign bars required
bool UseExplosionFilter; // Require momentum burst
double ExplosionMultiple; // |strength| > avg * multiple
double ExplosionZScore; // |z-score| threshold
bool UseTrendFilter;
int TrendEMAFast; // Fast trend EMA
int TrendEMASlow; // Slow trend EMA
bool UseADX; // Use ADX instead of EMA cross
int ADX_Period;
double ADXThreshold;
bool RequireSlope; // Require EMA slope confirmation
int SlopeBars; // Bars to check EMA slope
bool UseConfidenceFilter;
double MinConfidenceScore;
double MinATR; // Minimum ATR (0 = disabled)
int MaxSpreadPoints; // Max spread in points (0 = off)
bool RequireDirectionAgreement;// Stage 7
bool RequirePersistence; // Stage 9
bool RequireStrengthFilter; // Stage 8
};
struct GAE_Outputs
{
double SmoothPrice; // EMA(Close, PriceEMA_Period)
double Delta; // 1st derivative (current)
double DeltaPrev; // 1st derivative (previous bar)
double Gamma; // 2nd derivative (raw)
double GammaEMA; // Smoothed Gamma (current)
double GammaEMAPrev; // Smoothed Gamma (previous bar)
double GammaStrength; // GammaEMA / ATR (signed)
double Jerk; // 3rd derivative
double ATR; // Current ATR
double AvgGammaStrength; // Mean |strength| over lookback
double StdGammaStrength; // Std-dev of strength over lookback
double GammaZScore; // Current z-score
double AdaptiveThreshold; // Computed percentile threshold
GAE_DIRECTION Direction; // Bullish / Bearish / Neutral
GAE_MARKET_STATE State; // Market state (Stage 12)
int PersistenceCount; // Consecutive same-sign bars
double ConfidenceScore; // 0-100 signal quality
bool TrendBullish;
bool TrendBearish;
bool EntryAllowedLong;
bool EntryAllowedShort;
bool EntryAllowed; // Long OR Short
int SpreadPoints;
datetime EvalTime;
};
struct GAE_Cache
{
string symbol;
ENUM_TIMEFRAMES tf;
int shift;
datetime lastBar;
GAE_Outputs out;
double smoothedThreshold; // per-symbol regime smoother
bool inUse;
};
#define GAE_MAX_CACHE_SLOTS 16
GAE_Config GAE_DefaultConfig()
{
GAE_Config c;
c.PriceEMA_Period = 10;
c.GammaEMA_Period = 5;
c.ATR_Period = 14;
c.StrengthThreshold = 0.35;
c.StrengthEnable = 0.38;
c.StrengthDisable = 0.30;
c.UseAdaptiveThreshold = true;
c.AdaptiveLookback = 200;
c.AdaptivePercentile = 80.0;
c.PersistenceBars = 3;
c.UseExplosionFilter = false;
c.ExplosionMultiple = 2.0;
c.ExplosionZScore = 2.0;
c.UseTrendFilter = true;
c.TrendEMAFast = 50;
c.TrendEMASlow = 200;
c.UseADX = false;
c.ADX_Period = 14;
c.ADXThreshold = 20.0;
c.RequireSlope = true;
c.SlopeBars = 5;
c.UseConfidenceFilter = false;
c.MinConfidenceScore = 70.0;
c.MinATR = 0.0;
c.MaxSpreadPoints = 0;
c.RequireDirectionAgreement = true;
c.RequirePersistence = true;
c.RequireStrengthFilter = true;
return c;
}
double Clamp(double value, double minVal, double maxVal)
{
if(value < minVal) return minVal;
if(value > maxVal) return maxVal;
return value;
}
string GAE_StateToString(GAE_MARKET_STATE s)
{
switch(s)
{
case GAE_STATE_IDLE: return "Idle";
case GAE_STATE_BUILDING: return "Building";
case GAE_STATE_TRENDING: return "Trending";
case GAE_STATE_EXPLOSIVE: return "Explosive";
case GAE_STATE_EXHAUSTION: return "Exhaustion";
case GAE_STATE_REVERSAL: return "Reversal";
}
return "Unknown";
}
string GAE_DirectionToString(GAE_DIRECTION d)
{
switch(d)
{
case GAE_DIR_BULLISH: return "Bullish";
case GAE_DIR_BEARISH: return "Bearish";
default: return "Neutral";
}
}
double GAE_Percentile(const double &arr[], int size, double pct)
{
if(size <= 0) return 0.0;
if(pct <= 0.0) return arr[0];
if(pct >= 100.0) return arr[size-1];
double tmp[];
ArrayResize(tmp, size);
for(int i=0; i<size; i++) tmp[i] = arr[i];
ArraySort(tmp); // ascending
double rank = (pct / 100.0) * (double)(size - 1);
int lo = (int)MathFloor(rank);
int hi = (int)MathCeil(rank);
if(lo < 0) lo = 0;
if(hi > size - 1) hi = size - 1;
if(lo == hi) return tmp[lo];
double frac = rank - (double)lo;
return tmp[lo] + frac * (tmp[hi] - tmp[lo]);
}
static GAE_Cache gae_cache[GAE_MAX_CACHE_SLOTS];
int GAE_CacheFind(string symbol, ENUM_TIMEFRAMES tf, int shift, datetime barTime)
{
for(int i = 0; i < GAE_MAX_CACHE_SLOTS; i++)
{
if(!gae_cache[i].inUse) continue;
if(gae_cache[i].symbol == symbol &&
gae_cache[i].tf == tf &&
gae_cache[i].shift == shift &&
gae_cache[i].lastBar == barTime)
{
return i;
}
}
return -1;
}
int GAE_CacheGetSlot(string symbol, ENUM_TIMEFRAMES tf)
{
for(int i = 0; i < GAE_MAX_CACHE_SLOTS; i++)
{
if(!gae_cache[i].inUse) continue;
if(gae_cache[i].symbol == symbol && gae_cache[i].tf == tf)
return i;
}
for(int i = 0; i < GAE_MAX_CACHE_SLOTS; i++)
{
if(!gae_cache[i].inUse)
{
gae_cache[i].symbol = symbol;
gae_cache[i].tf = tf;
gae_cache[i].shift = -1;
gae_cache[i].lastBar = 0;
gae_cache[i].smoothedThreshold = 0.0;
gae_cache[i].inUse = true;
ZeroMemory(gae_cache[i].out);
return i;
}
}
int evictIdx = 0;
datetime oldestBar = gae_cache[0].lastBar;
for(int i = 1; i < GAE_MAX_CACHE_SLOTS; i++)
{
if(gae_cache[i].lastBar < oldestBar)
{
oldestBar = gae_cache[i].lastBar;
evictIdx = i;
}
}
gae_cache[evictIdx].symbol = symbol;
gae_cache[evictIdx].tf = tf;
gae_cache[evictIdx].shift = -1;
gae_cache[evictIdx].lastBar = 0;
gae_cache[evictIdx].smoothedThreshold = 0.0;
gae_cache[evictIdx].inUse = true;
ZeroMemory(gae_cache[evictIdx].out);
return evictIdx;
}
void GAE_CacheClear()
{
for(int i = 0; i < GAE_MAX_CACHE_SLOTS; i++)
{
gae_cache[i].inUse = false;
gae_cache[i].symbol = "";
gae_cache[i].tf = PERIOD_CURRENT;
gae_cache[i].shift = -1;
gae_cache[i].lastBar = 0;
gae_cache[i].smoothedThreshold = 0.0;
ZeroMemory(gae_cache[i].out);
}
}
bool GAE_Process_Internal(
const GAE_Context &ctx,
const GAE_Config &cfg,
int shift,
GAE_Outputs &out,
double &io_smoothedThreshold)
{
ZeroMemory(out);
if(shift < 0) shift = 0;
int winSize = cfg.GammaEMA_Period * 5 + 10;
int totalBars = winSize + cfg.AdaptiveLookback + 20;
int minBars = MathMax(totalBars, cfg.TrendEMASlow + cfg.SlopeBars + 20);
if(ctx.bars < minBars) return false;
out.EvalTime = iTime(ctx.symbol, ctx.tf, shift);
out.SpreadPoints = (int)MarketInfo(ctx.symbol, MODE_SPREAD);
double smooth[];
ArrayResize(smooth, totalBars);
for(int i=0; i<totalBars; i++)
smooth[i] = iMA(ctx.symbol, ctx.tf, cfg.PriceEMA_Period, 0, MODE_EMA, PRICE_CLOSE, shift+i);
double rawDelta[], rawGamma[];
ArrayResize(rawDelta, totalBars);
ArrayResize(rawGamma, totalBars);
for(int i=0; i<totalBars-2; i++)
{
rawDelta[i] = smooth[i] - smooth[i+1];
rawGamma[i] = rawDelta[i] - (smooth[i+1] - smooth[i+2]);
}
rawDelta[totalBars-2] = smooth[totalBars-2] - smooth[totalBars-1];
rawDelta[totalBars-1] = 0.0;
rawGamma[totalBars-2] = rawDelta[totalBars-2];
rawGamma[totalBars-1] = 0.0;
double gammaEMA[];
ArrayResize(gammaEMA, totalBars);
double mult = 2.0 / (1.0 + (double)cfg.GammaEMA_Period);
double ema = rawGamma[totalBars-1];
gammaEMA[totalBars-1] = ema;
for(int i=totalBars-2; i>=0; i--)
{
ema = rawGamma[i] * mult + ema * (1.0 - mult);
gammaEMA[i] = ema;
}
double atrNow = iATR(ctx.symbol, ctx.tf, cfg.ATR_Period, shift);
if(atrNow <= 0.0) atrNow = MarketInfo(ctx.symbol, MODE_POINT);
out.ATR = atrNow;
out.SmoothPrice = smooth[0];
out.Delta = rawDelta[0];
out.DeltaPrev = rawDelta[1];
out.Gamma = rawGamma[0];
out.GammaEMA = gammaEMA[0];
out.GammaEMAPrev = gammaEMA[1];
out.GammaStrength= gammaEMA[0] / atrNow;
out.Jerk = gammaEMA[0] - gammaEMA[1];
int lookback = cfg.AdaptiveLookback;
if(lookback > totalBars) lookback = totalBars;
double strengthHist[];
ArrayResize(strengthHist, lookback);
double sum = 0.0, sumSq = 0.0;
for(int i=0; i<lookback; i++)
{
double atr_i = iATR(ctx.symbol, ctx.tf, cfg.ATR_Period, shift+i);
if(atr_i <= 0.0) atr_i = MarketInfo(ctx.symbol, MODE_POINT);
double s = gammaEMA[i] / atr_i;
strengthHist[i] = s;
sum Показано первые 50% кода (символов: 15874)
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.