English Deutsch 日本語
preview
Возможности Мастера MQL5, которые вам нужно знать (Часть 14): Многоцелевое прогнозирование таймсерий с помощью STF

Возможности Мастера MQL5, которые вам нужно знать (Часть 14): Многоцелевое прогнозирование таймсерий с помощью STF

MetaTrader 5Тестер | 31 июля 2024, 14:32
51 0
Stephen Njuki
Stephen Njuki

Введение

Статья (на английском) о пространственно-временном слиянии (Spatial Temporal Fusion, STF) пробудила мой интерес к этой теме благодаря своему двустороннему подходу к прогнозированию. Статья основана на решении задачи вероятностного прогнозирования, которая учитывает как спрос, так и предложение на платформах такси, таких как Uber и Didi. Совместные отношения спроса и предложения распространены на различных двусторонних рынках, таких как Amazon, Airbnb и eBay, где, по сути, компания не только обслуживает традиционного "клиента" или покупателя, но также обслуживает поставщиков клиента.

Таким образом, двустороннее прогнозирование может быть важным для этих компаний, если предложение частично зависит от спроса. Однако этот двойной прогноз спроса и предложения, безусловно, является отходом от традиционного метода прогнозирования конкретного значения на основе временного ряда или набора данных. В статье также представлена структура causaltrans, в которой причинно-следственные связи между спросом и предложением отражены в виде матрицы G и все прогнозы делались через сеть трансформеров (transformer network).

Опираясь на это, мы пытаемся спрогнозировать спрос и предложение на торгуемые ценные бумаги, используя медвежий и бычий настрой в качестве индикаторов этих двух показателей. Строго говоря, типичный класс Expert-Signal действительно вычисляет оба этих значения как целые числа в диапазоне от 0 до 100, как это можно видеть в файлах библиотеки MQL5 или файлах, которые мы уже написали в этой серии. Мы добавим пространственную матрицу и время при составлении наших прогнозов (два дополнительных входных параметра, взятых из статьи).

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

В упомянутой выше статье использовались сети траснформеров. Мы не будем их использовать, поскольку они неэффективны для наших целей, однако все прогнозы будут осуществляться с помощью специального многослойного перцептрона с написанным вручную кодом. С таким количеством библиотек и примеров кода по этой теме попытка написать собственный многослойный перцептрон будет пустой тратой времени. Однако используемый сетевой класс имеет длину менее 300 строк и достаточно масштабируем в плане настройки количества слоев и размера, чего до сих пор не хватает в большинстве доступных шаблонных библиотек.

Таким образом мы не будем применять здесь структуру causaltrans, используя вместо нее единую нейронную сеть вместо трансформеров. Тем не менее, у нас все еще много дел, поскольку нам по-прежнему необходимо реализовать двойное прогнозирование спроса и предложения, а также использовать в этом процессе пространственную матрицу и время. Любая торговая система сопряжена с рисками, поэтому читателю предлагается проявить осмотрительность, прежде чем использовать материал, представленный здесь, в своих наработках.



Иллюстрация STF

STF преимущественно используется в дистанционном зондировании и других областях, связанных с визуализацией, в которых могут удачно сочетаться параметры пространства и времени.

Если вы не слишком заинтересованы в изучении потенциала STF вне трейдинга, вы можете пропустить этот раздел и перейти к реализации средствами MQL5.

Если мы посмотрим на дистанционное зондирование, например, изображения, снятые со спутника, то увидим, что они содержат пространственный компонент данных и исследуемого региона, тогда как параметр времени будет относиться к моменту съемки. Такая информация может не только формировать временные ряды, но и иметь важное значение для прогнозирования изменений погоды, растительного мира или даже среды обитания животных в исследуемой зоне, и все это благодаря STF.

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

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

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

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

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

Таким образом, прогнозирование с помощью модели будет осуществляться при успешных результатах обучения и тестирования, причем главное, о чем следует помнить, — это интерпретация, поскольку большая часть нормализации уже была выполнена, для выходных данных модели необходимо тщательно выполнить процесс в обратном порядке.

