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

adaptivesupertrendengine.mq4

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

ares_indicator.pineTradingView · 1 общих теговgold_trend_revers.mq5MQL5 / MetaTrader 5 · 1 общих тегов!!!-mt4 x-xardg-rsi.mq5MQL5 / MetaTrader 5 · 1 общих тегов! cycle-identifier.mq5MQL5 / MetaTrader 5 · 1 общих тегов!!! rsi ma simple+arrows 1.2 (mtf).mq5MQL5 / MetaTrader 5 · 1 общих теговprecisionflowea.mq5MQL5 / MetaTrader 5 · 1 общих тегов
Вы автор или правообладатель?

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

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

О программе

Данный файл представляет собой include-библиотеку (заголовочный модуль) для MetaTrader 4, реализующую адаптивный движок анализа SuperTrend. Модуль объединяет расчёт SuperTrend на основе ATR, скользящую среднюю осциллятора средней цены (MPO), индикатор RSI и детекцию дивергенций по пивотам для формирования адаптивного трендового сигнала. Предназначен для интеграции в торговых советников как безголовый (headless) многоинстансный модуль.

Класс CAdaptiveSuperTrend хранит данные, специфичные для каждой пары инструмент/таймфрейм, и выполняет пересчёт при каждом тике. При появлении нового бара массивы сдвигаются и обновляются значения. Модуль корректно обрабатывает изменение символа или таймфрейма, перестраивая состояние с нуля.

Адаптивная функция уменьшает множитель SuperTrend при обнаружении дивергенции, повышая чувствительность индикатора к потенциальным разворотам тренда. Класс предоставляет набор методов доступа для получения текущих значений SuperTrend, направления тренда, сигналов дивергенции, эффективного множителя и значения ATR.

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

НастройкаОписание
AST_SuperTrendPeriod Период SuperTrend — количество баров, используемых для расчёта среднего истинного диапазона (ATR).
AST_SuperTrendMultiplier Множитель SuperTrend — коэффициент, определяющий расстояние линий SuperTrend от медианной цены с учётом ATR.
AST_MPO_Period Период расчёта осциллятора средней цены (MPO) — количество баров, используемых для вычисления среднего тела свечи.
AST_MPO_smooth Период экспоненциального сглаживания MPO — используется для сглаживания сырого значения осциллятора.
AST_RsiPeriod Период индикатора RSI — количество баров для расчёта относительного индекса силы по ценам закрытия.
AST_DivSource Источник осциллятора для детекции дивергенций: 0 — сглаженный MPO, 1 — RSI.
AST_DivPivotLen Длина поиска пивотов для детекции дивергенций — количество баров в каждом направлении от кандидата пивота, используемое для проверки его валидности.
AST_DivSensitivity Чувствительность адаптивного сжатия — доля уменьшения множителя SuperTrend при наличии дивергенции (значение от 0 до 1).
AST_EnableAdaptiveShrink Переключатель адаптивного сжатия множителя SuperTrend при обнаружении дивергенции.
Получить полный код

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

#property strict

#property description " "
#property description "Headless, multi-instance SuperTrend analysis module that combines trend, momentum, and divergence information to produce an adaptive trend signal for an EA."
#property description " "

#ifndef ADAPTIVE_SUPERTREND_ENGINE_MQH
#define ADAPTIVE_SUPERTREND_ENGINE_MQH

input int    AST_SuperTrendPeriod      = 10;
input double AST_SuperTrendMultiplier  = 3.0;
input int    AST_MPO_Period            = 6;
input int    AST_MPO_smooth            = 7;
input int    AST_RsiPeriod             = 14;
input int    AST_DivSource             = 0;
input int    AST_DivPivotLen           = 2;
input double AST_DivSensitivity        = 0.3;
input bool   AST_EnableAdaptiveShrink  = true;

class CAdaptiveSuperTrend
{
private:

   string         m_symbol;
   ENUM_TIMEFRAMES m_timeframe;

   double m_st_up[];
   double m_st_dn[];
   double m_st_trend_calc[];

   double m_buf_ATR_ST[];
   double m_buf_MPO_Raw[];
   double m_buf_MPO_Smooth[];
   double m_buf_RSI[];

   double m_LastPivLowPriceBuffer[];
   double m_LastPivLowOscBuffer[];
   double m_LastPivHighPriceBuffer[];
   double m_LastPivHighOscBuffer[];
   double m_LastTypeBuffer[];
   double m_BarsSinceBuffer[];

