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

sensible guide confluence.mq5

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

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

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

О программе

Индикатор «Sensible Guide Confluence» — это инструмент мультитаймфреймного анализа для графика M1 в MetaTrader 5. Он использует временные горизонты H4, D1 и W1 для подтверждения трендов и поиска точек пересечения уровней поддержки и сопротивления на часовом графике.

Индикатор рассчитывает пять скользящих средних EMA, индикатор ATR и полосы Боллинджера на рабочем таймфрейме, а также загружает данные с более высоких таймфреймов (EMA, свинги, уровни Фибоначчи, предыдущий дневной максимум/минимум). На основании совпадения нескольких видов уровней формируются стрелки BUY/SELL с расчётом уровней Stop Loss и Take Profit.

Встроена система фильтрации: требование направления тренда H1, мультитаймфреймный фильтр тренда, фильтр торговой сессии, ограничение по размеру свечи и пауза между сигналами. Поддерживаются уведомления (pop-up, push, email), отрисовка зон и линий сделки, а также режим отладки с выводом статистики сканирования в лог.

Сигналы формируются только по закрытым свечам. Индикатор предназначен для образовательных целей.

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

НастройкаОписание
InpEMA1 Период первой EMA на рабочем таймфрейме.
InpEMA2 Период второй EMA на рабочем таймфрейме.
InpEMA3 Период третьей EMA на рабочем таймфрейме; также используется как уровень поддержки/сопротивления.
InpEMA4 Период четвёртой EMA на рабочем таймфрейме; также используется как уровень поддержки/сопротивления.
InpEMA5 Период пятой EMA на рабочем таймфрейме; также используется как уровень поддержки/сопротивления.
InpRequireTrend Разрешает сигналы только в направлении тренда H1.
InpMinTrend Минимальный баланс тренда H1 (количество согласованных пар EMA из 4 возможных).
InpTF_A Временной горизонт A — используется для подтверждения (EMA + свинги).
InpTF_B Временной горизонт B — используется для скрининга (EMA + свинги + Фибоначчи + направление рынка).
InpTF_C Временной горизонт C — макро-анализ (EMA + свинги + направление рынка).
InpTF_D Временной горизонт D — используется для определения предыдущего дневного максимума/минимума.
InpHTF_EMA1 Период первой EMA на более высоком таймфрейме.
InpHTF_EMA2 Период второй EMA на более высоком таймфрейме.
InpHTF_EMA3 Период третьей EMA на более высоком таймфрейме.
InpHTFSwingStr Минимальная сила свинга на более высоких таймфреймах (количество баров с каждой стороны).
InpHTFSwings Количество последних свингов, учитываемых на каждом более высоком таймфрейме.
InpFibBars Количество баров на таймфрейме B для поиска свинг-диапазона расчёта уровней Фибоначчи.
InpFibMinATR Минимальное движение цены для расчёта уровней Фибоначчи, выраженное в кратности ATR H1.
InpMTFMode Режим фильтрации тренда по более высоким таймфреймам: выключен, без контр-тренда или согласование с трендом.
InpHTFBars Количество баров истории для загрузки с каждого более высокого таймфрейма.
InpBlockOnMissingData Блокирует сигналы, если данные на более высоких таймфреймах недоступны.
InpRoundPips Шаг круглых ценовых уровней в пунктах.
InpSwingStr Сила свинга на рабочем таймфрейме — количество баров с каждой стороны для подтверждения свинга.
InpSwingBack Глубина поиска свингов на рабочем таймфрейме в барах (примерно 10 дней при M1).
InpBBPeriod Период расчёта индикатора полос Боллинджера.
InpBBDev Количество отклонений для расчёта полос Боллинджера.
InpZoneATR Ширина зоны поддержки/сопротивления в кратности ATR.
InpMinKinds Минимальное общее количество совпадающих видов уровней поддержки/сопротивления для формирования сигнала.
InpMinHTFKinds Минимальное количество видов уровней поддержки/сопротивления, которые должны приходиться с более высоких таймфреймов.
InpMinCandleATR Минимальный размер свечи в кратности ATR для рассмотрения как кандидата на сигнал.
InpCooldown Пауза в свечах H1 между последовательными сигналами.
InpATRPeriod Период расчёта индикатора ATR на рабочем таймфрейме.
InpStopATRPct Минимальное расстояние стоп-лосса в процентах от ATR.
InpMaxStopATR Максимально допустимое расстояние стоп-лосса в кратности ATR.
InpMinRRR Минимальное требуемое соотношение прибыли к риску после учёта спреда.
InpTargetKinds Требуемое количество совпадающих видов уровней поддержки/сопротивления для подтверждения цели (Take Profit).
InpMaxTPATR Максимальное расстояние до цели (Take Profit) в кратности ATR.
InpTPBufferATR Смещение тейк-профита в сторону от уровня в кратности ATR.
InpMaxSpreadRatio Максимальное значение спреда как доля от стоп-лосса (0 — отключено).
InpSessionOn Включает фильтр торговой сессии по серверному времени брокера.
InpSessionStartH Начальный час торговой сессии (включительно) по серверному времени брокера.
InpSessionEndH Конечный час торговой сессии (исключительно) по серверному времени брокера.
InpMaxBars Количество баров истории, подлежащих анализу.
InpShowZones Включает отрисовку зон поддержки/сопротивления на графике.
InpMaxZones Максимальное количество отображаемых зон поддержки/сопротивления на графике.
InpZoneBars Длина зоны поддержки/сопротивления в барах.
InpShowTradeLines Отображает линии входа, стоп-лосса и тейк-профита последнего сигнала на графике.
InpAlert Включает всплывающее уведомление при появлении нового сигнала.
InpPush Включает отправку push-уведомлений при появлении сигнала.
InpEmail Включает отправку уведомлений по электронной почте при появлении сигнала.
InpDebug Выводит статистику сканирования и фильтрации в журнал Expert Advisor.
Получить полный код

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