В упоминавшейся выше статье, недавно принятой сообществом ACM, уравнения будущего спроса и предложения представлены следующим образом:

x v (t+δt) = f x (x v (t), G v (t), δt),

y v (t+δt) = f y (x v (t), y v (t), G v (t), δt),

где:

  • x v - функция спроса по времени,
  • y v - функция предложения по времени,
  • G v - вектор или матрица пространственных данных,
  • δt - прогнозное приращение времени,
  • t - время.

Итак, в нашем случае функции f x и f y будут нейронными сетями с векторами параметров или матрицами, содержащими данные, которые подаются на соответствующие входные слои.


Реализация STF с помощью MQL5

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

Итак, общее количество буферов, учитывая перекрытие обоих уравнений, равно 4. Все они присутствуют в уравнении предложения: предыдущий спрос, предыдущее предложение, пространственные значения и приращение времени.

Буфер спроса интерпретируется как буфер временных рядов "бычьих" цен. Возможно, более кратким буфером мог бы быть реальный объем долгосрочных контрактов, но брокеры редко делятся такой информацией, и даже если бы они это делали, эти данные не были бы точным представлением объема, учитывая нестабильный характер информации об объемах на рынках Форекс. Таким образом, в качестве альтернативы реальным долгосрочным контрактам выбраны максимальные цены за вычетом цен открытия. Другими возможными буферами, которые могли бы выполнить эту роль, могли бы быть показатели, специфичные для конкретной валюты, такие как процентные ставки, инфляция или даже индексы денежной массы центрального банка. Выбор максимумов минус цены открытия в качестве буфера предназначен для измерения восходящей волатильности. Поскольку это положительно коррелирует с долгосрочными контрактами, они используются в качестве следующего лучшего показателя. Эти значения могут быть только положительными или нулевыми, при этом нулевое значение указывает на фигуру "повешенный" или флетовый ценовой бар.

Буфер предложения, как и его предшественник, описанный выше, также будет аппроксимироваться путем расчета цен открытия минус цен минимума. Это также можно рассматривать как показатель нисходящей волатильности, которая положительно коррелирует с медвежьими контрактами. Аналогично, значения буфера будут только положительными, нулевое значение указывает на фигуру "дожи-надгробие" или флетовый бар. Уравнение предложения отличается от спроса тем, что оно требует большего количества входных данных. Таким образом, планируется два экземпляра модели прогнозирования: один для спроса, другой для предложения. Поскольку нашим конечным результатом является получение единственного сигнала, прогноз предложения будет вычитаться из прогноза спроса. Напомню, что все входные данные для модели спроса и предложения являются положительными или нулевыми, поэтому, по всей вероятности, такими же должны быть и выходные данные, поэтому, вычитая выходные данные модели предложения из выходных данных спроса, мы получаем двойное число, положительное значение которого будет указывать на бычий настрой, а отрицательное - на медвежий.

Выбор временного буфера является индексом дня недели. Тестирование, о котором рассказывается в следующем разделе, будет проводиться на дневном временном интервале, поэтому индекс дня недели легко привязать к нему. Если нужно было бы выбрать другой временной интервал, скажем, меньший, чем дневной, тогда можно было бы рассмотреть индекс, охватывающий либо день, либо даже неделю. Например, при 8-часовом таймфрейме в торговую неделю вмещается пятнадцать 8-часовых баров, что дает пятнадцать возможных временных индексов внутри недели. Вы можете выбрать час дня или торговую сессию дня и т. д. Вариантов здесь много, и лучшим подходом может быть предварительное тестирование, чтобы выбрать то, что лучше всего подходит для вашей торговой системы. Наша простая функция, возвращающая индекс дня недели, выглядит следующим образом:

