Эксперименты с нейросетями (Часть 1): Вспоминая геометрию
Введение
Добрый день, уважаемые пользователи сообщества MQL5. В данной статье хотелось бы поделиться своими экспериментами с нейросетями. Прочитав большое количество имеющейся на MQL5 информации, я пришел к выводу, что теории вполне достаточно. Имеются очень хорошие статьи, библиотеки, исходные коды. Но очень огорчил тот факт, что данная информация не приводит к логическому заключению – прибыльной торговой системе. Это мы и попробуем с Вами исправить.
Сразу скажу, что я не являюсь специалистом в данной области и тем более писателем или журналистом, но постараюсь изложить ход своих мыслей доступно, так сказать, поделиться опытом.
Материал в первую очередь рассчитан на новичков, коим являюсь и я.
Как я это понимаю. Основы
Практически везде утверждается, что нейросети хорошо распознают паттерны, и тот факт, что очень важным критерием являются данные, которые мы передаем в нейросеть для обучения. С этого, пожалуй, и начнем. Используем геометрию. А именно будем передавать в нейросеть геометрические фигуры. Для начала возьмем обычный перцептрон, пример которого я нашел здесь (МTC Сombo - эксперт для MetaTrader 4). Проводя тесты, я решил отказаться от осцилляторов и использовать MA. Тестирование с осцилляторами не привело к хорошим результатам. Наверное, всем известен факт, когда цена движется вверх, а осциллятор вниз — так называемая дивергенция. Показатели MA более приближены к самой цене.
Фигуры и линии
За основу возьмем два индикатора Moving Average с параметром 1 и 24, метод Simple применить к Close. То есть идея в передаче нейросети не только текущего положения индикаторов а и состояния, в котором они были до текущего состояния. Во многих примерах, которые я видел, в нейросеть передают непосредственно цену, что я считаю в корне неправильным.
Все значения передаем в пунктах, что также очень важно, эти значения имеют некий диапазон, за которые они не могут выходить. Передавать в нейросеть просто цену не имеет смысла, цена может ходить в разных диапазонах на протяжении 10 лет, например. Также не стоит забывать, что мы можем использовать в построении фигур разное количество показателей индикаторов. Фигуры могут быть сложные и простые. Ниже приведу примеры возможных вариантов. Конечно, вы можете придумать и свои.
Расстояния в пунктах на 1, 4, 7 и 10 закрытой свече между индикаторами MA 1 и MA 24.
double perceptron1() { double w1 = x1 - 100.0; double w2 = x2 - 100.0; double w3 = x3 - 100.0; double w4 = x4 - 100.0; double a1 = (ind_In1[1]-ind_In2[1])/Point(); double a2 = (ind_In1[4]-ind_In2[4])/Point(); double a3 = (ind_In1[7]-ind_In2[7])/Point(); double a4 = (ind_In1[10]-ind_In2[10])/Point(); return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4); }
Фигура 2: простые линии
Расстояния в пунктах между 1-4, 4-7 и 7-10 закрытой свече индикатора MA 1.
double perceptron2() { double w1 = y1 - 100.0; double w2 = y2 - 100.0; double w3 = y3 - 100.0; double a1 = (ind_In1[1]-ind_In1[4])/Point(); double a2 = (ind_In1[4]-ind_In1[7])/Point(); double a3 = (ind_In1[7]-ind_In1[10])/Point(); return (w1 * a1 + w2 * a2 + w3 * a3); }
Фигура 3: простые линии
Расстояния в пунктах между 1-4, 4-7 и 7-10 закрытой свече индикатора MA 24.
double perceptron3() { double w1 = z1 - 100.0; double w2 = z2 - 100.0; double w3 = z3 - 100.0; double a1 = (ind_In2[1]-ind_In2[4])/Point(); double a2 = (ind_In2[4]-ind_In2[7])/Point(); double a3 = (ind_In2[7]-ind_In2[10])/Point(); return (w1 * a1 + w2 * a2 + w3 * a3); }
Фигура 4: бабочка (конверт)
Расстояния в пунктах между 1-10 закрытой свече индикатора MA 1. И расстояние в пунктах между 1-10 закрытой свече индикатора MA 24. Расстояние в пунктах между 1 свечей индикатора MA 1 и 10 свечей индикатора MA 24. Расстояние в пунктах между 1 свечей индикатора MA 24 и 10 свечей индикатора MA 1. Получится бабочка.
double perceptron4() { double w1 = f1 - 100.0; double w2 = f2 - 100.0; double w3 = f3 - 100.0; double w4 = f4 - 100.0; double a1 = (ind_In1[1]-ind_In1[10])/Point(); double a2 = (ind_In2[1]-ind_In2[10])/Point(); double a3 = (ind_In1[1]-ind_In2[10])/Point(); double a4 = (ind_In2[1]-ind_In1[10])/Point(); return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4); }
Фигура 5: четырёхугольник
Расстояния в пунктах между 1-1, 10-10 закрытой свече между индикаторами. И Расстояние в пунктах между 1-10 индикатора MA 1 и расстояние в пунктах между 1-10 индикатора MA 24. Получится четырёхугольник.
double perceptron5() { double w1 = c1 - 100.0; double w2 = c2 - 100.0; double w3 = c3 - 100.0; double w4 = c4 - 100.0; double a1 = (ind_In1[1]-ind_In1[10])/Point(); double a2 = (ind_In2[1]-ind_In2[10])/Point(); double a3 = (ind_In1[1]-ind_In2[1])/Point(); double a4 = (ind_In1[10]-ind_In2[10])/Point(); return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4); }
Фигура 6: сложная
Здесь мы объединим все вышеперечисленные фигуры в одну сложную.
double perceptron6() { double w1 = x1 - 100.0; double w2 = x2 - 100.0; double w3 = x3 - 100.0; double w4 = x4 - 100.0; double w5 = y1 - 100.0; double w6 = y2 - 100.0; double w7 = y3 - 100.0; double w8 = z1 - 100.0; double w9 = z2 - 100.0; double w10 = z3 - 100.0; double w11 = f1 - 100.0; double w12 = f2 - 100.0; double w13 = f3 - 100.0; double w14 = f4 - 100.0; double a1 = (ind_In1[1]-ind_In2[1])/Point(); double a2 = (ind_In1[4]-ind_In2[4])/Point(); double a3 = (ind_In1[7]-ind_In2[7])/Point(); double a4 = (ind_In1[10]-ind_In2[10])/Point(); double a5 = (ind_In1[1]-ind_In1[4])/Point(); double a6 = (ind_In1[4]-ind_In1[7])/Point(); double a7 = (ind_In1[7]-ind_In1[10])/Point(); double a8 = (ind_In2[1]-ind_In2[4])/Point(); double a9 = (ind_In2[4]-ind_In2[7])/Point(); double a10 = (ind_In2[7]-ind_In2[10])/Point(); double a11 = (ind_In1[1]-ind_In1[10])/Point(); double a12 = (ind_In2[1]-ind_In2[10])/Point(); double a13 = (ind_In1[1]-ind_In2[10])/Point(); double a14 = (ind_In2[1]-ind_In1[10])/Point(); return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4 + w5 * a5 + w6 * a6 + w7 * a7 + w8 * a8 + w9 * a9 + w10 * a10 + w11 * a11 + w12 * a12 + w13 * a13 + w14 * a14); }
Углы
Рассмотрим еще один очень интересный метод передачи данных цены в перцептрон. А именно углы наклона индикаторов. Эти данные также не могут выходить за определенный диапазон, что нам вполне подходит для передачи некого шаблона. Так же, как и в предыдущем случае с фигурами и линиями.
Методов определения углов я встречал очень много, но многие из них зависят от масштаба ценового графика, что нам не подходит. Решением является считать не угол, а тангенс угла, используя отношение количества пунктов к количеству баров. Тангенс угла tg(α) — есть отношение противолежащего катета a к прилежащему катету b.
Также есть возможность использовать разное количество индикаторов, обрабатывать сложные конструкции и использовать разное количество свечей для анализа. На скриншотах углы наклона показаны незафиксированными линиями. Рассмотрим несколько примеров.
Наклон индикатора MA 1 между 1-4 свечами, между 1-7 свечами, между 1-10 свечей.
double perceptront1() { double w1 = x1 - 100.0; double w2 = x2 - 100.0; double w3 = x3 - 100.0; double a1 = (ind_In1[1]-ind_In1[4])/4; double a2 = (ind_In1[1]-ind_In1[7])/7; double a3 = (ind_In1[1]-ind_In1[10])/10; return (w1 * a1 + w2 * a2 + w3 * a3); }
Наклон индикатора MA 1 между 1-5 свечами, между 1-10 свечами. Наклон индикатора MA 24 между 1-5 свечами, между 1-10 свечами.
double perceptront2() { double w1 = x1 - 100.0; double w2 = x2 - 100.0; double w3 = x3 - 100.0; double w4 = x4 - 100.0; double a1 = (ind_In1[1]-ind_In1[5])/5; double a2 = (ind_In1[1]-ind_In1[10])/10; double a3 = (ind_In2[1]-ind_In2[5])/5; double a4 = (ind_In2[1]-ind_In2[10])/10; return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4); }
Perceptront3. 4 углa наклона индикатора MA 1 и MA 24 (более-менее сложная конструкция, для примера)
Углы завязаны наклоном между двумя индикаторами, MA 1 и MA 24.
double perceptront3() { double w1 = x1 - 100.0; double w2 = x2 - 100.0; double w3 = x3 - 100.0; double w4 = x4 - 100.0; double a1 = (ind_In1[1]-ind_In1[10])/10; double a2 = (ind_In2[1]-ind_In1[4])/4; double a3 = (ind_In2[1]-ind_In1[7])/7; double a4 = (ind_In2[1]-ind_In1[10])/10; return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4); }
Perceptront4. 4 углa наклона индикатора MA 1 и MA 24 (более-менее сложная конструкция, для примера)
Углы завязаны наклоном между двумя индикаторами, MA 1 и MA 24.
double perceptront4() { double w1 = x1 - 100.0; double w2 = x2 - 100.0; double w3 = x3 - 100.0; double w4 = x4 - 100.0; double a1 = (ind_In1[1]-ind_In1[10])/10; double a2 = (ind_In2[1]-ind_In1[10])/10; double a3 = (ind_In1[1]-ind_In1[10])/10; double a4 = (ind_In2[1]-ind_In2[10])/10; return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4); }
Стратегия
Я решил, использовать контртрендовую стратегию для обучения, явно указав в коде ниже. Для продаж индикатор MA 1 на первой свече выше индикатора MA 24. Для покупок зеркально. Это необходимо из моих наблюдений для явного разделения продаж и покупок. Вы же можете поступить наоборот - использовать тренд.
Также вы можете использовать другие индикаторы или их значения, например индикатор TEMA. Спрогнозировать цену на движение в 400 пунктов по пятизнаку практически невозможно, никто не знает, куда пойдет рынок. Потому для проверки я установил фиксированный стоп лосс в 600 пунктов и тейк профит в 60 пунктов по пятизнаку. Дабы не перегружать статью излишними строками и не потерять смысл, готовые советники Вы сможете скачать ниже в приложении. Посмотрим на результаты.
//SELL++++++++++++++++++++++++++++++++++++++++++++++++ if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (ind_In1[1]>ind_In2[1]) && (perceptron1()<0) &&(SpreadS1<=MaxSpread)){//v1 OpenSell(symbolS1.Name(), LotsXSell, TakeProfit, StopLoss, EAComment); } //BUY++++++++++++++++++++++++++++++++++++++++++++++++ if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (ind_In1[1]<ind_In2[1]) && (perceptron1()>0) && (SpreadS1<=MaxSpread)){//v1 OpenBuy(symbolS1.Name(), LotsXBuy, TakeProfit, StopLoss, EAComment); }
Оптимизация, тестирование и ресурсы
Оптимизация нейросетей, как известно, требует больших вычислительных ресурсов. Потому используя тестер стратегий для этих целей, я рекомендую режим (Только цены открытия) с явным указанием цен закрытия в самом коде, иначе на наших довольно скромных мощностях это не выполнимая задача. Но даже в таких режимах оптимизации рекомендую сервис (Cloud Network). Целью оптимизации является нахождение нашими перцептронами неких закономерностей, при которых мы получим профит. Вхождений таких паттернов, то есть количество прибыльных сделок, должно быть на порядок выше убыточных в нашем случае. Все зависит от соотношения StopLoss к TakeProfit.
Забегая наперед скажу, что я провел по 10 оптимизаций каждого советника непрерывно. Все дело в том, что значений оптимизации очень много, что приводит к результатам примерно в 10 000-15 000 за один проход в режиме (Генетический алгоритм). Соответственно, чем больше проходов, тем больше шансов найти нужные значения весовых коэффициентов. Эту проблему необходимо решить средствами MQL5. Уж очень не хочется отказываться от тестера стратегий.
Шаг в 5 значений оптимизации, в отличие от приведенной выше статьи, где шаг равен 1, выбран неслучайно. В процессе экспериментов я заметил, что это приводит к более разбросанным результатам весовых коэффициентов перцептрона, что лучше сказывается на результатах.
- Дата оптимизации с 2010.05.31 по 2021.05.31.
- Режимы (Только цены открытия), (Генетический алгоритм), (Максимальная прибыльность) .
- Начальний депозит 10000.
- TakeProfit = 60, StopLoss = 600.
- Период H1.
- Лот фиксированный 0.01.
- Оптимизируемые параметры x1, x2, x3, x4 - весовые коэффициенты перцептрона. Оптимизируются значениями от 0 до 200 с шагом 5.
Результаты оптимизации и форвард-тестирования.
Как видим, результаты плачевные. Лучший результат 0.87. Проводить форвард-тестирования нет смысла. Идем дальше.
- Дата оптимизации с 2010.05.31 по 2021.05.31.
- Режимы (Только цены открытия), (Генетический алгоритм), (Максимальная прибыльность) .
- Начальний депозит 10000.
- TakeProfit = 60, StopLoss = 600.
- Период H1.
- Лот фиксированный 0.01.
- Оптимизируемые параметры x1, x2, x3, x4, y1, y2, y3, z1, z2, z3, f1, f2, f3, f4 - весовые коэффициенты перцептрона. Оптимизируются значениями от 0 до 200 с шагом 5.
Результаты оптимизации и форвард-тестирования.
Результат очень похож на предыдущий. Лучший результат 0.94.
Оптимизируем советник 4 perceptron 4 figure. (Четыре перцептрона с четырьмя разными фигурами).
Основной код выглядит так:
//SELL++++++++++++++++++++++++++++++++++++++++++++++++ if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (ind_In1[1]>ind_In2[1]) && (perceptron1()<0) && (perceptron2()<0) && (perceptron3()<0) && (perceptron4()<0) && (SpreadS1<=MaxSpread)){//v1 OpenSell(symbolS1.Name(), LotsXSell, TakeProfit, StopLoss, EAComment); } //BUY++++++++++++++++++++++++++++++++++++++++++++++++ if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (ind_In1[1]<ind_In2[1]) && (perceptron1()>0) && (perceptron2()>0) && (perceptron3()>0) && (perceptron4()>0) && (SpreadS1<=MaxSpread)){//v1 OpenBuy(symbolS1.Name(), LotsXBuy, TakeProfit, StopLoss, EAComment); }
- Дата оптимизации с 2010.05.31 по 2021.05.31.
- Режимы (Только цены открытия), (Генетический алгоритм), (Максимум комплексного критерия) .
- Начальний депозит 10000.
- TakeProfit = 200, StopLoss = 200.
- Период H1.
- Лот фиксированный 0.01.
- Оптимизируемые параметры x1, x2, x3, x4, y1, y2, y3, z1, z2, z3, f1, f2, f3, f4 - весовые коэффициенты перцептрона. Оптимизируются значениями от 0 до 200 с шагом 5.
Результаты оптимизации и форвард-тестирования.
Дата форвард-тестирования с 2021.05.31 по 2022.05.31. Необходимо выбрать из результатов тот, в котором наибольший профит-фактор с максимум комплексного критерия больше 40-50.
- Дата оптимизации с 2010.05.31 по 2021.05.31.
- Режимы (Только цены открытия), (Генетический алгоритм), (Максимальная прибыльность).
- Начальний депозит 10 000.
- TakeProfit = 60, StopLoss = 600
- Период H1.
- Лот фиксированный 0.01.
- Оптимизируемые параметры x1, x2, x3, x4, y1, y2, y3, z1, z2, z3, f1, f2, f3, f4 - весовые коэффициенты перцептрона. Оптимизируются значениями от 0 до 200 с шагом 5.
Результаты оптимизации и форвард-тестирования.
Результат получен. Лучший результат 32. Изменим дату с 2021.05.31 по 2022.05.31 и проведем форвард-тестирование. Необходимо выбрать из результатов тот, в котором наибольший профит-фактор с минимальным количеством сделок не меньше 10-20.
Оптимизируем советник 4 perceptron 4 tangent. (Четыре перцептрона с четырьмя разными углами).
- Дата оптимизации с 2010.05.31 по 2021.05.31.
- Режимы (Только цены открытия), (Генетический алгоритм), (Максимум комплексного критерия).
- Начальний депозит 10000.
- TakeProfit = 200, StopLoss = 200.
- Период H1.
- Лот фиксированный 0.01.
- Оптимизируемые параметры x1, x2, x3, x4, y1, y2, y3, z1, z2, z3, f1, f2, f3, f4 - весовые коэффициенты перцептрона. Оптимизируются значениями от 0 до 200 с шагом 5.
Результаты оптимизации и форвард-тестирования.
Дата форвард-тестирования с 2021.05.31 по 2022.05.31. Необходимо выбрать из результатов тот, в котором наибольший профит-фактор с максимумом комплексного критерия больше 20-40.
- Дата оптимизации с 2010.05.31 по 2021.05.31.
- Режимы (Только цены открытия), (Генетический алгоритм), (Максимальная прибыльность).
- Начальний депозит 10 000.
- TakeProfit = 60, StopLoss = 600.
- Период H1.
- Лот фиксированный 0.01.
- Оптимизируемые параметры x1, x2, x3, x4, y1, y2, y3, z1, z2, z3, f1, f2, f3, f4 - весовые коэффициенты перцептрона. Оптимизируются значениями от 0 до 200 с шагом 5.
Результаты оптимизации и форвард-тестирования.
Результат получен. Лучший результат 32. Форвард-тестирование оставлю на домашнее задание. Думаю, так будет интереснее. К тому же, следует заметить, что количество сделок по отношению к профит-фактору увеличилось.
В процессе моих экспериментов возникло несколько проблем, которые необходимо решить. А именно:
- Первое. В связи со сложностью оптимизации такого количества параметров необходимо перенести эти параметры вовнутрь кода советника. Имеется в виду, параметры весовых коэффициентов.
- Второе. Создать некую базу данных для всех оптимизированных параметров и дальнейшее использование их в советнике для торговли одновременно. Думаю, можно будет использовать файлы типа .CSV.
Заключение
Очень надеюсь, что мои эксперименты приведут Вас к новым открытиям, размышлениям и, в конце концов, к успеху. Перед нами ставилась задача получить готовую прибыльную стратегию. Частично мы ее достигли, получив хорошие результаты форвард-тестирования. Что же делать с тем, что получилось? Работы еще много. Нужно переходить к более сложным системам, не забывая полученный опыт. Также более широко использовать то, что есть. Об этом, и не только, мы поговорим во второй части наших экспериментов. Будет интересно. Не пропустите.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Не понял из статьи, какой процент проходов на форварде давал положительный результат?
Добрый день. Процент не считался. Читайте часть 2 и 3.
Добрый день. Процент не считался. Читайте часть 2 и 3.
Добрый-добрый :)
Ну по ощущениям тогда? :)
Добрый-добрый :)
Ну по ощущениям тогда? :)
70-80
70-80
Интересно.
Не думали о генерации "перцептронов"?
Интересно.
Не думали о генерации "перцептронов"?
Подробнее?