Блог им. _sk_

Про тестирование стратегий на фьючерсах

    • 26 ноября 2019, 09:29
    • |
    • _sk_
  • Еще
Просто несколько строк про свой опыт.

Тестер стратегий у меня самописный (java), что даёт неплохую производительность и возможность запрограммировать именно то, что нужно мне.

Обычная склейка фьючерсов не используется из-за нестыковок цены соседних контрактов, которые портят как расчёт прибылей/убытков, так и значения индикаторов.

Свечные данные сохраняются из терминала QUIK скриптом на QLua в ежедневном режиме отдельно по каждому инструменту. Получается, что для каждого фьючерса есть вся его история в виде csv-файлов «финамовского» OHLCV-формата. Тестер умеет загружать временные ряды из этих файлов за любой период времени.

Для каждого фьючерса прописаны 3 даты: дата экспирации, день, предшествующий экспирации, и день экспирации предыдущего фьючерса. В коде это выглядит примерно так:

SiH9("Si-3.19", "SiH9", "Si", 20190321, 20190320, 20181220),
SiM9("Si-6.19", "SiM9", "Si", 20190620, 20190619, 20190321),
SiU9("Si-9.19", "SiU9", "Si", 20190919, 20190918, 20190620),
SiZ9("Si-12.19", "SiZ9", "Si", 20191219, 20191218, 20190919),

В торговых системах используется правило: не торгуем истекающим фьючерсом в день экспирации. Позиции по фьючерсу в торговый день, предшествующий дню экспирации, закрываются по цене закрытия этого дня, а в день экспирации торгуется новый фьючерс.

Индикаторные торговые системы имеют некоторый период времени, пока эти самые индикаторы набирают историю котировок для расчёта. Иногда этот процесс растягивается на несколько дней. Если использовать по каждому фьючерсу данные только с момента экспирации предыдущего, получится, что торговая система «простаивает», ожидая, пока индикаторы начнут работать. Особенно ярко это проявляется на фьючерсах на нефть: 10 торговых дней собирается история для индикатора, после чего останется примерно столько же дней для торговли. Половина времени потрачено зря.

Поэтому лучше загружать данные с перекрытиями: до экспирации текущего фьючерса ещё несколько дней, а мы уже знаем котировки следующего, чтобы уже можно было рассчитать индикаторы к моменту смены фьючерса. В коде самого теста мы просто пропускаем все свечи нового фьючерса, для которых время меньше или равно времени последней свечи старого фьючерса, например так:

long position = 0;
final int len = timeCode.length();
for (int i = 0; i < len; i++) {
    final long t = timeCode.get(i);
    if (t <= tLast) {
        continue;
    } else {
        tLast = t;
    }
    // Тут уже доступны значения индикаторов
    final double c = close.get(i);
    ...

Думаю, что самописный или open-source тестер — это однозначный выбор для тех, кто умеет программировать.
★5
27 комментариев
Почему значение «день, предшествующий экспирации» не вычисляете из значения «дата экспирации»? Зачем лишний столбец в данных?
avatar
_sg_, могут быть праздники или какие-нибудь непредвиденные переносы от биржи. Решил, что пусть лучше в явном виде будет всё прописано.
avatar

>>«Думаю, что самописный или open-source тестер — это однозначный выбор для тех, кто умеет программировать.»

 

Согласен, особенно если дополнительно выполняется условие: стандартные решения не полностью устраивают в тех или иных аспектах.

avatar
Replikant_mih, так и есть.
avatar
Если вы так сильно паритесь по поводу разрывов цены, которые бывают раз в месяц на нефти и раз в три для других фьючей, ваша ТС не особо робастна.
То есть понятно, что со фьюча на фьюч перед экспирацией надо переходить, но саму ТС такие вещи как случайные гэпы не должны приводить в замешательство ))
Пафос Респектыч, я, скорее, не парюсь, а делаю реалистичный тест на истории, чтобы потом при реальной торговле было совпадение результатов. Понятно, что для каких-то систем (интрадей, например) и склейки будет достаточно.
avatar
_sk_, а, ну реалистичные тесты на истории это вообще отдельная дисциплина ) я просто хотел заметить, что именно с точки зрения построения ТС это не должно быть важно. Индикаторы это ж просто производные случайные величины от других случайных величин — цен, объёмов и т п, так что их точные конкретные значения, строго говоря, не особо важны.
Пафос Респектыч, учитывать переходы — вообще тривиальная задача. 
avatar
SergeyJu, не все даже тривиальные задачи полезно решать, всегда важно понимать зачем какая задача решается )
Пафос Респектыч, учет склеек фьючей, как и учет дивидендов, необходим при создании и тестировании систем. Причем назвать этот учет «задачей» язык не поворачивается. Только для тех, кто торгует строго внутри дня это почти  не имеет значения.
avatar
SergeyJu, насчёт прям необходим — не знаю, я вот не заморачиваюсь. Причём отчасти специально, чтобы для основного результата это было несущественно.
Вы java под Linux используете?
avatar
_sg_, java ведь тем и хороша, что она кросс-платформенная. На одном компьютере Windows, а на другом — Linux. Совместимость при этом сохраняется.
avatar
_sk_, а заявки в Quik как передаете в случае Linux?

