Всем привет!
Краткое содержание предыдущих серий :)
- В самом начале мы с вами обсудили на что в принципе способен торговый робот.
- Выбрали простенькую учебную стратегию.
- Заложили логику этой стратегии в мозг робота.
- Оптимизировали параметры стратегии.
Другими словами, в первом приближении мы прошли полный цикл, после которого в принципе можно было бы запустить робота на реальный счет торговать по взрослому. Но! Наш советник R1-SMA на текущий момент написан в сам простом виде, что с одной стороны удобно для понимания логики, заложенной в его программный код, но с другой - определяет ряд ограничений и “неуниверсальностей”, которые мы сегодня постараемся снять.
Давайте перед выводом робота на “реал” поставим себе следующую цель - добиться безошибочной (без фатальных ошибок) работу советника в режиме тестирования “Все тики” с качеством моделирования не менее 90%. Конечно одной статьи на все это не хватит, будем “кушать слона по частям”.
Режимы тестирования
Когда в прошлый раз мы проводили оптимизацию нашего советника, точнее его входных параметров, я отдельно оговорился о режимах его тестирования и сказал, что следует обязательно использовать режим “По ценам открытия”. А что, собственно, не так с остальными режимами? Давайте просто для интереса проведем тестирование в режиме “Контрольные точки”. Напомню, его следует выбрать в поле “Модель” в окне тестера стратегий и нажать “Старт”.
Покажу лишь первые две группы сделок (красные на продажу, синие на покупку):
| Скрин 1 |
Вероятно, вы уже нашли, как открыть окно графика со сделками после тестирования. На всякий случай - это кнопка “Открыть график” все в том же окне тестера.
Как видно на Скрин 1, при использовании контрольных точек на каждой сигнальной свече открывается не одна, а целая пачка сделок, каждая пунктирная линия - это отдельная сделка. Потом они все дружно закрываются и опять открывается целый “веер”.
Подобное поведение не предусмотрено нашей стратегией, у нас в каждый момент времени предполагается только одна сделка. Вот как это должно выглядеть:
| Скрин 2 |
Что же не так с контрольными точками? Забегая вперед, скажу, что и в режиме “Все тики” наш робот в текущем его состоянии “рисует веера”, причем в гораздо большем количестве, нежели контрольные точки.
А дело оказывается в том, что робот одинаково обрабатывает каждый отдельный тик сигнальной свечи и открывает дополнительную сделку на каждый из них - так и образуется “веер”. Надо научить его открывать одну единственную сделку.
Можно было бы сделать явный контроль первого тика новой свечи, а остальные игнорировать. И для исторического тестирования (читай “в инкубаторских условиях”) это наверняка прекрасно работало бы. Но в реальной жизни могут быть ситуации, когда сервер брокера по некоторой причине, например по причине перегруженности потоком ордеров, отказывает в исполнении рыночного ордера и открытии позиции, а у нас именно рыночные ордеры. С учетом этого первый вариант решения проблемы рискует оставить нас вообще без позиции, если не получится открыть ее на первом тике.
Лучше мы научим робота перед открытием сделки проверять, а нет ли уже таковой, и, если есть, то игнорировать тик. Так мы существенно снизим риск остаться без сделки - не откроется на первом тике, так откроется на втором или на каком-нибудь N-ном.
Отправка ордеров теперь будет выглядеть вот так:
if (NoBuy()) OrderSend(Symbol(), OP_BUY, 0.01, Ask, MarketInfo(Symbol(), MODE_SPREAD), 0, 0);
В чем отличие от того, что было? Появилось условие if (NoBuy()). Теперь нужно написать самодельную функцию NoBuy(), которая будет возвращать булево значение, то есть либо правду (true), либо ложь (false). Очень удобно за основу взять одну из уже имеющихся у нас функций обработки текущих позиций. Я взял все “внутренности” функции CloseAllLong() и чутка их поправил под нашу NoBuy():
Функция перебирает все открытые позиции и если встречает хоть одну OP_BUY, возвращает false, ну мол “таки есть уже BUY позиция, больше не надо”. Ну а если ни одной OP_BUY не нашлось, то так и говорит “нету открытых покупок”, то есть утверждение NoBuy=true.
С функцией NoSell() все ровно так же, только тип операции OP_SELL. В итоге советник стал выглядеть вот так:
Пробуем прогнать его на “Контрольных точках” - вуаля, получается в точности тот же результат, как на Скрин 2, что и требовалось. Со “Всеми тиками” что-то чуть сложнее, там вместо 19 сделок почему-то произошло только 18, по непонятной пока причине робот не отработал последнее пересечение SMA и итоговая прибыль оказалась чуть меньше - 900 USD вместо 1200 “с копейками”, но мы разберемся с этим, когда будем тестировать с высоким качеством моделирования (будет отдельная статья). В любом случае, если умозрительно “накинуть” неучтенную сделку, результат оказался очень близок к режиму “По ценам открытия”.
Изменяемый размер лота
Теперь проверим “домашку”, которую я задавал в прошлый раз :)
Напомню, надо было вывести размер лота в настраиваемые параметры. После всего, что мы уже изучили, это проще паренной репы - добавляем новый extern и прописываем соответствующую переменную в ордера.
Даже не буду приводить полный текст кода, лучше посмотрим, до какого максимального размера лота мы могли бы “размечтаться” при условии старта с 1000 USD и какую при этом прибыль получить. Включаем “Оптимизацию” и задаем параметру Lot диапазон от 0.01 до 1. Получаем:
| Скрин 3 |
Ммда, далеко мы не уехали, остановились на лоте 0.09, заработав при этом аж 10930 USD. Это почти 130% годовых. Внушает, не правда ли? Все банки вместе взятые нервно курят в коридоре! Но не торопитесь обольщаться, взгляните на размер максимальной просадки - она получилась около 90%. Другими словами, практически гарантированный “слив” депозита, особенно с учетом всяких форсмажорных факторов реальной торговли. С другой стороны, вы можете управлять этим риском, если у вас есть возможность положить на депозит больше, чем 1000 USD. Все в ваших руках.
Динамический размер лота
Его применяют для разных целей. Очень часто динамический лот используют в так называемых Мартингейл стратегиях. Их смысл - быстро “отбивать” проигрыши, агрессивно повышая ставки. Понятно, что и риск прогрессирует вместе с ростом ставок. Использовать “мартина” или нет, опять-таки дело каждого личное. Может когда-нибудь в другой раз мы для тренировки и сделаем такую модернизацию советника.
Но, как говаривал один киношный персонаж в озвучке Гоблина, сегодня мы про другое. Моя идея следующая - так изменить оптимизацию советника, чтобы больший вклад в конечную прибыль вносили более поздние периоды и соответствующие сделки, нежели сделки из далекой истории. Тем самым мы рассчитываем на то, что подобранные параметры будут более актуальными для текущего времени, так как известно, что характер рынка постоянно меняется и требуется постоянно адаптировать свою торговую стратегию под эти изменения.
Вполне возможно, что после такой модифицированной оптимизации мы получим ровно те же оптимальные значения параметров, как и до нее. Так тем лучше, это еще больше придаст нам уверенности в правоте нашего дела :)
Как же сделать адаптирующуюся оптимизацию? Я делаю очень просто - линейно увеличиваю лот для каждой следующей сделки. Да, наверно можно замутить более сложную схему, но я всегда за простоту.
Итак, задаем еще один extern параметр LotAdd, значение которого и будем прибавлять к текущему лоту каждый раз перед открытием новой сделки.
Финальный на сегодня вид советника таков:
Запускаем оптимизацию с фиксированными Lot и LotAdd (каждый по 0.01) и что же мы видим? Во-первых, видим существенно иной “узор” графика оптимизации с каким-то привидением в шарфе … или с фатой? :)
| Скрин 4 |
Во-вторых, видим очень интересную картину на закладке “Результаты оптимизации”:
| Скрин 5 |
Максимальную прибыль мы получили на комбинации (83,84)! Разница периодов всего на единицу! Вот тебе раз!
Вот только надо ли смотреть на прибыль? Но об этом в следующий раз.
А пока - пока!
С уважением,
Игорь Шепелев
Комментариев нет:
Отправить комментарий