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

engine.mqh

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

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

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

О программе

Engine.mqh — это библиотека исходного кода для MetaTrader 4, предназначенная для обработки многоинженерных паттернов волн и выполнения торговых операций. Модуль спроектирован для компиляции как в составе основного советника (при определении IS_EA), так и в автономном режиме с минимальной локальной поддержкой состояния.

Основной класс CEngine реализует многоэтапную логику: обнаружение свингов на графике, построение волн на основе объединённых свингов, сопоставление с заданными паттернами по сигнатурам направлений, коэффициентам Фибоначчи и длительностям. Перед входом в позицию выполняются проверки пробоя структуры (BOS), моментума и тренда на основе кэшированных EMA.

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

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

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

Классы
Класс class PatternData

Структура для хранения данных паттерна: активность, количество волн, сигнатура направления, массивы Фибоначчи и длительностей, код Меррилла и имя

Класс class CEngine

Класс движка обработки паттернов, построения волн и выполнения торговых операций

Функции
Функция int CountEAOpenOrders()

Возвращает количество открытых ордеров основного советника из кэша

Функция bool HasOtherEngineTrade(int magic, int unused)

Проверяет наличие сделок другого движка по магическому числу; в автономном режиме всегда возвращает false

Функция int iBars(string symbol, int timeframe)

Возвращает количество баров на графике символа; в автономном режиме возвращает 0

Функция double iHigh(string symbol, int timeframe, int shift)

Возвращает максимальную цену за указанный сдвиг; в автономном режиме возвращает 0.0

Функция double iLow(string symbol, int timeframe, int shift)

Возвращает минимальную цену за указанный сдвиг; в автономном режиме возвращает 0.0

Функция double MarketInfo(string symbolName, int mode)

Возвращает информацию о рынке по заданному режиму; в автономном режиме возвращает фиктивные значения

Функция void RefreshRates()

Обновляет текущие котировки; в автономном режиме является пустой функцией

Функция bool IsTradeContextBusy()

Проверяет занятость торгового контекста; в автономном режиме всегда возвращает false

Методы и конструкторы
Конструктор · CEngine CEngine()

Конструктор класса CEngine, инициализирующий внутренние массивы и счётчики

Метод · CEngine void Init(int engineIndex, int magic, int swingStr, int minWaveBars, double minWaveAtr, int fastEMA, int slowEMA, double minADX, int maxTrades, int cooldownBars)

Настройка параметров движка: индекс, магическое число, сила свинга, минимальные бары волн, фактор ATR, периоды EMA, минимальный ADX, максимум сделок и кулдаун

Метод · CEngine void Process(double globalATR, double globalADX, datetime currentTime)

Основной метод обработки: обнаружение свингов, построение волн, поиск совпадающих паттернов, проверка условий и выполнение сделок

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

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

#ifndef ENGINE_MQH
#define ENGINE_MQH

#property strict

#include "PatternTypes.mqh"

#ifndef ENGINE_COUNT
#define ENGINE_COUNT 10
#endif

#ifndef MAX_PATTERNS
#define MAX_PATTERNS 65
#endif

#ifndef DBL_MAX
#define DBL_MAX 1.7976931348623158e+308
#endif

#ifndef PATTERNDATA_TYPE_DEFINED
#define PATTERNDATA_TYPE_DEFINED

struct PatternData
{
   bool   active;
   int    waveCount;
   int    directionSignature;
   float  fibs[16];
   float  durs[16];
   int    merrillCode;
   int    groupType;
   string name;
};

#endif // PATTERNDATA_TYPE_DEFINED

#ifndef IS_EA

bool     g_CachedTradeTime             = true;
bool     g_CachedRollover              = false;

bool     UseMomentum                   = true;
double   MinATR                        = 0.0005;

int      g_CachedSpread                = 0;
double   g_CachedClose1                = 0.0;
double   g_CachedOpen1                 = 0.0;
double   g_CachedRecentHigh10          = 0.0;
double   g_CachedRecentLow10           = 0.0;

int      LookbackBars                  = 500;

double   FibTolerance                  = 0.25;
double   MinConfidence                 = 55.0;
double   DirMatchThreshold             = 0.65;

bool     UseMerrillRank                = true;
bool     DebugPrint                    = false;

int      MaximumSimultaneousOrders     = 50;
bool     AllowMultipleEngines          = true;

