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

orderblockdetector.mq5

Вы автор или правообладатель?

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

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

О программе

OrderBlockDetector — это пользовательский индикатор для MetaTrader 5, предназначенный для обнаружения и визуализации ордер-блоков на графике цен. Индикатор определяет свечные пивоты (локальные максимумы и минимумы), отслеживает пробой структуры и выявляет последнюю противоположную свечу перед импульсным движением, которое нарушает рыночную структуру.

Обнаруженные ордер-блоки отображаются в виде прямоугольных зон на графике. Зоны могут продлеваться в реальном времени до тех пор, пока цена не вернётся и не митигирует их. Индикатор поддерживает настройку цветов, стилей отрисовки, заливки и отображения меток с ценами зон.

Индикатор работает на закрытых барах для стабильности расчётов. Количество одновременно отслеживаемых ордер-блоков ограничивается настраиваемым параметром — при превышении лимита самые старые блоки удаляются. Доступны параметры минимального размера зоны, минимального процента тела свечи для импульса и расстояния пробоя уровня.

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

НастройкаОписание
InpSwingLookback Количество баров с каждой стороны для подтверждения свечного пивота
InpMinBreakPoints Минимальное расстояние пробоя за уровнем пивота (в очках)
InpMinImpulseBodyPercent Минимальный процент тела свечи от её диапазона для признания импульсной
InpMaxSearchBarsForOB Максимальное количество баров для поиска свечи ордер-блока назад от точки пробоя
InpUseBodyOnly Использовать только тело свечи для определения границ зоны, вместо полного диапазона с тенями
InpMinZoneSizePoints Минимальный размер зоны для отрисовки (в очках)
InpMaxOBsToTrack Максимальное количество ордер-блоков, сохраняемых на графике (самые старые удаляются первыми)
InpExtendUntilMitigated Продлевать прямоугольник зоны в реальном времени до момента, пока цена не митигирует ордер-блок
InpExtendBars Фиксированное продление зоны (в барах), используется только если не включено продление до митигации
InpRequireFullCloseForMitigation Требовать полное закрытие свечи внутри зоны для митигации, а не просто касание
InpHideMitigatedOBs Удалять прямоугольник ордер-блока после его митигации вместо изменения цвета
InpBullishOBColor Цвет бычьего ордер-блока
InpBearishOBColor Цвет медвежьего ордер-блока
InpMitigatedColor Цвет прямоугольника ордер-блока после его митигации
InpFillBox Заливать прямоугольник ордер-блока
InpBoxStyle Стиль границы прямоугольника ордер-блока
InpBoxWidth Толщина границы прямоугольника ордер-блока
InpShowLabels Отображать метку с ценой зоны ордер-блока
Получить полный код

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

#property version   "1.00"
#property description "Detects order blocks — the last opposing candle before an impulsive move "
#property description "that breaks market structure — and draws them as zones that extend live "
#property description "until price returns and mitigates them."
#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots   0
#property strict

input group "=== Structure Detection ==="
input int    InpSwingLookback          = 5;   // Swing Lookback (bars on each side to confirm a pivot)
input int    InpMinBreakPoints         = 30;  // Minimum Break Distance Beyond Swing Level (points)
input double InpMinImpulseBodyPercent  = 50.0; // Minimum Body-to-Range % for a Valid Impulse Candle
input int    InpMaxSearchBarsForOB     = 10;  // Max Bars Searched Back for the Order-Block Candle

input group "=== Order Block Zone ==="
input bool InpUseBodyOnly       = false; // Use Candle Body Only (instead of full wick range)
input int  InpMinZoneSizePoints = 30;    // Minimum Zone Size to Draw (points)
input int  InpMaxOBsToTrack     = 30;    // Maximum Order Blocks Kept on Chart (oldest removed first)

input group "=== Mitigation Behavior ==="
input bool InpExtendUntilMitigated          = true;  // Extend Box Live Until Price Mitigates It
input int  InpExtendBars                    = 40;    // Fixed Extension (bars) — used only if not extending until mitigated
input bool InpRequireFullCloseForMitigation = false;  // Require a Close Through the Zone (not just a touch)
input bool InpHideMitigatedOBs              = false;  // Delete a Block's Box Once Mitigated (instead of graying it out)