//+------------------------------------------------------------------+
//| Temporal (Time) Indexing function                                |
//+------------------------------------------------------------------+
int CSignalNetwork::T(datetime Time)
{  MqlDateTime _dt;
   if(TimeToStruct(Time,_dt))
   {  if(_dt.day_of_week==TUESDAY)
      {  return(1);
      }
      else if(_dt.day_of_week==WEDNESDAY)
      {  return(2);
      }
      else if(_dt.day_of_week==THURSDAY)
      {  return(3);
      }
      else if(_dt.day_of_week==FRIDAY||_dt.day_of_week==SATURDAY)
      {  return(4);
      }
   }
   return(0);
}

Матрица G фиксирует наши пространственные данные для этой модели. Как мы определяем пространство в торговой среде ценных бумаг? Например, в упомянутой статье, перекрестную таблицу метаданных между спросом и предложением "нормализуют", пропуская ее через "трансформеры внимания к графику" (Graph Attention Transformers, GAT). Они работают на двух уровнях: первый уровень фиксирует сложные взаимосвязи узлов, а второй объединяет информацию о соседях для окончательных прогнозов узла. Показания GAT затем становятся частью информации, передаваемой через соответствующие нейронные сети для прогнозирования спроса или предложения. В нашем случае метаданные для наших бычьих и медвежьих ценовых буферов будут получены из показаний корреляции, общих для этих буферов. Эти корреляции фиксируются, как показано в коде ниже:

//+------------------------------------------------------------------+
//| Spatial (Space) Indexing function. Returns Matrix Determinant    |
//| This however can be customised to return all matrix values as    |
//| a vector, depending on the detail required.                      |
//+------------------------------------------------------------------+
double CSignalNetwork::G(vector &X,vector &Y)
{  matrix _m;
   if(X.Size()!=2*m_train_set||Y.Size()!=2*m_train_set)
   {  return(0.0);
   }
   _m.Init(2,2);
   vector _x1,_x2,_y1,_y2;
   _x1.Init(m_train_set);_x1.Fill(0.0);
   _x2.Init(m_train_set);_x2.Fill(0.0);
   _y1.Init(m_train_set);_y1.Fill(0.0);
   _y2.Init(m_train_set);_y2.Fill(0.0);
   for(int i=0;i<m_train_set;i++)
   {  _x1[i] = X[i];
      _x2[i] = X[i+m_train_set];
      _y1[i] = Y[i];
      _y2[i] = Y[i+m_train_set];
   }
   _m[0][0] = _x1.CorrCoef(_x2);
   _m[0][1] = _x1.CorrCoef(_y2);
   _m[1][0] = _y1.CorrCoef(_x2);
   _m[1][1] = _y1.CorrCoef(_y2);
   return(_m.Det());
}


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

Учитывая все упомянутые четыре буфера данных, возможно, будет полезно поговорить о нашей очень элементарной модели, которая представляет собой простую нейронную сеть, написанную без использования каких-либо библиотек. Мы разбиваем сеть на ее самые основные компоненты (входы, веса, смещения, скрытые выходы, выходы и цель) и используем только их при прямом и обратном распространении. Наш сетевой интерфейс выглядит так:

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class Cnetwork
{
protected:
   matrix            weights[];
   vector            biases[];

   vector            inputs;
   vector            hidden_outputs[];
   vector            target;

   int               hidden_layers;
   double            Softplus(double X);
   double            SoftplusDerivative(double X);

public:
   vector            output;

   void              Get(vector &Target)
   {                 target.Copy(Target);
   }

   void              Set(vector &Inputs)
   {                 inputs.Copy(Inputs);
   }
   
   bool              Get(string File, double &Criteria, datetime &Version);
   bool              Set(string File, double Criteria);

   void              Forward();
   void              Backward(double LearningRate);

   void              Cnetwork(int &Settings[],double InitialWeight,double InitialBias)
   {                 
                        
                        ...
                        ...

   };
   void              ~Cnetwork(void) { };
};

