← К каталогу
Исходный код · ID 4762

Gold level breakout Enhanced

goldlevelbreakout 1.00 optimised.mq4

Похожие материалы по тегам

gold level breakout.mq5MQL5 / MetaTrader 5 · 2 общих теговlinear breakthrough strategy.pineTradingView · 2 общих теговgoldlevelbreakout 1.00 @simpleforextools.mq4MQL4 / MetaTrader 4 · 2 общих теговsmc+ict+indicators+scalping master.pineTradingView · 2 общих теговsmc & ict & indicators + scalping master(1)_5976621784668052077.pineTradingView · 2 общих теговtrendregimeindicator.mq5TradingView · 1 общих тегов
Вы автор или правообладатель?

Сообщите нам, если считаете, что материал размещён без разрешения.

Краткий обзор

О программе

Gold level breakout Enhanced — торговый советник для MetaTrader 4, предназначенный для скальпирования на золоте. Советник анализирует ценовые данные с помощью индикатора SuperTrend, формирует уровни покупок и продаж на основе текущего тренда и выполняет входы по этим уровням. В основе работы лежит адаптивная система восстановления позиций с контролем рисков.

Советник включает встроенную панель с отображением статистики по закрытым сделкам и прогнозного уровня, а также систему защиты от убытков (Safety Guard), автоматическое закрытие позиций в выходные и фильтрацию по торговым сессиям. Поддерживается независимое трейлинг-стоп управление и модуль восстановления корзины позиций при достижении целевой прибыли.

Входные параметры настраивают размеры лотов, уровни входа и выхода, временные фильтры, качество сигналов и условия срабатывания защитных механизмов. Все вычисления оптимизированы для снижения нагрузки: статистика пересчитывается только при изменении истории, а обновление интерфейса выполняется через таймер.

Настройки программы

НастройкаОписание
Lots Базовый размер лота для открытия позиции
LotMultiplier Множитель лота при восстановлении позиций
MinBarsBetween Минимальное количество баров между последовательными входами в восстановлении
MinDistancePoints Минимальное расстояние в пунктах от последней позиции для входа в восстановлении
TrailingPoints Расстояние трейлинг-стопа в пунктах от текущей цены
TrailingArmPoints Расстояние в пунктах от входа, после которого активируется трейлинг-стоп
TrailLockPercent Процент от выкупного расстояния для блокировки трейлинг-стопа
MinTrailStepPoints Минимальный шаг трейлинг-стопа в пунктах
Dist Отступ в пунктах от экстремумов для построения уровней покупок и продаж
STPeriod Период индикатора SuperTrend
STMultiplier Множитель ATR для расчёта полос SuperTrend
STBars Количество баров для анализа при построении уровней на основе SuperTrend
Slippage Допустимое проскальзывание при исполнении ордеров (в пунктах)
Magic Магический номер для идентификации ордеров советника
PanelShow Отображение информационной панели на графике
PanelX Горизонтальная позиция панели на графике
PanelY Вертикальная позиция панели на графике
ForecastShow Отображение прогнозного уровня на графике
ForecastRefreshSec Интервал обновления прогнозного уровня в секундах
TimeFilter Включает стандартный временной фильтр торговли по часам
StartHour Начальный час стандартного временного фильтра торговли
EndHour Конечный час стандартного временного фильтра торговли
AdaptiveSession Включает адаптивную сессию: внерабочее время торговли определяется по значению ADX на дневном таймфрейме
CoreStartHour Начальный час основной торговой сессии (в адаптивном режиме)
CoreEndHour Конечный час основной торговой сессии (в адаптивном режиме)
ExtendedHoursADX Пороговое значение ADX на дневном графике для разрешения торговли во внерабочие часы
WeekendProtection Защита от торговли в выходные: автоматическое закрытие позиций в субботу и воскресенье
FridayCloseHour Час автоматического закрытия позиций в пятницу
SafetyGuard Включает систему защиты от убытков по корзине позиций (Safety Guard)
MaxBasketLoss Максимальный суммарный убыток по корзине позиций, при котором происходит принудительное закрытие всех позиций
SafetyCooldownBars Количество баров ожидания после защитного закрытия перед следующей попыткой входа
HardStopCooldownBars Количество баров ожидания после принудительного закрытия перед следующей попыткой входа
HardStopControls Группа настроек жёсткой защиты от убытков
HardStopLossUSDPerPosition Максимальный допустимый убыток в долларах США на одну позицию для жёсткого стопа
TakeProfitUSDPerPosition Тейк-профит в долларах США на одну позицию (0 — без тейк-профита)
EnhancedQualityControls Группа настроек повышенного контроля качества сигналов
MacroEMAPeriod Период скользящей средней EMA для определения макро-направления на дневном графике
EntryLogic Логика входа: только откат от экстремума, только пробой тренда или оба варианта
EntryExecution Режим исполнения входа: немедленный, по достижении выкупного уровня или касанию уровня
ReclaimPercent Процент диапазона свечи для выкупного уровня при восстановлении
ReclaimValidityBars Количество баров, в течение которых выкупный уровень остаётся действительным
ReclaimBufferPoints Дополнительный буфер в пунктах при расчёте выкупного уровня
EntryQuality Критерии качества сигнала: только экстремальные свечи, подтверждение телом, расположение закрытия или полный откат
RejectionClosePercent Процент расположения закрытия свечи для подтверждения сигнала отката
MaxSignalRangeATRPercent Максимальный допустимый диапазон свечи в процентах от ATR для фильтрации сигналов (0 — без фильтра)
MaxSpreadPoints Максимально допустимый спред в пунктах для входа в позицию (0 — без фильтра)
RecoveryRequiresMacro Требуется ли смены макро-направления для восстановления позиции
EnableRecovery Включает модуль восстановления позиций при наличии убыточной позиции
RecoveryRequiresRejection Требуется ли сигнал отката (качественного) для восстановления позиции
RecoveryConfirmAfterSafetyBars Количество баров после защитного закрытия, в течение которых требуется подтверждение для восстановления
RecoveryBasketProfitUSD Целевая суммарная прибыль по корзине в долларах США для автоматического закрытия при восстановлении