Там ведь Quik из под vine работает.
Какой при этом интерфейс «java to Quik» для передачи ордеров используете?
avatar
_sg_, когда торговая система готова для боевой эксплуатации, я пишу скрипт на QLua. Java далее уже не используется.

Плохо, что приходится два раза писать код, но в роботе логика торговой системы занимает от силы 20%, а остальные 80% — это реализация исполнения (приведение текущих позиций к желаемым), ведение логов сделок и логов самого скрипта, инициализация и сохранение состояния скрипта на диск, борьба с многочисленными особенностями QUIK и т.п.

С другой стороны, когда ясно, что именно надо запрограммировать в QLua, то на это уходит немного времени. Гораздо больше его тратится на изобретение новых торговых систем.
avatar
_sk_, а для визуализации сделок тестера что-то используешь,
например чтоб глянуть как тестер сработал, почему в те или иные моменты он вдруг дал сильную просадку, есть у тебя «инструмент-программа», в которую загружаешь историю свечек, и/или  рассчитанные в тестере индикаторы, сделанные этим тестером сделки чтоб глянуть визуально как все в тестере получилось ??
avatar
Тихий омут, визуализатора нет. Возможно, это недостаток. Понятное дело, что после написания кода надо ещё как-то отлаживать его, чтобы быть уверенным, что алгоритм действий программы соответствует идее торговой системы.
avatar
_sg_, 
Какой при этом интерфейс «java to Quik» для передачи ордеров используете?
есть достаточно известный способ передачи инфы между приложениями. Когда есть риск всяких межпроцессорных плюшек не сработать и dll чужие не работают. На серверной части открываем tcp сокет, на клиентской тоже открываем tcp сокет и коннектимся к «серверному» сокету. И начинаем слать команды, а сервер обрабатывает их и принимает решение.

В данном случае на lua нужно написать серверную часть. Это геморно конечно на словах. Но зачастую действующий способ взаимовоздействия.
avatar
Андрей К, я изучал этот вопрос. Решил, что надёжнее будет путь только QLua. Чем меньше связок между программами, тем меньше шансов, что где-то порвётся.
avatar
_sk_, ну так то да, чем меньше, тем лучше.
avatar
Андрей К, уже есть серверная часть на луа написанная. можно почти без изменений вытащить отсюда github.com/finsight/QUIKSharp/tree/master/src/QuikSharp/lua
avatar
day0markets, 
насколько она надежна Вы проверяли?
Надежность в смысле описанном ниже ->
Мои Приложения работают в режиме 24/7 — я писал все сам.
Я их месяцами не тушу. У меня память не течет.
А вот когда начинаешь использовать всякие разные «прелести» сторонних разработчиков — вот тут и начинается «концерт».
Как правило, самая распространенная ошибка — это утечка памяти.
Потому что Приложения проверяются в режиме: утром включил — вечером выключил, и утечка памяти не заметна.
А когда оставляешь работать даже на неделю — начинается заметна утечка памяти и всякие разные «exceptions» прилетают.

avatar
_sg_, там есть проблемы на стороне луа. но допилить можно. я для быстрого запуска страт использую сейчас.
avatar
Андрей К, 
Что-нибудь можете сказать по надежности использования
Quik + Lua c использованием LuaTcp/Ip sockets c точки зрения утечки памяти для работы в режиме 24/7.
Я уже писал ниже, что тестирование обычно проводят в режиме «утром включил — вечером выключил» — этого недостаточно.
Терзают меня смутные сомнения в надежности использования компонентов QUIK + Lua + TCP/IP Sockets в режиме 24/7.
avatar
_sg_, извините, вот прям это не в курсах. Я так жестко lua не гонял неделями
avatar
Андрей К, Спасибо за ответ.
Я думаю со временем все на PLaza перейдут и не будет ни Квиков ни Луа и всего прочего

avatar
Плохо, что приходится два раза писать код,
Пральна. 

По-моему лучше использовать что-то вроде этого
https://github.com/Enfernuz/JavaTrans2Quik

Если мне не изменяет память, а она мне уже часто изменяет,
здесь на Смарте  по-моему товарищ ПВМ торгует на jave через interface похожий на то, что в ссылке сверху.

Получится правильная система — отдельно стратегии, Квик.
Между ними interface.
И код один, и только один раз писать.
Желаю успехов
avatar

теги блога _sk_

....все тэги



UPDONW
Новый дизайн