Генетические алгоритмы: в поисках священного грааля
|

Генетические алгоритмы: в поисках священного грааля

11(61)2004


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


   Подсмотрено у матушки-природы
   Генетические алгоритмы (ГА) – по сути, это методы эффективной оптимизации и поиска решений, подсмотренные у матушки-природы. Обычно они применяются для решения задач, имеющих большое количество параметров и не имеющих четко формализованного метода решения. Перебирать все варианты – нереально долго, а с помощью ГА можно справиться удивительно быстро и с необходимой степенью точности. Каждый параметр решаемой задачи становится геном, а полный набор параметров системы – это набор генов, одна хромосома, одна особь. Например, в системе пять параметров, каждый из которых может меняться в пределах от 0 до 255. Тогда наша особь (или хромосома) – это набор из пяти байтов, идущих друг за другом, представленных в двоичной форме и выглядящих как двоичная цепочка длиной 40 бит. На начальном этапе ГА создается популяция из большого количества особей, значения генов (параметров) которых берутся случайным образом. Далее для каждой особи производится расчет системы и вычисляется фитнесс – функция некоторых результирующих значений системы. Собственно, фитнесс и является признаком приспособленности особи – показателем ее соответствия решению, которое ищется.
   Далее популяция сортируется по значению фитнесса, и из нее берется половина особей, имеющих наилучший фитнесс. После чего в ход идут собственно механизмы ГА – скрещивание, мутация и инверсия. Для скрещивания из популяции выбираются две особи, которые будут родителями, определяется (случайным образом) точка разрыва, после чего создается потомок – как соединение части первого и второго родителя. Таким образом, потомок получает частично признаки обоих родителей. Это важнейшая часть ГА – собственно, здесь и происходит создание новой особи, несущей признаки обоих родителей и, возможно, более приспособленной, чем каждый из них.
   После того как все особи прошли скрещивание и их количество стало совпадать с начальной популяцией, производят мутацию. Для этого случайным образом выбирается несколько особей, в которых каждый бит меняется на противоположный. Также используется еще и метод инверсии, который заключается в том, что хромосома с определенной долей вероятности делится на две части, которые затем меняются местами. Эти два метода ГА служат для привнесения как бы извне новых признаков, не содержащихся в исходной популяции.


   После проведения всех вышеуказанных действий мы получаем популяцию, равную по численности исходной, но более приспособленную к решению задачи. Далее процесс повторяется заново: расчет фитнесса, скрещивание, мутации и инверсия. Пройдя большое количество итераций (поколений), мы получим особи, содержащие гены с наиболее удачными параметрами оптимизируемой системы. Для оптимизации существующих стратегий Рассмотрим простейшую механическую торговую систему (МТС). Две скользящие средние (МА1 и МА2) пересекаются. Их пересечение дает точку входа в рынок. Пересечение двух других (МА3 и МА4) дает точку выхода. У каждой МА есть два параметра – длина и сдвиг (в будущее на n баров). То есть общее количество параметров системы равно 8. Четыре отвечают за вход, четыре за выход. Для упрощения будем считать, что значения каждого параметра лежат в промежутке от 0 до 255 (один байт). Длина каждой хромосомы, таким образом, составляет 8 байтов, или 64 бита.


   Количество особей в популяции выбирается в зависимости от числа генов в хромосоме – эмпирически. Для рассматриваемого случая популяции в 300 особей будет достаточно. Фитнессом системы для простоты будем считать общую полученную прибыль. Запускаем ГА. На фазе расчета фитнесса прогоняем по историческим данным каждую особь – то есть нашу систему (MA1MA2-MA3MA4) с параметрами текущей особи. И получаем прибыль – она, напомню, у нас является фитнессом (или приспособленностью) данной особи. После прохождения некоторого количества итераций значения генов у особей с наибольшим фитнессом практически перестают изменяться. В этот момент можно считать, что итерационный процесс сошелся. Особь из получившейся популяции с наибольшим фитнессом – и будет тем набором параметров, который наилучшим образом подходит для нашей системы.


   Я протестировал подобную МТС для 5-минутных графиков EUR/USD. Процесс сходится примерно после 100-150 поколений. Скорость схождения процесса зависит от параметров ГА – вероятностей скрещивания, мутации и инверсии. Уменьшая вероятности мутации и инверсии, мы убыстряем схождение процесса, однако появляется опасность, что процесс сойдется на одном из локальных максимумов. После тестирования стало ясно, что данная система нежизнеспособна (что, в общем-то, и не вызывало сомнений), хотя ГА и порождали наборы параметров, при которых такая система дает большую прибыль. Однако данная система приведена здесь лишь из-за своей простоты и для демонстрации принципа функционирования генетического алгоритма.