Поиск по коду файла

#property strict
#property version   "1.80"
#property description "Gold level breakout Enhanced - MT4 adaptive level-recovery scalper (CPU-optimized)"

enum ENUM_GLB_ENTRY_QUALITY
{
   GLB_EXTREME_ONLY = 0,
   GLB_BODY_CONFIRM = 1,
   GLB_CLOSE_LOCATION = 2,
   GLB_FULL_REJECTION = 3
};

enum ENUM_GLB_ENTRY_LOGIC
{
   GLB_PULLBACK_EXTREME = 0,
   GLB_TREND_BREAKOUT   = 1,
   GLB_BOTH_EXTREMES    = 2
};

enum ENUM_GLB_ENTRY_EXECUTION
{
   GLB_ENTER_IMMEDIATE   = 0,
   GLB_ENTER_ON_RECLAIM  = 1,
   GLB_ENTER_LEVEL_TOUCH = 2
};

input double Lots               = 0.03;
input double LotMultiplier      = 1.0;
input int    MinBarsBetween     = 2;
input int    MinDistancePoints  = 51;
input int    TrailingPoints     = 90;
input int    TrailingArmPoints  = 110;
input int    TrailLockPercent   = 75;
input int    MinTrailStepPoints = 5;
input int    Dist               = 33;
input int    STPeriod           = 11;
input double STMultiplier       = 9.0;
input int    STBars             = 20;
input int    Slippage           = 3000;
input int    Magic              = 778001;
input bool   PanelShow          = true;
input int    PanelX             = 20;
input int    PanelY             = 20;
input bool   ForecastShow       = true;
input int    ForecastRefreshSec = 300;
input bool   TimeFilter         = false;
input int    StartHour          = 9;
input int    EndHour            = 18;
input bool   AdaptiveSession    = true;
input int    CoreStartHour      = 7;
input int    CoreEndHour        = 18;
input int    ExtendedHoursADX   = 35;
input bool   WeekendProtection  = true;
input int    FridayCloseHour    = 22;
input bool   SafetyGuard        = true;
input double MaxBasketLoss      = 20.0;
input int    SafetyCooldownBars = 20;
input int    HardStopCooldownBars = 2;