#property version     "2.00"
#property description "Multi-timeframe confluence (H4/D1/W1) for H1. BUY/SELL arrows."
#property description "Signals on closed bars only. For educational purposes only."
#property indicator_chart_window
#property indicator_buffers 12
#property indicator_plots   2

#property indicator_label1  "Buy"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrLime
#property indicator_width1  3
#property indicator_label2  "Sell"
#property indicator_type2   DRAW_ARROW
#property indicator_color2  clrRed
#property indicator_width2  3

enum ENUM_MTF_MODE
{
   MTF_OFF        = 0,   // Off
   MTF_NO_COUNTER = 1,   // No counter-trend on TF B and TF C
   MTF_ALIGNED    = 2    // Aligned with the trend on TF B and TF C
};

input group "=== Trend H1 (EMA alignment; EMAs are not drawn) ==="
input int    InpEMA1         = 10;     // EMA 1
input int    InpEMA2         = 20;     // EMA 2
input int    InpEMA3         = 50;     // EMA 3 (also S/R)
input int    InpEMA4         = 100;    // EMA 4 (also S/R)
input int    InpEMA5         = 200;    // EMA 5 (also S/R)
input bool   InpRequireTrend = true;   // Signals only in the direction of the H1 trend
input int    InpMinTrend     = 3;      // Minimum H1 trend score (0-4 aligned pairs)