string   TradeComment                  = "MW";
int      Slippage                      = 30;
double   LotSize                       = 0.01;
int      MaxSpread                     = 120;

#ifndef SWING_CACHE_MQH

#ifndef ENGINE_SHARED_SWINGS_DEFINED
#define ENGINE_SHARED_SWINGS_DEFINED

int g_SharedSwingCount2 = 0;
int g_SharedSwingCount3 = 0;
int g_SharedSwingCount4 = 0;

int g_SharedMergedCount2 = 0;
int g_SharedMergedCount3 = 0;
int g_SharedMergedCount4 = 0;

Swing g_SharedMergedSwings2[];
Swing g_SharedMergedSwings3[];
Swing g_SharedMergedSwings4[];

#endif // ENGINE_SHARED_SWINGS_DEFINED

#endif // SWING_CACHE_MQH

double g_CachedFastEMA[ENGINE_COUNT];
double g_CachedSlowEMA[ENGINE_COUNT];

int g_CachedEAOpenOrders = 0;
int g_CachedEngineOrders[ENGINE_COUNT];

PatternData g_Patterns[MAX_PATTERNS];
int        g_PatternCount = 0;

int CountEAOpenOrders()
{
   return g_CachedEAOpenOrders;
}

bool HasOtherEngineTrade(int magic, int unused)
{

   return false;
}

#ifndef OP_BUY
#define OP_BUY 0
#endif

#ifndef OP_SELL
#define OP_SELL 1
#endif

#ifndef MODE_LOTSTEP
#define MODE_LOTSTEP 23
#endif

#ifndef MODE_MINLOT
#define MODE_MINLOT 22
#endif

#ifndef MODE_MAXLOT
#define MODE_MAXLOT 21
#endif

#ifndef MODE_DIGITS
#define MODE_DIGITS 17
#endif

#ifndef ERR_REQUOTE
#define ERR_REQUOTE 138
#endif

#ifndef ERR_OFF_QUOTES
#define ERR_OFF_QUOTES 136
#endif

#ifndef ERR_PRICE_CHANGED
#define ERR_PRICE_CHANGED 135
#endif

double Ask = 0.0;
double Bid = 0.0;

int Digits = 0;

int iBars(string symbol, int timeframe)
{
   return 0;
}

double iHigh(string symbol, int timeframe, int shift)
{
   return 0.0;
}

double iLow(string symbol, int timeframe, int shift)
{
   return 0.0;
}

double MarketInfo(string symbolName, int mode)
{
   if(mode == MODE_LOTSTEP)
      return 0.01;

   if(mode == MODE_MINLOT)
      return 0.01;

   if(mode == MODE_MAXLOT)
      return 100.0;

   if(mode == MODE_DIGITS)
      return 2.0;

   return 0.0;
}

void RefreshRates()
{
}

bool IsTradeContextBusy()
{
   return false;
}

int OrderSend(
   string sym,
   int cmd,
   double vol,
   double price,
   int slip,
   double sl,
   double tp,
   string cmt,
   int magic,
   int expiry,
   int clr
)
{

   return -1;
}

#endif // IS_EA

class CEngine
{
private:

   int    m_magic;
   int    m_engineNumber;
   int    m_swingStrength;
   int    m_minWaveBars;
   double m_minWaveAtrFactor;
   int    m_fastEMA;
   int    m_slowEMA;
   double m_minADX;
   int    m_maxTrades;
   int    m_cooldownBars;

   datetime m_lastTradeTime;

   Swing m_swings[];
   Swing m_mergedSwings[];

   int m_mergedSwingCount;

   Wave m_waves[];

   int m_swingCount;
   int m_waveCount;

   int  m_merrillRankCache[];
   bool m_merrillRankCached[];
   int  m_merrillCacheSize;

   int m_directionSignature3[];
   int m_directionSignature4[];
   int m_directionSignature6[];

public:

   CEngine()
   {
      ArrayResize(m_swings, 0);
      ArrayResize(m_mergedSwings, 0);
      ArrayResize(m_waves, 0);

      m_swingCount = 0;
      m_mergedSwingCount = 0;
      m_waveCount = 0;
      m_lastTradeTime = 0;

      m_merrillCacheSize = 0;

      ArrayResize(m_merrillRankCache, 0);
      ArrayResize(m_merrillRankCached, 0);

      ArrayResize(m_directionSignature3, 0);
      ArrayResize(m_directionSignature4, 0);
      ArrayResize(m_directionSignature6, 0);
   }