input string HardStopControls = "Hard stop-loss controls";
input double HardStopLossUSDPerPosition = 9.0;
input double TakeProfitUSDPerPosition  = 0.0;

input string EnhancedQualityControls = "Enhanced quality controls";
input int    MacroEMAPeriod            = 20;
input ENUM_GLB_ENTRY_LOGIC EntryLogic  = GLB_PULLBACK_EXTREME;
input ENUM_GLB_ENTRY_EXECUTION EntryExecution = GLB_ENTER_IMMEDIATE;
input int    ReclaimPercent            = 50;
input int    ReclaimValidityBars       = 3;
input int    ReclaimBufferPoints       = 0;
input ENUM_GLB_ENTRY_QUALITY EntryQuality = GLB_EXTREME_ONLY;
input int    RejectionClosePercent     = 60;
input int    MaxSignalRangeATRPercent  = 0;
input int    MaxSpreadPoints           = 20;
input bool   RecoveryRequiresMacro     = true;
input bool   EnableRecovery            = true;
input bool   RecoveryRequiresRejection = false;
input int    RecoveryConfirmAfterSafetyBars = 288;
input double RecoveryBasketProfitUSD   = 5.0;

double g_tickSize       = 0.0;
double g_tickValue      = 0.0;
double g_minLot         = 0.0;
double g_maxLot         = 0.0;
double g_lotStep        = 0.0;
int    g_stopLevel      = 0;
double g_brokerMinStop  = 0.0;

int    g_cFridayCloseHour;
int    g_cCoreStartHour;
int    g_cCoreEndHour;
int    g_cSTPeriod;
int    g_cSTBars;
double g_cSTMultiplier;
int    g_cDist;
int    g_cTrailLockPct;
int    g_cMinTrailStep;
int    g_cTrailingArm;
int    g_cSafetyCooldown;
int    g_cHardStopCooldown;
int    g_cMinDist;
int    g_cMinBars;
double g_cLotMult;
int    g_cReclaimPct;
int    g_cReclaimBuf;
int    g_cReclaimValidity;
int    g_cRejectionClose;

int      g_signalTf = 0;
datetime g_lastBarTime = 0;
datetime g_lastForecastRefresh = 0;
datetime g_lastSafetyExit = 0;
datetime g_lastHardStopExit = 0;
double   g_buyLevel = 0.0;
double   g_sellLevel = 0.0;
double   g_stLine = 0.0;
int      g_bias = 0;
int      g_prevBias = 0;
bool     g_touchArmed = true;
int      g_armedDirection = 0;
double   g_armedTrigger = 0.0;
datetime g_armedAt = 0;
string   PFX = "GLB_CR_";

struct DealStats
{
   int trades;
   int wins;
   int losses;
   double net;
   double grossProfit;
   double grossLoss;
   double profitFactor;
   double winRate;
   double avgTrade;
   double bestTrade;
   double worstTrade;
   double maxDrawdown;
};

int      g_cachedHistoryTotal = -1;
DealStats g_cachedStats;
bool     g_statsReady = false;

double   g_histVals[36];
int      g_histCount = 0;

bool     g_adxResult = false;
int      g_adxDay    = -1;

void CacheSymbolProperties(void);
void NormalizeInputs(void);
void RefreshCachedStats(void);
bool CheckSessionADX(void);
void CloseAllManaged(void);

int OnInit()
{
      // код доступен только после оплаты
   }

void OnDeinit(const int reason)
{
   EventKillTimer();
   DeleteObjects();
}

