Gold Level Breakout Enhanced
Похожие материалы по тегам
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «gold level breakout.mq5» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
Gold Level Breakout Enhanced — это торговый советник для MetaTrader 5, ориентированный на скальпирование золотых фьючерсов с адаптивным восстановлением торговых уровней. Советник использует внутренние расчёты на основе SuperTrend, скользящей средней EMA и индикатора ADX для определения регистра тренда и структурных точек входа.
Основная логика входа в позицию срабатывает на новом баре при касании или прорыве структурного уровня. При наличии открытой позиции одного направления советник может добавлять восстановительные лоты с увеличением размера, управляя каждой позицией через независимый трейлинг-стоп.
Встроены средства защиты: ограничение убытка корзины, принудительное закрытие при достижении порога убытка, защита от торговых выходных и пятничное закрытие позиций. Реализованы фильтры торгового времени, адаптивная сессия с использованием дневного тренда и контроль максимального спреда.
Советник выводит на график панель со статистикой закрытых сделок и прогнозный уровень потенциального входа с индикатором расстояния и прогресса.
Настройки программы
| Настройка | Описание |
|---|---|
| Lots | Базовый объём позиции в лотах для первого входа в сделку. |
| LotMultiplier | Множитель для расчёта объёма восстановительных позиций. Каждый следующий лэйер умножается на это значение. |
| MinBarsBetween | Минимальное количество баров между последовательными восстановительными входами в одну сторону. |
| MinDistancePoints | Минимальное расстояние в пунктах между ценой входа и последней позицией для добавления восстановительного лэйера. |
| TrailingPoints | Расстояние трейлинг-стопа в пунктах от текущей цены после активации. |
| TrailingArmPoints | Расстояние в пунктах от точки входа, при котором активируется трейлинг-стоп. |
| TrailLockPercent | Процент от начального движения цены, который фиксируется как минимальное расстояние стоп-лосса от точки входа при трейлинге. |
| MinTrailStepPoints | Минимальный шаг в пунктах, на который может быть сдвинут уровень стоп-лосса при трейлинге. |
| Dist | Расстояние в пунктах для расчёта прогнозных уровней входа — отступ от структурного экстремума. |
| STPeriod | Период расчёта индикатора Average True Range (ATR), используемого в линии SuperTrend. |
| STMultiplier | Множитель ATR для расчёта линии SuperTrend. Определяет чувствительность индикатора. |
| STBars | Количество баров для расчёта структурных экстремумов и анализа SuperTrend. |
| Slippage | Допустимое проскальгивание в пунктах при исполнении рыночных ордеров и закрытии позиций. |
| Magic | Магический номер для идентификации позиций, ордеров и сделок, управляемых данным советником. |
| PanelShow | Отображает или скрывает информационную панель со статистикой на графике. |
| PanelX | Горизонтальная позиция (в пикселях от левого верхнего угла) панели статистики на графике. |
| PanelY | Вертикальная позиция (в пикселях от левого верхнего угла) панели статистики на графике. |
| ForecastShow | Отображает или скрывает прогнозную панель с информацией о потенциальном уровне входа на графике. |
| ForecastRefreshSec | Интервал обновления прогнозного уровня на графике в секундах. |
| TimeFilter | Включает или отключает фильтр торгового времени по часам сервера. |
| StartHour | Начальный час торгового фильтра. При активном фильтре вход разрешён только начиная с этого часа. |
| EndHour | Конечный час торгового фильтра. При активном фильтре вход разрешён только в интервале между StartHour и EndHour. |
| AdaptiveSession | Включает адаптивную торговую сессию, при которой вход разрешён только в основной торговый период или при сильном дневном тренде (ADX выше порога). |
| CoreStartHour | Начальный час основной торговой сессии в адаптивном режиме. Вход разрешён начиная с этого часа. |
| CoreEndHour | Конечный час основной торговой сессии в адаптивном режиме. Вход разрешён, пока текущий час меньше этого значения. |
| ExtendedHoursADX | Пороговое значение индекса ADX на дневном таймфрейме, при котором разрешён торговый вход за пределами основной сессии. |
| WeekendProtection | Включает защиту от выходных: блокировку входа в выходные дни и принудительное закрытие всех позиций в пятницу после указанного часа. |
| FridayCloseHour | Час, начиная с которого советник закрывает все позиции в пятницу для защиты от выходного разрыва. |
| SafetyGuard | Включает или отключает защиту корзины — автоматическое закрытие всех позиций при превышении максимального убытка. |
| MaxBasketLoss | Максимальный суммарный плавающий убыток в долларах по корзине позиций. При превышении все позиции закрываются. |
| SafetyCooldownBars | Минимальное количество баров между обычными закрытиями по защите корзины. |
| HardStopCooldownBars | Минимальное количество баров между принудительными закрытиями по стоп-лоссу (жёсткая защита). |
| HardStopLossUSDPerPosition | Максимальный убыток в долларах США на одну позицию, при достижении которого позиция закрывается по стоп-лоссу. |
| TakeProfitUSDPerPosition | Целевая прибыль в долларах США на одну позицию, при достижении которой позиция закрывается по тейку-профиту. |
| MacroEMAPeriod | Период скользящей средней EMA на дневном таймфрейме, используемой для определения макро-направления тренда. |
| EntryLogic | Логика формирования сигнала: вход при откате от экстремума, вход при прорыве тренда или комбинация обоих вариантов. |
| EntryExecution | Режим исполнения входа: немедленный рыночный вход, вход при возврате к уровню (reclaim) или вход при касании уровня. |
| ReclaimPercent | Процент диапазона от экстремума, на который цена должна вернуться для активации входа по reclaim. |
| ReclaimValidityBars | Количество баров, в течение которых уровень reclaim остаётся действительным до отмены. |
| ReclaimBufferPoints | Дополнительный отступ в пунктах при расчёте уровня возврата (reclaim) для входа. |
| EntryQuality | Критерий качества бара для входа: только экстремальные бары, подтверждение тела свечи, расположие закрытия или полное подтверждение отклонением. |
| RejectionClosePercent | Процент расположения закрытия свечи от диапазона бара, используемый как порог подтверждения качества сигнала. |
| MaxSignalRangeATRPercent | Максимальный допустимый диапазон бара в процентах от ATR. Если диапазон превышает порог, сигнал отклоняется. |
| MaxSpreadPoints | Максимально допустимый спред в пунктах. При превышении вход в сделку блокируется. |
| RecoveryRequiresMacro | Если включено, восстановительный вход разрешён только при совпадении макро-направления тренда с направлением позиции. |
| EnableRecovery | Включает или отключает режим восстановления (лэйеринг), при котором после первого входа добавляются дополнительные позиции того же направления. |
| RecoveryRequiresRejection | Если включено, восстановительный вход требует дополнительного подтверждения качеством сигнала через полный rejection-тест. |
| RecoveryConfirmAfterSafetyBars | Количество баров после последнего закрытия по защите корзины, в течение которого восстановительный вход требует дополнительного подтверждения. |
| RecoveryBasketProfitUSD | Целевой прибыльный баланс корзины в долларах. При достижении совокупной прибыли все позиции закрываются. |
Поиск по коду файла
#property strict
#property version "1.80"
#property description "Gold level breakout Enhanced - MT5 adaptive level-recovery scalper"
#include <Trade/Trade.mqh>
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 long 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 group "Hard stop-loss controls"
input double HardStopLossUSDPerPosition = 9.0;
input double TakeProfitUSDPerPosition = 0.0;
input group "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;
CTrade trade;
int g_atrHandle = INVALID_HANDLE;
int g_trendHandle = INVALID_HANDLE;
int g_dailyAdxHandle = INVALID_HANDLE;
ENUM_TIMEFRAMES g_signalTf = PERIOD_CURRENT;
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; // +1 bullish ST regime / BUY support, -1 bearish ST regime / SELL resistance
int g_prevBias = 0;
bool g_touchArmed = true;
double g_prevAsk = 0.0;
double g_prevBid = 0.0;
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 OnInit()
{
// код доступен только после оплаты
}
void OnDeinit(const int reason)
{
EventKillTimer();
if(g_atrHandle != INVALID_HANDLE) IndicatorRelease(g_atrHandle);
if(g_trendHandle != INVALID_HANDLE) IndicatorRelease(g_trendHandle);
if(g_dailyAdxHandle != INVALID_HANDLE) IndicatorRelease(g_dailyAdxHandle);
ObjectsDeleteAll(0, PFX);
}
void OnTick()
{
// код доступен только после оплаты
}
void OnTimer()
{
if(PanelShow || ForecastShow)
{
MqlTick tick;
if(SymbolInfoTick(_Symbol, tick))
UpdatePanel(tick);
}
}
void OnTradeTransaction(const MqlTradeTransaction &trans,
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
if(trans.type != TRADE_TRANSACTION_DEAL_ADD || trans.deal == 0) return;
if(!HistoryDealSelect(trans.deal)) return;
if(HistoryDealGetString(trans.deal, DEAL_SYMBOL) != _Symbol) return;
if((long)HistoryDealGetInteger(trans.deal, DEAL_MAGIC) != Magic) return;
ENUM_DEAL_ENTRY entry = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(trans.deal, DEAL_ENTRY);
ENUM_DEAL_REASON reason = (ENUM_DEAL_REASON)HistoryDealGetInteger(trans.deal, DEAL_REASON);
double net = HistoryDealGetDouble(trans.deal, DEAL_PROFIT)
+ HistoryDealGetDouble(trans.deal, DEAL_COMMISSION)
+ HistoryDealGetDouble(trans.deal, DEAL_SWAP);
if((entry == DEAL_ENTRY_OUT || entry == DEAL_ENTRY_OUT_BY) &&
reason == DEAL_REASON_SL && net < 0.0)
{
g_lastHardStopExit = iTime(_Symbol, g_signalTf, 0);
g_armedDirection = 0;
g_armedTrigger = 0.0;
g_armedAt = 0;
}
}
bool IsTradingTime()
{
MqlDateTime tm;
TimeToStruct(TimeCurrent(), tm); // broker/server time
if(WeekendProtection)
{
if(tm.day_of_week == 0 || tm.day_of_week == 6) return false;
if(tm.day_of_week == 5 && tm.hour >= MathMax(0, MathMin(23, FridayCloseHour)))
return false;
}
if(AdaptiveSession)
{
int coreStart = MathMax(0, MathMin(23, CoreStartHour));
int coreEnd = MathMax(0, MathMin(23, CoreEndHour));
bool inCore = (coreStart == coreEnd
? true
: coreStart < coreEnd
? (tm.hour >= coreStart && tm.hour < coreEnd)
: (tm.hour >= coreStart || tm.hour < coreEnd));
if(inCore) return true;
return StrongDailyTrend();
}
if(!TimeFilter) return true;
if(StartHour == EndHour) return true;
if(StartHour < EndHour)
return (tm.hour >= StartHour && tm.hour < EndHour);
return (tm.hour >= StartHour || tm.hour < EndHour);
}
bool StrongDailyTrend()
{
if(ExtendedHoursADX <= 0) return true;
if(g_dailyAdxHandle == INVALID_HANDLE) return false;
double adx[];
ArrayResize(adx, 1);
if(CopyBuffer(g_dailyAdxHandle, 0, 1, 1, adx) != 1) return false;
return (adx[0] >= ExtendedHoursADX);
}
bool ManageWeekendProtection()
{
if(!WeekendProtection) return false;
MqlDateTime tm;
TimeToStruct(TimeCurrent(), tm);
int cutoff = MathMax(0, MathMin(23, FridayCloseHour));
if(tm.day_of_week != 5 || tm.hour < cutoff) return false;
bool attempted = false;
for(int i=PositionsTotal()-1; i>=0; --i)
{
ulong ticket = PositionGetTicket(i);
if(ticket == 0) continue;
if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
if((long)PositionGetInteger(POSITION_MAGIC) != Magic) continue;
attempted = true;
if(!trade.PositionClose(ticket, (ulong)Slippage))
Print("Gold level weekend close failed: ", trade.ResultRetcode(),
" ", trade.ResultRetcodeDescription());
}
if(attempted)
{
g_armedDirection = 0;
g_armedTrigger = 0.0;
g_armedAt = 0;
}
return attempted;
}
void ApplyVisualTheme()
{
ChartSetInteger(0, CHART_COLOR_BACKGROUND, C'0,0,0');
ChartSetInteger(0, CHART_COLOR_FOREGROUND, C'155,160,168');
ChartSetInteger(0, CHART_COLOR_GRID, C'45,50,58');
ChartSetInteger(0, CHART_COLOR_CHART_UP, C'30,255,60');
ChartSetInteger(0, CHART_COLOR_CHART_DOWN, C'30,255,60');
ChartSetInteger(0, CHART_COLOR_CANDLE_BULL, C'30,255,60');
ChartSetInteger(0, CHART_COLOR_CANDLE_BEAR, C'30,255,60');
ChartSetInteger(0, CHART_COLOR_BID, C'160,165,175');
ChartSetInteger(0, CHART_SHOW_ASK_LINE, false);
ChartSetInteger(0, CHART_SHOW_VOLUMES, CHART_VOLUME_HIDE);
ChartRedraw(0);
}
void RefreshLevels(bool force)
{
if(Bars(_Symbol, g_signalTf) < MathMax(STBars, STPeriod) + 20) 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 = MathMax(2, STBars);
double pad = MathMax(0, Dist) * _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()
{
if(g_trendHandle == INVALID_HANDLE) return +1;
double ema[];
ArrayResize(ema, 2);
ArraySetAsSeries(ema, true);
if(CopyBuffer(g_trendHandle, 0, 1, 2, ema) != 2) return +1;
double closeMacro = iClose(_Symbol, PERIOD_D1, 1);
if(closeMacro <= 0.0) return +1;
return (closeMacro >= ema[0] ? +1 : -1);
}
bool CalculateSuperTrend(double &line, int &trend)
{
int need = MathMax(80, MathMax(STBars + STPeriod + 20, STPeriod * 4));
MqlRates rates[];
double atr[];
ArraySetAsSeries(rates, true);
ArraySetAsSeries(atr, true);
int got = CopyRates(_Symbol, g_signalTf, 0, need, rates);
if(got < MathMax(STBars, STPeriod) + 5) return false;
int gotAtr = CopyBuffer(g_atrHandle, 0, 0, got, atr);
if(gotAtr < got) return false;
double upper[], lower[], st[];
ArrayResize(upper, got);
ArrayResize(lower, got);
ArrayResize(st, got);
double mult = MathMax(0.10, STMultiplier);
int oldest = got - 1;
double hl2 = (rates[oldest].high + rates[oldest].low) * 0.5;
double a0 = MathMax(atr[oldest], _Point);
upper[oldest] = hl2 + mult * a0;
lower[oldest] = hl2 - mult * a0;
st[oldest] = (rates[oldest].close >= hl2 ? lower[oldest] : upper[oldest]);
for(int i=oldest-1; i>=1; --i)
{
int p = i + 1;
double mid = (rates[i].high + rates[i].low) * 0.5;
double av = MathMax(atr[i], _Point);
double basicUpper = mid + mult * av;
double basicLower = mid - mult * av;
upper[i] = (basicUpper < upper[p] || rates[p].close > upper[p])
? basicUpper : upper[p];
lower[i] = (basicLower > lower[p] || rates[p].close < lower[p])
? basicLower : lower[p];
bool prevWasUpper = (MathAbs(st[p] - upper[p]) <= MathAbs(st[p] - lower[p]));
if(prevWasUpper)
st[i] = (rates[i].close <= upper[i]) ? upper[i] : lower[i];
else
st[i] = (rates[i].close >= 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);
}
void HandleConfirmedTrendFlip()
{
if(g_prevBias == 0 || g_bias == 0 || g_prevBias == g_bias) return;
ENUM_POSITION_TYPE wrong = (g_bias > 0 ? POSITION_TYPE_SELL : POSITION_TYPE_BUY);
ClosePositionsOfType(wrong);
}
void ClosePositionsOfType(ENUM_POSITION_TYPE type)
{
for(int i=PositionsTotal()-1; i>=0; --i)
{
ulong ticket = PositionGetTicket(i);
if(ticket == 0) continue;
if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
if((long)PositionGetInteger(POSITION_MAGIC) != Magic) continue;
if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) != type) continue;
if(!trade.PositionClose(ticket, (ulong)Slippage))
Print("GLB CR flip-close failed: ", trade.ResultRetcode(), " ", trade.ResultRetcodeDescription());
}
}
bool SignalQualityPass(int direction, bool forceRejection)
{
if(!forceRejection && EntryQuality == GLB_EXTREME_ONLY &&
MaxSignalRangeATRPercent <= 0)
return true;
MqlRates signal[1];
if(CopyRates(_Symbol, g_signalTf, 1, 1, signal) != 1) return false;
double range = signal[0].high - signal[0].low;
if(range <= _Point) return false;
if(MaxSignalRangeATRPercent > 0)
{
double atr[1];
if(CopyBuffer(g_atrHandle, 0, 1, 1, atr) != 1) return false;
if(atr[0] <= _Point) return false;
if(range * 100.0 > atr[0] * MaxSignalRangeATRPercent)
return false;
}
bool bodyConfirm = (direction > 0
? signal[0].close > signal[0].open
: signal[0].close < signal[0].open);
double closeLocation = 100.0 * (signal[0].close - signal[0].low) / range;
int threshold = MathMax(50, MathMin(95, RejectionClosePercent));
bool locationConfirm = (direction > 0
? closeLocation >= threshold
: closeLocation <= 100 - threshold);
if(forceRejection)
return bodyConfirm && locationConfirm;
if(EntryQuality == GLB_BODY_CONFIRM) return bodyConfirm;
if(EntryQuality == GLB_CLOSE_LOCATION) return locationConfirm;
if(EntryQuality == GLB_FULL_REJECTION) return bodyConfirm && locationConfirm;
return true;
}
void ProcessEntries(const MqlTick &tick, bool newBar)
{
int buys=0, sells=0;
double lastBuy=0.0, lastSell=0.0;
datetime lastBuyTime=0, lastSellTime=0;
GetOpenState(buys, sells, lastBuy, lastSell, lastBuyTime, lastSellTime);
if(buys > 0 && sells > 0) return;
if(MaxSpreadPoints > 0)
{
double spreadPoints = (tick.ask - tick.bid) / _Point;
if(spreadPoints > MaxSpreadPoints) return;
}
if(g_lastSafetyExit > 0 &&
BarsSince(g_lastSafetyExit) < MathMax(1, SafetyCooldownBars))
return;
if(g_lastHardStopExit > 0 &&
BarsSince(g_lastHardStopExit) < MathMax(0, HardStopCooldownBars))
return;
if(buys == 0 && sells == 0)
{
if(EntryExecution == GLB_ENTER_LEVEL_TOUCH)
{
if(newBar)
{
if(g_bias >= 0 && g_buyLevel > 0.0 && tick.ask > g_buyLevel)
g_touchArmed = true;
else if(g_bias < 0 && g_sellLevel > 0.0 && tick.bid < g_sellLevel)
g_touchArmed = true;
}
if(g_touchArmed)
{
if(g_bias >= 0 && g_buyLevel > 0.0 && tick.ask <= g_buyLevel)
{
g_touchArmed = false;
OpenMarket(ORDER_TYPE_BUY, Lots, "Gold level touch buy");
}
else if(g_bias < 0 && g_sellLevel > 0.0 && tick.bid >= g_sellLevel)
{
g_touchArmed = false;
OpenMarket(ORDER_TYPE_SELL, Lots, "Gold level touch sell");
}
}
return;
}
if(EntryExecution == GLB_ENTER_ON_RECLAIM && g_armedDirection != 0)
{
bool expired = (BarsSince(g_armedAt) > MathMax(1, ReclaimValidityBars));
bool invalidBias = (g_armedDirection > 0 ? g_bias < 0 : g_bias > 0);
if(expired || invalidBias)
{
g_armedDirection = 0;
g_armedTrigger = 0.0;
g_armedAt = 0;
}
else
{
bool crossed = (g_armedDirection > 0
? tick.ask >= g_armedTrigger
: tick.bid <= g_armedTrigger);
if(crossed)
{
int direction = g_armedDirection;
g_armedDirection = 0;
g_armedTrigger = 0.0;
g_armedAt = 0;
OpenMarket(direction > 0 ? ORDER_TYPE_BUY : ORDER_TYPE_SELL,
Lots, direction > 0 ? "Gold reclaim buy" : "Gold reclaim sell");
return;
}
}
}
if(!newBar) return;
int lookback = MathMax(2, STBars);
if(g_bias >= 0)
{
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);
bool pullback = (signalLow > 0.0 && olderLow > 0.0 && signalLow <= olderLow);
bool breakout = (signalHigh > 0.0 && olderHigh > 0.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(ORDER_TYPE_BUY, Lots, "Gold level buy");
else if(EntryExecution == GLB_ENTER_ON_RECLAIM)
ArmReclaim(+1, signalLow, signalHigh);
}
}
else
{
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);
bool breakout = (signalLow > 0.0 && olderLow > 0.0 && signalLow <= olderLow);
bool pullback = (signalHigh > 0.0 && olderHigh > 0.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(ORDER_TYPE_SELL, Lots, "Gold level sell");
else if(EntryExecution == GLB_ENTER_ON_RECLAIM)
ArmReclaim(-1, signalLow, signalHigh);
}
}
return;
}
if(!newBar) return;
if(!EnableRecovery) return;
if(buys == 1)
{
if(RecoveryRequiresMacro && g_bias < 0) return;
bool confirmRecovery = RecoveryRequiresRejection ||
(RecoveryConfirmAfterSafetyBars > 0 && g_lastSafetyExit > 0 &&
BarsSince(g_lastSafetyExit) < RecoveryConfirmAfterSafetyBars);
if(confirmRecovery && !SignalQualityPass(+1, true)) return;
if(BarsSince(lastBuyTime) >= MathMax(0, MinBarsBetween) &&
tick.ask <= lastBuy - MathMax(1, MinDistancePoints) * _Point)
{
double v = Lots * MathPow(MathMax(LotMultiplier, 0.01), buys);
OpenMarket(ORDER_TYPE_BUY, v, "GLB buy layer");
}
}
else if(sells == 1)
{
if(RecoveryRequiresMacro && g_bias > 0) return;
bool confirmRecovery = RecoveryRequiresRejection ||
(RecoveryConfirmAfterSafetПоказано первые 50% кода (символов: 32972)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.