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

cfvgclosedbarengine (1).mq5

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

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

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

О программе

CFVGClosedBarEngine — это индикатор для MetaTrader 5, предназначенный для обнаружения и визуализации Fair Value Gap (FVG) на ценовых графиках. Индикатор реализует трёхбарную методику обнаружения дисбалансов, используя только закрытые бары, что исключает перерисовку при формировании текущего бара.

Для каждого обнаруженного разрыва индикатор отрисовывает прямоугольник на графике и опционально линию Consequent Encroachment (CE) на уровне 50% от разрыва. Доступны четыре режима отображения смягчённых разрывов: усечение до барьера заполнения, удаление, затемнение или сохранение полного размера.

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

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

НастройкаОписание
InpLookbackBars Количество баров назад от текущего момента, которые сканируются при загрузке индикатора на график.
InpMinGapPoints Минимальный размер разрыва в пунктах для его обнаружения. Значение 0 означает автоматический определение минимума.
InpMitigationMode Режим отображения разрыва после его заполнения: усечение прямоугольника до барьера заполнения, удаление прямоугольника, затемнение или сохранение без изменений.
InpShowBullish Включает или отключает обнаружение и отображение бычьих разрывов FVG.
InpShowBearish Включает или отключает обнаружение и отображение медвежьих разрывов FVG.
InpShowCE Включает или отключает отображение линии Consequent Encroachment (50% уровня разрыва) для каждого обнаруженного разрыва.
InpExtendBars Количество баров вправо, на которые продлевается отображение открытого разрыва от момента его создания.
InpAlertTouch Включает или отключает уведомление при первом касании ценой открытого разрыва. Уведомление срабатывает один раз для каждого разрыва.
InpAuditDepth Задаёт количество закрытых баров, которые перепроверяются при загрузке на график для контроля согласованности уровней разрывов. Значение 0 отключает самопроверку.
InpBullBorder Цвет границы прямоугольника бычьего разрыва.
InpBullFill Цвет заливки прямоугольника бычьего разрыва.
InpBullCE Цвет линии Consequent Encroachment для бычьего разрыва.
InpBearBorder Цвет границы прямоугольника медвежьего разрыва.
InpBearFill Цвет заливки прямоугольника медвежьего разрыва.
InpBearCE Цвет линии Consequent Encroachment для медвежьего разрыва.
InpDimBorder Цвет границы затемнённого прямоугольника разрыва в режиме смягчения DIM.
InpDimFill Цвет заливки затемнённого прямоугольника разрыва в режиме смягчения DIM.
Получить полный код

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

#property version     "1.10"
#property description "Non-repainting three-bar Fair Value Gap engine with Consequent Encroachment."
#property indicator_chart_window
#property indicator_plots 0

enum ENUM_MITIGATION_MODE
  {
   MITIGATION_TRIM,    // Shorten the rectangle to the mitigation bar
   MITIGATION_DELETE,  // Remove the rectangle once the gap is filled
   MITIGATION_DIM,     // Keep it visible but greyed out
   MITIGATION_NONE     // Leave the rectangle at full length
  };

input int                  InpLookbackBars   = 300;               // Bars scanned on attach
input double               InpMinGapPoints   = 0.0;               // Minimum gap size in points (0 = auto)
input ENUM_MITIGATION_MODE InpMitigationMode = MITIGATION_TRIM;   // Mitigation presentation
input bool                 InpShowBullish    = true;              // Detect bullish FVGs
input bool                 InpShowBearish    = true;              // Detect bearish FVGs
input bool                 InpShowCE         = true;              // Draw the 50% Consequent Encroachment
input int                  InpExtendBars     = 20;                // Forward extension of open gaps (bars)
input bool                 InpAlertTouch     = true;              // Alert the first time price enters a gap

input int                  InpAuditDepth     = 50;                // Closed bars re-checked on attach (0 = off)

input color                InpBullBorder     = clrMediumSeaGreen;
input color                InpBullFill       = C'220,245,230';
input color                InpBullCE         = clrSeaGreen;
input color                InpBearBorder     = clrIndianRed;
input color                InpBearFill       = C'255,230,230';
input color                InpBearCE         = clrFireBrick;
input color                InpDimBorder      = clrLightGray;
input color                InpDimFill        = C'235,235,235';

struct SFvgRecord
  {
   bool        bullish;          // Direction of the imbalance
   int         impulseIndex;     // Bar index of the third bar, which completed the gap
   datetime    impulseTime;      // Open time of the middle (impulse) bar, one bar before it
   datetime    startTime;        // Open time of the bar before the impulse
   double      top;              // Upper price edge of the gap
   double      bottom;           // Lower price edge of the gap
   double      ce;               // Consequent Encroachment (midpoint)
   bool        mitigated;        // State machine flag
   datetime    mitigatedTime;    // When it was first touched
   bool        alertFired;       // Guard so we alert only once per gap
   datetime    lastWarnBar;      // Bar on which a provisional warning was shown
   string      boxName;          // Chart object holding the rectangle
   string      ceName;           // Chart object holding the midpoint line
  };

