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

XMC EA 1.02 d_Grid_v1

xmc ea 1.02 d_grid_v1.mq5

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

xmc ea 1.02 d_grid_v1.mq4MQL4 / MetaTrader 4 · 2 общих теговmulti-signal trading signal system.pineTradingView · 2 общих теговle van do® - swing signals & overlays private.pineTradingView · 2 общих теговwae_smc_htf_v2.pineTradingView · 2 общих тегов#dtosc 2.06 + bells&whistles nmc.mq5MQL5 / MetaTrader 5 · 2 общих тегов!!!-mt4 x-xardg-rsi.mq5MQL5 / MetaTrader 5 · 2 общих тегов
Вы автор или правообладатель?

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

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

О программе

XMC EA 1.02 d_Grid_v1 — торговый советник для MetaTrader 5, реализующий сеточную торговлю в направлении тренда с циклами фиксации прибыли по корзине. Советник работает на символе текущего графика и открывает сетку из лимитов (слоёв) в выбранном направлении; при достижении целевого плавающего дохода вся корзина закрывается, после чего запускается пауза перед повторным входом.

Система включает комплекс фильтров: проверку тренда на старшем таймфрейме (EMA), определение флэт-режима (Choppiness), фильтр истощения тренда по RSI, новостной фильтр (NFP и CSV-события), а также временные ограничения по сессии, дням недели и окну ролловера. Фильтр спреда блокирует вход при чрезмерно широком спреде.

Шаг сетки может адаптироваться к волатильности через ATR или использоваться фиксированный в пунктах. Управление лотами предусматривает множитель на каждый уровень сетки. Встроен trailing-стоп как резервный механизм выхода. Советник требует хеджинговый счёт и не допускает одновременной работы покупательской и продавческой корзин.

Встроена система телеметрии с логированием в CSV-файлы (heartbeat, diagnostics, baskets, trades) для детального анализа торговой активности.

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

