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

Human-Level SMC Market Structure Engine

human_level_structure_engine.mq5

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

#__slope direction line.mq5MQL5 / MetaTrader 5 · 1 общих теговrange breakout @meowforex1.pineTradingView · 1 общих тегов#1.mtf_collider_h4_close_13_v18bar.mq4MQL4 / MetaTrader 4 · 1 общих тегов!mth_fasttmaline_edit3.mq4MQL4 / MetaTrader 4 · 1 общих тегов!mth_fasttmaline_edit2.mq4MQL4 / MetaTrader 4 · 1 общих тегов!mth_fasttmaline_edit.mq4MQL4 / MetaTrader 4 · 1 общих тегов
Вы автор или правообладатель?

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

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

О программе

Human-Level SMC Market Structure Engine — это индикатор для MetaTrader 5, отображающий аналитическую структуру рынка на графике через объекты. Продукт реализует автоматическое обнаружение ключевых свечных точек (HH, HL, LH, LL) и анализ ценовых данных с применением технических показателей.

Индикатор рассчитывает фрактальные свинги на основе параметра силы, а затем классифицирует их как максимумы и минимумы более высокого или более низкого уровня. На основе чередующихся свингов определяются события BOS (прорыв структуры) и CHoCH (изменение характера) с хронологической обработкой без задержек.

Дополнительно индикатор строит уровни Фибоначчи на подтверждённых событиях CHoCH, определяет сигналы отката на уровне 50%, а также обнаруживает зоны FVG (Fair Value Gap) в трёхсвечной последовательности после CHoCH и сигнализирует о их митигации. Все отрисовки управляются параметрами визуализации и отображают статус в виде HUD на графике.

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

НастройкаОписание
InpSwingStrength Количество баров слева и справа от анализируемой точки для определения фрактального свинга (пивота).
InpMinPullbackATR Минимальная глубина отката между свингами, выраженная в кратности ATR, для признания чередования структуры.
InpATRPeriod Период расчёта индикатора ATR (Average True Range), используемого для определения глубины отката и отступов при отрисовке меток.
InpMaxBars Максимальное количество баров для анализа при расчёте свингов и событий.
InpShowSwingPoints Отображение точечных маркеров (кружков) на свинговых точках HH, HL, LH, LL на графике.
InpShowStructureLabels Отображение текстовых меток HH, HL, LH, LL рядом с соответствующими свинговыми точками на графике.
InpTextSize Размер шрифта меток свинговых точек (HH, HL, LH, LL) и маркеров на графике.
InpBullishColor Цвет отрисовки бычьих объектов: метки HH, HL, линии BOS ↑ и CHoCH ↑, а также стрелки и тексты бычьих сигналов.
InpBearishColor Цвет отрисовки медвежьих объектов: метки LH, LL, линии BOS ↓ и CHoCH ↓, а также стрелки и тексты медвежьих сигналов.
InpShowBOS Отображение событий BOS (Break of Structure — прорыв структуры) на графике в виде линий и меток.
InpShowCHoCH Отображение событий CHoCH (Change of Character — изменение характера) на графике в виде линий и меток.
InpShowBreakLines Отображение горизонтальных линий прорыва для событий BOS и CHoCH на графике.
InpUseCloseForBreak Признание прорыва структуры по закрытию свечи (true) или по экстремуму свечи (false — по верхней/нижней тени).
InpBreakLineWidth Толщина линий прорыва (BOS и CHoCH) в пикселях.
InpBreakLineStyle Стиль линий прорыва (BOS и CHoCH), задающий тип линии для отрисовки событий на графике.
InpEventTextSize Размер шрифта текстовых меток событий BOS и CHoCH на графике.
InpShowCHoCHFibo Автоматическая отрисовка уровней Фибоначчи на подтверждённых событиях CHoCH.
InpFiboColor Цвет линий и уровней Фибоначчи, рисуемых на событиях CHoCH.
InpFiboWidth Толщина линий Фибоначчи в пикселях.
InpFiboStyle Стиль линий Фибоначчи, задающий тип линии для отрисовки уровней.
InpShowRetestSignals Отображение сигналов отката на уровне 50% Фибоначчи после CHoCH в виде стрелок и текстовых меток.
InpSignalArrowSize Размер стрелок сигналов отката на 50% уровня Фибоначчи и сигналов митигации FVG.
InpShowSignalText Отображение текстовых меток Buy/Sell рядом со стрелками сигналов отката и митигации FVG.
InpShowCHoCHFVG Обнаружение и отрисовка зон FVG (Fair Value Gap) после событий CHoCH на графике.
InpShowFVGSignals Отображение стрелок и текстовых меток сигналов митигации (тапа) зон FVG на графике.
InpBullishFVGColor Цвет прямоугольника зоны FVG (Fair Value Gap) для бычьих событий CHoCH.
InpBearishFVGColor Цвет прямоугольника зоны FVG (Fair Value Gap) для медвежьих событий CHoCH.
InpFillFVGBox Заливка прямоугольника зоны FVG цветом при отрисовке на графике.
InpFVGTextSize Размер шрифта текста метки зоны FVG на графике.
InpShowStatus Отображение информационной панели (HUD) в левом верхнем углу графика с текущим состоянием структуры и количеством объектов.
InpDeleteObjectsOnExit При деинициализации индикатора удаляет все созданные им графические объекты с графика, если установлено в true.
Получить полный код

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

