Обсуждение статьи "Нейросети в трейдинге: Рекуррентное моделирование микродвижений рынка (Окончание)"

 

Опубликована статья Нейросети в трейдинге: Рекуррентное моделирование микродвижений рынка (Окончание):

Реализация фреймворка EV-MGRFlowNet демонстрирует его ключевые преимущества: модульность, устойчивость к рыночным колебаниям и способность к самостоятельной выработке стратегии. Эти особенности делают фреймворк мощным инструментом для анализа, прогнозирования и развития автономных торговых стратегий.

После интерграции фреймворк EV-MGRFlowNet в Энкодер состояния окружающей среды, наша модель готова выйти на первую тренировочную арену. Этот этап можно сравнить с репетицией начинающего трейдера на исторических данных. Она получает карту прошлого рынка, изучает движения цен и пытается понять, как вести себя в разных ситуациях.

Представьте, что EURUSD за период с Января 2024 по Июнь 2025 года — это её тренировочная площадка. Модель, словно новичок на бирже, смотрит на каждую свечу, изучает объёмы и скрытые закономерности между ключевыми признаками. А EV-MGRFlowNet — её наставник: подсказывает, куда обратить внимание, формирует информативное состояние для Актёра и Критика, подталкивает к выработке интуиции трейдера. С каждым шагом она учится прогнозировать движение рынка и оценивать риски, постепенно превращаясь из ученицы в уверенного практиканта.

Следующий этап — онлайн-тренировка в реальном времени через тестер стратегий MetaTrader 5. Теперь нет роскошного спокойствия исторических данных. Каждая свеча — как живая реакция рынка. Модель реагирует моментально, анализирует шумовые колебания, приспосабливается к резким всплескам и корректирует свои действия при низкой ликвидности. EV-MGRFlowNet действует как невидимый наставник, удерживая сеть от ошибок, подсказывая, когда действовать смело, а когда проявить осторожность. Базовая структура, выстроенная на исторических данных, остаётся её опорой, но теперь модель учится гибко реагировать на текущую ситуацию, словно трейдер с опытом живой торговли.

Финальный экзамен — тестирование модели на новых данных за Июль–Сентябрь 2025 года. Все навыки, накопленные на предыдущих этапах, проверяются на честность: никаких подсказок, только рынок и её собственные решения. Результаты тестирования представлены ниже.

Автор: Dmitriy Gizlyk

 

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

Пожалуйста, подскажите - куда смотреть, что запускать?

Скриншот

 
Vadim Zotov #:

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

Пожалуйста, подскажите - куда смотреть, что запускать?


Добрый вечер, Вадим.
Название папок соответствует моделям. К данной статье "MQL5\Experts\EVMGRFlowNet\"
 
Dmitriy Gizlyk #:
Добрый вечер, Вадим.
Название папок соответствует моделям. К данной статье "MQL5\Experts\EVMGRFlowNet\"
Понял. Спасибо!
 
Здравствуйте, при компиляции ругается. Что могу делать не так?
Файлы:
hgn_mg7bp.jpg  98 kb
 
djgagarin #:
Здравствуйте, при компиляции ругается. Что могу делать не так?

У вас ошибка в файле, который не указан в статье.  Поэтому картинка ничем не поможет

Программы, используемые в статье

# Имя Тип Описание
1 Study.mq5 Советник Советник офлайн обучения моделей
2 StudyOnline.mq5 Советник Советник онлайн обучения моделей
3 Test.mq5 Советник Советник для тестирования модели
4 Trajectory.mqh Библиотека класса Структура описания состояния системы и архитектуры моделей
5 NeuroNet.mqh Библиотека класса Библиотека классов для создания нейронной сети
6 NeuroNet.cl Библиотека Библиотека кода OpenCL-программы


 
Rashid Umarov #:

У вас ошибка в файле, который не указан в статье.  Поэтому картинка ничем не поможет

Я взял файлы из нужной папки и разложил в правильные места, но файл  Study не компилируется.

 
djgagarin #:

Я взял файлы из нужной папки и разложил в правильные места, но файл  Study не компилируется.

Да, явно в таблице статьи не прописано. По ошибкам компилятора определил, что нужно скопировать еще 2 папки - выделил красным


 
djgagarin #:
Здравствуйте, при компиляции ругается. Что могу делать не так?

Добрый день,

Откуда Вы брали "...\Trajectory.mqh"?
Должен быть файл из вложения с функцией

