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

Divergence Panel

divergencepanel.mq5

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

key trading system.mq5MQL5 / MetaTrader 5 · 1 общих тегов#momentum onchartsignals indicator v2.0.mq5MQL5 / MetaTrader 5 · 1 общих тегов#momentum onchartsignals indicator v1.0.mq5MQL5 / MetaTrader 5 · 1 общих тегов#dtosc 2.06 + bells&whistles nmc.mq5MQL5 / MetaTrader 5 · 1 общих теговfiborsi8_singleshot_mt4_v124.mq4MQL4 / MetaTrader 4 · 1 общих теговindicator candle pressure flip engine for tradingview.pineTradingView · 1 общих тегов
Вы автор или правообладатель?

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

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

О программе

DivergencePanel — пользовательский индикатор для MetaTrader 5, отображающий панель дивергенций по нескольким таймфреймам. Панель строится в окне графика и содержит по одной строке на каждый таймфрейм (M1, M5, M15, M30, H1, H4, D1, W1, MN1) и шесть столбцов: пять закрытых бар и текущий бар. В каждой ячейке отображаются квадраты, соответствующие включённым осцилляторам: зелёный цвет означает бычью дивергенцию, красный — медвежью, пустой цвет — отсутствие сигнала.

Индикатор рассчитывает набор технических осцилляторов (MACD, гистограмма MACD, RSI, Stochastic, CCI, Momentum, OBV, VWMACD, CMF, MFI) на каждом из девяти таймфреймов. Для каждого осциллятора выполняется поиск дивергенций относительно пивотов, определяемых по ценам закрытия или по теням свечей. Поддерживаются регулярные и скрытые дивергенции. Отображение сигналов следует правилу замены: более новый сигнал того же направления заменяет предыдущий, если между ними не сформировался новый пивот соответствующей стороны.

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

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

НастройкаОписание
SepPivots Разделитель группы настроек поиска пивотов и дивергенций.
InpSpan Количество бар слева и справа от бара, необходимое для подтверждения пивота.
InpSource Источник для определения пивотов: цены закрытия или тени свечей.
InpKinds Тип отображаемых дивергенций: регулярные, скрытые или оба типа.
InpMinCount Минимальное количество дивергенций на баре, необходимое для отображения сигнала.
InpMaxPivots Максимальное количество пивотов, проверяемых в обратном направлении при поиске дивергенций.
InpMaxReach Максимальное количество бар, проверяемых в обратном направлении при поиске дивергенций.
InpConfirm Если включено, сигнал на закрытом баре подтверждается только после закрытия следующего бара; текущий бар не влияет на закрытые столбцы.
InpLastOnly Если включено, сохраняется только последняя дивергенция каждого направления, как на графическом индикаторе.
InpBars Количество бар, загружаемых для каждого таймфрейма при расчёте.
SepOsc Разделитель группы настроек выбора осцилляторов.
InpUseMacd Включает использование осциллятора MACD при поиске дивергенций.
InpUseHist Включает использование гистограммы MACD при поиске дивергенций.
InpUseRsi Включает использование осциллятора RSI при поиске дивергенций.
InpUseStoch Включает использование осциллятора Stochastic при поиске дивергенций.
InpUseCci Включает использование осциллятора CCI при поиске дивергенций.
InpUseMom Включает использование осциллятора Momentum при поиске дивергенций.
InpUseObv Включает использование осциллятора OBV при поиске дивергенций.
InpUseVwmacd Включает использование осциллятора VWMACD при поиске дивергенций.
InpUseCmf Включает использование осциллятора CMF при поиске дивергенций.
InpUseMfi Включает использование осциллятора MFI при поиске дивергенций.
SepPanel Разделитель группы настроек внешнего вида панели.
InpX Горизонтальное смещение панели от левого верхнего угла графика.
InpY Вертикальное смещение панели от левого верхнего угла графика.
InpSquare Размер стороны квадрата в пикселях.
InpGap Расстояние между квадратами внутри ячейки.
InpFontSize Размер шрифта текстовых элементов панели.
InpEmptySlots Если включено, пустые квадраты отображаются на панели; иначе они скрыты.
InpShowBg Если включено, отображается фон панели с рамкой и чередующимися полосами.
InpBullColor Цвет квадратов, обозначающих бычью дивергенцию.
InpBearColor Цвет квадратов, обозначающих медвежью дивергенцию.
InpEmptyColor Цвет пустых квадратов, не содержащих сигнала.
InpBgColor Цвет фона панели.
InpBorderColor Цвет рамки и разделительных линий панели.
InpStripeColor Цвет чередующихся полос фона строк панели.
InpTitleColor Цвет заголовка панели.
InpTextColor Цвет основного текста панели, например названий таймфреймов и заголовков столбцов.
InpAccentColor Цвет акцентных элементов панели, например заголовка текущего бара и выделения текущего таймфрейма.
Получить полный код

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