Помимо общих функций для установки и получения входных данных и целевых значений, мы также включили некоторые функции экспорта весов и смещений после обучения. Алгоритм прямого прохода является обычным, использует soft-plus для активации на каждом уровне, а функция обратного распространения ошибки также является стандартной и основана на методах цепочки и градиентного спуска при настройке весов и смещений сети. Однако для инициализации сети требуются некоторые входные данные, и они проходят "проверку", прежде чем экземпляр класса можно будет безопасно использовать. Входными данными для создания сети являются массив настроек, значение начальных весов (по всей сети), а также начальные значения смещения. Массив настроек определяет количество скрытых слоев, которые будет иметь сеть по своему размеру, а каждое целое число в его индексах задает размер соответствующего слоя.

   void              Cnetwork(int &Settings[],double InitialWeight,double InitialBias)
   {                 int _size =    ArraySize(Settings);
                     if(_size >= 2 && _size <= USHORT_MAX && Settings[ArrayMinimum(Settings)] > 0 && Settings[ArrayMaximum(Settings)] < USHORT_MAX)
                     {  ArrayResize(weights, _size - 1);
                        ArrayResize(biases, _size - 1);
                        ArrayResize(hidden_outputs, _size - 2);
                        hidden_layers = _size - 2;
                        for(int i = 0; i < _size - 1; i++)
                        {  weights[i].Init(Settings[i + 1], Settings[i]);
                           weights[i].Fill(InitialWeight);
                           biases[i].Init(Settings[i + 1]);
                           biases[i].Fill(InitialBias);
                           if(i < _size - 2)
                           {  hidden_outputs[i].Init(Settings[i + 1]);
                              hidden_outputs[i].Fill(0.0);
                           }
                        }
                        output.Init(Settings[_size - 1]);
                        target.Init(Settings[_size - 1]);
                     }
                     else
                     {  printf(__FUNCSIG__ + " invalid network settings. ");
                        //~Cnetwork(void);
                     }
   };


Поскольку мы прогнозируем как спрос, так и предложение, нам понадобятся два отдельных экземпляра нашей сети — по одному для выполнения каждой задачи. Наша функция вывода get, которая действует как источник для функций Check Open Long и Check Open Short, заполнит соответствующие входные слои каждой сети буферами данных, уже упомянутыми выше. Что касается спроса, поскольку он зависит только от своих предыдущих значений, а также параметров пространства и времени, его входной слой имеет размер 3. Однако на предложение, в дополнение к зависимости от его предыдущих значений, может влиять предыдущий спрос, поэтому его входной слой имеет размер 4 при условии аналогичных входных данных пространства и времени. Заполнение этих слоев обрабатывается функцией вывода get для каждого нового бара следующим образом:

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double CSignalNetwork::GetOutput()
{  

        ...
        ...

   for(int i = 0; i < m_train_set; i++)
   {  for(int ii = 0; ii < __LONGS_INPUTS; ii++)
      {  if(ii==0)//time
         {  m_model_longs.x[i][ii] = T(m_time.GetData(i));
         }
         else if(ii==1)//spatial matrix
         {  vector _x,_y;
            _x.CopyRates(m_symbol.Name(),m_period,2,StartIndex() + ii + i,2*m_train_set);
            _y.CopyRates(m_symbol.Name(),m_period,4,StartIndex() + ii + i,2*m_train_set);
            m_model_longs.x[i][ii] = G(_x,_y);
         }
         else if(ii==2)//demand
         {  m_model_longs.x[i][ii] = (m_high.GetData(StartIndex() + ii + i) - m_open.GetData(StartIndex() + ii + i));
         }
      }
      if(i > 0) //assign classifier 
      {  m_model_longs.y[i - 1] = (m_high.GetData(StartIndex() + i - 1) - m_open.GetData(StartIndex() + i - 1));
      }
   }
   for(int i = 0; i < m_train_set; i++)
   {  for(int ii = 0; ii < __SHORTS_INPUTS; ii++)
      {  if(ii==0)//time
         {  m_model_shorts.x[i][ii] = T(m_time.GetData(i));
         }
         else if(ii==1)//spatial matrix
         {  vector _x,_y;
            _x.CopyRates(m_symbol.Name(),m_period,4,StartIndex() + ii + i,2*m_train_set);
            _y.CopyRates(m_symbol.Name(),m_period,2,StartIndex() + ii + i,2*m_train_set);
            m_model_shorts.x[i][ii] = G(_x,_y);
         }  
         else if(ii==2)//demand
         {  m_model_shorts.x[i][ii] = (m_high.GetData(StartIndex() + ii + i) - m_open.GetData(StartIndex() + ii + i));
         }  
         else if(ii==3)//supply
         {  m_model_shorts.x[i][ii] = (m_open.GetData(StartIndex() + ii + i) - m_low.GetData(StartIndex() + ii + i));
         }
      }
      if(i > 0) //assign classifier
      {  m_model_shorts.y[i - 1] = (m_open.GetData(StartIndex() + i - 1) - m_low.GetData(StartIndex() + i - 1));
      }
   }

        ...
        ...

}

После этого мы назначаем входные и целевые значения для двух сетей, получая эту информацию из структуры модели в циклах обучения, где каждый цикл проходит по сетям в течение заданного количества эпох. В результате предварительного тестирования было обнаружено, что идеальное количество эпох составляет около 10 000 при скорости обучения 0,5 на цикл обучения. Это, безусловно, требует больших вычислительных ресурсов, поэтому в результатах тестов, представленных в следующем разделе, используются очень консервативные значения около 250 эпох.

Функция вывода set позволяет нам регистрировать веса и смещения сети на каждом проходе, при условии, что результаты прохода превосходят критерии, установленные весами, использованными при инициализации. При инициализации есть возможность считывать веса, и критерии, установленные этими весами, служат ориентиром для текущего теста.


Тестовые запуски

Проведем тестовые прогоны на паре EURUSD на дневном таймфрейме за 2023 год с очень простыми настройками сети. Сеть прогнозирования спроса имеет в общей сложности 3 слоя, один из которых скрыт, а их размеры — 3, 5 и 1. Сеть прогнозирования предложения также имеет три слоя, но, как указано выше, входной слой имеет другой размер, поэтому их размеры равны 4, 5 и 1. 1 в конце обеих сетей хранит выходные данные каждой сети.

Как всегда, добавление кода, приложенного в конце этой статьи, в советник осуществляется с помощью Мастера MQL5. Если вы незнакомы с ним, пожалуйста, обратитесь к следующим статьям: первая и вторая.

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

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

rep

Кривая эквити:

curv

Как видим, в течение года было размещено слишком мало сделок, что неплохо, потому что их качество было стабильным, поскольку они удерживались в течение длительных периодов времени до тех пор, пока не сработали развороты сигналов. В данном тестовом периоде они пережили минимальные просадки. Однако проблема заключается в том, что на флэтовых или нестабильных рынках часто бывает разумно, особенно в случаях, когда используется кредитное плечо, уделять особое внимание микродвижениям цены. В системе, которую мы тестировали, мы использовали дневной таймфрейм, и это нормально, поскольку он дает общую картину, но для решения наших задач, нам пришлось бы рассмотреть меньшие таймфреймы, вероятно, 4 часа или даже 1 час. В этом случае потребление вычислительных ресурсов для тестирования значительно вырастет. Не будет преувеличением сказать, что эта зависимость является экспоненциальной. Имейте в виду, что это была очень элементарная сеть из трех слоев со скрытым слоем, имеющим 5 точек, и пространственной матрицей, сведенной к определителю. Все эти факторы важны, потому что, когда мы имеем дело с меньшими таймфреймами, необходимость фильтровать шум становится еще более важной, и один из лучших способов сделать это — проявить немного педантичности. 

