Форум о трейдинге, автоматических торговых системах и тестировании торговых стратегий
Матрицы и векторы в MQL5. Поделитесь своим мнением
Слава, 2023.06.02 16:00
В конце 2021 года мы начали внедрять в MQL5 новые сущности - матрицы и векторы. В январе 2022 года в документации появился новый раздел "Типы данных - матрицы и векторы" и первый анонс "Новая версия платформы MetaTrader 5 build 3180: Векторы и матрицы в MQL5 и улучшенное удобство использования". Летом 2022 года в документации появился полноценный раздел "Методы матриц и векторов".
И работа продолжается. Мы пишем коды приложений (для внутреннего потребления и для статей) и сразу видим, что удобно, что неудобно, что нужно прямо сейчас, что в принципе необходимо, но может подождать. Однако нам нужно больше обратной связи. Возможно, у членов MQL5-сообщества есть идеи и предложения. Делитесь!
В свою очередь, я могу показать компактный код модели классификации
//+------------------------------------------------------------------+ //| NeuralNetworkClassification.mqh | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| neural network for classification model | //+------------------------------------------------------------------+ class CNeuralNetwork { protected : int m_layers; // layers count ENUM_ACTIVATION_FUNCTION m_activation_functions[]; // layers activation functions matrix m_weights[]; // weights matrices between layers vector m_values[]; // layer values vector m_values_a[]; // layer values after activation vector m_errors[]; // error values for back propagation public : //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CNeuralNetwork( const int layers, const int & layer_sizes[], const ENUM_ACTIVATION_FUNCTION & act_functions[]) { m_layers=layers; ArrayCopy (m_activation_functions,act_functions); ArrayResize (m_weights,layers- 1 ); ArrayResize (m_values,layers); ArrayResize (m_values_a,layers); ArrayResize (m_errors,layers); //--- init weight matrices with uniform random for ( int i= 0 ; i<m_layers- 1 ; i++) { double div= 32767.0 * layer_sizes[i]; // divider m_weights[i].Init(layer_sizes[i],layer_sizes[i+ 1 ]); for ( ulong j= 0 ; j<m_weights[i].Rows()*m_weights[i].Cols(); j++) m_weights[i].Flat(j, rand ()/div); } } //+------------------------------------------------------------------+ //| Forward pass | //+------------------------------------------------------------------+ void ForwardFeed( const vector & input_data, vector & vector_pred) { m_values_a[ 0 ]=input_data; for ( int i= 0 ; i<m_layers- 1 ; i++) { m_values[i+ 1 ]=m_values_a[i].MatMul(m_weights[i]); m_values[i+ 1 ].Activation(m_values_a[i+ 1 ],m_activation_functions[i+ 1 ]); } //--- predicted class probabilities vector_pred=m_values_a[m_layers- 1 ]; } //+------------------------------------------------------------------+ //| error back propagation | //+------------------------------------------------------------------+ void BackPropagation( const vector & vector_true, double learning_rate) { //--- categorical cross entropy loss gradient m_errors[m_layers- 1 ]=vector_true-m_values_a[m_layers- 1 ]; for ( int i=m_layers- 1 ; i> 0 ; i--) m_errors[i- 1 ].GeMM(m_errors[i],m_weights[i- 1 ], 1 , 0 , TRANSP_B ); //--- weights update for ( int i=m_layers- 1 ; i> 0 ; i--) { vector back; m_values[i].Derivative(back,m_activation_functions[i]); back*=m_errors[i]*learning_rate; m_weights[i- 1 ].GeMM(m_values_a[i- 1 ],back, 1 , 1 ); } } }; //+------------------------------------------------------------------+
Всего 60 строк чистого кода. Исключительно (кроме ArrayResize) матричные и векторные операции и методы. Это было сделано для нейронной сети "Hello world" - распознавание рукописных цифр на наборе картинок MNIST.
Вот конец журнала обучения и тестирования скрипта нейронной сети.
... 2023.06 . 02 16 : 54 : 21.608 mnist_original (GBPUSD,H1) Epoch # 15 2023.06 . 02 16 : 54 : 24.523 mnist_original (GBPUSD,H1) Time: 2.907 seconds. Right answers: 98.682 % 2023.06 . 02 16 : 54 : 24.523 mnist_original (GBPUSD,H1) Total time: 71 seconds 2023.06 . 02 16 : 54 : 24.558 mnist_original (GBPUSD,H1) Read 10000 images. Test begin 2023.06 . 02 16 : 54 : 24.796 mnist_original (GBPUSD,H1) Time: 0.234 seconds. Right answers: 96.630 %
Исходный код скрипта и исходные данные MNIST - во вложении
Форум о трейдинге, автоматизированных торговых системах и тестировании торговых стратегий
Как начать работать с Metatrader 5
Сергей Голубев, 2022.02.12 07:49
Матрицы и векторы в MQL5Используя специальные типы данных 'matrix' и 'vector', можно создавать код, очень близкий к математической нотации, избегая при этом необходимости создавать вложенные циклы или учитывать правильную индексацию массивов в вычислениях. В этой статье мы рассмотрим, как создавать, инициализировать и использовать объекты матрицы и вектора в MQL5.
Форум о трейдинге, автоматизированных торговых системах и тестировании торговых стратегий
Как начать работать с Metatrader 5
Сергей Голубев, 2023.02.11 03:41
Matrix Utils, расширение функционала стандартной библиотеки матриц и векторов - статья
В python класс Utils - это класс утилиты общего назначения с функциями и строками кода, которые мы можем использовать повторно, не создавая экземпляр класса.
Стандартная библиотека для матриц предоставляет нам некоторые очень важные функции и методы, которые мы можем использовать для инициализации, преобразования, работы с матрицами и многого другого, но, как и любая другая библиотека, она может быть расширена для выполнения дополнительных функций, которые могут быть необходимы в некоторых приложениях.
Форум о трейдинге, автоматизированных торговых системах и тестировании торговых стратегий
Как начать работать с Metatrader 5
Сергей Голубев, 2023.04.12 06:48
В этой статье мы кратко напомним теорию сетей обратного распространения и создадим универсальные классы для построения сетей по этой теории: приведенные формулы будут практически идентично отражены в исходном коде. Таким образом, новички смогут пройти все шаги при изучении этой технологии, не обращаясь к сторонним публикациям.
Если вы уже знаете теорию, то можете смело переходить ко второй части статьи, в которой рассматривается практическое использование классов в скрипте, индикаторе и советнике.
Матрицы и векторы в MQL5: Функции активации
Здесь мы опишем только один из аспектов машинного обучения - функции активации. Мы углубимся во внутреннюю работу этого процесса.