НастройкаОписание
TradeCooldown Минимальное количество секунд между открытием новых лиментов (слоёв) внутри работающей корзины.
Lookback Период (в барах) для расчёта импульса ценового изменения (ROC), используемого в телеметрии и диагностике.
basket_tp_amount Размер плавающего дохода (в валюте счёта), при достижении которого вся корзина закрывается и запускается цикл реэнтри.
reentry_cooldown Количество секунд ожидания после закрытия корзины перед открытием новой.
use_exhaustion_filter Включает фильтр истощения тренда по RSI: входы в перегретую сторону блокируются.
exhaustion_rsi_period Период расчёта RSI для фильтра истощения тренда.
exhaustion_buy_level Порог RSI, при достижении которого входы в направлении BUY блокируются (истощение тренда).
exhaustion_sell_level Порог RSI, при достижении которого входы в направлении SELL блокируются (истощение тренда).
use_news_filter Главный переключатель новостного фильтра: блокирует входы вокруг новостных событий.
news_buffer_min Количество минут до и после новостного события, в течение которых входы блокируются.
news_auto_nfp Автоматическая блокировка входов в первую пятницу месяца в момент публикации данных NFP.
nfp_hour_gmt Час публикации NFP по GMT, используемый для автоматической блокировки входов.
nfp_minute_gmt Минута публикации NFP по GMT, используемая для автоматической блокировки входов.
news_use_csv Включает чтение дат новостных событий из CSV-файла (FOMC/CPI) в дополнение к автоматическому NFP-фильтру.
news_csv_name Имя CSV-файла в MQL5\Files для загрузки дат дополнительных новостных событий (FOMC, CPI и др.).
use_time_filter Включает временной фильтр: открытие новых корзин ограничено по дням недели и часам сессии.
trade_sunday Включает торговлю в воскресенье (серверный день).
trade_monday Включает торговлю в понедельник (серверный день).
trade_tuesday Включает торговлю во вторник (серверный день).
trade_wednesday Включает торговлю в среду (серверный день).
trade_thursday Включает торговлю в четверг (серверный день).
trade_friday Включает торговлю в пятницу (серверный день).
session_start_hour Начальный серверный час (включительно), с которого разрешено открытие новых корзин. При start > end окно переходит через полночь.
session_end_hour Конечный серверный час (включительно), до которого разрешено открытие новых корзин. При start > end окно переходит через полночь.
friday_no_new_hour Серверный час, начиная с которого в пятницу не разрешается открытие новых корзин.
skip_rollover Включает блокировку всех входов в окно ролловера.
rollover_start_hour Начальный серверный час (с учётом перехода через полночь) окна ролловера, в которое блокируются все входы.
rollover_end_hour Конечный серверный час (включительно) окна ролловера, в которое блокируются все входы.
use_spread_filter Включает фильтр спреда: входы блокируются при превышении максимально допустимого спреда.
max_spread_points Максимально допустимый спред в пунктах, при превышении которого входы блокируются.
use_htf_filter Включает фильтр старшего таймфрейма: EMA на HTF должна совпадать с направлением корзины.
htf_tf Старший таймфрейм для фильтра тренда: EMA на этом таймфрейме должна совпадать с направлением текущей корзины.
use_chop_filter Включает фильтр флэт-режима (Choppiness): при превышении порога все входы блокируются.
chop_period Период расчёта индекса Choppiness для определения режима рынка (тренд/флэт).
chop_max Пороговое значение индекса Choppiness, выше которого рынок считается флэтовым и входы блокируются.
max_layers Максимальное количество слоёв (лиментов) в одной корзине. При достижении лимита система переходит в состояние LOCKDOWN.
ema_fast_period Период быстрой EMA для определения направления тренда на текущем таймфрейме.
ema_slow_period Период медленной EMA для определения направления тренда на текущем таймфрейме.
adx_period Период расчёта индекса ADX для оценки силы тренда.
adx_trend_strength Пороговое значение ADX, выше которого считается, что тренд достаточно силён для перехода в состояние TRENД.
use_atr_distance Включает адаптивный шаг сетки на основе ATR вместо фиксированного значения в пунктах.
atr_period Период расчёта индикатора ATR для определения волатильности и шага сетки.
atr_smoothing Период сглаживания ATR, используемого для определения средней волатильности и состояния системы.
atr_multiplier Множитель ATR, определяющий шаг сетки как произведение ATR на это значение (при включённой адаптации по ATR).
fallback_distance_pts Шаг сетки в пунктах, используемый как резервный при недоступности ATR.
max_volatility_factor Множитель волатильности: если текущий ATR превышает средний ATR на это значение, система переходит в состояние LOCKDOWN.
fixed_lot Базовый размер лота для первого слоя сетки.
lot_multiplier Множитель увеличения лота на каждый следующий уровень сетки (1.0 означает постоянный размер лота).
trail_start_amount Размер плавающего дохода корзины, при достижении которого активируется trailing-стоп.
trail_dist_amount Величина отката от пика прибыли, при достижении которой корзина закрывается (trailing-стоп).
initial_magic Магический номер для идентификации позиций, открытых данным советником.
trade_comment Текстовый комментарий, добавляемый к каждой открытой позиции для идентификации.
Получить полный код

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

#property version   "1.02"
#property description "XMC EA 1.02 d_Grid_v1: trend-direction grid with basket TP cycles."
#property description "Filters: HTF trend, Choppiness regime, RSI exhaustion, news (NFP/CSV),"
#property description "session/day/Friday-cutoff/rollover time windows, spread."
#property description "No hedging: a buy and sell basket never run at the same time."
#property description "REQUIRES a HEDGING account (multiple positions per symbol)."
#property description "Modded by Prof. Morris"

#include <Trade\Trade.mqh>

CTrade trade;

input group "=== ENTRY RULES ==="
input int    TradeCooldown    = 30;     // min seconds between opening layers
input int    Lookback         = 60;     // ROC lookback (momentum telemetry)

input group "=== BASKET TP CYCLE ==="
input double basket_tp_amount = 15.0;   // close whole basket at this floating profit (account currency)
input int    reentry_cooldown = 300;    // seconds to wait after basket close before re-entering

