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

HaramiEngine

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 и перейдите к оплате.

Стоимость полного кода
1 010,70₽ ≈ $12.35