Нейросетевой предиктор на ALGLIB в MQL5: Руководство

Нейросетевой предиктор на ALGLIB в MQL5: Руководство КРЕДИТЫ, ИПОТЕКА и БАНКИ
Пошаговое руководство по созданию нейросетевого предиктора (MLP) на базе библиотеки ALGLIB в MQL5. Исходный код, разбор параметров и интеграция в советник.
Суть: Для создания нейросетевого предиктора в MQL5 не нужно подключать внешние Python-скрипты или DLL. Достаточно использовать встроенный порт библиотеки ALGLIB. Мы реализуем класс многослойного перцептрона (MLP), обучим его прямо в терминале методом Левенберга-Марквардта на разностях цен и получим прогноз направления следующего бара.

Исходный код

Ниже представлен чистый объектно-ориентированный код класса предиктора CMLPPredictor и пример его интеграции в торговый советник (EA). Код использует современные нативные типы данных MQL5 (matrix и vector) для удобной подготовки обучающей выборки.

//+------------------------------------------------------------------+
//|                                                 MLPPredictor.mq5 |
//|                                      Copyright 2024, Finfluct.com|
//|                                              https://finfluct.com|
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Finfluct.com"
#property link      "https://finfluct.com"
#property version   "1.00"

// Подключаем модуль анализа данных ALGLIB
#include 

//+------------------------------------------------------------------+
//| Класс нейросетевого предиктора на базе ALGLIB MLP                |
//+------------------------------------------------------------------+ 
class CMLPPredictor
{
private:
   CMultilayerPerceptron m_network;  // Объект нейросети ALGLIB
   CMLPReport            m_report;   // Отчет об обучении
   int                   m_inputs;   // Количество входов (фичей)
   int                   m_hidden;   // Количество нейронов в скрытом слое
   int                   m_outputs;  // Количество выходов (1 для регрессии)

public:
   CMLPPredictor(const int inputs, const int hidden, const int outputs)
   {
      m_inputs = inputs;
      m_hidden = hidden;
      m_outputs = outputs;
   }

   // Обучение модели на исторических данных
   bool Train(const matrix &X, const vector &y, const double decay = 0.001, const int restarts = 2)
   {
      int npoints = (int)X.Rows();
      if(npoints == 0)
      {
         Print("Ошибка: пустая матрица признаков.");
         return false;
      }

      // Подготовка обучающей выборки в формате ALGLIB (X и Y в одной матрице)
      CMatrixDouble xy;
      xy.Resize(npoints, m_inputs + m_outputs);

      for(int i = 0; i < npoints; i++)
      {
         for(int j = 0; j < m_inputs; j++)
         {
            xy.Set(i, j, X[i][j]);
         }
         for(int j = 0; j < m_outputs; j++)
         {
            xy.Set(i, m_inputs + j, y[i]);
         }
      }

      // Инициализация структуры сети (1 скрытый слой с гиперболическим тангенсом)
      CMLPCreate1(m_inputs, m_hidden, m_outputs, m_network);

      // Обучение методом Левенберга-Марквардта (LM)
      int info = 0;
      CMLPTrainLM(m_network, xy, npoints, decay, restarts, info, m_report);

      if(info < 0)
      {
         Print("Ошибка обучения ALGLIB MLP. Код ошибки: ", info);
         return false;
      }

      return true;
   }

   // Получение предсказания
   double Predict(const vector &features)
   {
      if((int)features.Size() != m_inputs)
      {
         Print("Ошибка: размер вектора фичей не совпадает с количеством входов.");
         return 0.0;
      }

      double x_in[];
      double y_out[];
      ArrayResize(x_in, m_inputs);
      ArrayResize(y_out, m_outputs);

      for(int i = 0; i < m_inputs; i++)
      {
         x_in[i] = features[i];
      }

      CMLPProcess(m_network, x_in, y_out);
      return y_out[0];
   }
};