SFvgRecord g_fvg[];      // All gaps currently tracked
int        g_count    = 0; // Number of valid entries in g_fvg
int        g_nextIdx  = 0; // Next bar index to test for a new gap
int        g_scannedLo = 0;// Oldest bar index actually scanned
datetime   g_lastBar  = 0; // Bar time processed by the last incremental pass
datetime   g_firstBar = 0; // Oldest bar on the chart, used to detect a rebuild

const string OBJ = "cfvg_";

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

void OnDeinit(const int reason)
  {
   ObjectsDeleteAll(0, OBJ);
   ChartRedraw();
  }

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[])
  {
      // код доступен только после оплаты
   }

void RebuildAll(const int total,
                const datetime &time[],
                const double &high[],
                const double &low[])
  {
   ObjectsDeleteAll(0, OBJ);
   ArrayResize(g_fvg, 0);
   g_count     = 0;
   g_nextIdx   = MathMax(2, total - InpLookbackBars);
   g_scannedLo = g_nextIdx;

   const int lastClosed = total - 2;

   for(int i = g_nextIdx; i <= lastClosed; i++)
      TryAddGap(i, total, time, high, low);

   g_nextIdx = lastClosed + 1;

   const datetime rightEdge = (datetime)(time[total - 1] + PeriodSeconds() * InpExtendBars);
   for(int g = 0; g < g_count; g++)
      ExtendObject(g_fvg[g], rightEdge);

   ChartRedraw();
  }

void ExtendScan(const int total,
                const datetime &time[],
                const double &high[],
                const double &low[])
  {
   const int lastClosed = total - 2;

   for(int i = g_nextIdx; i <= lastClosed; i++)
      TryAddGap(i, total, time, high, low);

   g_nextIdx = total - 1;

   for(int g = 0; g < g_count; g++)
     {
      if(g_fvg[g].mitigated)
         continue;

      if(g_fvg[g].impulseIndex >= lastClosed)
         continue;
      if(IsTouched(g_fvg[g], low[lastClosed], high[lastClosed]))
        {
         g_fvg[g].mitigated     = true;
         g_fvg[g].mitigatedTime = time[lastClosed];
         OnMitigated(g, time[lastClosed]);
        }
     }

   const datetime rightEdge = (datetime)(time[total - 1] + PeriodSeconds() * InpExtendBars);
   for(int g = 0; g < g_count; g++)
      ExtendObject(g_fvg[g], rightEdge);

   ChartRedraw();
  }

void TryAddGap(const int i,
               const int total,
               const datetime &time[],
               const double &high[],
               const double &low[])
  {
   const double minGap = InpMinGapPoints * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
   const int    lastClosed = total - 2;

   if(InpShowBullish)
     {
      const double bottom = high[i - 2];
      const double top    = low[i];

      if(top > bottom && (top - bottom) >= minGap)
        {
         const int idx = AddRecord(true, i, time[i - 1], time[i - 2], top, bottom);
         ReplayMitigation(idx, i, time, low, high, lastClosed);
        }
     }

   if(InpShowBearish)
     {
      const double top    = low[i - 2];
      const double bottom = high[i];

      if(bottom < top && (top - bottom) >= minGap)
        {
         const int idx = AddRecord(false, i, time[i - 1], time[i - 2], top, bottom);
         ReplayMitigation(idx, i, time, low, high, lastClosed);
        }
     }
  }

int AddRecord(const bool bullish,
              const int impulseIndex,
              const datetime impulseTime,
              const datetime startTime,
              const double top,
              const double bottom)
  {
   SFvgRecord rec;
   rec.bullish       = bullish;
   rec.impulseIndex  = impulseIndex;
   rec.impulseTime   = impulseTime;
   rec.startTime     = startTime;
   rec.top           = top;
   rec.bottom        = bottom;
   rec.ce            = bottom + (top - bottom) * 0.5;
   rec.mitigated     = false;
   rec.mitigatedTime = 0;
   rec.alertFired    = false;
   rec.boxName       = StringFormat("%sbox_%s_%I64d", OBJ, bullish ? "bull" : "bear", (long)impulseTime);
   rec.ceName        = StringFormat("%sce_%s_%I64d",  OBJ, bullish ? "bull" : "bear", (long)impulseTime);

   const int idx = g_count++;
   ArrayResize(g_fvg, g_count);
 

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

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

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

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

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

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

Стоимость полного кода
1 084₽ ≈ $13.38