bool CreateDescriptions(CArrayObj *&encoder,
                        CArrayObj *&stfs,
                        CArrayObj *&actor,
                        CArrayObj *&critic
                       )
  {
//---
   CLayerDescription *descr;
//---
   if(!encoder)
     {
      encoder = new CArrayObj();
      if(!encoder)
         return false;
     }
   if(!stfs)
     {
      stfs = new CArrayObj();
      if(!stfs)
         return false;
     }
   if(!actor)
     {
      actor = new CArrayObj();
      if(!actor)
         return false;
     }
   if(!critic)
     {
      critic = new CArrayObj();
      if(!critic)
         return false;
     }
//--- Encoder
   encoder.Clear();
//--- Input layer
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   uint prev_count = descr.count = (HistoryBars * BarDescr);
   descr.activation = None;
   descr.optimization = ADAM;
   if(!encoder.Add(descr))
     {
      delete descr;
      return false;
     }
   iLatentLayer = 0;
//--- layer 1
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBatchNormWithNoise;
   descr.count = prev_count;
   descr.batch = BatchSize;
   descr.activation = None;
   descr.optimization = ADAM;
   if(!encoder.Add(descr))
     {
      delete descr;
      return false;
     }
   iLatentLayer++;
//--- layer 2
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronConcatDiff;
   prev_count = descr.count = HistoryBars;
   descr.layers = BarDescr;
   descr.step = 1;
   descr.batch = BatchSize;
   descr.optimization = ADAM;
   descr.activation = None;
   if(!encoder.Add(descr))
     {
      delete descr;
      return false;
     }
   iLatentLayer++;
   uint prev_out = descr.layers * 2 ;
//--- layer 3
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defMamba4CastEmbeding;
   prev_count = descr.count = HistoryBars;
   descr.window = prev_out;
   prev_out = descr.window_out = NSkills;
     {
      uint temp[] = {PeriodSeconds(PERIOD_D1), PeriodSeconds(PERIOD_MN1)};
      if(ArrayCopy(descr.windows, temp) < (int)temp.Size())
         return false;
     }
   descr.batch = BatchSize;
   descr.optimization = ADAM;
   descr.activation = None;
   if(!encoder.Add(descr))
     {
      delete descr;
      return false;
     }
   iLatentLayer++;
//--- layer 4
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronEVMGRFlowNet;
     {
      uint temp[] = {prev_out,                  // Chanels In
                     32,
                     64,
                     128                        // Chanels Out
                    };
      if(ArrayCopy(descr.windows, temp) < (int)temp.Size())
         return false;
     }
   descr.count = prev_count;              // Units In
   descr.optimization = ADAM;
   descr.batch = BatchSize;
   if(!encoder.Add(descr))
     {
      delete descr;
      return false;
     }
   iLatentLayer++;
//---
   uint window = descr.windows[0];
   uint count = descr.count;
//--- STFS
   stfs.Clear();
//--- Input layer
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   descr.count = (window * count);
   descr.activation = None;
   descr.optimization = ADAM;
   if(!stfs.Add(descr))
     {
      delete descr;
      return false;
     }
//--- layer 1
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronSTFS;
     {
      uint temp[] = {window,              // Chanels In
                     BarDescr             // Chanels Out
                    };
      if(ArrayCopy(descr.windows, temp) < (int)temp.Size())
         return false;
     }
     {
      uint temp[] = {count,               // Units In
                     NForecast            // Units Out
                    };
      if(ArrayCopy(descr.units, temp) < (int)temp.Size())
         return false;
     }
   descr.activation = TANH;
   descr.optimization = ADAM;
   if(!stfs.Add(descr))
     {
      delete descr;
      return false;
     }
//--- layer 2
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBatchNormOCL;
   descr.count = NForecast * BarDescr;
   descr.batch = BatchSize;
   descr.activation = None;
   descr.optimization = ADAM;
   if(!stfs.Add(descr))
     {
      delete descr;
      return false;
     }
//--- Actor
   actor.Clear();
//--- Input layer
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   descr.count = AccountDescr;
   descr.activation = None;
   descr.optimization = ADAM;
   if(!actor.Add(descr))
     {
      delete descr;
      return false;
     }
//--- layer 1
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBatchNormOCL;
   descr.count = AccountDescr;
   descr.batch = BatchSize;
   descr.activation = None;
   descr.optimization = ADAM;
   if(!actor.Add(descr))
     {
      delete descr;
      return false;
     }
//--- layer 2
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronCrossDMHAttention;
     {
      uint temp[] = {AccountDescr,           // Inputs window
                     window                  // Cross window
                    };
      if(ArrayCopy(descr.windows, temp) < (int)temp.Size())
         return false;
     }
     {
      uint temp[] = {1,                      // Inputs units
                     count                   // Cross units
                    };
      if(ArrayCopy(descr.units, temp) < (int)temp.Size())
         return false;
     }
   descr.step = NHeads;                      // Heads
   descr.window_out = 32;
   descr.batch = 1e4;
   descr.layers = AttentionLayers;
   descr.activation = None;
   descr.optimization = ADAM;
   if(!actor.Add(descr))
     {
      delete descr;
      return false;
     }
//--- layer 3
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronSpikeConv;
   descr.count = 1;
   descr.window = AccountDescr;
   descr.step = AccountDescr;
   descr.window_out = EmbeddingSize;
   descr.variables = 1;
   descr.batch = BatchSize;
   descr.optimization = ADAM;
   if(!actor.Add(descr))
     {
      delete descr;
      return false;
     }
//--- layer 4
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronSpikeConv;
   descr.count = 1;
   descr.window = EmbeddingSize;
   descr.step = EmbeddingSize;
   descr.window_out = LatentCount;
   descr.variables = 1;
   descr.batch = BatchSize;
   descr.optimization = ADAM;
   if(!actor.Add(descr))
     {
      delete descr;
      return false;
     }
//--- layer 5
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   descr.count = 2 * NActions;
   descr.activation = SIGMOID;
   descr.optimization = ADAM;
   if(!actor.Add(descr))
     {
      delete descr;
      return false;
     }
//--- layer 6
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronVAEOCL;
   descr.count = NActions;
   descr.optimization = ADAM;
   if(!actor.Add(descr))
     {
      delete descr;
      return false;
     }
//--- layer 7
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronConvOCL;
   descr.count = NActions / 3;
   descr.window = 3;
   descr.step = 3;
   descr.window_out = 3;
   descr.activation = SIGMOID;
   descr.optimization = ADAM;
   if(!actor.Add(descr))
     {
      delete descr;
      return false;
     }
//--- Critic
   critic.Clear();
//--- Input layer
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   descr.count = NActions;
   descr.activation = None;
   descr.optimization = ADAM;
   if(!critic.Add(descr))
     {
      delete descr;
      return false;
     }
//--- layer 1
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBatchNormOCL;
   descr.count = NActions;
   descr.batch = BatchSize;
   descr.activation = None;
   descr.optimization = ADAM;
   if(!critic.Add(descr))
     {
      delete descr;
      return false;
     }
//--- layer 2
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronCrossDMHAttention;
     {
      uint temp[] = {3,                // Inputs window
                     window            // Cross window
                    };
      if(ArrayCopy(descr.windows, temp) < (int)temp.Size())
         return false;
     }
     {
      uint temp[] = {NActions / 3,     // Inputs units
                     count             // Cross units
                    };
      if(ArrayCopy(descr.units, temp) < (int)temp.Size())
         return false;
     }
   descr.step = NHeads;                     // Heads
   descr.window_out = 32;
   descr.batch = 1e4;
   descr.layers = AttentionLayers;
   descr.activation = None;
   descr.optimization = ADAM;
   if(!critic.Add(descr))
     {
      delete descr;
      return false;
     }
//--- layer 3
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronSpikeConv;
   descr.count = NActions / 3;
   descr.window = 3;
   descr.step = 3;
   descr.window_out = EmbeddingSize;
   descr.variables = 1;
   descr.batch = BatchSize;
   descr.optimization = ADAM;
   if(!critic.Add(descr))
     {
      delete descr;
      return false;
     }
//--- layer 4
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronSpikeConv;
   descr.count = NActions / 3;
   descr.window = EmbeddingSize;
   descr.step = EmbeddingSize;
   descr.window_out = LatentCount / descr.count;
   descr.variables = 1;
   descr.batch = BatchSize;
   descr.optimization = ADAM;
   if(!critic.Add(descr))
     {
      delete descr;
      return false;
     }
//--- layer 5
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   prev_count = descr.count = NRewards;
   descr.activation = None;
   descr.batch = BatchSize;
   descr.optimization = ADAM;
   if(!critic.Add(descr))
     {
      delete descr;
      return false;
     }
//---
   return true;
  }