#property version     "2.70"
#property description "Human-Level SMC Market Structure Engine with CHoCH Fibo & FVG Mitigation Signals."
#property indicator_chart_window
#property indicator_plots 0

enum ENUM_SWING_TYPE
  {
   SW_NONE = 0,
   SW_HIGH,
   SW_LOW
  };

enum ENUM_LABEL_TYPE
  {
   LB_NONE = 0,
   LB_HH,
   LB_HL,
   LB_LH,
   LB_LL
  };

enum ENUM_TREND_STATE
  {
   TREND_UNKNOWN = 0,
   TREND_BULL,
   TREND_BEAR
  };

struct SSwingPoint
  {
   int               bar_idx;
   datetime          time;
   double            price;
   ENUM_SWING_TYPE   type;
   ENUM_LABEL_TYPE   label;
  };

struct SBreakEvent
  {
   int               break_bar;
   int               swing_bar;
   int               anchor_bar;     // Origin swing bar for Fibonacci anchor
   bool              is_bullish;
   bool              is_choch;
   double            level;          // Broken level (100%)
   double            anchor_level;   // Origin level (0%)
   datetime          t_start;
   datetime          t_end;
  };

struct SFiboSignal
  {
   int               bar_idx;
   datetime          time;
   double            price;
   bool              is_buy;
   double            fibo_50_level;
  };

struct SFVGZone
  {
   int               fvg_idx;
   int               choch_evt_idx;
   int               formed_bar;
   datetime          t_start;
   datetime          t_end;
   double            top;
   double            bottom;
   bool              is_bullish;
   bool              is_mitigated;
   int               mitigate_bar;
   datetime          mitigate_time;
   double            mitigate_price;
  };

input group "=== Structural Wave & Pivot Filter ==="
input int             InpSwingStrength       = 15;            // Pivot Strength (Bars on Left/Right)
input double          InpMinPullbackATR      = 0.85;          // Minimum Pullback Depth (ATR Multiplier)
input int             InpATRPeriod           = 14;            // ATR Period
input int             InpMaxBars             = 2000;          // Max Lookback Bars

input group "=== Visuals: Swings & Labels ==="
input bool            InpShowSwingPoints     = true;          // Show Dot Markers at Swings
input bool            InpShowStructureLabels = true;          // Show HH / HL / LH / LL Labels
input int             InpTextSize            = 9;             // Label Font Size
input color           InpBullishColor        = C'0,225,120';  // Bullish Color (HH / HL / BOS ↑ / CHoCH ↑)
input color           InpBearishColor        = C'255,75,90';   // Bearish Color (LH / LL / BOS ↓ / CHoCH ↓)

input group "=== Visuals: BOS & CHoCH ==="
input bool            InpShowBOS             = true;          // Show BOS (Continuation)
input bool            InpShowCHoCH           = true;          // Show CHoCH (Reversal)
input bool            InpShowBreakLines      = true;          // Show Break Lines
input bool            InpUseCloseForBreak    = true;          // Confirm Break by Candle Close (false = Wick)
input int             InpBreakLineWidth      = 1;             // Line Width
input ENUM_LINE_STYLE InpBreakLineStyle      = STYLE_DASH;    // Line Style
input int             InpEventTextSize       = 8;             // Event Label Size