Выбор фитнесса
Одна из важнейших задач, которые необходимо решить при тестировании систем с помощью ГА, – выбор фитнесса. Как я уже говорил, фитнесс – это некоторая функция результирующих значений системы. Выше рассматривался вариант, когда фитнесс (Fit) равен прибыли (Profit). Однако оптимизация по такому фитнессу приводит к тому, что ГА порождает параметры, при которых система может выдавать, например, только одну (на периоде тестирования) сделку – прибыльную, конечно, но для устойчивости системы этого явно не достаточно. Хорошим решением будет ввести в расчет фитнесса количество сделок, совершаемых системой (CountTrade):


Fit = Profit * CountTrade.


   Но тогда у нас появляются сделки с очень большой просадкой, и общая устойчивость системы уменьшается. Решить эту проблему довольно просто. Введем в формулу максимальную просадку (Prosadka) по одной сделке:


Fit = (Profit * CountTrade) / (Prosadka/10).


   Так как просадка для нас все же менее важна, чем прибыль и количество сделок, мы уменьшили ее вес, разделив на 10. Эта формула уже довольна хороша, и системы, оптимизированные по ней, дают довольно неплохие результаты. Однако можно добавить в нее, например, количество минусовых сделок (KolvoMinus) или размер стопа (Stop), а также поэкспериментировать с различными весами параметров. Я использую также следующие формулы для определения фитнесса:


Fit = Profit/(1+Prosadka/10)* (CountTrade/20);
Fit = Profit/(1+Prosadka/10 + Stop / 10 ) * (CountTrade/10);
Fit = (Profit+KolvoPlus/5) / (1 + Prosadka / 10 + KolvoMinus/5).


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


   Если формула построена некорректно, вы не придете ни к какому конечному результату: процесс как бы застрянет между несколькими максимумами.


Новый взгляд
Давайте немного отвлечемся от ГА и подумаем вот над чем. График движения валютной пары, который мы видим на экране, – это случайный процесс или он содержит какие-то законы, скрытые от нас? Скорее всего, второе. Иначе существование технического анализа, да и вообще какого-либо анализа рынка, можно было бы поставить под вопрос. Из высшей математики нам известны некоторые методы, позволяющие с достаточной точностью определить формулу, по которой построен произвольный график какой-то неизвестной нам функции. Например, разложение в ряд Фурье. Не будем останавливаться на методах и обсуждать, насколько они хороши, нам это сейчас не важно.


   А важно то, что рынок – система, которая меняется, и меняется достаточно плавно. Найдя закономерности в движении рынка, мы можем экстраполировать их на некоторое расстояние в будущее, где они еще будут работать (хотя, возможно, несколько хуже). Почему ни одна система, придуманная полвека назад, сейчас нормально не работает? Да потому, что условия изменились, а системы – нет. Нет гибкости. А нам необходимо создать систему, непрерывно подстраивающуюся под рынок. Этого можно добиться, применяя ГА и непрерывно оптимизируя существующую систему на новых поступающих данных. Выше мы рассмотрели, как применять генетические алгоритмы для оптимизации параметров уже существующей механической торговой системы. А что нам мешает заставить ГА самим придумывать систему, наилучшим образом подходящую под данный рынок?


   Давайте попробуем.
   В таблице 1 сведены некоторые возможные сигналы и их параметры, которые можно использовать для входа или выхода из рынка. Это далеко не полный перечень, но нам пока хватит. В первом столбце таблицы 1 – названия сигналов. Мы будем кодировать номер сигнала одним геном. Далее – 4 параметра (у каких-то сигналов их меньше, но это не суть важно), их мы кодируем еще четырьмя генами. У нас получается цепочка из 5 генов, описывающая сигнал на вход в рынок. Однако этого явно маловато. Давайте добавим фильтрующие сигналы или индикаторы.





   В таблице 2 представлен краткий перечень таких фильтров. Их мы кодируем аналогичным образом: номер фильтра – один ген, параметры – еще четыре. Таким образом, мы получаем сигнал на вход, который должен быть подтвержден фильтрующим индикатором. Полный сигнал на вход в рынок у нас состоит из 10 генов: 5 – сам сигнал и 5 – фильтр. Аналогичным образом кодируется и сигнал на выход. Также 10 генов: 5 – сигнал и 5 – фильтр. Итого получается одна хромосома длиной 20 генов. Запускаем ГА. Для такого количества генов размер популяции должен составить не менее 1000 особей. В результате работы ГА через 340 поколений получаем результаты, приведенные в таблице 3. Итак, ГА для нас создали механическую торговую систему и оптимизировали ее параметры для данного исторического промежутка. При прогонке по более свежим данным (по которым оптимизация не проводилась) МТС показывает некоторую неустойчивость. На протяжении более недели она достаточно прибыльна. Далее МТС перестает приносить прибыль и становится убыточной. Это и не удивительно, если учесть простоту системы. Для улучшения работы системы будем использовать при фильтрации сигналов на вход и на выход не один фильтр, а, например, по четыре – построенных аналогичным образом. Также можно добавить временной период для возможного входа (например, вход только с 3 до 17 часов – кодируется двумя генами) и временной период для возможного выхода. Возможны также стоп и лимитпределы (в этой статье не рассматриваются). Итого у нас получается 27 генов, описывающих вход, и 27 – выход из рынка. Всего 54 гена в хромосоме. Так как хромосома значительно удлинилась, стоит увеличить и количество особей в популяции. Я использовал популяции в 2000 особей.


   После того как ГА отработал и процесс сошелся, получаем результаты. Они представлены в таблице 4. Получившаяся система имеет достаточно неплохие показатели и на свежих исторических данных хорошо ведет себя в течение месяца после оптимизации (9 сделок, 2 убыточные, общая прибыль 400 пунктов).


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