input group "=== TREND EXHAUSTION FILTER ==="
input bool   use_exhaustion_filter = true;   // block entries when trend is exhausted (RSI)
input int    exhaustion_rsi_period = 14;
input double exhaustion_buy_level  = 70.0;   // block BUY entries when RSI >= this
input double exhaustion_sell_level = 30.0;   // block SELL entries when RSI <= this

input group "=== NEWS FILTER (pause new layers around events) ==="
input bool   use_news_filter        = true;   // master switch
input int    news_buffer_min        = 30;     // minutes before/after event to block entries
input bool   news_auto_nfp          = true;   // auto-block first Friday of month (NFP)
input int    nfp_hour_gmt           = 13;     // NFP release hour (GMT) - 13:30 GMT = 8:30 ET
input int    nfp_minute_gmt         = 30;
input int    news_server_gmt_offset = 2;      // broker server hours ahead of GMT (+2 winter / +3 summer)
input bool   news_use_csv           = true;   // also read MQL5\Files\news_events.csv (FOMC/CPI dates)
input string news_csv_name          = "news_events.csv";

input group "=== TIME FILTER ==="
input bool   use_time_filter     = true;
input bool   trade_sunday        = false;   // day toggles (server days)
input bool   trade_monday        = true;
input bool   trade_tuesday       = true;
input bool   trade_wednesday     = true;
input bool   trade_thursday      = true;
input bool   trade_friday        = true;
input int    session_start_hour  = 0;       // server hour: new baskets allowed from (inclusive)
input int    session_end_hour    = 23;      // server hour: until (inclusive; wraps if start > end)
input int    friday_no_new_hour  = 20;      // on Friday: no NEW baskets from this server hour on
input bool   skip_rollover       = true;    // block ALL new entries in rollover window
input int    rollover_start_hour = 23;      // window start (server hour, wraps midnight)
input int    rollover_end_hour   = 0;       // window end (server hour, inclusive)

input group "=== SPREAD FILTER ==="
input bool   use_spread_filter = true;
input int    max_spread_points = 120;       // block new entries above this spread (points)

input group "=== TREND FILTERS ==="
input bool   use_htf_filter    = true;      // Filter 1: higher-TF EMA trend must agree
input ENUM_TIMEFRAMES htf_tf   = PERIOD_H4;
input bool   use_chop_filter   = true;      // Filter 2: block entries in ranging markets
input int    chop_period       = 14;
input double chop_max          = 61.8;

input group "=== GRID ENGINE ==="
input int    max_layers             = 89;
input int    ema_fast_period        = 3;      // trend direction: fast EMA
input int    ema_slow_period        = 20;     // trend direction: slow EMA
input int    adx_period             = 10;
input int    adx_trend_strength     = 20;
input bool   use_atr_distance       = true;   // grid step adapts to ATR
input int    atr_period             = 14;
input int    atr_smoothing          = 20;
input double atr_multiplier         = 0.5;    // grid step = ATR * this
input double fallback_distance_pts  = 90.0;   // grid step if ATR unavailable
input double max_volatility_factor  = 2.5;

input group "=== LOT SIZING ==="
input double fixed_lot              = 0.01;
input double lot_multiplier         = 1.3;    // lot growth per grid level (1.0 = flat lots)

input group "=== TRAILING BACKSTOP ==="
input double trail_start_amount     = 50.0;   // trailing exit arms at this basket profit
input double trail_dist_amount      = 10.0;   // giveback from peak that closes the basket

input group "=== IDENTIFICATION ==="
input long   initial_magic          = 202609011;
input string trade_comment          = "XMC_Grid_v1";

string TradeSymbol          = "";
datetime g_last_trade_time  = 0;
datetime g_last_basket_close_time = 0;   // when the last basket closed (starts re-entry cooldown)

int    g_buy_layers      = 0;
int    g_sell_layers     = 0;
double g_last_buy_price  = 0;
double g_last_sell_price = 0;
double g_current_profit  = 0;   // floating basket profit (profit + swap)
double g_peak_profit     = 0;
bool   g_trailing_active = false;
datetime g_last_bar_time = 0;

double g_roc            = 0;
double g_roc_hist[6];
int    g_roc_hist_bars  = 0;
double g_total_lots     = 0;
bool   g_new_bar_flag   = false;
bool   g_telemetry_basket_active = false;
int    g_close_reason   = 0;