input group "=== CHoCH Fibonacci & 50% Retest Signals ==="
input bool            InpShowCHoCHFibo       = true;          // Draw Fibonacci on CHoCH
input color           InpFiboColor           = clrYellow;     // Fibonacci Color
input int             InpFiboWidth           = 1;             // Fibonacci Line Width
input ENUM_LINE_STYLE InpFiboStyle           = STYLE_SOLID;   // Fibonacci Line Style
input bool            InpShowRetestSignals   = true;          // Show 50% Fibo Retest Signals
input int             InpSignalArrowSize     = 2;             // Signal Arrow Size (Wingdings 233/234)
input bool            InpShowSignalText      = true;          // Show Buy/Sell Text Label

input group "=== CHoCH Post-3-Candle FVG & Mitigation Signals ==="
input bool            InpShowCHoCHFVG        = true;          // Detect & Draw FVG after CHoCH
input bool            InpShowFVGSignals      = true;          // Show FVG Mitigation Buy/Sell Signals
input color           InpBullishFVGColor     = C'0,120,65';   // Bullish FVG Box Color
input color           InpBearishFVGColor     = C'130,35,45';  // Bearish FVG Box Color
input bool            InpFillFVGBox          = true;          // Fill FVG Box
input int             InpFVGTextSize         = 8;             // FVG Text Size

input group "=== Display & Dashboard ==="
input bool            InpShowStatus          = true;          // Show Status HUD
input bool            InpDeleteObjectsOnExit = true;          // Delete Objects on Remove

const string PREFIX = "SMC_PRO_";
MqlRates     Rates[];
double       ATR[];
int          BarsCount = 0;

string       g_active_objects[];
int          g_active_count = 0;

void ResetActiveTracker()
  {
   ArrayResize(g_active_objects, 0);
   g_active_count = 0;
  }

void RegisterActiveObject(const string name)
  {
   ArrayResize(g_active_objects, g_active_count + 1);
   g_active_objects[g_active_count] = name;
   g_active_count++;
  }

void CleanupUnusedObjects()
  {
   int total = ObjectsTotal(0, -1, -1);
   for(int i = total - 1; i >= 0; i--)
     {
      string name = ObjectName(0, i, -1, -1);
      if(StringFind(name, PREFIX) == 0 || StringFind(name, "HLSE2_") == 0 || StringFind(name, "HLSE_") == 0)
        {
         bool is_active = false;
         for(int j = 0; j < g_active_count; j++)
           {
            if(name == g_active_objects[j])
              {
               is_active = true;
               break;
              }
           }
         if(!is_active)
            ObjectDelete(0, name);
        }
     }
  }

void DeleteAllIndicatorObjects()
  {
   ObjectsDeleteAll(0, PREFIX);
   ObjectsDeleteAll(0, "HLSE2_");
   ObjectsDeleteAll(0, "HLSE_");
  }

void CalcATR()
  {
   ArrayResize(ATR, BarsCount);
   if(BarsCount <= 0)
      return;

   int p = MathMax(1, InpATRPeriod);
   double tr[];
   ArrayResize(tr, BarsCount);

   tr[0] = Rates[0].high - Rates[0].low;
   for(int i = 1; i < BarsCount; i++)
     {
      double a = Rates[i].high - Rates[i].low;
      double b = MathAbs(Rates[i].high - Rates[i - 1].close);
      double c = MathAbs(Rates[i].low  - Rates[i - 1].close);
      tr[i] = MathMax(a, MathMax(b, c));
     }

   double sum = 0.0;
   for(int i = 0; i < BarsCount; i++)
     {
      sum += tr[i];
      if(i >= p)
         sum -= tr[i - p];
      ATR[i] = sum / MathMin(i + 1, p);
     }
  }

bool IsPivotHigh(int idx)
  {
   int s = MathMax(1, InpSwingStrength);
   if(idx < s || idx + s >= BarsCount)
      return false;

   double h = Rates[idx].high;
   for(int k = 1; k <= s; k++)
     {
      if(Rates[idx - k].high >= h || Rates[idx + k].high >= h)
         return false;
     }
   return true;
  }

bool IsPivotLow(int idx)
  {
   int s = MathMax(1, InpSwingStrength);
   if(idx < s || idx + s >= BarsCount)
      return false;

   double l = Rates[idx].low;
   for(int k = 1; k <= s; k++)
     {
      if(Rates[idx - k].low <= l || Rates[idx + k].low <= l)
         return false;
     }
   return true;
  }