#property version   "1.20"

#property description "Divergence Panel - same engine and display rules as MultiIndicatorDivergence"

#property strict

#property indicator_chart_window

enum ENUM_PIVOT_SOURCE { PIVOT_CLOSE, PIVOT_WICKS };

enum ENUM_DIV_KINDS    { KINDS_REGULAR, KINDS_HIDDEN, KINDS_BOTH };

input string SepPivots = "------------";

input int               InpSpan      = 5;             // pivot period, bars on each side

input ENUM_PIVOT_SOURCE InpSource    = PIVOT_CLOSE;   // pivot source

input ENUM_DIV_KINDS    InpKinds     = KINDS_REGULAR; // divergence type

input int               InpMinCount  = 1;             // minimum divergences on a bar

input int               InpMaxPivots = 10;            // pivots checked back

input int               InpMaxReach  = 100;           // bars checked back

input bool              InpConfirm   = true;          // wait for the next bar to confirm

input bool              InpLastOnly  = false;         // keep only the latest divergence (same as the chart indicator)

input int               InpBars      = 1200;          // bars loaded per timeframe

input string SepOsc = "------------";

input bool InpUseMacd   = true;

input bool InpUseHist   = true;

input bool InpUseRsi    = true;

input bool InpUseStoch  = true;

input bool InpUseCci    = true;

input bool InpUseMom    = true;

input bool InpUseObv    = true;

input bool InpUseVwmacd = true;

input bool InpUseCmf    = true;

input bool InpUseMfi    = true;

input string SepPanel = "------------";

input int   InpX          = 8;

input int   InpY          = 18;

input int   InpSquare     = 7;

input int   InpGap        = 2;

input int   InpFontSize   = 8;

input bool  InpEmptySlots = true;

input bool  InpShowBg     = true;

input color InpBullColor  = C'0,214,143';

input color InpBearColor  = C'255,82,82';

input color InpEmptyColor = C'52,56,66';

input color InpBgColor    = C'22,25,31';

input color InpBorderColor= C'62,67,80';

input color InpStripeColor= C'30,34,42';

input color InpTitleColor = C'235,238,245';

input color InpTextColor  = C'150,157,172';

input color InpAccentColor= C'255,196,61';

#define OSCILLATORS  10

#define KINDS        4

#define PIVOT_SLOTS  20

#define MIN_REACH    5

#define NO_VALUE     DBL_MAX

#define WARMUP       400

#define BULL_REGULAR 0

#define BEAR_REGULAR 1

#define BULL_HIDDEN  2

#define BEAR_HIDDEN  3

#define TFS          9

#define SLOTS        10

#define COLS         6

#define PAD          8

#define COL_GAP      12

#define TAG          "DP_"

int    g_tfs[TFS]     = {PERIOD_M1,PERIOD_M5,PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4,PERIOD_D1,PERIOD_W1,PERIOD_MN1};