double g_choppiness       = 0;      // 0..100 (high = ranging)
int    g_htf_trend        = -1;     // ORDER_TYPE_BUY / ORDER_TYPE_SELL / -1 (flat)
double g_exhaustion_rsi   = 50.0;   // cached RSI for exhaustion filter
bool   g_news_blocked     = false;  // true while inside a news window
string g_news_source      = "";     // which event is blocking (NFP/CSV)

#define CLOSE_REASON_TRAILING   1
#define CLOSE_REASON_BASKET_TP  2
#define CLOSE_REASON_STOPOUT    3

enum ENUM_SYSTEM_STATE { STATE_SCOUT, STATE_TREND, STATE_RECOVERY, STATE_LOCKDOWN };

int hEmaFast     = INVALID_HANDLE;
int hEmaSlow     = INVALID_HANDLE;
int hEmaFastHTF  = INVALID_HANDLE;
int hEmaSlowHTF  = INVALID_HANDLE;
int hAtr         = INVALID_HANDLE;
int hAtrAvg      = INVALID_HANDLE;
int hAdx         = INVALID_HANDLE;
int hTr          = INVALID_HANDLE;   // ATR(1) = true range, for Choppiness
int hRsi         = INVALID_HANDLE;   // RSI for exhaustion filter

string  tly_ea_name        = "";
long    tly_magic          = 0;
bool    tly_ready          = false;
string  tly_dir            = "";

datetime tly_last_beat     = 0;
int      tly_beat_interval = 60;
int      tly_ticks         = 0;

string   tly_basket_symbol = "";
int      tly_basket_trades = 0;
double   tly_basket_peak   = 0;
datetime tly_basket_opened = 0;

datetime tly_last_upd_write  = 0;
int      tly_last_upd_layers = -1;
int      tly_upd_interval    = 5;

double Ind(int handle, int buffer, int shift) {
    double tmp[1];
    if(handle == INVALID_HANDLE) return 0.0;
    if(CopyBuffer(handle, buffer, shift, 1, tmp) != 1) return 0.0;
    return tmp[0];
}

int DayOfWeek(datetime t) { MqlDateTime st; TimeToStruct(t, st); return st.day_of_week; }  // 0=Sunday
int HourOf(datetime t)    { MqlDateTime st; TimeToStruct(t, st); return st.hour; }
int YearOf(datetime t)    { MqlDateTime st; TimeToStruct(t, st); return st.year; }
int MonthOf(datetime t)   { MqlDateTime st; TimeToStruct(t, st); return st.mon; }

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

void OnDeinit(const int reason) {
    TelemetryShutdown();
    Comment("");
    if(hEmaFast    != INVALID_HANDLE) IndicatorRelease(hEmaFast);
    if(hEmaSlow    != INVALID_HANDLE) IndicatorRelease(hEmaSlow);
    if(hEmaFastHTF != INVALID_HANDLE) IndicatorRelease(hEmaFastHTF);
    if(hEmaSlowHTF != INVALID_HANDLE) IndicatorRelease(hEmaSlowHTF);
    if(hAtr        != INVALID_HANDLE) IndicatorRelease(hAtr);
    if(hAtrAvg     != INVALID_HANDLE) IndicatorRelease(hAtrAvg);
    if(hAdx        != INVALID_HANDLE) IndicatorRelease(hAdx);
    if(hTr         != INVALID_HANDLE) IndicatorRelease(hTr);
    if(hRsi        != INVALID_HANDLE) IndicatorRelease(hRsi);
}

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

void CalculateMomentum() {
    for(int j=5; j>0; j--) {
        g_roc_hist[j] = g_roc_hist[j-1];
    }

    g_roc = 0;
    if(Bars(TradeSymbol, PERIOD_CURRENT) > Lookback) {
        double cur  = iClose(TradeSymbol, PERIOD_CURRENT, 0);
        double prev = iClose(TradeSymbol, PERIOD_CURRENT, Lookback);
        if(prev != 0) {
            g_roc = (cur - prev) / prev * 100.0;
        }
    }
    g_roc_hist[0] = g_roc;
    if(g_roc_hist_bars < 6) g_roc_hist_bars++;
}