Некоторые пояснения и выводы
Интересный вопрос – выбор временного интервала графиков для поиска МТС. В принципе, механическую торговую систему таким образом можно построить на любых графиках. Но если использовать графики размерностью более 4 часов, то на их форму влияют в основном фундаментальные факторы. А факторы такого типа могут со временем круто поменяться на противоположные (например, преобладающий тренд сменится на горизонтальный коридор). Это не лучшим образом скажется на стабильности работы МТС. Чем ниже мы спускаемся к тиковым графикам, тем больше психологичности в их форме. Однако тиковые графики слишком зашумлены и мало поддаются вообще какому-либо анализу.


   Для тестирования я использовал 5-минутные графики EUR/USD с сентября 2003 г. по июнь 2004 г. Принцип тестирования комплекса, построенного описанным выше образом, следующий.


1. Задаются всевозможные сигналы и описываются их параметры.
2. Выбирается функция расчета фитнесса.
3. На достаточно длительном историческом промежутке проводится оптимизация.
4. Систему, полученную в результате оптимизации, прогоняют на данных, идущих непосредственно за промежутком оптимизации.
5. Если система показывает хорошие результаты, промежуток оптимизации сдвигается в будущее на размер свежих данных.
6. После этого процесс повторяют с пункта 3 до тех пор, пока не наступит уверенность в стабильности полученного комплекса.


   Работа с полученным комплексом проходит аналогичным образом. ГА запускается, например, на 3-месячных данных. Находится оптимальная МТС, по которой торгуют, например, в течение недели. После чего период оптимизации сдвигается на неделю вперед, и все повторяется заново. Таким образом, мы всегда имеем МТС, оптимально подстроенную под рынок.


   Стоит отметить некоторые трудности, с которыми приходится сталкиваться при разработке таких систем. Во-первых, существуют вполне понятные проблемы с механизмом определения таких инструментов технического анализа, как, например, уровни поддержки и сопротивления, линии тренда, волн и растяжений. Во-вторых, программы, построенные с использованием ГА, очень требовательны к производительности компьютеров. Так, например, при расчете варианта 54 гена в хромосоме, 2000 особей в популяции, на истории в 18000 свечей одно поколение считается на ИнтелПентиуме-4 с частотой 2400 герц примерно 40 минут, а весь расчет занимает больше недели.


   Далее двигаться можно в следующих направлениях.


1. Предоставить в распоряжение ГА все инструменты технического анализа, используемые человеком.
2. Значительно усложнить структуру МТС, добавив в нее большое количество сигналов, которые могут одновременно присутствовать в системе, а не только на этапе оптимизации.
3. Привнести в логику МТС элементы искусственного интеллекта – например, нечеткую логику. Это, а также многое другое, позволит создать, пока только теоретически, квинтэссенцию технического анализа – идеальную механическую торговую систему. Священный грааль где-то рядом.


Сергей Головин