string g_tfNames[TFS] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN1"};

struct ScanRules {

   int  span;

   bool wicks;

   bool regular;

   bool hidden;

   int  maxPivots;

   int  maxReach;

   bool liveBar;

   bool lastOnly;

   int  minCount;

   bool enabled[OSCILLATORS];

};

struct PivotStack {

   int    bar[PIVOT_SLOTS];

   double level[PIVOT_SLOTS];

   int    count;

};

struct Pivots {

   PivotStack highs;

   PivotStack lows;

};

double g_emaFast[], g_emaSlow[], g_macd[], g_signal[], g_hist[];

double g_gain[], g_loss[], g_rsi[], g_rawK[], g_stoch[];

double g_cci[], g_mom[], g_obv[], g_vwmacd[], g_cmf[], g_mfi[];

double g_high[], g_low[], g_close[];

long   g_vol[];

ScanRules g_rules;

int       g_state[TFS][COLS][SLOTS];

bool      g_pending = false;

double MeanAt(const double &v[], const int i, const int n, const int first) {

   if(i-n+1 < first) return(NO_VALUE);

   double sum = 0;

   for(int k = i-n+1; k <= i; k++) {

      if(v[k] == NO_VALUE) return(NO_VALUE);

      sum += v[k];

   }

   return(sum / n);

}

double EmaAt(const double &src[], const double &dst[], const int i, const int n, const int first) {

   if(src[i] == NO_VALUE) return(NO_VALUE);

   if(i > first && dst[i-1] != NO_VALUE) {

      double alpha = 2.0 / (n + 1);

      return(alpha * src[i] + (1 - alpha) * dst[i-1]);

   }

   return(MeanAt(src, i, n, first));

}

void MacdAt(const double &close[], double &fast[], double &slow[], double &line[],

            double &signal[], double &hist[], const int i, const int first) {

   fast[i] = EmaAt(close, fast, i, 12, first);

   slow[i] = EmaAt(close, slow, i, 26, first);

   line[i] = (fast[i] == NO_VALUE || slow[i] == NO_VALUE) ? NO_VALUE : fast[i] - slow[i];

   signal[i] = EmaAt(line, signal, i, 9, first);

   hist[i] = (signal[i] == NO_VALUE) ? NO_VALUE : line[i] - signal[i];

}

void RsiAt(const double &close[], double &gain[], double &loss[], double &rsi[],

           const int i, const int first) {

   const int n = 14;

   gain[i] = NO_VALUE;

   loss[i] = NO_VALUE;

   rsi[i] = NO_VALUE;

   if(i-1 < first) return;

   double up = MathMax(close[i] - close[i-1], 0.0);

   double down = MathMax(close[i-1] - close[i], 0.0);

   if(gain[i-1] != NO_VALUE) {

      gain[i] = (up + (n-1)*gain[i-1]) / n;

      loss[i] = (down + (n-1)*loss[i-1]) / n;

   } else {

      if(i-n < first) return;

      double sumUp = 0, sumDown = 0;

      for(int k = i-n+1; k <= i; k++) {

         sumUp += MathMax(close[k] - close[k-1], 0.0);

         sumDown += MathMax(close[k-1] - close[k], 0.0);

      }

      gain[i] = sumUp / n;

      loss[i] = sumDown / n;

   }

   if(loss[i] == 0) rsi[i] = (gain[i] > 0) ? 100 : NO_VALUE;

   else rsi[i] = 100 - 100 / (1 + gain[i]/loss[i]);

}

void StochAt(const double &high[], const double &low[], const double &close[], double &raw[],

             double &smooth[], const int i, const int first) {

   raw[i] = NO_VALUE;

   if(i-13 >= first) {

      double top = high[i], bottom = low[i];

      for(int k = i-13; k < i; k++) {

         top = MathMax(top, high[k]);

         bottom = MathMin(bottom, low[k]);

      }

      if(top > bottom) raw[i] = 100 * (close[i] - bottom) / (top - bottom);

   }

   smooth[i] = MeanAt(raw, i, 3, first);

}