   void Init(int engineIndex, int magic, int swingStr, int minWaveBars, double minWaveAtr, 
             int fastEMA, int slowEMA, double minADX, 
             int maxTrades, int cooldownBars) 
   {
      m_engineNumber = engineIndex;
      m_magic = magic;
      m_swingStrength = swingStr;
      m_minWaveBars = minWaveBars;
      m_minWaveAtrFactor = minWaveAtr;
      m_fastEMA = fastEMA;
      m_slowEMA = slowEMA;
      m_minADX = minADX;
      m_maxTrades = maxTrades;
      m_cooldownBars = cooldownBars;
   }

   void Process(double globalATR, double globalADX, datetime currentTime)
   {
      DetectSwings();
      BuildWaves(globalATR);

      if(m_waveCount < 3)
         return;

      if(m_lastTradeTime > 0)
      {
         if(currentTime - m_lastTradeTime < m_cooldownBars * PeriodSeconds())
            return;
      }

      if(!g_CachedTradeTime)
         return;

      if(g_CachedRollover)
         return;

      if(globalATR < MinATR)
         return;

      if(g_CachedSpread > MaxSpread)
         return;

      FindAndTrade(globalATR, globalADX, currentTime);
   }

private:

   void DetectSwings()
   {
      if(m_swingStrength == 2)
      {
         m_swingCount = g_SharedSwingCount2;
         return;
      }

      if(m_swingStrength == 3)
      {
         m_swingCount = g_SharedSwingCount3;
         return;
      }

      if(m_swingStrength == 4)
      {
         m_swingCount = g_SharedSwingCount4;
         return;
      }

      m_swingCount = 0;

      int bars = iBars(_Symbol, _Period);
      int requiredSize = MathMin(bars - 1, LookbackBars);

      if(requiredSize <= m_swingStrength * 2)
         return;

      if(ArraySize(m_swings) < requiredSize)
         ArrayResize(m_swings, requiredSize);

      int limit = requiredSize;

      for(int i = m_swingStrength; i < limit - m_swingStrength; i++)
      {
         double h = iHigh(_Symbol, _Period, i);
         double l = iLow(_Symbol, _Period, i);

         bool isHigh = true;
         bool isLow  = true;

         for(int j = 1; j <= m_swingStrength; j++)
         {
            if(h <= iHigh(_Symbol, _Period, i + j) ||
               h <= iHigh(_Symbol, _Period, i - j))
            {
               isHigh = false;
            }

            if(l >= iLow(_Symbol, _Period, i + j) ||
               l >= iLow(_Symbol, _Period, i - j))
            {
               isLow = false;
            }

            if(!isHigh && !isLow)
               break;
         }

         if(isHigh)
         {
            m_swings[m_swingCount].bar   = i;
            m_swings[m_swingCount].price = h;
            m_swings[m_swingCount].type  = 1;
            m_swingCount++;
         }
         else if(isLow)
         {
            m_swings[m_swingCount].bar   = i;
            m_swings[m_swingCount].price = l;
            m_swings[m_swingCount].type  = -1;
            m_swingCount++;
         }
      }
   }

   bool GetMergedSwing(
      int index,
      int &bar,
      double &price,
      char &type
   )
   {
      if(index < 0 || index >= m_mergedSwingCount)
         return false;

      if(m_swingStrength == 2)
      {
         if(index >= g_SharedMergedCount2) return false;
         bar   = g_SharedMergedSwings2[index].bar;
         price = g_SharedMergedSwings2[index].price;
         type  = g_SharedMergedSwings2[index].type;
         return true;
      }

      if(m_swingStrength == 3)
      {
         if(index >= g_SharedMergedCount3) return false;
         bar   = g_SharedMergedSwings3[index].bar;
         price = g_SharedMergedSwings3[index].price;
         type  = g_SharedMergedSwings3[index].type;
         return true;
      }

      if(m_swingStrength == 4)
      {
         if(index >= g_SharedMergedCount4) return false;
         bar   = g_SharedMergedSwings4[index].bar;
         price = g_SharedMergedSwings4[index].price;
         type  = g_SharedMergedSwings4[index].type;
         return true;
      }

      bar   = m_mergedSwings[index].bar;
      price = m_mergedSwings[index].price;
      type  = m_mergedSwings[index].type;

      return true;
   }