void CacheSymbolProperties(void)
{
   g_tickSize  = MarketInfo(Symbol(), MODE_TICKSIZE);
   g_tickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
   g_minLot    = MarketInfo(Symbol(), MODE_MINLOT);
   g_maxLot    = MarketInfo(Symbol(), MODE_MAXLOT);
   g_lotStep   = MarketInfo(Symbol(), MODE_LOTSTEP);
   g_stopLevel = (int)MarketInfo(Symbol(), MODE_STOPLEVEL);

   if(g_tickSize <= 0.0) g_tickSize  = Point;
   if(g_minLot   <= 0.0) g_minLot    = 0.01;
   if(g_lotStep  <= 0.0) g_lotStep   = g_minLot;

   g_brokerMinStop = (g_stopLevel + 2) * Point;
}

void NormalizeInputs(void)
{
   g_cFridayCloseHour  = MathMax(0, MathMin(23, FridayCloseHour));
   g_cCoreStartHour    = MathMax(0, MathMin(23, CoreStartHour));
   g_cCoreEndHour      = MathMax(0, MathMin(23, CoreEndHour));
   g_cSTPeriod         = MathMax(2, STPeriod);
   g_cSTBars           = MathMax(2, STBars);
   g_cSTMultiplier     = MathMax(0.10, STMultiplier);
   g_cDist             = MathMax(0, Dist);
   g_cTrailLockPct     = MathMax(0, MathMin(100, TrailLockPercent));
   g_cMinTrailStep     = MathMax(1, MinTrailStepPoints);
   g_cTrailingArm      = (TrailingArmPoints > 0 ? TrailingArmPoints : TrailingPoints);
   g_cSafetyCooldown   = MathMax(1, SafetyCooldownBars);
   g_cHardStopCooldown = MathMax(0, HardStopCooldownBars);
   g_cMinDist          = MathMax(1, MinDistancePoints);
   g_cMinBars          = MathMax(0, MinBarsBetween);
   g_cLotMult          = MathMax(0.01, LotMultiplier);
   g_cReclaimPct       = MathMax(0, MathMin(100, ReclaimPercent));
   g_cReclaimBuf       = MathMax(0, ReclaimBufferPoints);
   g_cReclaimValidity  = MathMax(1, ReclaimValidityBars);
   g_cRejectionClose   = MathMax(50, MathMin(95, RejectionClosePercent));
}

void OnTick()
{
      // код доступен только после оплаты
   }

void OnTimer()
{
   if(!PanelShow && !ForecastShow) return;

   RefreshCachedStats();
   UpdatePanel();
}

void RefreshCachedStats(void)
{
   int total = OrdersHistoryTotal();
   if(total == g_cachedHistoryTotal) return;
   g_cachedHistoryTotal = total;
   CalculateStats(g_cachedStats);
   g_statsReady = true;

   g_histCount = 0;
   ArrayInitialize(g_histVals, 0.0);
   for(int i = total - 1; i >= 0 && g_histCount < 36; i--)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
      if(OrderSymbol() != Symbol() || OrderMagicNumber() != Magic) continue;
      if(OrderType() != OP_BUY && OrderType() != OP_SELL) continue;
      g_histVals[g_histCount] = OrderProfit() + OrderCommission() + OrderSwap();
      g_histCount++;
   }
}

bool CheckSessionADX(void)
{
   if(ExtendedHoursADX <= 0) return(true);

   datetime now = TimeCurrent();
   MqlDateTime dt;
   TimeToStruct(now, dt);
   int today = dt.day_of_year;

   if(today != g_adxDay)
   {
      g_adxDay = today;
      double adx = iADX(Symbol(), PERIOD_D1, 14, PRICE_CLOSE, MODE_MAIN, 1);
      g_adxResult = (adx > 0.0 && adx >= ExtendedHoursADX);
   }

   return(g_adxResult);
}

bool IsTradingTime()
{
   int dow = TimeDayOfWeek(TimeCurrent());
   int hr  = TimeHour(TimeCurrent());

   if(WeekendProtection)
   {
      if(dow == 0 || dow == 6) return(false);
      if(dow == 5 && hr >= g_cFridayCloseHour)
         return(false);
   }

   if(AdaptiveSession)
   {
      int cs = g_cCoreStartHour;
      int ce = g_cCoreEndHour;
      bool inCore = (cs == ce ? true :
                       cs < ce ? (hr >= cs && hr < ce) :
                                 (hr >= cs || hr < ce));
      if(inCore) return(true);
      return(CheckSessionADX());
   }

   if(!TimeFilter) return(true);
   if(StartHour == EndHour) return(true);
   if(StartHour < EndHour)
      return(hr >= StartHour && hr < EndHour);
   return(hr >= StartHour || hr < EndHour);
}