input group "=== Multi-timeframe (PERIOD_CURRENT = disabled) ==="
input ENUM_TIMEFRAMES InpTF_A = PERIOD_H4;   // TF A: confirmation (EMAs + swings)
input ENUM_TIMEFRAMES InpTF_B = PERIOD_D1;   // TF B: screening (EMAs + swings + Fib + bias)
input ENUM_TIMEFRAMES InpTF_C = PERIOD_W1;   // TF C: macro (EMAs + swings + bias)
input ENUM_TIMEFRAMES InpTF_D = PERIOD_D1;   // TF D: previous day high/low
input int    InpHTF_EMA1     = 50;     // Higher-TF EMA: 1
input int    InpHTF_EMA2     = 100;    // Higher-TF EMA: 2
input int    InpHTF_EMA3     = 200;    // Higher-TF EMA: 3
input int    InpHTFSwingStr  = 3;      // Swing strength on higher TFs
input int    InpHTFSwings    = 6;      // Number of recent swings per higher TF
input int    InpFibBars      = 30;     // Fibonacci: window on TF B (bars)
input double InpFibMinATR    = 10.0;   // Fibonacci: minimum move (x H1 ATR)
input ENUM_MTF_MODE InpMTFMode = MTF_NO_COUNTER; // Multi-timeframe trend filter
input int    InpHTFBars      = 1000;   // History loaded per higher TF
input bool   InpBlockOnMissingData = false; // Block signals if a higher-TF dataset is unavailable

input group "=== Support / Resistance (confluence) ==="
input double InpRoundPips    = 100;    // Round-number level step (pips)
input int    InpSwingStr     = 5;      // H1 swing strength (bars on each side)
input int    InpSwingBack    = 240;    // H1 swing lookback (bars = 10 days)
input int    InpBBPeriod     = 20;     // Bollinger: period
input double InpBBDev        = 2.0;    // Bollinger: deviations
input double InpZoneATR      = 0.6;    // Zone width (x H1 ATR)
input int    InpMinKinds     = 2;      // Minimum number of converging S/R kinds
input int    InpMinHTFKinds  = 1;      // Of which at least from higher TFs

input group "=== Signal ==="
input double InpMinCandleATR = 0.4;    // Minimum candle size (x ATR)
input int    InpCooldown     = 4;      // Pause between signals (H1 bars)

input group "=== Risk and money management ==="
input int    InpATRPeriod    = 14;     // ATR period
input double InpStopATRPct   = 100;    // Minimum stop (% of ATR)
input double InpMaxStopATR   = 2.5;    // Maximum accepted stop (x ATR)
input double InpMinRRR       = 1.5;    // Minimum reward/risk ratio (after spread)
input int    InpTargetKinds  = 2;      // Converging S/R kinds required for the target
input double InpMaxTPATR     = 20.0;   // Maximum target distance (x ATR)
input double InpTPBufferATR  = 0.1;    // TP placed before the level (x ATR)
input double InpMaxSpreadRatio = 0.2;  // Maximum spread as a fraction of the stop (0 = off)

input group "=== Session (broker server time) ==="
input bool   InpSessionOn    = false;  // Session filter
input int    InpSessionStartH = 7;     // Start hour (inclusive)
input int    InpSessionEndH  = 21;     // End hour (exclusive)

input group "=== Display and alerts ==="
input int    InpMaxBars      = 2000;   // Number of history bars evaluated
input bool   InpShowZones    = true;   // Draw strong S/R zones
input int    InpMaxZones     = 6;      // Maximum number of zones drawn
input int    InpZoneBars     = 60;     // Zone length (bars)
input bool   InpShowTradeLines = true; // Entry/SL/TP lines for the last signal
input bool   InpAlert        = true;   // Pop-up alert
input bool   InpPush         = false;  // Push notification
input bool   InpEmail        = false;  // Email
input bool   InpDebug        = true;   // Print scan statistics to the Experts log

