Каждая стратегия состоит, с одной стороны, из алгоритма — торговых правил системы — и, с другой стороны, из ряда параметров, фиксированных числовых значений, которые влияют на результат. В контртрендовом сценарии это, например, цикл полосового фильтра (30), коэффициент расстояния стоп-лосса (4) и другие числовые значения, оказывающие явное влияние на поведение сделки. Во время обучения поведение стратегии проверяется при изменении этих параметров.
Это направлено на достижение трех целей. Во-первых, необходимо выяснить, является ли прибыль стратегии не просто результатом случайной комбинации параметров, а действительно обусловлена методом торговли. Только в этом случае можно ожидать, что стратегия будет использовать реальную неэффективность и будет успешной в реальной торговле. Во-вторых, «устойчивость» стратегии улучшается благодаря тому, что в процессе обучения находятся оптимальные значения параметров, небольшие изменения которых оказывают незначительное влияние на стратегию. Это также делает их менее чувствительными к изменениям на рынке, пока они остаются в пределах нормы. Третья цель — автоматическая адаптация стратегии к изменяющимся рыночным ситуациям и к другим активам. Часто бывает так, что одна и та же стратегия работает с целой серией похожих активов, но каждый с разными параметрами. Для этого процесс обучения просто проводится отдельно для каждого актива и создает индивидуальный набор параметров в каждом случае.
Обучение в некоторых отношениях отличается от оптимизации параметров, предлагаемой некоторыми торговыми платформами. Оптимизация определяет комбинацию значений, при которой стратегия с исторической кривой цен приносит наибольшую прибыль. Это дает наилучшие результаты в бэктестинге, но чаще всего не в реальной торговле — наоборот, стратегия с оптимизированными параметрами часто чувствительна к небольшим изменениям. Поэтому оптимизация — особенно с использованием генетических алгоритмов — в основном имеет противоположный эффект обучению. При этом генерируются не самые надежные значения, а те, которые лучше всего соответствуют исторической кривой цен. Этот эффект называется чрезмерной подгонкой или подгонкой кривой. Если представить себе прибыль стратегии как изрезанную поверхность в пространстве, охватываемом параметрами, то оптимизация всегда находит единственную самую высокую вершину этой поверхности. Поскольку другие ценовые кривые и рыночные условия всегда смещают и несколько искажают эту поверхность прибыли, в реальной торговле может внезапно возникнуть глубокая долина там, где при моделировании с историческими данными все еще находился одинокий пик. Тогда стратегия будет приносить только убытки, несмотря на отличные показатели бэктестов.
Подгонка кривых — одна из основных проблем при разработке стратегии. Поэтому некоторые разработчики стратегий обычно воздерживаются от оптимизации своих параметров. Но и это не совсем решение, потому что даже начальные параметры, выбранные «вручную», могут лечь на случайный пик прибыли. Это происходит чаще, чем можно подумать. Вряд ли кто-то устоит перед искушением побаловаться с параметрами при разработке стратегии и подобрать их таким образом, чтобы получилась максимально возможная прибыль.
Zorro использует другой подход. Во время обучения поиск ведется не для вершины, а для достаточно широкого холма прибыли, который все еще обещает хорошую прибыль на расстоянии от своей высшей точки. Какие параметры и каким образом должны быть скорректированы для этого, определяется в сценарии. Поэтому обучение параметров — это не обособленный процесс, а неотъемлемая часть стратегии, которая может осуществляться в любое время — даже во время торговли.
Для этого Алиса добавила в свою стратегию несколько новых команд (сценарий Alice2c.c):
function run() { set(PARAMETERS+LOGFILE); BarPeriod = 240; LookBack = 500; if(Train) Detrend = TRADES; vars Price = series(price()); var BestCycle = optimize(30,25,35); vars Filtered = series(BandPass(Price,BestCycle,0.5)); vars Signal = series(FisherN(Filtered,500)); var Threshold = optimize(1,0.5,1.5,0.1); Stop = optimize(4,2,10) * ATR(100); Trail = 4*ATR(100); var Cycle = DominantPeriod(Price,10); if(between(Cycle,BestCycle-10,BestCycle+10)) { if(crossUnder(Signal,-Threshold)) reverseLong(1); else if(crossOver(Signal,Threshold)) reverseShort(1); } }
Обучение параметрам требует некоторых дополнительных инструкций в начале сценария:
set(PARAMETERS+LOGFILE); BarPeriod = 240; LookBack = 500;
PARAMETERS — это флаг, который можно включить командой set, так же как и флаг LOGFILE, который мы использовали в прошлой главе. Здесь оба флага устанавливаются простым сложением их вместе в команде set. PARAMETERS указывает Zorro настраивать параметры скрипта в тренировочном прогоне и использовать скорректированные значения при тестировании или торговле. LookBack — это «время ожидания», которое необходимо стратегии для расчета начальных значений индикаторов или функций. Только после этого он может начать торговать. Если время ожидания зависит от параметров, изменяемых в процессе обучения, как в данном случае, Zorro не может рассчитать его самостоятельно. Поэтому при обучении стратегии нам приходится указывать его вручную. В данном случае мы установили его на 500 баров, требуемых функцией FisherN. Все остальные функции требуют меньшего времени обратного отсчета, поэтому мы подстраховываемся, выбрав 500. Слишком большое время ожидания ничего не дает, кроме сокращения периода тестирования, а слишком малое время приводит к появлению сообщения об ошибке.
if(Train) Detrend = TRADES;
Условие if(Train) выполняет следующую команду только во время тренировки. В этом случае для данной переменной Detrend устанавливается значение TRADES. Детренд используется для изменения кривой цен. Например, вы можете наклонить кривую так, чтобы убрать из нее долгосрочный восходящий или нисходящий тренд. Другие возможности могут быть использованы для тестирования и экспериментов, например, обратить все тенденции вспять или произвольно изменить кривую так, чтобы из нее исчезли все неэффективности. В этом случае используется режим TRADES, благодаря которому длинные и короткие сделки в среднем достигают одинаковой прибыли, независимо от тренда кривой. В противном случае, например, в случае долгосрочного роста цен все длинные сделки будут приносить более высокую прибыль, что может несколько исказить результат обучения. Однако мы хотим учесть это только во время обучения, тест будет проводиться с исходной кривой цен — отсюда условие if(Train).
Ключевым моментом обучения является вычисление сигналов с настроенными параметрами:
var BestCycle = optimize(30,25,35); vars Filtered = series(BandPass(Price,BestCycle,0.5)); ... var Threshold = optimize(1,0.5,1.5,0.1); ... Stop = optimize(4,2,10) * ATR(100);
Здесь тренируются три параметра стратегии. Цикл полосового фильтра — второй параметр функции BandPass — теперь вычисляется функцией optimise и присваивается переменной BestCycle. Мы видим, что optimise вызывается с 3 числовыми значениями. Первый (30) — это значение по умолчанию, когда оптимизация не производится — в данном случае просто предыдущий цикл полосового фильтра. Следующие два числа, 20 и 40, — это допустимый диапазон параметров, т.е. верхняя и нижняя границы цикла. Таким образом, цикл полосы пропускания теперь будет варьироваться от 20 до 40. В процессе обучения Zorro будет пытаться найти самый надежный цикл в этом диапазоне.
Следующим параметром, который необходимо обучить, является порог. На этот раз optimise вызывается с 4 цифрами. Четвертое число, которое также может быть опущено, — это размер шага изменения параметра. Порог теперь работает в диапазоне от 0,5 до 1,5 с шагом 0,1. Пороги для запуска торговых сигналов обычно следует оптимизировать с фиксированным шагом. Если размер шага не указан, Zorro просто увеличивает значение обучаемого параметра на 10% на каждом шаге оптимизации.
Третий параметр обучения — это коэффициент для стоп-лосс. Он обучается в диапазоне от 2 до 10. Кстати, порядок вызовов optimise в скрипте также важен. Параметры, определяющие вход в сделку — в данном случае цикл и пороговое значение — должны быть обучены в первую очередь, затем параметры выхода, такие как расстояние стопа. Теоретически, можно обучить гораздо больше параметров, например, временной период для функции ATR. Но чем больше параметров мы тренируем, тем выше риск «переподгонки» стратегии под историческую кривую цен — той самой подгонки кривой, о которой говорилось выше. Это приводит к тому, что стратегии, блестяще работающие в симуляции, терпят неудачу в реальной торговле — и даже при более совершенных методах тестирования. Вскоре мы подробнее рассмотрим такие методы тестирования. До тех пор мы должны помнить, что обучать следует только несколько важных параметров, и только в разумных диапазонах параметров.
Поскольку значение цикла полосового фильтра теперь может изменяться в пределах от 25 до 35, это также должно быть учтено при сравнении с доминирующим циклом:
if(between(Cycle,BestCycle-10,BestCycle+10)) { ...
В условии «между» теперь проверяется диапазон допуска в 10 баров вокруг BestCycle. Например, если BestCycle имеет значение 35, то для заключения сделок доминирующий цикл должен находиться между 25 и 45.
Чтобы обучить стратегию, нажмите на [Train] и наблюдайте за тем, что делают вызовы оптимизации. После этапа обучения, который занимает около минуты в зависимости от скорости вашего компьютера, в вашем браузере должна появиться веб-страница с тремя диаграммами, которые выглядят примерно так:
Рис. 27 — Цикл полосы пропускания (параметр 1)
Рис. 28 — Пороговое значение (параметр 2)
Рис. 29 — Коэффициент останова (параметр 3)
Эти диаграммы создаются в процессе обучения, когда установлен флаг LOGFILE. Они показывают, какое влияние оказывают значения параметров на результат стратегии. Черные полосы (красные на веб-странице) — это целевые значения периода обучения, т.е. значения, к которым система должна быть обучена. По умолчанию целевым значением является пессимистический коэффициент доходности (PRR) — общая прибыль, деленная на общий убыток, умноженный на «штрафной коэффициент», который наказывает результаты, основанные на меньшем количестве сделок. При PRR, равном 1,0, стратегия является прибыльной даже с учетом штрафного коэффициента. Темно-серые столбики — количество выигрышных сделок, светлые — количество проигрышных сделок. Горизонтальная ось показывает значение параметра, при котором был достигнут соответствующий результат. Мы видим, что стратегия остается прибыльной во всем диапазоне трех параметров. Полосовой цикл дает слегка возрастающую прибыль до значения около 35. Пороговое значение имеет наилучшие показатели при значении около 1,0, а стоп-фактор — третий параметр — имеет два максимума при 2,2 и при 7,5. Второй максимум сопровождается большим количеством выигрышных сделок и, следовательно, лучшей «точностью» стратегии. Тем не менее, Zorro выбирает первый максимум, потому что он несколько выше и, следовательно, дает лучшие результаты в целом.
Поскольку почти все красные столбики заканчиваются выше 1,0, то есть в прибыльном диапазоне, стратегия кажется очень надежной и не очень чувствительной к изменениям параметров — по крайней мере, с протестированной ценовой кривой. Определенные значения параметров с наибольшей робастностью сохраняются в каталоге данных в файле с именем Alice2c_EURUSD.par (для других активов имя файла будет другим) для последующего использования в тестировании и торговле.
Нажатие на [Test] показывает, что обучение действительно улучшило стратегию. Но связано ли это только с лучшей адаптацией к исторической кривой цен или с лучшими параметрами, которые также приносят больше прибыли в реальных сделках? Это неясно с самого начала. Доверять результату без лишних слов было бы серьезной ошибкой.
Продолжение следует...