Тестирование доходности торговых роботов на реальных торгах

Редакция кода от 12 января 2012 года. Архив тоже обновлен.
Дорогие друзья, поздравляю Вас с Новым Годом! Желаю успехов в делах, больших профитов, и чтобы независимо от погоды в Вашей жизни всегда было солнечно!
Теперь к нашей теме. У меня часто спрашивают: как я тестирую торговые стратегии? Раньше тестировал в MultiCharts, но быстро понял, что тесты там не имеют никакого смысла. Во-первых на большом таймфрейме, историю которого можно относительно просто найти в сети, результат получается без учета резких движений цены, без учета спреда, и в итоге мы имеем неверные данные о доходности (по большей части обнадеживающие).
В последствии, переложив все тонкости стратегии в код торгового робота, удивляемся, почему он не показывает тех результатов, какие были при тесте. Во-вторых, если тестировать на тиках (на которых тоже нет возможности учитывать спред) то история тиков огромна, и доступна только за текущий день. Т.о. чтоб тестировать на тиках надо запастись терпением, и долго выкачивать историю, чтоб более менее тестировать на бОльшем промежутке времени. Очень неудобно. Справедливости ради скажу что я выкачивал из Квика графики Бидов и Офферов отдельно, загонял их в MultiCharts, и на них тестировал скальпинговые стратегии, но это все равно не то.
По мне — лучший тест — это в реале. Мы тестируем и стратегию, и сам алгоритм торгового робота. Тут есть два пути: учебный счет и реальный счет. На первом, в зависимости от брокера, либо нереальные котировки, либо котировки за какой-нибудь предыдущий день. За то бесплатно и нет риска потерять деньги.
На реальном-же счете — полностью боевые условия, но бабосики родные, заработанные потом и кровью. Что же делать? Правильно, тестируем без денег! Открываем и закрываем позиции «виртуально», запоминая их в памяти робота, нанося соответствующие метки на сам график для визуализации, и записывая в файл лог сделок, для последующего анализа. Таким образом достигаем всех наших целей. Да, долго, но зато 99% верный результат, 1% погрешности остается из-за того, что мы не используем стакан котировок, хотя это тоже важно, но приблизительно можно тоже эмулировать.
В качестве примера рассмотрим простенький торговый робот, построенный на базе популярной стратегии «PARABOLIC_SAR». Алгоритм:
1) если параболик выше котировки — лонг, ниже — шорт. Реверс. Контроль периодичности лонг\шорт\лонг...
2) тейкпрофит и стоплосс в пунктах
Для контроля торговых действий заводим глобальную переменную ТР, в которой мы будем запоминать текущую позицию. Создаем график цены настроенной бумаги, присваиваем ему идентификатор, добавляем прямо на него график индикатора PARABOLIC_SAR, ему тоже назначаем идентификатор. прямо на этот график будут наноситься автоматически метки — цветные кружки (заранее заготовленные файлики bmp, они должны лежать в тойже папке что и робот, мной они уже заготовлены и находятся в архиве с кодом). Робот сам создает текстовый файл с логом сделок и пищет туда все «торговые» действия.
Вот скриншот графика с метками и таблицы самого торгового робота:

Тестирование торгового робота
Зеленый кружок — вошли в лонг. Желтый — выход. Если желтый сверху лонга — значит вышли по тейку, снизу — по стопу. Красный — шорт. Если прочитать всю историю трех сделок со скриншота то получится так: вошли в лонг — вышли по тейку:прибыль. Затем вошли в шорт, выбило по стопу:убыток. Потом опять в лонг, опять тейк:прибыль.
К каждой метке есть комментарий, если навести курсор на саму метку и подержать — отобразится подсказка с подробностями.
А вот так выглядит файл с «историей» этих сделок:
20120104 114330 20120104 114330 1 142930 142930 20120104 114506 ТЕЙКПРОФИТ 143030 143040 100 20120104 115548 -1 142935 142945 20120104 120102 СТОПЛОСС 143030 143035 5 20120104 120218 1 143065 143060 20120104 120310 ТЕЙКПРОФИТ 143175 143185 115 20120104 122210 -1 143785 143795
Первая строка — это старт робота. он пишет дату и время. Это нужно для того, если тестируем несколько дней подряд сразу видеть границы дней.
Вторая строка — вошли в лонг. Видим дату и время сделки, «1» — это текущая позиция, 142930 — это цена по которой вошли (текущий оффер на момент входа), и последняя цифра — это текущая котировка на момент входа. Т.е. все входя и выходы мы делаем по соответствующему офферу или биду (в зависимости от направления), этим достигается учет спреда.
Третья строка — наш выход по тейку. Соответственно 143030 — цена выхода (в роботе настройка тейкпрофит=100 пунктов, и как видим тейк «сработал» именно на этом уровне, этим мы «эмулируем» стакан). 143040 — текущая котировка на момент выхода, 100 — это профит
). профит в течении дня суммируется, и в конце дня мы можем оценить его целиком.
Есть еще синии метки — это реверс, который происходит когда у нас например открыт лонг, стоп и тейк еще не сработали, а параболик показал шорт — мы переворачиваемся.
В роботе предусмотрен контроль направления, это значит что мы обязательно чередуем лонги и шорты. Два раза в лонг подряд мы не входим. В конце дня тестирования неожиданно получилась Елка:)