   datetime m_LastBarTime;
   bool     m_Initialized;
   int      m_LastBars;

   double   m_Point;
   double   m_SmoothAlpha;
   int      m_MPO_Period;
   int      m_DivPivotLen;

   int Bars()
   {
      if(m_symbol == "")
         return 0;

      return iBars(m_symbol, m_timeframe);
   }

   bool ShiftArrays()
   {
      int newSize = Bars();

      if(newSize < 3)
         return false;

      if(m_LastBars < 3)
      {
         Init(m_symbol, m_timeframe);
         return false;
      }

      if(newSize != m_LastBars + 1)
      {

         Init(m_symbol, m_timeframe);
         return false;
      }

      int oldSize = ArraySize(m_st_up);

      if(oldSize != m_LastBars)
      {
         Init(m_symbol, m_timeframe);
         return false;
      }

      ArrayResize(m_st_up,                  newSize);
      ArrayResize(m_st_dn,                  newSize);
      ArrayResize(m_st_trend_calc,          newSize);
      ArrayResize(m_buf_ATR_ST,             newSize);
      ArrayResize(m_buf_MPO_Raw,            newSize);
      ArrayResize(m_buf_MPO_Smooth,         newSize);
      ArrayResize(m_buf_RSI,                newSize);
      ArrayResize(m_LastPivLowPriceBuffer,  newSize);
      ArrayResize(m_LastPivLowOscBuffer,    newSize);
      ArrayResize(m_LastPivHighPriceBuffer, newSize);
      ArrayResize(m_LastPivHighOscBuffer,   newSize);
      ArrayResize(m_LastTypeBuffer,         newSize);
      ArrayResize(m_BarsSinceBuffer,        newSize);

      ArraySetAsSeries(m_st_up,                  true);
      ArraySetAsSeries(m_st_dn,                  true);
      ArraySetAsSeries(m_st_trend_calc,          true);
      ArraySetAsSeries(m_buf_ATR_ST,             true);
      ArraySetAsSeries(m_buf_MPO_Raw,            true);
      ArraySetAsSeries(m_buf_MPO_Smooth,         true);
      ArraySetAsSeries(m_buf_RSI,                true);
      ArraySetAsSeries(m_LastPivLowPriceBuffer,  true);
      ArraySetAsSeries(m_LastPivLowOscBuffer,    true);
      ArraySetAsSeries(m_LastPivHighPriceBuffer, true);
      ArraySetAsSeries(m_LastPivHighOscBuffer,   true);
      ArraySetAsSeries(m_LastTypeBuffer,         true);
      ArraySetAsSeries(m_BarsSinceBuffer,        true);

      for(int i = oldSize - 1; i >= 0; i--)
      {
         m_st_up[i + 1]                  = m_st_up[i];
         m_st_dn[i + 1]                  = m_st_dn[i];
         m_st_trend_calc[i + 1]          = m_st_trend_calc[i];
         m_buf_ATR_ST[i + 1]             = m_buf_ATR_ST[i];
         m_buf_MPO_Raw[i + 1]            = m_buf_MPO_Raw[i];
         m_buf_MPO_Smooth[i + 1]         = m_buf_MPO_Smooth[i];
         m_buf_RSI[i + 1]                = m_buf_RSI[i];
         m_LastPivLowPriceBuffer[i + 1]  = m_LastPivLowPriceBuffer[i];
         m_LastPivLowOscBuffer[i + 1]    = m_LastPivLowOscBuffer[i];
         m_LastPivHighPriceBuffer[i + 1] = m_LastPivHighPriceBuffer[i];
         m_LastPivHighOscBuffer[i + 1]   = m_LastPivHighOscBuffer[i];
         m_LastTypeBuffer[i + 1]         = m_LastTypeBuffer[i];
         m_BarsSinceBuffer[i + 1]        = m_BarsSinceBuffer[i];
      }

      m_LastBars = newSize;
      return true;
   }

   void Update(int limit)
   {
      int bars = Bars();

      if(bars < 3)
         return;

      if(limit < 0)
         limit = 0;

      if(limit > bars - 2)
         limit = bars - 2;

      for(int i = limit; i >= 0; i--)
      {

         m_buf_ATR_ST[i] =
            iATR(m_symbol,
                 m_timeframe,
                 AST_SuperTrendPeriod,
                 i);

         m_buf_RSI[i] =
            iRSI(m_symbol,
                 m_timeframe,
                 AST_RsiPeriod,
                 PRICE_CLOSE,
                 i);

         double rollingSum = 0.0;
         double sumBodies  = 0.0;

         int mpoCount = m_MPO_Period;

         if(i + mpoCount >= bars)
            mpoCount = bars - i - 1;

         if(mpoCount < 1)
            mpoCount = 1;

         for(int k = 0; k < mpoCount; k++)
         {
            double op = iOpen(m_symbol, m_timeframe, i + k);
            double cl = iClose(m_symbol, m_timeframe, i + k);
            sumBodies += MathAbs(cl - op);
         }

         double avgBody =
            (sumBodies > 0.0)
            ? sumBodies / mpoCount
            : m_Point;

         if(avgBody <= 0.0)
            avgBody = m_Point;

         for(int k = 0; k < mpoCount; k++)
         {
            double op   = iOpen(m_symbol, m_timeframe, i + k);
            double cl   = iClose(m_symbol, m_timeframe, i + k);
            double body = MathAbs(cl - op);

            double dir =
               (cl > op) ? 1.0 :
               (cl < op) ? -1.0 :
               0.0;

            double weight =
               (avgBody > 0.0)
               ? body / avgBody
               : 1.0;

            rollingSum += dir * weight;
         }

         m_buf_MPO_Raw[i] =
            (rollingSum / (mpoCount * 2.0)) * 100.0;

         if(i + 1 < bars)
         {
            m_buf_MPO_Smooth[i] =
               (m_buf_MPO_Raw[i] * m_SmoothAlpha) +
               (m_buf_MPO_Smooth[i + 1] * (1.0 - m_SmoothAlpha));
         }
         else
         {
            m_buf_MPO_Smooth[i] = m_buf_MPO_Raw[i];
         }

         bool isPivLow  = false;
         bool isPivHigh = false;

         int pIdx = i + m_DivPivotLen;

         if(pIdx >= 0 && pIdx < bars)
         {
            isPivLow  = true;
            isPivHigh = true;

            for(int j = 1; j <= m_DivPivotLen; j++)
            {
               if(pIdx + j < bars)
               {
                  double low1  = iLow(m_symbol, m_timeframe, pIdx);
                  double low2  = iLow(m_symbol, m_timeframe, pIdx + j);
                  double high1 = iHigh(m_symbol, m_timeframe, pIdx);
                  double high2 = iHigh(m_symbol, m_timeframe, pIdx + j);

                  if(low1 >= low2)
                     isPivLow = false;
                  if(high1 <= high2)
                     isPivHigh = false;
               }

               if(pIdx - j >= 0 && pIdx - j < bars)
               {
                  double low1  = iLow(m_symbol, m_timeframe, pIdx);
                  double low2  = iLow(m_symbol, m_timeframe, pIdx - j);
                  double high1 = iHigh(m_symbol, m_timeframe, pIdx);
                  double high2 = iHigh(m_symbol, m_timeframe, pIdx - j);

                  if(low1 >= low2)
                     isPivLow = false;
                  if(high1 <= high2)
                     isPivHigh = false;
               }
            }
         }

         if(i + 1 < bars)
         {
            m_LastPivLowPriceBuffer[i]  = m_LastPivLowPriceBuffer[i + 1];
            m_LastPivLowOscBuffer[i]    = m_LastPivLowOscBuffer[i + 1];
            m_LastPivHighPriceBuffer[i] = m_LastPivHighPriceBuffer[i + 1];
            m_LastPivHighOscBuffer[i]   = m_LastPivHighOscBuffer[i + 1];
            m_LastTypeBuffer[i]         = m_LastTypeBuffer[i + 1];
            m_BarsSinceBuffer[i]        = m_BarsSinceBuffer[i + 1] + 1.0;
         }

         if(isPivLow)
         {
            double oscValPiv =
               (AST_DivSource == 0)
               ? m_buf_MPO_Smooth[pIdx]
               : m_buf_RSI[pIdx];

            double pivotLow =
               iLow(m_symbol, m_timeframe, pIdx);

            if(m_LastPivLowPriceBuffer[i + 1] != 0.0 &&
               pivotLow < m_LastPivLowPriceBuffer[i + 1] &&
               oscValPiv > m_LastPivLowOscBuffer[i + 1])
            {
               m_LastTypeBuffer[i]  = 1.0;
               m_BarsSinceBuffer[i] = 0.0;
            }

            m_LastPivLowPriceBuffer[i] = pivotLow;
            m_LastPivLowOscBuffer[i]   = oscValPiv;

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

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

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

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

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

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

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