#define K_RND 0    // round-number level
#define K_SWG 1    // swing on the chart timeframe
#define K_MA  2    // EMA on the chart timeframe
#define K_BB  3    // Bollinger
#define K_FIB 4    // Fibonacci (TF B)
#define K_HMA 5    // EMA from higher TFs
#define K_HSW 6    // swing from higher TFs
#define K_PDH 7    // previous day high/low
#define KM_HTF 0xF0          // mask of kinds coming from higher TFs
#define LEVEL_CAP   768
#define ST_BARS  0     // bars evaluated
#define ST_SESS  1     // skipped: outside session
#define ST_SMALL 2     // skipped: candle too small
#define ST_COOL  3     // skipped: cooldown
#define ST_CAND  4     // candidates: pattern + trend OK
#define ST_MTF   5     // rejected: higher-TF trend filter
#define ST_CONF  6     // rejected: not enough S/R confluence
#define ST_STOP  7     // rejected: stop too wide
#define ST_SPR   8     // rejected: spread too high
#define ST_TGT   9     // rejected: no valid target
#define ST_RRR   10    // rejected: reward/risk too low
#define ST_BUY   11    // BUY signals
#define ST_SELL  12    // SELL signals
#define ST_SIZE  13

struct SLevel { double price; int kind; int side; };   // side: +1 support only, -1 resistance only, 0 both
struct STrade { int dir; double entry; double sl; double tp; double rrr; double dist; int kinds; datetime t; };

bool IsValid(const double v) { return (v > 0.0 && v < 1.0e100); }

class CHtf
{
public:
   ENUM_TIMEFRAMES tf;
   bool      active;      // configured and valid
   bool      ready;       // data loaded
   bool      wantEMA;
   bool      wantSwing;
   int       hE[3];
   int       swStr;
   int       n;
   int       nsw;
   int       per;         // seconds
   datetime  lastBar;
   MqlRates  r[];         // chronological (oldest first)
   double    e1[], e2[], e3[];
   int       swConf[];    // index of the bar at which the swing is confirmed
   double    swPrice[];

   CHtf()
   {
      tf = PERIOD_CURRENT; active = false; ready = false;
      wantEMA = false; wantSwing = false; swStr = 3;
      n = 0; nsw = 0; per = 0; lastBar = 0;
      for(int k = 0; k < 3; k++) hE[k] = INVALID_HANDLE;
   }

   ~CHtf()
   {
      for(int k = 0; k < 3; k++)
         if(hE[k] != INVALID_HANDLE) IndicatorRelease(hE[k]);
   }

   bool Init(const ENUM_TIMEFRAMES t, const bool ema, const bool swing,
             const int p1, const int p2, const int p3, const int ss)
   {
      tf = t; wantEMA = ema; wantSwing = swing; swStr = ss;
      active = false; ready = false;
      if(t == PERIOD_CURRENT) return true;                    // disabled, not an error
      per = PeriodSeconds(t);
      if(per <= PeriodSeconds(_Period))
      {
         PrintFormat("SGC: TF %s is not higher than the chart (%s) - disabled.",
                     EnumToString(t), EnumToString((ENUM_TIMEFRAMES)_Period));
         return true;
      }
      if(wantEMA)
      {
         int p[3];
         p[0] = p1; p[1] = p2; p[2] = p3;
         for(int k = 0; k < 3; k++)
         {
            hE[k] = iMA(_Symbol, t, p[k], 0, MODE_EMA, PRICE_CLOSE);
            if(hE[k] == INVALID_HANDLE)
            {
               PrintFormat("SGC: iMA(%s, %d) failed, error %d", EnumToString(t), p[k], GetLastError());
               return false;
            }
         }
      }
      active = true;
      return true;
   }