double Choppiness(int period) {
    if(Bars(TradeSymbol, PERIOD_CURRENT) < period + 2) return 100.0;   // not enough data -> ranging (safe)

    double sum_tr = 0;
    for(int i = 1; i <= period; i++) {
        double tr = Ind(hTr, 0, i);         // ATR(1) at shift i = true range of bar i
        if(tr <= 0) return 100.0;
        sum_tr += tr;
    }

    double highs[], lows[];
    if(CopyHigh(TradeSymbol, PERIOD_CURRENT, 1, period, highs) != period) return 100.0;
    if(CopyLow (TradeSymbol, PERIOD_CURRENT, 1, period, lows ) != period) return 100.0;

    double hh = highs[ArrayMaximum(highs)];
    double ll = lows [ArrayMinimum(lows )];
    double range = hh - ll;
    if(range <= 0 || sum_tr <= 0) return 100.0;

    return 100.0 * MathLog10(sum_tr / range) / MathLog10((double)period);
}

int GetHTFTrend() {
    double hf = Ind(hEmaFastHTF, 0, 0);
    double hs = Ind(hEmaSlowHTF, 0, 0);
    if(hf > hs) return ORDER_TYPE_BUY;
    if(hf < hs) return ORDER_TYPE_SELL;
    return -1;   // flat, or HTF history still downloading -> block entries (safe)
}

datetime FirstFridayOfMonthGMT(int year, int month) {
    for(int d = 1; d <= 7; d++) {
        datetime dt = StringToTime(StringFormat("%04d.%02d.%02d", year, month, d));
        if(DayOfWeek(dt) == 5) return dt;
    }
    return 0;
}

bool NewsWindowActive() {
    if(!use_news_filter) return false;

    datetime now_srv = TimeCurrent();
    datetime now_gmt = now_srv - news_server_gmt_offset * 3600;

    if(news_auto_nfp) {
        int y = YearOf(now_gmt);
        int m = MonthOf(now_gmt);
        datetime ff = FirstFridayOfMonthGMT(y, m);
        if(ff > 0) {
            datetime event = ff + nfp_hour_gmt * 3600 + nfp_minute_gmt * 60;
            if(now_gmt >= event - news_buffer_min * 60 &&
               now_gmt <= event + news_buffer_min * 60)
            {
                g_news_source = "NFP " + TimeToString(event, TIME_DATE|TIME_MINUTES) + " GMT";
                return true;
            }
        }
    }

    if(news_use_csv && FileIsExist(news_csv_name)) {
        int fh = FileOpen(news_csv_name, FILE_READ|FILE_TXT|FILE_ANSI);
        if(fh != INVALID_HANDLE) {
            while(!FileIsEnding(fh)) {
                string line = FileReadString(fh);
                StringTrimLeft(line);
                StringTrimRight(line);
                if(StringLen(line) == 0) continue;
                if(StringFind(line, "#") == 0) continue;   // comment line

                string parts[];
                if(StringSplit(line, ';', parts) < 1) continue;
                datetime ev = StringToTime(parts[0]);
                if(ev <= 0) continue;
                int before = (ArraySize(parts) > 1) ? (int)StringToInteger(parts[1]) : news_buffer_min;
                int after  = (ArraySize(parts) > 2) ? (int)StringToInteger(parts[2]) : before;
                if(now_srv >= ev - before * 60 && now_srv <= ev + after * 60) {
                    g_news_source = "CSV " + parts[0];
                    FileClose(fh);
                    return true;
                }
            }
            FileClose(fh);
        }
    }

    g_news_source = "";
    return false;
}

bool IsTradingDay() {
    switch(DayOfWeek(TimeCurrent())) {
        case 0: return trade_sunday;
        case 1: return trade_monday;
        case 2: return trade_tuesday;
        case 3: return trade_wednesday;
        case 4: return trade_thursday;
        case 5: return trade_friday;
        default: return false;   // Saturday
    }
}