- www.mql5.com
Хотелось бы узнать, кто использует объекты векторов и матриц в MQL5?
- Я спрашиваю, потому что лично мне кажется, что они плохо проработаны в общей концепции. - Или, может быть, я не вижу примеров использования функциональности и API-дизайна, которые были созданы для этих двух объектов.
В документации есть глава, посвященная инициализации:
https://www.mql5.com/en/docs/matrix/matrix_initialization
Где говорится следующее:
Серьезно???
Какой в этом смысл или сценарий использования???? - Это можно было бы реализовать с помощью AVX. - Я вообще не представляю, какой крайний случай это должно покрыть, есть идеи?
Я имею в виду, что нет необходимости в сигнатуре переменной функции, это можно было бы легко сделать напрямую с помощью функции-члена, и любая функциональность, которая нуждалась бы во внешней настройке, могла бы быть сделана с помощью простого указателя функции, получающего предыдущее значение и счетчик и возвращающего текущее значение.
То есть вот так:
template <typename T> const T next_value(const ulong current_count, const T last_value) { return(last_value + 1.0); };
И BTW, как создать указатель на шаблонизированную функцию в MQL5? - Компилятор был расширен для специальной поддержки объектных типов матриц и векторов.
Еще одна аннотация, векторы можно использовать как массивы, даже со списками инициализации, они выделяются динамически. - К сожалению, они ограничены только типами double, float и сложными скалярными типами. - Это не имеет смысла.
Также тот факт, что матрица по умолчанию равна matrix<double> - это концепция, которая не поддерживается MQL5, а значит, для нас недоступна. - Почему??? - Какой смысл реализовывать объект таким "из ряда вон выходящим" способом?
И еще, пока я не забыл об этом: ALGLIB на CodeBase https://www.mql5.com/en/code/1146 не поддерживает матричные или векторные типы, у него есть свой объект представления для работы с матрицами..... Как следствие, реализация того, чем славится ALGLIB (скорость и гибкость), была более или менее обделена, векторы и матрицы должны поддерживать AVX при использовании, но для преобразования ALGLIB эти возможности пришлось убрать из библиотеки, так как они недоступны в MQL5 напрямую.
В заключение хочу сказать, что лично я считаю, что данная реализация не очень хорошо вписывается в MQL5 на данный момент и нуждается в некоторой чистке и переработке.