   bool Refresh(const int want)
   {
      if(!active) return false;
      MqlRates probe[];
      CopyRates(_Symbol, tf, 0, 1, probe);                   // triggers series build / download if needed
      int cnt = MathMin(want, Bars(_Symbol, tf));
      if(wantEMA)
         for(int k = 0; k < 3; k++)
         {
            int bc = BarsCalculated(hE[k]);
            if(bc <= 0) return false;
            cnt = MathMin(cnt, bc);
         }
      if(cnt < 30) return false;

      MqlRates tr[];
      ArraySetAsSeries(tr, false);
      if(CopyRates(_Symbol, tf, 0, cnt, tr) != cnt) return false;

      double t1[], t2[], t3[];
      if(wantEMA)
      {
         ArraySetAsSeries(t1, false); ArraySetAsSeries(t2, false); ArraySetAsSeries(t3, false);
         if(CopyBuffer(hE[0], 0, 0, cnt, t1) != cnt) return false;
         if(CopyBuffer(hE[1], 0, 0, cnt, t2) != cnt) return false;
         if(CopyBuffer(hE[2], 0, 0, cnt, t3) != cnt) return false;
      }

      ArrayResize(r, cnt);
      for(int k = 0; k < cnt; k++) r[k] = tr[k];
      if(wantEMA)
      {
         ArrayCopy(e1, t1); ArrayCopy(e2, t2); ArrayCopy(e3, t3);
      }
      n = cnt;
      lastBar = r[n - 1].time;
      if(wantSwing) FindSwings();
      ready = true;
      return true;
   }

   void FindSwings()
   {
      nsw = 0;
      ArrayResize(swConf, 2 * n);
      ArrayResize(swPrice, 2 * n);
      const int s = swStr;
      for(int k = s; k < n - s; k++)
      {
         bool sh = true, sl = true;
         for(int j = 1; j <= s && (sh || sl); j++)
         {
            if(r[k].high <= r[k - j].high || r[k].high < r[k + j].high) sh = false;
            if(r[k].low  >= r[k - j].low  || r[k].low  > r[k + j].low)  sl = false;
         }
         if(sh) { swConf[nsw] = k + s; swPrice[nsw] = r[k].high; nsw++; }
         if(sl) { swConf[nsw] = k + s; swPrice[nsw] = r[k].low;  nsw++; }
      }
   }

   int Closed(const datetime tClose)
   {
      int lo = 0, hi = n - 1, res = -1;
      while(lo <= hi)
      {
         const int mid = (lo + hi) >> 1;
         if((long)r[mid].time + per <= (long)tClose) { res = mid; lo = mid + 1; }
         else hi = mid - 1;
      }
      return res;
   }

   int SwingCount(const int j)
   {
      int lo = 0, hi = nsw - 1, res = 0;
      while(lo <= hi)
      {
         const int mid = (lo + hi) >> 1;
         if(swConf[mid] <= j) { res = mid + 1; lo = mid + 1; }
         else hi = mid - 1;
      }
      return res;
   }

   int Bias(const int j)
   {
      if(!wantEMA || j < 0 || j >= n) return 0;
      const double a = e1[j], b = e2[j], c = e3[j];
      if(!IsValid(a) || !IsValid(b) || !IsValid(c)) return 0;
      if(a > b && b > c) return 1;
      if(a < b && b < c) return -1;
      return 0;
   }
};

double bEMA1[], bEMA2[], bEMA3[], bEMA4[], bEMA5[];
double bBuy[], bSell[];
double bATR[], bBBu[], bBBl[], bSL[], bTP[];

int    g_hE[5];
int    g_hATR = INVALID_HANDLE;
int    g_hBB  = INVALID_HANDLE;
CHtf  *g_h[4];                       // A, B, C, D

SLevel g_lv[];
int    g_n = 0;
STrade g_last;
double g_pip = 0.0;
int    g_warm = 250;
bool   g_needFull = false;
uint   g_tickInit = 0;
datetime g_alertT = 0;
const string g_pfx = "SGC_";

int    g_zonesDrawn = 0;
int    g_st[ST_SIZE];               // scan statistics (funnel)

int Bits(int m)
{
   int c = 0;
   while(m > 0) { c += (m & 1); m >>= 1; }
   return c;
}

