class SRLine
Класс-контейнер данных для линий поддержки и сопротивления (начало бара, конец бара, цена, количество касаний, таймфрейм).
Сообщите нам, если считаете, что материал размещён без разрешения.
Обращение по товару «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
Основной класс для расчёта, проверки и отрисовки уровней поддержки и сопротивления на графике.
int Compare(SRLine* el1, SRLine* el2)
Метод сравнения двух линий поддержки/сопротивления по цене (возвращает -1, 0 или 1).
CSupportResistance(string symbol, int timeperiod)
Конструктор класса, принимающий торговый символ и таймфрейм для анализа.
~CSupportResistance()
Деструктор класса, освобождающий выделенную память для линий.
void Draw(string key, color colorText, color &colors[], bool showAgeLabels, bool showLastTouch, bool showAllSRLines)
Отрисовка линий поддержки и сопротивления на графике с цветовой кодировкой и текстовыми метками.
void ClearAll(string key)
Удаление графических объектов с графика по заданному ключу.
void Calculate(bool forceRefresh)
Расчёт уровней поддержки и сопротивления на основе исторических данных цены.
bool IsAtSupport(double price, double pips, double& srLevelFound, bool checkAbove)
Проверка, находится ли заданная цена вблизи уровня поддержки.
bool IsAtResistance(double price, double pips, double& srLevelFound, bool checkBelow)
Проверка, находится ли заданная цена вблизи уровня сопротивления.
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? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.