- www.mql5.com
Хотелось бы узнать, кто использует объекты векторов и матриц в MQL5?
- Я спрашиваю, потому что лично мне кажется, что они плохо проработаны в общей концепции. - Или, может быть, я не вижу примеров использования функциональности и API-дизайна, которые были созданы для этих двух объектов.
В документации есть глава, посвященная инициализации:
https://www.mql5.com/en/docs/matrix/matrix_initialization
Где говорится следующее:
Серьезно???
Какой в этом смысл или сценарий использования???? - Это можно было бы реализовать с помощью AVX. - Я вообще не представляю, какой крайний случай это должно покрыть, есть идеи?
Я имею в виду, что нет необходимости в сигнатуре переменной функции, это можно было бы легко сделать напрямую с помощью функции-члена, и любая функциональность, которая нуждалась бы во внешней настройке, могла бы быть сделана с помощью простого указателя функции, получающего предыдущее значение и счетчик и возвращающего текущее значение.
То есть вот так:
И BTW, как создать указатель на шаблонизированную функцию в MQL5? - Компилятор был расширен для специальной поддержки объектных типов матриц и векторов.
Еще одна аннотация, векторы можно использовать как массивы, даже со списками инициализации, они выделяются динамически. - К сожалению, они ограничены только типами double, float и сложными скалярными типами. - Не имеет смысла.
Также тот факт, что матрица по умолчанию равна matrix<double> - это концепция, которая не поддерживается MQL5, а значит, для нас недоступна. - Почему??? - Какой смысл реализовывать объект таким "из ряда вон выходящим" способом?
И еще, пока я не забыл об этом: ALGLIB на CodeBase https://www.mql5.com/en/code/1146 не поддерживает матричные или векторные типы, у него есть свой объект представления для работы с матрицами..... Как следствие, реализация того, чем славится ALGLIB (скорость и гибкость), была более или менее обделена, векторы и матрицы должны поддерживать AVX при использовании, но для преобразования ALGLIB эти возможности пришлось удалить из библиотеки, потому что они недоступны в MQL5 напрямую.
В заключение хочу сказать, что лично я считаю, что данная реализация не очень хорошо вписывается в MQL5 на данный момент и нуждается в некоторой чистке и переработке.
Я думаю, что вы передаете имя функции, опускаете матрицу / вектор, который она будет корректировать (или инициировать), но добавляете остальные параметры функции. (и вектор матрицы, который она будет корректировать / инициировать, должен быть в параметрах функции первым)
Я работал с этим недавно, дайте мне 5, чтобы откопать код
Это мутация между кодированием на c++ и python
нашёл его
template <typename T> void init_based_on_values(vector<T> &out,//the vector you will init / adjust you omit this on the init call vector &source,//you can have any other params which you add sep by commas on the init call vector &controller, double allow_value){ int total=0; for(int i=0;i<(int)source.Size();i++){ if(controller[i]==allow_value){ total++; out[total-1]=source[i]; } } out.Resize(total,0); } template <typename T> void your_function(vector<T> &out){ out.Fill(3); } int OnInit() { //--- vector source={1,2,3,4,5,6,7}; vector pass={0,1,0,1,0,1,0}; vector result(7,init_based_on_values,source,pass,1.0); Print(result); return(INIT_SUCCEEDED); }
Итак, что это делает, извините, надо было написать это изначально:
- у нас есть исходный вектор (мы используем вектор, потому что это просто) со значениями
- у нас есть вектор фильтра пропуска, не то чтобы он был нужен, но для проверки многочисленных и разнообразных параметров, когда он равен 1.0, мы передаем значение в вектор out
- мы не передаем ссылку на вектор out в параметрах конструктора (init), потому что то, что мы "конструируем", является первым параметром, на который ссылаемся.
Это действительно аккуратно, я не тестировал это на скорости, но это удобно.
vector source={1,2,3,4,5,6,7}; vector pass={0,1,0,1,0,1,0}; vector result=source*pass;

- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Это сводная тема о матрицах и векторах в MQL5