string KindNames(const int mask)
{
   string n[8] = {"Rnd", "Swg", "MA", "BB", "Fib", "hMA", "hSw", "PDH"};
   string s = "";
   for(int k = 0; k < 8; k++)
      if((mask & (1 << k)) != 0) s += (s == "" ? "" : "+") + n[k];
   return (s == "" ? "-" : s);
}

string TfName(const ENUM_TIMEFRAMES t) { return StringSubstr(EnumToString(t), 7); }

void AddLevel(const double p, const int kind, const int side)
{
   if(g_n >= LEVEL_CAP || !IsValid(p)) return;
   g_lv[g_n].price = p;
   g_lv[g_n].kind  = kind;
   g_lv[g_n].side  = side;
   g_n++;
}

int KindMask(const double p, const double tol, const int side)
{
   int mask = 0;
   for(int k = 0; k < g_n; k++)
   {
      if(side != 0 && g_lv[k].side == -side) continue;
      if(MathAbs(g_lv[k].price - p) <= tol) mask |= (1 << g_lv[k].kind);
   }
   return mask;
}

int TrendScore(const int i, const int dir)
{
   double e[5];
   e[0] = bEMA1[i]; e[1] = bEMA2[i]; e[2] = bEMA3[i]; e[3] = bEMA4[i]; e[4] = bEMA5[i];
   int sc = 0;
   for(int k = 0; k < 4; k++)
   {
      if(dir > 0) { if(e[k] > e[k + 1]) sc++; }
      else        { if(e[k] < e[k + 1]) sc++; }
   }
   return sc;
}

bool InSession(const datetime t)
{
   if(!InpSessionOn) return true;
   MqlDateTime dt;
   TimeToStruct(t, dt);
   if(InpSessionStartH < InpSessionEndH) return (dt.hour >= InpSessionStartH && dt.hour < InpSessionEndH);
   return (dt.hour >= InpSessionStartH || dt.hour < InpSessionEndH);
}

bool RecentSignal(const int i)
{
   const int from = MathMax(0, i - InpCooldown);
   for(int k = from; k < i; k++)
      if(bBuy[k] != EMPTY_VALUE || bSell[k] != EMPTY_VALUE) return true;
   return false;
}

double SpreadPrice(const int i, const int last, const int &spread[])
{
   long sp = spread[i];
   if(sp <= 0 && i == last) sp = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
   return (double)sp * _Point;
}

bool IsHammer(const int i, const double &o[], const double &h[], const double &l[], const double &c[])
{
   const double rg = h[i] - l[i];
   if(rg <= 0.0) return false;
   const double body = MathAbs(c[i] - o[i]);
   const double lw = MathMin(o[i], c[i]) - l[i];
   const double uw = h[i] - MathMax(o[i], c[i]);
   return (lw >= 2.0 * body && lw >= 0.5 * rg && uw <= 0.25 * rg);
}

bool IsStar(const int i, const double &o[], const double &h[], const double &l[], const double &c[])
{
   const double rg = h[i] - l[i];
   if(rg <= 0.0) return false;
   const double body = MathAbs(c[i] - o[i]);
   const double lw = MathMin(o[i], c[i]) - l[i];
   const double uw = h[i] - MathMax(o[i], c[i]);
   return (uw >= 2.0 * body && uw >= 0.5 * rg && lw <= 0.25 * rg);
}

bool BullPattern(const int i, const double &o[], const double &h[], const double &l[], const double &c[])
{
   if(IsHammer(i, o, h, l, c)) return true;
   if(c[i] > o[i] && c[i - 1] < o[i - 1] && c[i] >= o[i - 1] && o[i] <= c[i - 1]) return true;   // engulfing
   if(IsHammer(i - 1, o, h, l, c) && c[i] > o[i] && c[i] > c[i - 1]) return true;               // confirmed hammer
   return false;
}