Файлы:
Trajectory.mqh  70 kb
 

..продолжу. У вас ОЧЕНЬ интересные статьи. Мне все интересно, что касается нейронных сетей, в особенности в трейдинге. Стараюсь познавать что-то новое. Но в статьях, правда, ОЧЕНЬ не хватает инструкции, что, куда, из какой папки раскладывать, на каком фрейме запускать, чтобы получить ваш  же результат. В итоге все запустилось, только когда файл trajectory поместил в папку experts, хотя считал файлы *.mqh нужно копировать в папку include.

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

Я ни в коем случае не придираюсь к вам, мне правда очень интересно, что вы пишете и адаптируете на Mql, но многие прочитав и попытавшись запустить ваши работы, сталкиваются с ошибками компиляции, не зная что куда копировать. И, как результат, бросают и проходят мимо. Это только мои пожелания, как простого обывателя.

Теперь по поводу этой работы. Расскажу свои этапы запуска, а вы меня пожалуйста поправьте:

1. EURUSD H1

2. експерт Study. Выбрал тот же период времени, что указан в эксперте. (можно или нужно ли менять его и должен ли он в эксперте соответствовать мною выбранному периоду, отличного от вашего)

3. Создались 4 файла в папке files с расширением *.nnw

4. запуск StudyOnline на этом же периоде времени (если я правильно понимаю). Появляются торги. Закончил.

5. запуск Test на периоде теста. И тут просто сплошная линия баланса, ни одного трейда.


Что я делаю не так?

 Использовал те же временные промежутки, что указаны в статье, чтобы выйти на ваш результат.

 
djgagarin #:

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

Добрый день,
Прежде всего, спасибо за интерес к моим работам.
Папка Experts допускает наличие подкаталогов, что минимизирует путаницу даже при наличии одинаковых названий экспертов. К примеру, у меня в терминале выглядит так