Блог им. grepan
Здесь периодически возникают статьи про применение нейронок в трейдинге.
Я решил поделиться примером того, как в одном пайплайне (единая структура программного кода) можно построить, обучить и протестировать нейронку в торговом алгоритме.
Статья будет более полезна и понятна тем, кто имеет хоть небольшой опыт работы с Python.
Итак, наша задача проверить, есть ли вообще надежда на успешное применение нейронных сетей в трейдинге, проверить гипотезу на простом алгоритме, понять, как можно в случае успеха перенести все на боевую среду (реальный торговый робот), и желательно, продемонстрировать все это понятно и доходчиво.
Чтобы в конце концов сделать вывод о перспективности применения нейронок, будем соревноваться с индексом РТС.
Сразу сделаю дисклеймер, все рассматриваемые и полученные в статье результаты являются лишь простым примером, и применять их на реальных деньгах не рекомендую. И я не буду давать теорию по нейронным сетям и работе с ними. Всё это находится/читается/выучивается.
Итак, приступим. Работать будем с фьючерсом РТС, торгуемым на Московской бирже.
Первый кусок кода с импортом библиотек и определением начальных переменных:
Обратите внимание, переключение таймфрейма алгоритма (дневки/минутки) делается указанием соответствующих констант в переменных. Далее в программе нигде ничего менять не надо.
Данные будем забирать автоматически, возиться с CSV и прочими файлами не спортивно.
Данные получены. На выходе стандартный массив OHLCV. Проверяем:
По горизонтальной шкале порядковый номер свечи, по вертикальной — цена закрытия.
Делаем небольшие, но важные манипуляции с данными: добавляем новые фичи, нарезаем данные скользящим окном, определяем целевую переменную, разделяем на обучающую и тестовую выборки, нормализуем. Тестовая выборка составляет долю [test_rate] от первичного набора данных. Здесь и далее в квадратных скобках приведены названия переменных, определенных в самом первом скриншоте программного кода.
Самое важное — целевая переменная. Это тот главный вопрос, который надо задать искусственному интеллекту, чтобы он на обучающей выборке научился с достаточно высокой вероятностью давать правильный ответ.
В нашем случае целевая переменная такая: смотрим на данные за период [period_to_analize], и пытаемся предсказать, что через период [period_to_predict], цена будет либо расти, либо падать, либо оставаться во флэте. Чтобы система понимала, что такое тренд, мы вводим порог [treshold]:
Вот так у нас разбились данные на обучающую и тестовую выборки:
Пора приступать к архитектуре нейронки. Делать будем с помощью библиотеки Keras. И самая главная причина этому – наличие open-source библиотеки Keras2cpp, которая позволяет «обернуть» готовую обученную нейронную сеть в виде dll-библиотеки, которую уже можно подтягивать из Lua, С++ или другого языка, на котором будет реализован конечный боевой робот.
Архитектура нейронной сети простая, жалких пол-ляма нейронов.
На выходе сети конечный слой нейронки отвечает за классификацию входных данных на 3 возможных сценария развития на прогнозируемый горизонт: тренд вниз, флэт, или тренд вверх (вероятность для каждого сценария, в сумме 1).
Теперь обучаем сеть. В процессе сеть выдает нам статистику потерь и точности для каждой эпохи (итерации) обучения:
В принципе, не самый плохой результат обучения. Насторожить должны всплески потерь и точности, но для наших исследовательских целей нейронка сойдет.
Еще раз прогоняем обученную нейросеть на тестовых данных:
Точность обучения сети 82.38%.
Сразу же сохраняем обученную модель в целях дальнейшего «обертывания» в DLL-библиотеку и использования в боевом роботе. Мы до этого не дойдем, но покажем возможность сразу максимально приблизить успешный бэктест к внедрению в боевой алгоритм.
Теперь пора приступать к бэктесту. Бэктест проводим с помощью open-source библиотеки Zipline (детище безвременно закрытого ресурса Quantopian). Библиотека была допилена до возможности работать с минутками, в отличие от оригинала, работающего на таймфреймах не ниже дней.
Задаем класс, эмулирующий обработку ордера. Класс возвращает цену исполнения ордера. Делаем по-простому, эмулируем мгновенное исполнение ордера по рынку без проскальзывания. При желании, в этом классе можно заложить любое, хоть самое пессимистичное проскальзывание (ухудшая цену исполнения ордера в зависимости от направления ордера) для дальнейшего тестирования.
Делаем начальную инициализацию параметров бэктеста:
Работаем одним ордером, комиссию устанавливаем в 70 копеек (можно указать точнее, но для простоты пойдет). За бэнчмарк для итогового сравнения принимаем сам индекс РТС, по которому будем работать с помощью алгоритма с использованием нейросети.
Суть проста: простой переворотный алгоритм, в зависимости от предсказанного направления тренда [signal] открывает, либо переворачивает, либо закрывает позицию, работая одним контрактом. Среда бэктеста позволяет реализовать практически любой торговый алгоритм.
Добавляем процедуру для анализа и отображения результатов.
Задаем начальный баланс capital_base = 100000 и стартуем наконец бэктест. При этом пропускаем данные, на которых нейронка тренировалась. Это у нас форвардное тестирование.
Смотрим на результаты теста:
Над красной чертой самые ключевые результаты. Далее первый график – результат работы алгоритма (% возврата), второй график: изменение цены индекса, третий график – классификация трендов на разных периодах (пока не умею делать красиво, раскрашивая график цены актива в разные цвета в зависимости от тренда, может кто научит?).
Далее для полноты анализа приводим полную статистику портфеля:
Итак, что у нас получилось?
В одном пайплайне (структуре кода с последовательностью работ и процедур) мы:
В результате нейронная сеть обогнала индекс. Особенно если помнить, что для торговли одним контрактом фьючерса на индекс РТС можно использовать начальный депозит в 3 раза ниже заданного, что еще улучшит результат. Но, конечно, нейросеть не оптимальна. На это нам показывают:
Как можно улучшить результаты:
Для перехода к боевому роботу, остается сделать всего несколько вещей:
Явно видно, что из-за одного «выброса» сделана практически вся доходность:
При том, что рынок за то же время заметно вырос.
Полугодовые бесприбыльные/убыточные периоды неприемлемы.
2. Перспективы у ML, таки, есть.
3. Вот так, в тупую, ML не работают.
Не так давно наткнулся на ряд интересных статей в нете по поводу альтернативных источников данных и как их применяют нынче, так вот там как раз таки мл и нейросети очень нужны. Правда на данный момент с данными тоже не все просто, сложность экспертизы, дороговизна и тд, короче обычному человеку надо сильно уж постараться и раскошелиться.
В итогда всегда фирмы будут обгонять физиков в плане используемых технологий и данных, а мы так и будет пытаться на ohlc построить нечто, убеждая себя, что вот у меня то точно получится :)
Данные по истории торгов могут быть только одни, без вариантов.
Но если хочешь поизощряться, есть БЕСПЛАТНЫЕ тиковые данные как по сделкам, так и по очереди заявок. Я их для удобства конвертирую в секундные свечи.
erinrv.qscalp.ru/
www.qscalp.ru/store/qsh.pdf
www.qscalp.ru/download
1. Подход, когда для отдельной бумаги на вход подается помимо цен окрашенные новости по ней, руководству, рынку, фундаментальные данные, и все это на достаточно крупных таймфреймах крутится (то есть минутки, 5-минтуки, и выше). Вариант требует работы команды с покупкой данных и реализации нескольких нейросеток.
2. Когда для отдельной бумаги на вход подается ее микроструктура рынка (тики, сделки) и ищутся микротренды на горизонте нескольких сотен микросекунд. Это о чем месяц назад говорил
Алексей Афанасьевский в своем видео. Здесь можно и без большой команды справиться.
Возьмите backtrader и тестируйте тики :)
СПАСИБО
через час удалю
Но к сожалению, у меня пока нет бэктестера на тиках на языке python ((
Если сделка не скальперская, т.е. вход и выход из позиции в разные торговые сессии, то она стоит вдвое дороже скальперской, т.е. около 7 руб за вход+выход.
А проскальзывание в 1 шаг цены фьючерса откусит от выигрыша каждой сделки ещё более 10 руб.
У меня знакомая работает в авиаконструкторской фирме. Говорит, беда. Молодые не отходят от компа, а железа никогда в руках не держали и не понимают, как все нарисованное будет работать. Или не будет. А старики, которые руками все понимают, все норовят комп кульманом заменить. Разрыв поколений.
При всем уважении к питону-нейронкам-нампи-керасу и всему подобному, Вы пошли стандартным и неверным путем, потому что не учитываете специфику ценовых данных. И не считаете это важным, вероятно.
Данные нестационарны, очень сильно зашумлены и их мало (для всех, кроме ХФТ, конечно). Поэтому полляма нейронов и Ваша целевая функция не подходят для решения поставленной задаче получить хорошую торговую систему.
А Вы начали с того, с чего все начинают. Уже много лет пишут почти одно и тоже. Предсказывают направление на один такт и оптимизируют нейронку стандартным методом оверфитинга.
Суть нейронки в том, что на каждом ее слое вы задаете КОЛИЧЕСТОВ индикаторов (очень по сути похожих на свечные паттерны, но только работающих на обработанных и нормализованных данных). И какие конкретно паттерны должны сформироваться, чтобы настроиться на обучающую выборку, нейронка решит сама (с некоторой долей допущений).
Поэтому пусть число пол-ляма параметров не смущает, если Вы об этом.
Оно никак не соотносится с размером выборки.