double CciAt(const double &close[], const int i, const int first) {

   double mean = MeanAt(close, i, 10, first);

   if(mean == NO_VALUE) return(NO_VALUE);

   double dev = 0;

   for(int k = i-9; k <= i; k++) dev += MathAbs(close[k] - mean);

   dev /= 10;

   return(dev > 0 ? (close[i] - mean) / (0.015 * dev) : NO_VALUE);

}

double MomentumAt(const double &close[], const int i, const int first) {

   return(i-10 >= first ? close[i] - close[i-10] : NO_VALUE);

}

double ObvAt(const double &close[], const long &volume[], const double &obv[], const int i, const int first) {

   if(i <= first || obv[i-1] == NO_VALUE) return(0);

   double move = close[i] - close[i-1];

   double sign = (move > 0) ? 1 : (move < 0 ? -1 : 0);

   return(obv[i-1] + sign * (double)volume[i]);

}

double VwmaAt(const double &close[], const long &volume[], const int i, const int n, const int first) {

   if(i-n+1 < first) return(NO_VALUE);

   double weighted = 0, total = 0;

   for(int k = i-n+1; k <= i; k++) {

      weighted += close[k] * (double)volume[k];

      total += (double)volume[k];

   }

   return(total > 0 ? weighted / total : NO_VALUE);

}

double VwmacdAt(const double &close[], const long &volume[], const int i, const int first) {

   double fast = VwmaAt(close, volume, i, 12, first);

   double slow = VwmaAt(close, volume, i, 26, first);

   return((fast == NO_VALUE || slow == NO_VALUE) ? NO_VALUE : fast - slow);

}

double CmfAt(const double &high[], const double &low[], const double &close[], const long &volume[], const int i, const int first) {

   const int n = 21;

   if(i-n+1 < first) return(NO_VALUE);

   double flow = 0, total = 0;

   for(int k = i-n+1; k <= i; k++) {

      double range = high[k] - low[k];

      if(range <= 0) return(NO_VALUE);

      flow += ((close[k] - low[k]) - (high[k] - close[k])) / range * (double)volume[k];

      total += (double)volume[k];

   }

   return(total > 0 ? flow / total : NO_VALUE);

}

double MfiAt(const double &close[], const long &volume[], const int i, const int first) {

   const int n = 14;

   if(i-n < first) return(NO_VALUE);

   double rising = 0, falling = 0;

   for(int k = i-n+1; k <= i; k++) {

      double move = close[k] - close[k-1];

      if(move > 0) rising += (double)volume[k] * close[k];

      if(move < 0) falling += (double)volume[k] * close[k];

   }

   if(falling == 0) return(rising > 0 ? 100 : NO_VALUE);

   return(100 - 100 / (1 + rising / falling));

}

bool Beyond(const double b, const double a, const int dir) {

   if(b == NO_VALUE || a == NO_VALUE) return(false);

   return(dir > 0 ? b > a : b < a);

}

bool IsTurn(const double &v[], const int c, const int span, const int dir) {

   for(int k = 1; k <= span; k++) {

      if(dir * (v[c] - v[c-k]) <= 0) return(false);

      if(dir * (v[c] - v[c+k]) < 0) return(false);

   }

   return(true);

}

void PushPivot(PivotStack &stack, const int bar, const double level) {

   for(int k = MathMin(stack.count, PIVOT_SLOTS-1); k > 0; k--) {

      stack.bar[k] = stack.bar[k-1];

      stack.level[k] = stack.level[k-1];

   }

   stack.bar[0] = bar;

   stack.level[0] = level;

   stack.count = MathMin(stack.count + 1, PIVOT_SLOTS);

}

