_sk_
_sk_ личный блог
26 ноября 2019, 09:29

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

Просто несколько строк про свой опыт.

Тестер стратегий у меня самописный (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 тестер — это однозначный выбор для тех, кто умеет программировать.
27 Комментариев
  • _sg_
    26 ноября 2019, 11:27
    Почему значение «день, предшествующий экспирации» не вычисляете из значения «дата экспирации»? Зачем лишний столбец в данных?
  • Replikant_mih
    26 ноября 2019, 11:50

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

     

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

  • Пафос Респектыч
    26 ноября 2019, 11:54
    Если вы так сильно паритесь по поводу разрывов цены, которые бывают раз в месяц на нефти и раз в три для других фьючей, ваша ТС не особо робастна.
    То есть понятно, что со фьюча на фьюч перед экспирацией надо переходить, но саму ТС такие вещи как случайные гэпы не должны приводить в замешательство ))
      • Пафос Респектыч
        26 ноября 2019, 12:09
        _sk_, а, ну реалистичные тесты на истории это вообще отдельная дисциплина ) я просто хотел заметить, что именно с точки зрения построения ТС это не должно быть важно. Индикаторы это ж просто производные случайные величины от других случайных величин — цен, объёмов и т п, так что их точные конкретные значения, строго говоря, не особо важны.
    • SergeyJu
      26 ноября 2019, 13:03
      Пафос Респектыч, учитывать переходы — вообще тривиальная задача. 
      • Пафос Респектыч
        26 ноября 2019, 20:57
        SergeyJu, не все даже тривиальные задачи полезно решать, всегда важно понимать зачем какая задача решается )
        • SergeyJu
          26 ноября 2019, 21:50
          Пафос Респектыч, учет склеек фьючей, как и учет дивидендов, необходим при создании и тестировании систем. Причем назвать этот учет «задачей» язык не поворачивается. Только для тех, кто торгует строго внутри дня это почти  не имеет значения.
          • Пафос Респектыч
            27 ноября 2019, 11:54
            SergeyJu, насчёт прям необходим — не знаю, я вот не заморачиваюсь. Причём отчасти специально, чтобы для основного результата это было несущественно.
  • _sg_
    26 ноября 2019, 12:11
    Вы java под Linux используете?
      • _sg_
        26 ноября 2019, 12:23
        _sk_, а заявки в Quik как передаете в случае Linux?

        Там ведь Quik из под vine работает.
        Какой при этом интерфейс «java to Quik» для передачи ордеров используете?
          • Тихий омут
            26 ноября 2019, 13:00
            _sk_, а для визуализации сделок тестера что-то используешь,
            например чтоб глянуть как тестер сработал, почему в те или иные моменты он вдруг дал сильную просадку, есть у тебя «инструмент-программа», в которую загружаешь историю свечек, и/или  рассчитанные в тестере индикаторы, сделанные этим тестером сделки чтоб глянуть визуально как все в тестере получилось ??
        • Андрей К
          26 ноября 2019, 13:37
          _sg_, 
          Какой при этом интерфейс «java to Quik» для передачи ордеров используете?
          есть достаточно известный способ передачи инфы между приложениями. Когда есть риск всяких межпроцессорных плюшек не сработать и dll чужие не работают. На серверной части открываем tcp сокет, на клиентской тоже открываем tcp сокет и коннектимся к «серверному» сокету. И начинаем слать команды, а сервер обрабатывает их и принимает решение.

          В данном случае на lua нужно написать серверную часть. Это геморно конечно на словах. Но зачастую действующий способ взаимовоздействия.
            • Андрей К
              26 ноября 2019, 13:41
              _sk_, ну так то да, чем меньше, тем лучше.
          • day0markets.ru
            26 ноября 2019, 14:22
            Андрей К, уже есть серверная часть на луа написанная. можно почти без изменений вытащить отсюда github.com/finsight/QUIKSharp/tree/master/src/QuikSharp/lua
            • _sg_
              26 ноября 2019, 17:02
              day0markets, 
              насколько она надежна Вы проверяли?
              Надежность в смысле описанном ниже ->
              Мои Приложения работают в режиме 24/7 — я писал все сам.
              Я их месяцами не тушу. У меня память не течет.
              А вот когда начинаешь использовать всякие разные «прелести» сторонних разработчиков — вот тут и начинается «концерт».
              Как правило, самая распространенная ошибка — это утечка памяти.
              Потому что Приложения проверяются в режиме: утром включил — вечером выключил, и утечка памяти не заметна.
              А когда оставляешь работать даже на неделю — начинается заметна утечка памяти и всякие разные «exceptions» прилетают.

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

  • _sg_
    26 ноября 2019, 20:06
    Плохо, что приходится два раза писать код,
    Пральна. 

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

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

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

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн