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

csupportresistance.mqh

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

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

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

О программе

Библиотека CSupportResistance для MetaTrader 4 предоставляет инструменты для расчёта, проверки и визуализации уровней поддержки и сопротивления на ценовых графиках. Основной класс CSupportResistance анализирует исторические данные цены заданного символа и таймфрейма, формируя набор горизонтальных уровней и отрисовывая их на графике с информационными подписями.

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

Библиотека включает вспомогательный класс данных SRLine для хранения параметров каждого уровня и класс сравнения SRLevelComparer для сортировки уровней по цене. Расчёт пересчитывается ежедневно или при принудительном обновлении. Настройки включают глубину истории в барах и детализацию уровней.

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

НастройкаОписание
__srSettings__ Настройки S/R — Заголовок текстового параметра для группы настроек поддержки и сопротивления.
BarsHistory Глубина истории в барах — Количество баров исторических данных, используемых для расчёта уровней.
SR_Detail Детализация уровней — Уровень детализации расчёта уровней поддержки и сопротивления (от Минимум до Максимум).

Состав библиотеки

Классов: 3 · методов: 7 · конструкторов: 1 · деструкторов: 1 · отдельных функций: 0

Классы
Класс class SRLine

Класс-контейнер данных для линий поддержки и сопротивления (начало бара, конец бара, цена, количество касаний, таймфрейм).

Класс class SRLevelComparer

Класс сравнения для сортировки линий поддержки и сопротивления по цене.

Класс class CSupportResistance

Основной класс для расчёта, проверки и отрисовки уровней поддержки и сопротивления на графике.

Методы и конструкторы
Метод · SRLevelComparer int Compare(SRLine* el1, SRLine* el2)

Метод сравнения двух линий поддержки/сопротивления по цене (возвращает -1, 0 или 1).

Конструктор · CSupportResistance CSupportResistance(string symbol, int timeperiod)

Конструктор класса, принимающий торговый символ и таймфрейм для анализа.

Деструктор · CSupportResistance ~CSupportResistance()

Деструктор класса, освобождающий выделенную память для линий.

Метод · CSupportResistance void Draw(string key, color colorText, color &colors[], bool showAgeLabels, bool showLastTouch, bool showAllSRLines)

Отрисовка линий поддержки и сопротивления на графике с цветовой кодировкой и текстовыми метками.

Метод · CSupportResistance void ClearAll(string key)

Удаление графических объектов с графика по заданному ключу.

Метод · CSupportResistance void Calculate(bool forceRefresh)

Расчёт уровней поддержки и сопротивления на основе исторических данных цены.

Метод · CSupportResistance bool IsAtSupport(double price, double pips, double& srLevelFound, bool checkAbove)

Проверка, находится ли заданная цена вблизи уровня поддержки.

Метод · CSupportResistance bool IsAtResistance(double price, double pips, double& srLevelFound, bool checkBelow)

Проверка, находится ли заданная цена вблизи уровня сопротивления.

Метод · CSupportResistance bool GetSupportResistance(double price, double &supportLevel, double &resistanceLevel)

Получение ближайших уровней поддержки и сопротивления для заданной цены.

Получить полный код

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

#property strict

enum Details 
{
   Minium,
   MediumLow,
   Medium,
   MediumHigh,
   Maximum
};

extern string      __srSettings__  = "---- S/R settings ----";
extern int         BarsHistory     = 3000;
extern Details     SR_Detail       = Medium;

#include <CZigZag.mqh>
#include <CSelectionSort.mqh>

class SRLine
{
public:
   int      StartBar;
   int      EndBar;
   datetime StartDate;
   datetime EndDate;
   double   Price;
   int      Touches;  
   int      Timeframe;
};

class SRLevelComparer: public ICompare<SRLine*>
{
public:
   int Compare(SRLine* el1, SRLine* el2)
   {
      if (  el1.Price < el2.Price) return -1;
      if (  el1.Price > el2.Price) return 1;
      return 0;
   }
};

class CSupportResistance
{
private:
   string  _symbol;
   int     _maxLine;
   double  _maxDistance;
   int     _previousDay;
   int     _period;
   SRLine* _lines[];

public:

   CSupportResistance(string symbol, int timeperiod)
   {
      _period      = timeperiod;
      _symbol      = symbol;
      _maxLine     = 0;
      _previousDay = -1;
      ArrayResize(_lines, 5000, 0);
   }

   ~CSupportResistance()
   {
      for (int i=0; i < _maxLine; ++i)
      {
         delete _lines[i];
      }
      ArrayFree(_lines);
   }

private:

   bool DoesSupportLevelExists(double price, double priceRange, double& srLevelFound, bool checkAbove)
   { 
      if (_maxLine <= 0) return false;

      for (int i=0; i < _maxLine;++i)
      {
         if (!checkAbove || price >= _lines[i].Price)
         {
            double diff = MathAbs(price - _lines[i].Price);
            if (diff <= priceRange) 
            {
               srLevelFound = _lines[i].Price;
               return true;
            }
         }
      }
      return false;
   }

   bool DoesResistanceLevelExists(double price, double priceRange, double& srLevelFound, bool checkBelow)
   { 
      if (_maxLine <= 0) return false;

      for (int i=0; i < _maxLine;++i)
      {
         if (!checkBelow || price <= _lines[i].Price)
         {
            double diff = MathAbs(price - _lines[i].Price);
            if (diff <= priceRange) 
            {
               srLevelFound = _lines[i].Price;
               return true;
            }
         }
      }
      return false;
   }

   int GetTouches(CZigZag* zigZag, int barPrice, int maxBars, double& price, datetime& startTime, int& startBar)
   {
      int    cnt        = 0;
      double totalPrice = price;
      double totalCnt   = 1.0; 
      double lowest     = price;
      double highest    = price; 
      double points       = MarketInfo(_symbol, MODE_POINT);

      for (int bar = barPrice + 1; bar < maxBars; bar++)
      {  
         ARROW_TYPE arrow = zigZag.GetArrow(bar);
         if (arrow == ARROW_NONE) continue;

         double lo = iLow (_symbol, _period, bar);
         double hi = iHigh(_symbol, _period, bar);

         double diffLo = MathAbs(lo - price);
         double diffHi = MathAbs(hi - price);
         if (diffLo < _maxDistance )
         {
            cnt++;
            startTime   = iTime(_symbol, _period, bar);
            startBar    = bar;
            totalPrice += lo;
            totalCnt   += 1.0;
            lowest      = MathMin(lowest,lo);
            double pips = diffLo / (10.0 * points);

         }
         else if ( diffHi <= _maxDistance) 
         {
            cnt++;
            startTime  = iTime(_symbol, _period, bar);
            startBar   = bar;
            totalPrice += hi;
            totalCnt   += 1.0;
            highest    = MathMax(highest,hi);
            double pips=diffHi / (10.0 * points);

         }
      }

      return cnt;
   }

   bool DoesLevelExists(int bar, double price, datetime mostRecent)
   {
      for (int i=0; i < _maxLine;++i)
      {
         double diff = MathAbs(price - _lines[i].Price);
         if (diff < _maxDistance) 
         {
            if ( mostRecent > _lines[i].EndDate)
            {
               _lines[i].EndDate = mostRecent;   
               _lines[i].EndBar  = bar;
            }
            return true;
         }
      }
      return false;
   }