bool BearPattern(const int i, const double &o[], const double &h[], const double &l[], const double &c[])
{
   if(IsStar(i, o, h, l, c)) return true;
   if(c[i] < o[i] && c[i - 1] > o[i - 1] && c[i] <= o[i - 1] && o[i] >= c[i - 1]) return true;
   if(IsStar(i - 1, o, h, l, c) && c[i] < o[i] && c[i] < c[i - 1]) return true;
   return false;
}

void BuildLevels(const int i, const datetime tClose, const double &high[], const double &low[], const double &close[])
{
   g_n = 0;
   const double atr = bATR[i];

   const double step = InpRoundPips * g_pip;
   if(step > 0.0)
   {
      const double base = MathFloor(close[i] / step) * step;
      for(int k = -2; k <= 3; k++) AddLevel(base + k * step, K_RND, 0);
   }

   const int s = InpSwingStr;
   const int kFrom = i - 1 - s;
   const int kTo   = MathMax(s, i - InpSwingBack);
   for(int k = kFrom; k >= kTo; k--)
   {
      bool sh = true, sl = true;
      for(int j = 1; j <= s && (sh || sl); j++)
      {
         if(high[k] <= high[k - j] || high[k] < high[k + j]) sh = false;
         if(low[k]  >= low[k - j]  || low[k]  > low[k + j])  sl = false;
      }
      if(sh) AddLevel(high[k], K_SWG, 0);
      if(sl) AddLevel(low[k],  K_SWG, 0);
   }

   AddLevel(bEMA3[i], K_MA, 0);
   AddLevel(bEMA4[i], K_MA, 0);
   AddLevel(bEMA5[i], K_MA, 0);

   AddLevel(bBBl[i], K_BB, +1);
   AddLevel(bBBu[i], K_BB, -1);

   for(int q = 0; q < 3; q++)
   {
      CHtf *h = g_h[q];
      if(h == NULL || !h.active || !h.ready) continue;
      const int j = h.Closed(tClose);
      if(j < 0) continue;
      if(h.wantEMA)
      {
         AddLevel(h.e1[j], K_HMA, 0);
         AddLevel(h.e2[j], K_HMA, 0);
         AddLevel(h.e3[j], K_HMA, 0);
      }
      if(h.wantSwing)
      {
         const int c = h.SwingCount(j);
         const int f = MathMax(0, c - InpHTFSwings);
         for(int m = c - 1; m >= f; m--) AddLevel(h.swPrice[m], K_HSW, 0);
      }
   }

   CHtf *hb = g_h[1];
   if(hb != NULL && hb.active && hb.ready)
   {
      const int j = hb.Closed(tClose);
      if(j >= 0)
      {
         const int from = MathMax(0, j - InpFibBars + 1);
         int hi = from, lo = from;
         for(int k = from; k <= j; k++)
         {
            if(hb.r[k].high >= hb.r[hi].high) hi = k;
            if(hb.r[k].low  <= hb.r[lo].low)  lo = k;
         }
         const double hiP = hb.r[hi].high, loP = hb.r[lo].low;
         const double range = hiP - loP;
         if(range >= InpFibMinATR * atr)
         {
            double fr[4];
            fr[0] = 0.236; fr[1] = 0.382; fr[2] = 0.5; fr[3] = 0.618;
            for(int q = 0; q < 4; q++)
               AddLevel((lo < hi) ? hiP - fr[q] * range : loP + fr[q] * range, K_FIB, 0);
         }
      }
   }

   CHtf *hd = g_h[3];
   if(hd != NULL && hd.active && hd.ready)
   {
      const int j = hd.Closed(tClose);
      if(j >= 0)
      {
         AddLevel(hd.r[j].high, K_PDH, 0);
         AddLevel(hd.r[j].low,  K_PDH, 0);
      }
   }
}

double NextTarget(const double entry, const int dir, const double tol, const double maxDist)
{
   double be

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

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

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

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

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

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

Стоимость полного кода
2 565,70₽ ≈ $31.36