int BuildCleanSwings(SSwingPoint &swings[])
  {
   ArrayResize(swings, 0);
   int s = MathMax(1, InpSwingStrength);

   SSwingPoint raw[];
   int raw_cnt = 0;

   for(int i = s; i < BarsCount - s; i++)
     {
      bool hi = IsPivotHigh(i);
      bool lo = IsPivotLow(i);

      if(!hi && !lo)
         continue;

      SSwingPoint sp;
      sp.bar_idx = i;
      sp.time    = Rates[i].time;
      sp.label   = LB_NONE;

      if(hi && !lo)
        {
         sp.type  = SW_HIGH;
         sp.price = Rates[i].high;
        }
      else
         if(lo && !hi)
           {
            sp.type  = SW_LOW;
            sp.price = Rates[i].low;
           }
         else
           {
            if(Rates[i].close > (Rates[i].high + Rates[i].low) * 0.5)
              {
               sp.type  = SW_HIGH;
               sp.price = Rates[i].high;
              }
            else
              {
               sp.type  = SW_LOW;
               sp.price = Rates[i].low;
              }
           }

      ArrayResize(raw, raw_cnt + 1);
      raw[raw_cnt] = sp;
      raw_cnt++;
     }

   if(raw_cnt == 0)
      return 0;

   for(int i = 0; i < raw_cnt; i++)
     {
      int n = ArraySize(swings);
      if(n == 0)
        {
         ArrayResize(swings, 1);
         swings[0] = raw[i];
         continue;
        }

      SSwingPoint last = swings[n - 1];

      if(raw[i].type == last.type)
        {
         if(raw[i].type == SW_HIGH && raw[i].price > last.price)
            swings[n - 1] = raw[i];
         else
            if(raw[i].type == SW_LOW && raw[i].price < last.price)
               swings[n - 1] = raw[i];
        }
      else
        {
         double min_pullback = (ATR[raw[i].bar_idx] > 0) ? (ATR[raw[i].bar_idx] * InpMinPullbackATR) : (15 * _Point);
         double delta = MathAbs(raw[i].price - last.price);

         if(delta >= min_pullback)
           {
            ArrayResize(swings, n + 1);
            swings[n] = raw[i];
           }
        }
     }

   return ArraySize(swings);
  }

void ClassifySwings(SSwingPoint &swings[])
  {
   double last_high = -1.0;
   double last_low  = DBL_MAX;

   int n = ArraySize(swings);
   for(int i = 0; i < n; i++)
     {
      swings[i].label = LB_NONE;

      if(swings[i].type == SW_HIGH)
        {
         if(last_high < 0.0)
            swings[i].label = LB_HH;
         else
            if(swings[i].price > last_high + (_Point * 0.5))
               swings[i].label = LB_HH;
            else
               swings[i].label = LB_LH;

         last_high = swings[i].price;
        }
      else
         if(swings[i].type == SW_LOW)
           {
            if(last_low == DBL_MAX)
               swings[i].label = LB_HL;
            else
               if(swings[i].price < last_low - (_Point * 0.5))
                  swings[i].label = LB_LL;
               else
                  swings[i].label = LB_HL;

            last_low = swings[i].price;
           }
     }
  }