//+------------------------------------------------------------------+
//| Интеграция предиктора в советник                                 |
//+------------------------------------------------------------------+
input int      InpInputs      = 5;     // Количество лагов цены (фичи)
input int      InpHidden      = 8;     // Нейроны в скрытом слое
input int      InpTrainBars   = 500;   // Глубина истории для обучения

CMLPPredictor *predictor = NULL;

int OnInit()
{
   predictor = new CMLPPredictor(InpInputs, InpHidden, 1);
   return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
   if(predictor != NULL)
      delete predictor;
}

void OnTick()
{
   static datetime last_bar = 0;
   datetime current_bar = iTime(_Symbol, _Period, 0);
   if(current_bar == last_bar) return;
   last_bar = current_bar;

   // Сбор данных для обучения
   matrix X;
   vector y;
   X.Init(InpTrainBars - InpInputs, InpInputs);
   y.Init(InpTrainBars - InpInputs);

   double closes[];
   ArraySetAsSeries(closes, true);
   if(CopyClose(_Symbol, _Period, 1, InpTrainBars, closes) < InpTrainBars) return;

   // Заполняем фичи разностями цен (стационарный ряд)
   for(int i = 0; i < InpTrainBars - InpInputs - 1; i++)
   { 
      for(int j = 0; j < InpInputs; j++)
      {
         X[i][j] = closes[i + j] - closes[i + j + 1];
      }
      y[i] = closes[i] - closes[i + 1]; // Целевая переменная
   }

   // Обучаем модель
   if(predictor.Train(X, y))
   { 
      vector current_features;
      current_features.Init(InpInputs);
      for(int j = 0; j < InpInputs; j++)
      {
         current_features[j] = closes[j] - closes[j + 1];
      }

      double prediction = predictor.Predict(current_features);
      Print("Предсказание изменения цены: ", DoubleToString(prediction, _Digits));

      if(prediction > 0)
         Print("Сигнал: BUY");
      else if(prediction < 0)
         Print("Сигнал: SELL");
   }
}

Разбор параметров

Для гибкой настройки нейросети крайне важно понимать ключевые параметры инициализации и обучения:

  • inputs: Количество входных признаков (фичей). В нашем примере это InpInputs — разности цен закрытия предыдущих баров.
  • hidden: Число нейронов в скрытом слое. Определяет емкость сети. Слишком маленькое значение приведет к недообучению, слишком большое — к переобучению (overfitting).
  • outputs: Количество выходов сети. Для задач регрессии (прогноз величины изменения цены) используется 1 выход.
  • decay: Коэффициент регуляризации (весового затухания). Помогает предотвратить переобучение, штрафуя модель за слишком большие веса.
  • restarts: Количество случайных перезапусков алгоритма оптимизации. Позволяет избежать попадания в локальные минимумы при обучении.

Как запустить

Чтобы запустить нейросетевой предиктор на своем торговом счете, выполните следующие шаги:

1. Убедитесь, что у вас установлена стандартная библиотека ALGLIB. Она поставляется вместе с терминалом MetaTrader 5 и находится в папке MQL5\Include\Math\Alglib\.

2. Создайте нового эксперта в MetaEditor, скопируйте туда представленный выше код и скомпилируйте его.

3. При практическом применении полученных сигналов критически важно фильтровать рыночные шумы. Резкое расширение спреда способно уничтожить математическое ожидание любой нейросети. Чтобы избежать этого, интегрируйте в свой советник Фильтр максимального спреда в MQL4: Защита ночного скальпера (логика легко адаптируется под MQL5).

4. Если вы решите усложнить логику и проводить дообучение (Reinforcement Learning) на основе результатов закрытых сделок, вам понадобится надежный доступ к истории ордеров. Обязательно изучите руководство по Обходу лимитов HistorySelect в MQL5, чтобы избежать пропусков данных при анализе торговой истории.

5. Для оперативного контроля за процессом обучения сети на удаленном VPS и отправки логов предсказаний в реальном времени настройте Асинхронный Telegram-бот в MQL5 через Socket API.

Оцените статью
FinFluct