void TrackPivots(Pivots &pv, const int bar, bool &newTop, bool &newBottom) {

   newTop = false;

   newBottom = false;

   int c = bar - g_rules.span;

   if(c - g_rules.span < 0) return;

   newTop = g_rules.wicks ? IsTurn(g_high, c, g_rules.span, 1) : IsTurn(g_close, c, g_rules.span, 1);

   newBottom = g_rules.wicks ? IsTurn(g_low, c, g_rules.span, -1) : IsTurn(g_close, c, g_rules.span, -1);

   if(newTop) PushPivot(pv.highs, c, g_rules.wicks ? g_high[c] : g_close[c]);

   if(newBottom) PushPivot(pv.lows, c, g_rules.wicks ? g_low[c] : g_close[c]);

}

bool ClearPath(const double &osc[], const double &close[], const int bar, const int from, const int reach, const int dir) {

   double stepOsc = (osc[bar-from] - osc[bar-reach]) / (reach - from);

   double stepPx = (close[bar-from] - close[bar-reach]) / (reach - from);

   double lineOsc = osc[bar-from] - stepOsc;

   double linePx = close[bar-from] - stepPx;

   for(int k = from + 1; k < reach; k++) {

      if(Beyond(lineOsc, osc[bar-k], dir) || Beyond(linePx, close[bar-k], dir)) return(false);

      lineOsc -= stepOsc;

      linePx -= stepPx;

   }

   return(true);

}

int SeekPivot(const double &osc[], const double &close[], const double &probe[],

              const int bar, const PivotStack &stack, const int dir, const bool hidden) {

   if(!g_rules.liveBar && !Beyond(osc[bar], osc[bar-1], dir) && !Beyond(close[bar], close[bar-1], dir))

      return(0);

   int from = g_rules.liveBar ? 0 : 1;

   int end = bar - from;

   int depth = MathMin(g_rules.maxPivots, stack.count);

   for(int n = 0; n < depth; n++) {

      int reach = bar - stack.bar[n];

      if(reach > g_rules.maxReach) break;

      if(reach <= MIN_REACH) continue;

      int pivot = stack.bar[n];

      bool shape;

      if(hidden)

         shape = Beyond(osc[pivot], osc[end], dir) && Beyond(probe[end], stack.level[n], dir);

      else

         shape = Beyond(osc[end], osc[pivot], dir) && Beyond(stack.level[n], probe[end], dir);

      if(shape && ClearPath(osc, close, bar, from, reach, dir))

         return(reach);

   }

   return(0);

}

void ScanOsc(const double &osc[], const int bar, const Pivots &pv, int &found[]) {

   ArrayInitialize(found, 0);

   if(g_rules.wicks) {

      if(g_rules.regular) {

         found[BULL_REGULAR] = SeekPivot(osc, g_close, g_low, bar, pv.lows, 1, false);

         found[BEAR_REGULAR] = SeekPivot(osc, g_close, g_high, bar, pv.highs, -1, false);

      }

      if(g_rules.hidden) {

         found[BULL_HIDDEN] = SeekPivot(osc, g_close, g_low, bar, pv.lows, 1, true);

         found[BEAR_HIDDEN] = SeekPivot(osc, g_close, g_high, bar, pv.highs, -1, true);

      }

   } else {

      if(g_rules.regular) {

         found[BULL_REGULAR] = SeekPivot(osc, g_close, g_close, bar, pv.lows, 1, false);

         found[BEAR_REGULAR] = SeekPivot(osc, g_close, g_close, bar, pv.highs, -1, false);

      }

      if(g_rules.hidden) {

         found[BULL_HIDDEN] = SeekPivot(osc, g_close, g_close, bar, pv.lows, 1, true);

         found[BEAR_HIDDEN] = SeekPivot(osc, 

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

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

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

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

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

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

Стоимость полного кода
1 849,40₽ ≈ $22.68