bool ManageWeekendProtection()
{
   if(!WeekendProtection) return(false);

   int dow    = TimeDayOfWeek(TimeCurrent());
   int cutoff = g_cFridayCloseHour;
   if(dow != 5 || TimeHour(TimeCurrent()) < cutoff) return(false);

   bool attempted = false;
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if(!IsManagedOrder()) continue;
      attempted = true;
      CloseSelectedOrder();
   }

   if(attempted)
      ResetArmedState();

   return(attempted);
}

void RefreshLevels(bool force)
{
   int minBars = MathMax(g_cSTBars, g_cSTPeriod) + 20;
   if(iBars(Symbol(), g_signalTf) < minBars) return;

   double st = 0.0;
   int trend = 0;
   if(!CalculateSuperTrend(st, trend)) return;

   g_prevBias = g_bias;
   g_bias     = MacroDirection();
   g_stLine   = st;

   int lookback = g_cSTBars;
   double pad   = g_cDist * Point;

   int lowShift  = iLowest(Symbol(), g_signalTf, MODE_LOW, lookback, 1);
   int highShift = iHighest(Symbol(), g_signalTf, MODE_HIGH, lookback, 1);

   g_buyLevel  = (lowShift >= 1 ?
                  NormalizeDouble(iLow(Symbol(), g_signalTf, lowShift) - pad, Digits) : 0.0);
   g_sellLevel = (highShift >= 1 ?
                  NormalizeDouble(iHigh(Symbol(), g_signalTf, highShift) + pad, Digits) : 0.0);

   if(g_prevBias != 0 && g_bias != g_prevBias)
      g_touchArmed = true;

   if(force || TimeCurrent() - g_lastForecastRefresh >= ForecastRefreshSec)
   {
      g_lastForecastRefresh = TimeCurrent();
      DrawForecastLevel();
   }
}

int MacroDirection()
{
   double ema = iMA(Symbol(), PERIOD_D1, MathMax(2, MacroEMAPeriod), 0, MODE_EMA, PRICE_CLOSE, 1);
   double cls = iClose(Symbol(), PERIOD_D1, 1);
   if(ema <= 0.0 || cls <= 0.0) return(1);
   return(cls >= ema ? 1 : -1);
}

bool CalculateSuperTrend(double &line, int &trend)
{
   int need = MathMax(80, MathMax(g_cSTBars + g_cSTPeriod + 20, g_cSTPeriod * 4));
   int got  = iBars(Symbol(), g_signalTf);
   if(got < MathMax(g_cSTBars, g_cSTPeriod) + 5) return(false);
   need = MathMin(need, got - 1);

   double upper[], lower[], st[];
   ArrayResize(upper, need);
   ArrayResize(lower, need);
   ArrayResize(st, need);

   int oldest = need - 1;

   double h   = iHigh(Symbol(), g_signalTf, oldest);
   double l   = iLow(Symbol(), g_signalTf, oldest);
   double c   = iClose(Symbol(), g_signalTf, oldest);
   double atr = iATR(Symbol(), g_signalTf, g_cSTPeriod, oldest);

   double hl2 = (h + l) * 0.5;
   double a0  = MathMax(atr, Point);
   upper[oldest] = hl2 + g_cSTMultiplier * a0;
   lower[oldest] = hl2 - g_cSTMultiplier * a0;
   st[oldest]    = (c >= hl2 ? lower[oldest] : upper[oldest]);

   for(int i = oldest - 1; i >= 1; i--)
   {
      int p = i + 1;
      h   = iHigh(Symbol(), g_signalTf, i);
      l   = iLow(Symbol(), g_signalTf, i);
      c   = iClose(Symbol(), g_signalTf, i);
      double pc = iClose(Symbol(), g_signalTf, p);
      double av = MathMax(iATR(Symbol(), g_signalTf, g_cSTPeriod, i), Point);

      double mid        = (h + l) * 0.5;
      double basicUpper = mid + g_cSTMultiplier * av;
      double basicLower = mid - g_cSTMultiplier * av;

      upper[i] = (basicUpper < upper[p] || pc > upper[p]) ? basicUpper : upper[p];
      lower[i] = (basicLower > lower[p] || pc < lower[p]) ? basicLower : lower[p];

      bool prevWasUpper = (MathAbs(st[p] - upper[p]) <= MathAbs(st[p] - lower[p]));
      st[i] = (prevWasUpper ?
               (c <= upper[i] ? upper[i] : lower[i]) :
               (c >= lower[i] ? lower[i] : upper[i]));
   }

   bool onLower = (MathAbs(st[1] - lower[1]) <= MathAbs(st[1] - upper[1]));
   trend = onLower ? 1 : -1;
   line  = NormalizeDouble(st[1], Digits);
   return(line > 0.0);
}

