class HaramiSettings
Класс-структура для хранения настроек обнаружения паттерна Харами.
Сообщите нам, если считаете, что материал размещён без разрешения.
Обращение по товару «haramiengine.mqh» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
HaramiEngine — библиотека MQL5 для обнаружения паттерна «Харами» на ценовых графиках. Модуль анализирует пары свечей (материнскую и харами) и определяет наличие паттерна на основе заданных параметров размеров, соотношений тел, подтверждения тенями и фильтров тренда.
Библиотека предоставляет гибкую систему оценки: каждому обнаруженному паттерну начисляются баллы по нескольким критериям — цвет свечей, полнота включения, соотношение тел, тренд, тени и волатильность (ATR). Результат содержит итоговый счёт и направление сигнала.
Модуль поддерживает как классический паттерн «Харами», так и кросс-вариант (когда вторая свеча является доджи). Встроенное кэширование ATR и настраиваемые пороги позволяют оптимизировать работу в советниках и индикаторах.
Классов: 3 · методов: 0 · конструкторов: 0 · деструкторов: 0 · отдельных функций: 16
class HaramiSettings
Класс-структура для хранения настроек обнаружения паттерна Харами.
class HaramiResult
Класс-структура для хранения результатов обнаружения паттерна и начисленных баллов.
class CandleData
Класс-структура для хранения данных свечи (открытие, закрытие, максимум, минимум, тело, тени).
string HaramiGetSymbol()
Возвращает имя текущего торгового инструмента.
ENUM_TIMEFRAMES HaramiGetTimeframe()
Возвращает текущий таймфрейм графика.
double HaramiGetPoint()
Возвращает минимальное допустимое изменение цены (шаг) для текущего инструмента.
int HaramiGetBars()
Возвращает количество баров на текущем графике.
double HaramiOpen(int shift)
Возвращает цену открытия свечи с указанным сдвигом.
double HaramiClose(int shift)
Возвращает цену закрытия свечи с указанным сдвигом.
double HaramiHigh(int shift)
Возвращает максимальную цену свечи с указанным сдвигом.
double HaramiLow(int shift)
Возвращает минимальную цену свечи с указанным сдвигом.
datetime HaramiTime(int shift)
Возвращает время открытия свечи с указанным сдвигом.
double HaramiATR(int period, int shift)
Вычисляет среднее истинное диапазон (ATR) по методу Уилдера для заданного периода и сдвига.
void HaramiDefaults(HaramiSettings &s)
Инициализирует структуру HaramiSettings значениями по умолчанию.
void ParseCandle(int shift, CandleData &c, int dojiPoints)
Парсит данные свечи по указанному сдвигу и заполняет структуру CandleData.
double GetCachedATR(HaramiSettings &s, int shift)
Возвращает кэшированное значение ATR для заданных настроек и сдвига, обновляя кэш при необходимости.
int CheckBodyRatioQuality(double ratio)
Оценивает качество соотношения тел свечей и возвращает балл от 0 до 2.
string HaramiScoreBreakdown(HaramiResult &r)
Формирует строку с разбивкой набранных баллов по критериям для переданного результата.
void HaramiResetCache()
Сбрасывает кэш ATR, заставляя пересчитать значения при следующем обращении.
#ifndef HARAMIENGINE_MQH
#define HARAMIENGINE_MQH
#property strict
#property description "This EA is licensed for FREE Unlimited Private Use, and has been distributed at Telegram group FREE FOREX ROBOTS for members-only."
#property description " "
#property description "Instructions: any asset, any timeframe."
#property description " "
#property description "Risk Warning! Test this EA on Demo account first. Understand how this EA operates. Trading is risky and not suitable for every investor."
string HaramiGetSymbol()
{
return(_Symbol);
}
ENUM_TIMEFRAMES HaramiGetTimeframe()
{
return((ENUM_TIMEFRAMES)Period());
}
double HaramiGetPoint()
{
return(_Point);
}
int HaramiGetBars()
{
return(iBars(_Symbol, Period()));
}
double HaramiOpen(int shift)
{
return(iOpen(_Symbol, Period(), shift));
}
double HaramiClose(int shift)
{
return(iClose(_Symbol, Period(), shift));
}
double HaramiHigh(int shift)
{
return(iHigh(_Symbol, Period(), shift));
}
double HaramiLow(int shift)
{
return(iLow(_Symbol, Period(), shift));
}
datetime HaramiTime(int shift)
{
return(iTime(_Symbol, Period(), shift));
}
double HaramiATR(int period, int shift)
{
if(period <= 0 || shift < 0)
return(0.0);
if(iBars(_Symbol, Period()) <= shift + period)
return(0.0);
return(iATR(_Symbol, Period(), period, shift));
}
struct HaramiSettings
{
int MinMasterSize;
int MaxMasterSize;
int MinHaramiSize;
int MaxHaramiSize;
double MaxRatioHaramiToMaster;
double MinRatioHaramiToMaster;
bool EnableHaramiCross;
bool StrictHaramiCross;
int DojiBodyPoints;
bool EnableWickConfirmation;
double MinWickToBodyRatio;
bool EnableTrendFilter;
int TrendLookback;
bool RequireStrictTrend;
bool EnableATRFilter;
int ATRPeriod;
double MinMasterToATRRatio;
double MaxMasterToATRRatio;
bool EnableScoring;
int MinScoreToSignal;
};
struct HaramiResult
{
bool Valid;
bool IsCross;
int Direction;
int Score;
int BullScore;
int BearScore;
int PointsColours;
int PointsBodyContain;
int PointsFullContain;
int PointsBodyRatio;
int PointsTrend;
int PointsWick;
int PointsATR;
int PointsCross;
};
struct CandleData
{
double Open;
double Close;
double High;
double Low;
double Body;
double UpperWick;
double LowerWick;
bool IsBullish;
bool IsBearish;
bool IsDoji;
};
static int s_atrPeriod = -1;
static int s_atrShift = -1;
static datetime s_atrBar = 0;
static double s_cachedATR = 0.0;
void HaramiDefaults(HaramiSettings &s)
{
s.MinMasterSize = 40;
s.MaxMasterSize = 500;
s.MinHaramiSize = 20;
s.MaxHaramiSize = 300;
s.MaxRatioHaramiToMaster = 0.75;
s.MinRatioHaramiToMaster = 0.50;
s.EnableHaramiCross = true;
s.StrictHaramiCross = true;
s.DojiBodyPoints = 5;
s.EnableWickConfirmation = true;
s.MinWickToBodyRatio = 1.0;
s.EnableTrendFilter = true;
s.TrendLookback = 5;
s.RequireStrictTrend = false;
s.EnableATRFilter = false;
s.ATRPeriod = 14;
s.MinMasterToATRRatio = 0.5;
s.MaxMasterToATRRatio = 3.0;
s.EnableScoring = true;
s.MinScoreToSignal = 8;
}
void ParseCandle(int shift, CandleData &c, int dojiPoints)
{
c.Open = iOpen(_Symbol, Period(), shift);
c.Close = iClose(_Symbol, Period(), shift);
c.High = iHigh(_Symbol, Period(), shift);
c.Low = iLow(_Symbol, Period(), shift);
c.Body = MathAbs(c.Open - c.Close);
double bodyHigh = MathMax(c.Open, c.Close);
double bodyLow = MathMin(c.Open, c.Close);
c.UpperWick = c.High - bodyHigh;
c.LowerWick = bodyLow - c.Low;
c.IsBullish = (c.Close > c.Open);
c.IsBearish = (c.Close < c.Open);
c.IsDoji = (c.Body <= dojiPoints * _Point);
}
double GetCachedATR(HaramiSettings &s, int shift)
{
if(s.ATRPeriod <= 0 || shift < 0)
return(0.0);
datetime barTime = iTime(_Symbol, Period(), shift);
if(s_atrPeriod != s.ATRPeriod ||
s_atrShift != shift ||
s_atrBar != barTime)
{
s_cachedATR = HaramiATR(s.ATRPeriod, shift);
s_atrPeriod = s.ATRPeriod;
s_atrShift = shift;
s_atrBar = barTime;
}
return(s_cachedATR);
}
int CheckDownTrendQuality(
int barIndex,
HaramiSettings &s,
int barsAvailable
)
{
int lookback = s.TrendLookback;
if(lookback < 2)
return(0);
int startBar = barIndex + 2;
int endBar = barIndex + 1 + lookback;
if(endBar >= barsAvailable)
return(0);
int consecutive = 0;
int total = 0;
double startClose = iClose(_Symbol, Period(), startBar);
double endClose = iClose(_Symbol, Period(), endBar);
for(int j = 0; j < lookback - 1; j++)
{
int older = barIndex + 3 + j;
int newer = barIndex + 2 + j;
if(older >= barsAvailable)
break;
double olderClose = iClose(_Symbol, Period(), older);
double newerClose = iClose(_Symbol, Period(), newer);
total++;
if(olderClose > newerClose)
{
consecutive++;
}
else if(s.RequireStrictTrend)
{
break;
}
}
if(s.RequireStrictTrend)
{
if(consecutive >= 4)
return(2);
if(consecutive >= 2)
return(1);
return(0);
}
if(total <= 0)
return(0);
double fallRatio = (double)consecutive / total;
double atr = GetCachedATR(s, startBar);
if(atr <= 0.0)
return(0);
double moveATR =
MathAbs(startClose - endClose) / atr;
if(fallRatio >= 0.80 && moveATR >= 0.50)
return(2);
if(fallRatio >= 0.60 && moveATR >= 0.25)
return(1);
return(0);
}
int CheckUpTrendQuality(
int barIndex,
HaramiSettings &s,
int barsAvailable
)
{
int lookback = s.TrendLookback;
if(lookback < 2)
return(0);
int startBar = barIndex + 2;
int endBar = barIndex + 1 + lookback;
if(endBar >= barsAvailable)
return(0);
int consecutive = 0;
int total = 0;
double startClose = iClose(_Symbol, Period(), startBar);
double endClose = iClose(_Symbol, Period(), endBar);
for(int j = 0; j < lookback - 1; j++)
{
int older = barIndex + 3 + j;
int newer = barIndex + 2 + j;
if(older >= barsAvailable)
break;
double olderClose = iClose(_Symbol, Period(), older);
double newerClose = iClose(_Symbol, Period(), newer);
total++;
if(olderClose < newerClose)
{
consecutive++;
}
else if(s.RequireStrictTrend)
{
break;
}
}
if(s.RequireStrictTrend)
{
if(consecutive >= 4)
return(2);
if(consecutive >= 2)
return(1);
return(0);
}
if(total <= 0)
return(0);
double riseRatio = (double)consecutive / total;
double atr = GetCachedATR(s, startBar);
if(atr <= 0.0)
return(0);
double moveATR =
MathAbs(endClose - startClose) / atr;
if(riseRatio >= 0.80 && moveATR >= 0.50)
return(2);
if(riseRatio >= 0.60 && moveATR >= 0.2Показано первые 50% кода (символов: 10107)
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.