void DetectBreaksChronological(const SSwingPoint &swings[], SBreakEvent &events[], ENUM_TREND_STATE &final_trend)
  {
   ArrayResize(events, 0);
   int n = ArraySize(swings);
   if(n < 2)
     {
      final_trend = TREND_UNKNOWN;
      return;
     }

   ENUM_TREND_STATE current_trend = TREND_UNKNOWN;

   for(int i = 0; i < MathMin(3, n); i++)
     {
      if(swings[i].label == LB_HH || swings[i].label == LB_HL)
         current_trend = TREND_BULL;
      else
         if(swings[i].label == LB_LH || swings[i].label == LB_LL)
            current_trend = TREND_BEAR;
     }

   int next_swing_idx  = 0;
   int active_high_idx = -1;
   int active_low_idx  = -1;

   for(int b = 0; b < BarsCount; b++)
     {
      while(next_swing_idx < n && swings[next_swing_idx].bar_idx <= b)
        {
         if(swings[next_swing_idx].type == SW_HIGH)
            active_high_idx = next_swing_idx;
         else
            if(swings[next_swing_idx].type == SW_LOW)
               active_low_idx = next_swing_idx;

         next_swing_idx++;
        }

      if(active_high_idx >= 0)
        {
         double target_h = swings[active_high_idx].price;
         bool broken_h = InpUseCloseForBreak ? (Rates[b].close > target_h) : (Rates[b].high > target_h);

         if(broken_h && b > swings[active_high_idx].bar_idx)
           {
            bool is_choch = (swings[active_high_idx].label == LB_LH) || (current_trend == TREND_BEAR);

            int anchor_idx = active_low_idx;
            if(anchor_idx < 0 || anchor_idx >= active_high_idx)
              {
               for(int k = active_high_idx - 1; k >= 0; k--)
                 {
                  if(swings[k].type == SW_LOW)
                    {
                     anchor_idx = k;
                     break;
                    }
                 }
              }

            SBreakEvent ev;
            ev.break_bar     = b;
            ev.swing_bar     = swings[active_high_idx].bar_idx;
            ev.anchor_bar    = (anchor_idx >= 0) ? swings[anchor_idx].bar_idx : swings[active_high_idx].bar_idx;
            ev.is_bullish    = true;
            ev.is_choch      = is_choch;
            ev.level         = target_h;
            ev.anchor_level  = (anchor_idx >= 0) ? swings[anchor_idx].price : target_h;
            ev.t_start       = swings[active_high_idx].time;
            ev.t_end         = Rates[b].time;

            int cnt = ArraySize(events);
            ArrayResize(events, cnt + 1);
            events[cnt] = ev;

            current_trend   = TREND_BULL;
            active_high_idx = -1;
           }
        }

      if(active_low_idx >= 0)
        {
         double target_l = swings[active_low_idx].price;
         bool broken_l = InpUseCloseForBreak ? (Rates[b].close < target_l) : (Rates[b].low < target_l);

         if(broken_l && b > swings[active_low_idx].bar_idx)
           {
            bool is_choch = (swings[active_low_idx].label == LB_HL) || (current_trend == TREND_BULL);

            int anchor_idx = active_high_idx;
            if(anchor_idx < 0 || anchor_idx >= active_low_idx)
              {
               for(int k = active_low_idx - 1; k >= 0; k--)
                 {
                  if(swings[k].type == SW_HIGH)
                    {
                     anchor_idx = k;
                     break;
                    }
                 }
              }

            SBreakEvent ev;
            ev.break_bar     = b;
            ev.swing_bar     = swings[active_low_idx].bar_idx;
            ev.anchor_bar    = (anchor_idx >= 0) ? swings[anchor_idx].bar_idx : swings[active_low_idx].bar_idx;
            ev.is_bullish    = false;
            ev.is_choch      = is_choch;
            ev.level         = target_l;
            ev.anchor_level  = (anchor_idx >= 0) ? swings[anchor_idx].price : target_l;
            ev.t_start       = swings[active_low_idx].time;
            ev.t_end         = Rates[b].time;

            int cnt = ArraySize(events);
            ArrayResize(events, cnt + 1);
            events[cnt] = ev;

            current_trend  = TREND_BEAR;
            active_low_idx = -1;
           }
        }
     }

   final_trend = current_trend;
  }

void DetectFiboRetestSignals(const SBreakEvent &events[], SFiboSignal &signals[])
  {
   ArrayResize(signals, 0);
   int event_cnt = ArraySize(events);

   for(int i = 0; i < event_cnt; i++)
     {
      if(!events[i].is_choch)
         continue;

      double p_0   = events[i].anchor_level; // 0.0%
      double p_100 = events[i].level;        // 100.0%
      double p_50  = p_0 + (p_100 - p_0) * 0.50; // 50% level

      for(int b = events[i].break_bar + 1; b < BarsCount; b++)
        {
         if(events[i].is_bullish)
           {
            if(Rates[b].low <= p_50)
              {
               SFiboSignal sig;
               sig.bar_idx       = b;
               sig.time          = Rates[b].time;
               sig.price         = Rates[b].low;
               sig.is_buy        = true;
               sig.fibo_50_level = p_50;

               int sc = ArraySize(signals);
               ArrayResize(signals, sc + 1);
               signals[sc] = sig;
               break;
              }
           }
         else
           {
            if(Rates[b].high >= p_50)
              {
               SFiboSignal sig;
               sig.bar_idx       = b;
               sig.time          = Rates[b].time;
               sig.price         = Rates[b].high;
               sig.is_buy        = false;
               sig.fibo_50_level = p_50;

               int sc = ArraySize(signals);
               ArrayResize(signals, sc + 1);
               signals[sc] = sig;
               break;
              }
           }
        }
     }
  }

void DetectCHoCHFVGs(const SBreakEvent &events[], SFVGZone &fvgs[])
  {
   ArrayResize(fvgs, 0);
   int event_cnt = ArraySize(events);

   for(int i = 0; i < event_cnt; i++)
     {
      if(!events[i].is_choch)
         continue;

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

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

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

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

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

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

Стоимость полного кода
2 125,20₽ ≈ $25.98