bool SignalQualityPass(int direction, bool forceRejection)
{
   if(!forceRejection && EntryQuality == GLB_EXTREME_ONLY &&
      MaxSignalRangeATRPercent <= 0)
      return(true);

   double o = iOpen(Symbol(), g_signalTf, 1);
   double h = iHigh(Symbol(), g_signalTf, 1);
   double l = iLow(Symbol(), g_signalTf, 1);
   double c = iClose(Symbol(), g_signalTf, 1);

   double range = h - l;
   if(range <= Point) return(false);

   if(MaxSignalRangeATRPercent > 0)
   {
      double atr = iATR(Symbol(), g_signalTf, g_cSTPeriod, 1);
      if(atr <= Point) return(false);
      if(range * 100.0 > atr * MaxSignalRangeATRPercent)
         return(false);
   }

   bool body         = (direction > 0 ? c > o : c < o);
   double closeLoc   = 100.0 * (c - l) / range;
   int threshold     = g_cRejectionClose;
   bool location     = (direction > 0 ?
                        closeLoc >= threshold :
                        closeLoc <= 100 - threshold);

   if(forceRejection) return(body && location);
   if(EntryQuality == GLB_BODY_CONFIRM) return(body);
   if(EntryQuality == GLB_CLOSE_LOCATION) return(location);
   if(EntryQuality == GLB_FULL_REJECTION) return(body && location);
   return(true);
}