Ну еще в коде есть фенечки типа раскраски таблицы робота в зависимости от направления — чтоб при одном взгляде на нее было понятно что он делает. применены блоки контроля данных — если робот не получает чтото нужного он об этом пишет, отслеживает время сессии и время клирингов на ФОРТС.
Код на QPILE и архив с файлами доступен только зарегистрированным пользователям.
Для тех кто видит мои идиотские рисунки впервые — не гадайте, это робот на сцене
После опубликования оставил этого робота до конца дня. С дефолтными настройками параболика на минутках на 20.00 мск робот «заработал» 1300 пунктов.
Привет
Сам долгое время так тестил, выводя в лог входы-выходы. Идеально для неотработанной стратегии и/или неотлаженного робота. Затем уже можно выпустить свою железяку на реал, но на маловолатильный (SBRF, SiH...). Тут уже поинтереснее, можно полюбоваться возможным проскальзыванием
или отладить код функций отправки транзакций.
А рисунки у тебя всегда веселые своеобразные, характерные именно этому сайту
Евгений Reply:
января 6, 2012 at 16:27
Привет.
Да, я тоже начинал с вывода только в лог, визуализация добавилось — стало лучше.
Спасибо!
Что надо изменить в коде, чтоб сделки окрывались рельно? Спасибо!
Евгений Reply:
января 6, 2012 at 16:29
Привет.
Менять нужно многое, в этом коде вообще нет блоков работы с транзакциями и блоков учета заявок, стопов, и пр. Если есть желание собрать реального такого робота самостоятельно — читайте сайт, на нем эти блоки есть. Если желания делать самостоятельно нет — пишите через контактную форму.
ЗДРАВСТВУЙТЕ! Не обессудьте — вопрос от новичка! Зарегистрировался, скачал данную стратегию, в квике задал портфель, график с индикатором а как дальше запустить не понимаю. Может подскажете, где то на сайте есть тема по этому вопросу... ? Спасибо.
Евгений Reply:
января 6, 2012 at 20:42
Все правильно делали, а что не работает? Таблица робота появилась в квике? Время в ней тикает? Идентификаторы назначили в графике? Путь прописали в настройках робота?
Что за таблица робота в квике? Идентификаторы? Есть ли пошаговая инструкция для правильной установки??? Просто пытаюсь произвести загрузку робота в квик в первый раз.
Евгений Reply:
января 7, 2012 at 16:08
1. www.hirobot.ru/2009/03/ka...orgovogo-robota/
2. НА ГРАФИК ЦЕНЫ ДОБАВЛЯЕМ ИНДИКАТОР PARABOLIC_SAR, И ПРИСВАИВАЕМ ПОСЛЕДНЕМУ В СВОЙСТВАХ НА ВКЛАДКЕ «ДОПОЛНИТЕЛЬНО» ИДЕНТИФИКАТОР PARABOLIC, А ГРАФИКУ ЦЕНЫ НАЗНАЧАЕМ ИДЕНТИФИКАТОР PRICE
А теперь ответь те мне на вопрос — На сколько высока вероятность того что заявка исполнила В ДАННЫЙ МОМЕНТ? Этот вопрос и поставил крест на дальнейшей разработке торговых систем. (прошу ответить более развернуто и аргументированно)
Евгений Reply:
января 12, 2012 at 9:46
Привет.
Отвечаю. В этом роботе используется «эмуляция» трех видов транзакций:
1. Вход маркетом. При выполнении условий входа по параболику робот должен открыть позицию маркетом. Что это значит при реальных торгах? Для лонга мы посылаем заявку с завышенной ценой, чтоб ГАРАНТИРОВАННО войти. При такой заявке на покупку торговый сервер берет нашу цену и смотрит стакан в части предложений (асков, офферов) и если наша запрашиваемая цена выше или равна лучшему аску — то сервер сразу и исполняет нашу заявку по лучшему аску. При эмуляции в этом роботе входа маркетом мы принимаем за цену входа просто лучший аск:
PRICE_ENTER=ASK, конечно тут может быть тоже проскальзывание, если придираться, что в этот же момент кто то отправит тоже большую заявку и мы не сможем войти по жтому лучшему аску, но я считаю это очень незначительным фактором. Тем более что в этого робота можно заложить проскальзывание на вход и каждый раз «ухудшать» цену входа, т.е.:
PRICE_ENTER=ASK+SLIPPAGE.
2. Стопзаявка. Эмуляция работает по алгоритму (опять смотрим лонг): если ласт меньше или равен нашей расчетной стопцене — то выходим из лонга по лучшему биду на тот момент. Именно также в реальных торгах действует торговый сервер, когда активируется стопзаявка с заложенным проскальзыванием. Конечно же вероятна та же ситуация что и п.1. Но опять же я отмечу что она маловероятна.
3. Выход по лимиту. Тут вообще все просто — при реальных торгах, когда есть открытая позиция и мы хотим поставить «вперед» в прибыль лимит-тейкпрофит — мы ставим его в стакан и его видим. Торговый сервер не может его игнорировать, и если цена станет выше цены нашего лимита (мы опять смотрим открытый лонг и соответственно лимит на продажу для его закрытия) то это 100% гарантия что наш лимит сработал. В этом роботе именно также организована эмуляция срабатывания лимита:
IF TP>0 AND (LAST>=PRICE_ENTER+TAKEPROFIT OR BID>=PRICE_ENTER+TAKEPROFIT)
т.е. если ласт или бид выше расчетной цены нашего лимита на выход, то
...
PRICE_EXIT=PRICE_ENTER+TAKEPROFIT
принимаем за цену выхода цену нашего расчетного лимита. (я немного в этой части поправил код — было несколько хуже).
Что получаем в итоге? Все программы теханализа, точнее те, что тестируют на истории оперируют историей сделок. А что есть история сделок — это перечень LAST. Вот именно все эти программы ошибаются потому что нет гарантии что они сделают сделку по историческому ласт. они не учитывают ни стакан ни даже направление этого LAST. В этом же роботе я постарался максимально. насколько это возможно приблизить эмуляцию входа-выхода к реальности, поэтому все расчеты ведем от бидов/асков в первую очередь, и действуем по алгоритму торгового сервера.
Kobalt Reply:
января 13, 2012 at 22:34
Евгений ОГРОМНОЕ Вам спасибо, за то что делетись такими тонкостями и вообще за такой проект!!!
Евгений Reply:
января 14, 2012 at 19:19
Рад оказаться полезным!
Евгений здравсвуйте,а как переносить позицию через ночь чтобы после обновления портфеля позиция сохранялась,можно конечно комп невыключаь на ночь но это не айс,
с Уважением
Евгений Reply:
января 26, 2012 at 18:56
Привет!
Хранить текущую позицию и цену входа в отдельном файле
alex_davyd Reply:
февраля 9, 2012 at 19:59
Евгений здравсвуйте,а как подстовлять текущую позицию и цену входа мз
отдельного файла,получать данные из файла с помощью READ_LINE
понятно,а вот как связать не могу понять просмотрел робота" Ретронслятор"
но там немного другое .
Евгений Reply:
февраля 12, 2012 at 9:31
Привет.
Все просто: когда в этом роботе мы приравниваем ТР к какому то значению — записывайте это значение в определенный файл в тех же местах. А в самом начале робота каждую итерацию считывать значение из файла, а глобальную переменную ТР убрать.
alex_davyd Reply:
февраля 14, 2012 at 17:32
Евгений спасибо,теперь все понятно.
а если за закомментарить блок ПЕРВЫЙ СТАРТ сответственно переменая FIRSTRUN обновлятся небудут .
Евгений Reply:
января 30, 2012 at 9:07
FIRSTRUN нужен только для записи в файл с логом строки разграничивающей дни.
А как его переделать под ММВБ?
Евгений Reply:
января 31, 2012 at 23:03
Просто вписать нужный код бумаги с ММВБ в настройках.
Спасибо за разработки, Евгений. При адаптации к реалу после запуска робота с уже имеющейся открытой «вручную» позиции, необходимо учитывать цену входа по этой позиции. Т.е. код PRICE_ENTER будет равнятся 0 и модули ВЫХОДА ПО ПРИБЫЛИ и ВЫХОДА ПО СТОПУ уже не работают(также как и робот)! Или, еще ситуация, робот закрывает позицию по профиту, а цена продолжает идти в ту же сторону и робот не войдет в позицию для удержания прибыли, а будет ждать реверса (шортлонг) и дальнейший мой ручной вход будет опять не учтен роботом. Есть ли решение? Подскажите.
Евгений Reply:
февраля 20, 2012 at 20:22
PRICE_ENTER на реале это цена сделки, которую получаем из таблицы «Сделки». Закрываем позицию по профиту — сразу после ее открытия ставим лимит-тейкпрофит в стакан, и поза закроется сама — отдельно это не контролируем. То же самое «по стопу». Т.к. в моих роботах блоки «тейкпрофита» и «стоплосса» контролируют размер открытой позиции, то и на открытые вручную позиции все выставляются все нужные заявки.
В целом этот робот предназначен именно для эмуляции процесса и тестирования, архитектура «боевого» робота будет совсем иной. В принципе у меня такой есть — пишите в форму Контакты.