Кроме того, в указанном классе сети есть функции, которые помогают импортировать и экспортировать настройки веса и смещения сети в начале и конце каждого прохода. Я не использовал их для этих тестовых прогонов, поскольку это также немного замедляло процесс, но их нужно было бы использовать при тестировании в течение длительных периодов времени (для этого теста мы рассматривали только один год). При их использовании необходимо тщательно взвешивать критерии, по которым проводятся тестовые прогоны, поскольку по умолчанию в классе сети большие значения означают лучший результат. Таким образом, если кого-то больше беспокоит, например, просадка, то код, прикрепленный в сетевом классе, необходимо соответствующим образом изменить, чтобы отразить это так, чтобы при каждом прогоне веса, записанные в файл, обновлялись только в том случае, если значение критерия этого прогона МЕНЬШЕ предыдущего значения. Это также означает, что начальное значение или значение по умолчанию при каждом запуске должно быть DBL_MAX или достаточно большим, чтобы избежать ненужных ошибок.


Заключение

Способность STF выполнять двойное прогнозирование, безусловно, представляет собой интересный подход, который не очень распространен и, несомненно, имеет потенциал для улучшения. Например, матрица G для пространственной информации, используемая в нашем тестировании, может быть расширена до n x n путем разделения векторов входных данных на более мелкие части, и даже каждое из ее значений может быть точками входных данных для сети, а также многими другими корректировками. Однако эти изменения происходят за счет вычислительных ресурсов.

Реализация STF с помощью нейронной сети — трудоемкая задача, требующая тестирования на довольно больших объемах данных для получения надежной перекрестной проверки. Это его основное ограничение, которое становится еще более очевидным при реализации в цитируемой выше статье, где использовались сетевые трансформеры.

Однако этот аспект постепенно осознается индустрией. В частности, мы видим, что NVIDIA становится все более активной в этой сфере. Можно изучить альтернативные, более эффективные модели, такие как случайные леса, при условии, что сопутствующие настройки также не слишком сложны, но по мере того, как затраты на вычисления начинают снижаться, рентабельность этого подхода может оказаться сомнительной.

В свою очередь, Мастер MQL5 остается инструментом для быстрого прототипирования и тестирования идей, что и было продемонстрировано в этой статье.



Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/14552

Прикрепленные файлы |
Network.mqh (10.87 KB)
SignalWZ_14_aa.mqh (14.03 KB)
nn_a.mq5 (6.59 KB)
Разработка системы репликации (Часть 43): Проект Chart Trade (II) Разработка системы репликации (Часть 43): Проект Chart Trade (II)
Большинство людей, которые хотят или мечтают научиться программировать, на самом деле не имеют представления о том, что делают. Их деятельность заключается в попытках создавать вещи определенным образом. Однако программирование – это вовсе не подгонка под ответ подходящих решений. Если действовать таким образом, можно создать больше проблем, чем решений. Здесь мы будем делать нечто более продвинутое и, следовательно, другое.
Машинное обучение и Data Science (Часть 21): Сравниваем алгоритмы оптимизации в нейронных сетях Машинное обучение и Data Science (Часть 21): Сравниваем алгоритмы оптимизации в нейронных сетях
В этой статье мы заглянем в самую глубь нейронных сетей и поговорим об используемых в них алгоритмах оптимизации. В частности обсудим ключевые методы, которые позволяют раскрыть потенциал нейронных сетей и повысить точность и эффективность моделей.
Особенности написания экспертов Особенности написания экспертов
Написание и тестирование экспертов в торговой системе MetaTrader 4.
Разрабатываем мультивалютный советник (Часть 16): Влияние разных историй котировок на результаты тестирования Разрабатываем мультивалютный советник (Часть 16): Влияние разных историй котировок на результаты тестирования
Разрабатываемый советник должен показывать хорошие результаты при торговле у разных брокеров. Но мы пока что для тестов использовали котировки с демо-счёта от MetaQuotes. Посмотрим, готов ли наш советник к работе на торговом счёте с другими котировками по сравнению с теми, которые использовались при тестировании и оптимизации.