bool InSession() {
    int h = HourOf(TimeCurrent());
    if(session_start_hour <= session_end_hour)
        return (h >= session_start_hour && h <= session_end_hour);
    return (h >= session_start_hour || h <= session_end_hour);   // wraps midnight
}

bool IsLateFriday() {
    if(friday_no_new_hour < 0) return false;
    if(DayOfWeek(TimeCurrent()) != 5) return false;
    return (HourOf(TimeCurrent()) >= friday_no_new_hour);
}

bool InRolloverWindow() {
    int h = HourOf(TimeCurrent());
    if(rollover_start_hour <= rollover_end_hour)
        return (h >= rollover_start_hour && h <= rollover_end_hour);
    return (h >= rollover_start_hour || h <= rollover_end_hour);  // wraps midnight (23->0)
}

bool EntryAllowed(bool new_basket, int dir) {

    if(use_spread_filter) {
        if((int)SymbolInfoInteger(TradeSymbol, SYMBOL_SPREAD) > max_spread_points) return false;
    }

    if(skip_rollover && InRolloverWindow()) return false;

    if(use_news_filter && g_news_blocked) return false;

    if(use_exhaustion_filter) {
        if(dir == ORDER_TYPE_BUY  && g_exhaustion_rsi >= exhaustion_buy_level)  return false;
        if(dir == ORDER_TYPE_SELL && g_exhaustion_rsi <= exhaustion_sell_level) return false;
    }

    if(new_basket && use_time_filter) {
        if(!IsTradingDay())  return false;
        if(!InSession())     return false;
        if(IsLateFriday())   return false;
    }
    return true;
}

void UpdateFilters() {
    g_choppiness     = Choppiness(chop_period);
    g_htf_trend      = GetHTFTrend();
    g_exhaustion_rsi = Ind(hRsi, 0, 0);
    g_news_blocked   = NewsWindowActive();

    static bool was_chop_block = false;
    static int  was_htf_trend  = -999;
    static bool was_news       = false;

    bool chop_block = (use_chop_filter && g_choppiness > chop_max);
    if(chop_block != was_chop_block) {
        Print("FILTER: Choppiness ", DoubleToString(g_choppiness, 1),
              (chop_block ? " > " : " <= "), DoubleToString(chop_max, 1),
              (chop_block ? " -> RANGE regime, new entries BLOCKED"
                          : " -> trend regime, new entries ALLOWED"));
        was_chop_block = chop_block;
    }
    if(g_htf_trend != was_htf_trend) {
        Print("FILTER: ", EnumToString(htf_tf), " trend -> ",
              (g_htf_trend == ORDER_TYPE_BUY  ? "BULLISH (buys allowed)"  :
               g_htf_trend == ORDER_TYPE_SELL ? "BEARISH (sells allowed)" : "FLAT (no HTF agreement)"));
        was_htf_trend = g_htf_trend;
    }
    if(g_news_blocked != was_news) {
        if(g_news_blocked)
            Print("FILTER: NEWS window ACTIVE - new entries paused (", g_news_source, ")");
        else
            Print("FILTER: News window ended - entries allowed");
        was_news = g_news_blocked;
    }
}

bool ConfirmTrend(int dir) {

    if(use_chop_filter && g_choppiness > chop_max) return false;

    if(use_htf_filter) {
        if(dir == ORDER_TYPE_BUY  && g_htf_trend != ORDER_TYPE_BUY)  return false;
        if(dir == ORDER_TYPE_SELL && g_htf_trend != ORDER_TYPE_SELL) return false;
    }
    return true;
}

void UpdateHUD() {
    int layers = g_buy_layers + g_sell_layers;
    string dir = (g_buy_layers > 0) ? "BUY" : (g_sell_layers > 0 ? "SELL" : "flat");

    string s = "=== XMC EA 1.02 d_Grid_v1 (MT5) ===\n";
    s += "Trades THIS chart's symbol: " + TradeSymbol + "\n";
    s += "Basket: " + (layers > 0 ? dir + "  " + IntegerToStrin

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

Открыть по тарифу

Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.

Разовая покупка файла

На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.

Чтобы оформить заказ, введите email и перейдите к оплате.

Стоимость полного кода
3 574,50₽ ≈ $43.90