input group "=== Colors & Style ==="
input color InpBullishOBColor  = clrLime;    // Bullish Order Block Color
input color InpBearishOBColor  = clrRed;     // Bearish Order Block Color
input color InpMitigatedColor  = clrDimGray; // Color Once a Block Has Been Mitigated
input bool  InpFillBox         = true;       // Fill the Order Block Box
input ENUM_LINE_STYLE InpBoxStyle = STYLE_SOLID; // Box Border Style
input int   InpBoxWidth        = 1;          // Box Border Width
input bool  InpShowLabels      = true;       // Show a Label With the Zone Price

string g_Prefix = "OB_";

int    g_ObFormIndex[]; // bar index of the order-block candle itself
double g_ObTop[];
double g_ObBottom[];
bool   g_ObBullish[];
bool   g_ObMitigated[];
string g_ObName[];
int    g_ObCount = 0;

double g_PendingHighPrice = 0.0;
int    g_PendingHighIndex = -1;
bool   g_PendingHighValid = false;

double g_PendingLowPrice = 0.0;
int    g_PendingLowIndex = -1;
bool   g_PendingLowValid = false;

int g_LastConfirmedPivotIndex = -1; // last bar index already checked for a new swing pivot
int g_LastProcessedIndex      = -1; // last closed bar index already checked for breaks/mitigation

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

void OnDeinit(const int reason)
  {

   ObjectsDeleteAll(0, g_Prefix);
   ChartRedraw(0);
  }

void ResetState()
  {
   ObjectsDeleteAll(0, g_Prefix);

   g_ObCount = 0;
   ArrayResize(g_ObFormIndex, 0);
   ArrayResize(g_ObTop, 0);
   ArrayResize(g_ObBottom, 0);
   ArrayResize(g_ObBullish, 0);
   ArrayResize(g_ObMitigated, 0);
   ArrayResize(g_ObName, 0);

   g_PendingHighValid = false;
   g_PendingLowValid  = false;

   g_LastConfirmedPivotIndex = InpSwingLookback - 1;
   g_LastProcessedIndex      = -1;
  }

int OnCalculate(const int rates_total,
                 const int prev_calculated,
                 const datetime &time[],
                 const double &open[],
                 const double &high[],
                 const double &low[],
                 const double &close[],
                 const long &tick_volume[],
                 const long &volume[],
                 const int &spread[])
  {
      // код доступен только после оплаты
   }

   if(rates_total < 2 * InpSwingLookback + 3)
      return(0);

   if(prev_calculated == 0)
      ResetState();

   int confirmIndex = rates_total - 1 - InpSwingLookback;

   for(int i = g_LastConfirmedPivotIndex + 1; i <= confirmIndex; i++)
     {
      if(i - InpSwingLookback < 0)
         continue;

      if(IsSwingHigh(i, high))
        {
         g_PendingHighPrice = high[i];
         g_PendingHighIndex = i;
         g_PendingHighValid = true;
        }

      if(IsSwingLow(i, low))
        {
         g_PendingLowPrice = low[i];
         g_PendingLowIndex = i;
         g_PendingLowValid = true;
        }
     }

   if(confirmIndex > g_LastConfirmedPivotIndex)
      g_LastConfirmedPivotIndex = confirmIndex;

   int lastClosedIndex = rates_total - 2;

   for(int j = g_LastProcessedIndex + 1; j <= lastClosedIndex; j++)
     {

      for(int L = 0; L < g_ObCount; L++)
        {
         if(g_ObMitigated[L])
            continue;
         if(g_ObFormIndex[L] >= j)
            continue; // the block must already exist before the bar being checked

         CheckMitigation(L, j, time, high, low, close);
        }

      if(g_PendingHighValid && (close[j] - g_PendingHighPrice) >= InpMinBreakPoints * _Point)
        {
         if(BodyPercent(j, open, high, low, close) >= InpMinImpulseBodyPercent)
           {
            int searchFloor = MathMax(g_PendingHighIndex, j - InpMaxSearchBarsForOB);
            int obIdx = FindLastDownCandle(j, searchFloor, open, close);
            if(obIdx != -1)
               TryAddOrderBlock(obIdx, j, time, open, high, low, close, true);
           }
         g_PendingHighValid = false; // the level is broken either way — consumed
        }

      if(g_PendingLowValid && (g_PendingLowPrice - close[j]) >= InpMinBreakPoints * _Point)
        {
         if(BodyPercent(j, open, high, low, close) >= InpMinImpulseBodyPercen

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

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

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

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

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

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

Стоимость полного кода
944,80₽ ≈ $11.55