   void Refresh( )
   {
      int barsAvailable = iBars(_symbol, _period);
      int bars          = MathMin( BarsHistory, barsAvailable); 

      int lowestBar       = iLowest(_symbol , _period, MODE_LOW , bars, 0);
      int highestBar      = iHighest(_symbol, _period, MODE_HIGH, bars, 0);
      double highestPrice = iHigh(_symbol, _period, highestBar);
      double lowestPrice  = iLow(_symbol , _period, lowestBar);
      double digits       = MarketInfo(_symbol, MODE_DIGITS);
      double points       = MarketInfo(_symbol, MODE_POINT);

      double priceRange = highestPrice - lowestPrice;

      double mult   = (digits==3 || digits==5) ? 10.0 : 1.0;
      mult *= points;

      double div = 30.0;
      switch (SR_Detail)
      {
         case Minium:
            div=10.0;
         break;
         case MediumLow:
            div=20.0;
         break;
         case Medium:
            div=30.0;
         break;
         case MediumHigh:
            div=40.0;
         break;
         case Maximum:
            div=50.0;
         break;
      }
      _maxDistance =  priceRange/div;

      CZigZag* zigZag      = new CZigZag(bars, _period);  
      zigZag._extDepth     = 12;
      zigZag._extDeviation = 5;
      zigZag._extBackstep  = 3;
      zigZag.Refresh(_symbol);

      bool skipFirstArrow=true;
      for (int bar = 1; bar < bars; bar++)
      {
         ARROW_TYPE arrow = zigZag.GetArrow(bar);
         if (arrow == ARROW_NONE) continue; 
         if (skipFirstArrow)
         {
            skipFirstArrow = false;
            continue;
         }

         if (arrow == ARROW_BUY) 
         {  
            double   price = iLow (_symbol, _period, bar);
            datetime time  = iTime(_symbol, _period, bar);
            datetime startTime = time;
            int startBar = bar;
            if (!DoesLevelExists(bar, price, startTime )) 
            {
               int touches = GetTouches(zigZag, bar, bars, price, startTime, startBar);
               if (touches >= 0)
               {
                  _lines[_maxLine] = new SRLine();
                  _lines[_maxLine].Price     = price;
                  _lines[_maxLine].Touches   = touches;
                  _lines[_maxLine].EndBar    = bar;
                  _lines[_maxLine].EndDate   = time;
                  _lines[_maxLine].StartDate = startTime;
                  _lines[_maxLine].StartBar  = startBar;
                  _lines[_maxLine].Timeframe = _period;
                  _maxLine++;
               }
             }
         }
         else if (arrow == ARROW_SELL) 
         {
            double   price     = iHigh(_symbol, _period, bar);
            datetime time      = iTime(_symbol, _period, bar);
            datetime startTime = time;
            int startBar = bar;
            if (!DoesLevelExists(bar, price, startTime) )
            {
               int touches = GetTouches(zigZag, bar,bars, price, startTime, startBar);
               if (touches >= 0)
               {
                  _lines[_maxLine] = new SRLine();
                  _lines[_maxLine].Price     = price;
                  _lines[_maxLine].Touches   = touches;
                  _lines[_maxLine].EndBar    = bar;
                  _lines[_maxLine].EndDate   = time;
                  _lines[_maxLine].StartDate = startTime;
                  _lines[_maxLine].StartBar  = startBar;
                  _lines[_maxLine].Timeframe = _period;
                  _maxLine++;
               }
            }
         }
      }

      datetime mostRecentTime = iTime(_symbol, _period, highestBar);
      if (!DoesLevelExists(highestBar, highestPrice, mostRecentTime) )
      {
         _lines[_maxLine] = new SRLine();
         _lines[_maxLine].Price     = highestPrice;
         _lines[_maxLine].Touches   = 1;
         _lines[_maxLine].StartBar  = highestBar;
         _lines[_maxLine].StartDate = iTime(_symbol, _period,highestBar);
         _lines[_maxLine].EndDate   = TimeCurrent();
         _lines[_maxLine].EndBar    = 0;
         _lines[_maxLine].Timeframe = _period;
         _maxLine++;
      }

      mostRecentTime = iTime(_symbol, _period, lowestBar);
      if (!DoesLevelExists(lowestBar, lowestPrice, mostRecentTime) )
      {
         _lines[_maxLine] = new SRLine();
         _lines[_maxLine].Price     = lowestPrice;
         _lines[_maxLine].Touches   = 1;
         _lines[_maxLine].StartBar  = lowestBar;
         _lines[_maxLine].Star

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

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

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

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

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

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

Стоимость полного кода
1 114,10₽ ≈ $13.62