void ProcessEntries(bool newBar)
{
   int buys, sells;
   double lastBuy, lastSell;
   datetime lastBuyTime, lastSellTime;
   GetOpenState(buys, sells, lastBuy, lastSell, lastBuyTime, lastSellTime);

   if(buys > 0 && sells > 0) return;

   if(MaxSpreadPoints > 0)
   {
      double spread = (Ask - Bid) / Point;
      if(spread > MaxSpreadPoints) return;
   }

   if(g_lastSafetyExit > 0 &&
      BarsSince(g_lastSafetyExit) < g_cSafetyCooldown)
      return;

   if(g_lastHardStopExit > 0 &&
      BarsSince(g_lastHardStopExit) < g_cHardStopCooldown)
      return;

   if(buys == 0 && sells == 0)
   {
      if(EntryExecution == GLB_ENTER_LEVEL_TOUCH)
      {
         if(newBar)
         {
            if(g_bias >= 0 && g_buyLevel > 0.0 && Ask > g_buyLevel)
               g_touchArmed = true;
            else if(g_bias < 0 && g_sellLevel > 0.0 && Bid < g_sellLevel)
               g_touchArmed = true;
         }

         if(g_touchArmed)
         {
            if(g_bias >= 0 && g_buyLevel > 0.0 && Ask <= g_buyLevel)
            {
               g_touchArmed = false;
               OpenMarket(OP_BUY, Lots, "Gold level touch buy");
            }
            else if(g_bias < 0 && g_sellLevel > 0.0 && Bid >= g_sellLevel)
            {
               g_touchArmed = false;
               OpenMarket(OP_SELL, Lots, "Gold level touch sell");
            }
         }
         return;
      }

      if(EntryExecution == GLB_ENTER_ON_RECLAIM && g_armedDirection != 0)
      {
         bool expired     = BarsSince(g_armedAt) > g_cReclaimValidity;
         bool invalidBias = (g_armedDirection > 0 ? g_bias < 0 : g_bias > 0);

         if(expired || invalidBias)
            ResetArmedState();
         else
         {
            bool crossed = (g_armedDirection > 0 ?
                           Ask >= g_armedTrigger :
                           Bid <= g_armedTrigger);
            if(crossed)
            {
               int dir = g_armedDirection;
               ResetArmedState();
               OpenMarket(dir > 0 ? OP_BUY : OP_SELL, Lots,
                          dir > 0 ? "Gold reclaim buy" : "Gold reclaim sell");
               return;
            }
         }
      }

      if(!newBar) return;

      int lookback   = g_cSTBars;
      double signalLow  = iLow(Symbol(), g_signalTf, 1);
      double signalHigh = iHigh(Symbol(), g_signalTf, 1);

      int lowShift  = iLowest(Symbol(), g_signalTf, MODE_LOW, lookback, 2);
      int highShift = iHighest(Symbol(), g_signalTf, MODE_HIGH, lookback, 2);

      double olderLow  = (lowShift >= 2 ? iLow(Symbol(), g_signalTf, lowShift) : 0.0);
      double olderHigh = (highShift >= 2 ? iHigh(Symbol(), g_signalTf, highShift) : 0.0);

      if(g_bias >= 0)
      {
         bool pullback = (signalLow > 0 && olderLow > 0 && signalLow <= olderLow);
         bool breakout = (signalHigh > 0 && olderHigh > 0 && signalHigh >= olderHigh);
         bool triggered = (EntryLogic == GLB_PULLBACK_EXTREME ? pullback :
                           EntryLogic == GLB_TREND_BREAKOUT ? breakout :
                           pullback || breakout);

         if(triggered && SignalQualityPass(1, false))
         {
            if(EntryExecution == GLB_ENTER_IMMEDIATE)
               OpenMarket(OP_BUY, Lots, "Gold level buy");
            else if(EntryExecution == GLB_ENTER_ON_RECLAIM)
               ArmReclaim(1, signalLow, signalHigh);
         }
      }
      else
      {
         bool breakout = (signalLow > 0 && olderLow > 0 && signalLow <= olderLow);
         bool pullback = (signalHigh > 0 && olderHigh > 0 && signalHigh >= olderHigh);
         bool triggered = (EntryLogic == GLB_PULLBACK_EXTREME ? pullback :
                           EntryLogic == GLB_TREND_BREAKOUT ? breakout :
                           pullback || breakout);

         if(triggered && SignalQualityPass(-1, false))
         {
            if(EntryExecution == GLB_ENTER_IMMEDIATE)
               OpenMarket(OP_SELL, Lots, "Gold level sell");
            else if(EntryExecution == GLB_ENTER_ON_RECLAIM)
               ArmReclaim(-1, signalLow, signalHigh);
         }
      }
      return;
   }

   if(!newBar || !EnableRecovery) return;

   if(buys == 1)
   {
      if(RecoveryRequiresMacro && g_bias < 0) return;

      bool confirm = RecoveryRequiresRejection ||
         (RecoveryConfirmAfterSafetyBars > 0 && g_lastSafetyExit > 0 &&
          BarsSince(g_lastSafetyExit) < RecoveryConfirmAfterSafetyBars);

      if(confirm && !SignalQualityPass(1, true)) return;

      if(BarsSince(lastBuyTime) >= g_cMinBars &&
         Ask <= lastBuy - g_cMinDist * Point)
      {
         double v = Lots * MathPow(g_cLotMult, buys);
         OpenMarket(OP_BUY, v, "GLB buy layer");
      }
   }
   else if(sells == 1)
   {
      if(RecoveryRequiresMacro && g_bias > 0) return;

      bool confirm = 

Показано первые 50% кода (символов: 27314)