   void BuildDirectionSignatureCaches()
   {
      int count = m_waveCount;

      if(count < 1)
      {
         ArrayResize(m_directionSignature3, 0);
         ArrayResize(m_directionSignature4, 0);
         ArrayResize(m_directionSignature6, 0);
         return;
      }

      ArrayResize(m_directionSignature3, count);
      ArrayResize(m_directionSignature4, count);
      ArrayResize(m_directionSignature6, count);

      int sig3 = 0;
      int sig4 = 0;
      int sig6 = 0;

      for(int i = 0; i < count; i++)
      {
         int bit = (m_waves[i].direction > 0) ? 1 : 0;

         sig3 = ((sig3 << 1) | bit) & 7;
         sig4 = ((sig4 << 1) | bit) & 15;
         sig6 = ((sig6 << 1) | bit) & 63;

         m_directionSignature3[i] = 0;
         m_directionSignature4[i] = 0;
         m_directionSignature6[i] = 0;

         if(i >= 2) m_directionSignature3[i - 2] = sig3;
         if(i >= 3) m_directionSignature4[i - 3] = sig4;
         if(i >= 5) m_directionSignature6[i - 5] = sig6;
      }
   }

   void BuildWaves(double atr)
   {
      int sourceCount = m_swingCount;

      if(m_swingStrength == 2)
      {
         m_mergedSwingCount = g_SharedMergedCount2;
      }
      else if(m_swingStrength == 3)
      {
         m_mergedSwingCount = g_SharedMergedCount3;
      }
      else if(m_swingStrength == 4)
      {
         m_mergedSwingCount = g_SharedMergedCount4;
      }
      else
      {
         if(sourceCount < 2)
         {
            m_mergedSwingCount = 0;
            m_waveCount = 0;
            m_merrillCacheSize = 0;
            ArrayResize(m_merrillRankCache, 0);
            ArrayResize(m_merrillRankCached, 0);
            ArrayResize(m_directionSignature3, 0);
            ArrayResize(m_directionSignature4, 0);
            ArrayResize(m_directionSignature6, 0);
            return;
         }

         m_mergedSwingCount = 0;

         if(ArraySize(m_mergedSwings) < sourceCount)
            ArrayResize(m_mergedSwings, sourceCount);

         int i = 0;

         while(i < sourceCount)
         {
            Swing current = m_swings[i];

            while(i + 1 < sourceCount)
            {
               Swing next = m_swings[i + 1];

               if(next.type != current.type)
                  break;

               if(current.type == 1)
               {
                  if(next.price > current.price)
                     current = next;
               }
               else
               {
                  if(next.price < current.price)
                     current = next;
               }

               i++;
            }

            m_mergedSwings[m_mergedSwingCount] = current;
            m_mergedSwingCount++;
            i++;
         }
      }

      if(m_mergedSwingCount < 2)
      {
         m_waveCount = 0;
         m_merrillCacheSize = 0;
         ArrayResize(m_merrillRankCache, 0);
         ArrayResize(m_merrillRankCached, 0);
         ArrayResize(m_directionSignature3, 0);
         ArrayResize(m_directionSignature4, 0);
         ArrayResize(m_directionSignature6, 0);
         return;
      }

      int requiredWaves = m_mergedSwingCount - 1;

      if(ArraySize(m_waves) < requiredWaves)
         ArrayResize(m_waves, requiredWaves);

      m_waveCount = 0;

      for(int k = requiredWaves - 1; k >= 0; k--)
      {
         int idx1 = k + 1;
         int idx2 = k;

         int bar1, bar2;
         double price1, price2;
         char type1, type2;

         if(!GetMergedSwing(idx1, bar1, price1, type1))
            continue;

         if(!GetMergedSwing(idx2, bar2, price2, type2))
            continue;

         int dur = (int)MathAbs(bar2 - bar1);

         if(dur < m_minWaveBars)
            continue;

         double amp = MathAbs(price2 - price1);

         if(amp < atr * m_minWaveAtrFactor)
            continue;

         m_waves[m_waveCount].amplitude = amp;
         m_waves[m_waveCount].duration  = dur;
         m_waves[m_waveCount].direction = pric

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

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

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

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

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

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

Стоимость полного кода
1 638,80₽ ≈ $20.03