Бэктестинг: торгуем SPY по сигналам RSI(3)

В этот раз будем тестировать стратегию разворотов по сигналам 3-х-дневного индикатора RSI. Начнем с проведения анализа пересечения границ перепроданности/перекупленности методом, описанным в предыдущей статье.

Анализ и тесты будем проводить на Python🐍, используем библиотеку Zipline и Quantopian.

  • Индикатор RSI описан здесь.
  • Алгоритм анализа пересечения порогов описан здесь.

Ниже я публикую результаты анализа пересечения 30 и 70 порогов RSI(3) для NYSE:SPY с 1995 до 2017 гг. Нам интересны количество и продолжительность нахождения вне порогов и продолжительность движения от одного порога к другому.

Мы захватили несколько бычьих и медвежьих рынков. Анализ показывает, что в 75% случаев значение RSI(3) находится ниже 30 менее трёх дней. При этом значение находится выше 70 в течение одного дня реже, чем ниже 30. А 75% процентиль находится на четырёх днях. За весь период мы видим, что покупать SPY от нижней границы в первый день безопаснее, чем шортить от верхней.

На нижних гистограммах мы видим, что в 75% случаев значение RSI(3) проходит вверх от 30 до 70 за восемь дней . А вот сверху вниз цена идёт дольше и 75% процентиль лежит на 12 днях.

Выводы наводят на мысль, что торговать SPY нужно только в длинную.

Если постараться😉, на графике можно увидеть, что в периоды медвежьих рынков индикатор RSI(3) плотнее ниже нижней границы (30). В этот раз мы данные периоды отфильтруем пересечением скользящих средних SMA(50) и SMA(200).

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

Параметры стратегии, используемые в данной статье, удалось обнаружить с помощью оптимизатора на основе Zipline, о котором мы обязательно поговорим в следующих статьях.

📋Условия алгоритма

Тестировать будем на двух платформах:

  • Локальный тест на дневной истории с помощью Zipline.
  • Тест на минутной истории с сигналом в конце дня на Quantopian.

Условия:

  • SPY.
  • Капитал $100 000.
  • Торгуем с 2004 до 2017 гг на закрытии рынка только в длинную.
  • Бычий/медвежий рынок фильтруем с помощью SMA(50) x SMA(200).
  • 3-х дневный RSI.
  • Динамические пороги 30 и 70 с отклонением 15 в зависимости от рынка:
    • Бычий 30 и 85.
    • Медвежий 15 и 70.
  • Фильтр по вероятности разворота проверяем за 30 торговых дней и покупаем, если вероятность выше 20%. Вероятность падает в ноль, если пересечения отсутствуют.
  • Максимальное удержание позиции 5 торговых дней.
  • Без стопов.

👌Тестирование на дневной истории

Первым делом протестируем локально с помощью Zipline на дневной истории. Код алгоритма доступен в Jupyter блокноте и обычном скрипте.

В первую очередь сделаем отступление. На первом графике видно, что сделки проводятся только на следующий день. Что логично, ведь сигнал мы получили в конце дня и открыться можем только в следующую торговую сессию. Это свойство тестирования на дневной истории.

Тестирование показало следующие результаты:

  • Доходность: +143%
  • Максимальная просадка: -12%
  • SPY(Купи-Держи): +189%

Результаты удовлетворительные, особенно учитывая просадку всего в -12%.

На графике RSI(3) мы можем видеть изменение порогов в разные периоды рынка. Красная линия показывает вероятность разворота от нижней границы. Фильтр не идеальный, но позволяет увеличить доход на 10%.

Фильтр по пересечению средних спасает лишь от пары резких просадок в 2008 году, которые категорически портят результаты. А медлительность разворота средних слишком долго запрещает алгоритму торговать. Так что стратегию можно улучшить, фильтруя сигналы во время высокой волатильности или сокращая размер позиции. Например, фильтровать можно проверяя положение внутри канала 52-недельных максимума и минимума.

👌Тестирование на Quantopian

Теперь протестируем нашу стратегрию на минутной истории цен при условии проверки сигналов один раз в день. Код алгоритма ниже.

Наилучшие результаты удалось получить при проверке сигнала в конце дня на закрытии рынка. Это может быть связано с оптимизацией алгоритма на дневной истории.

Результаты любопытней:

  • Доходность: +166%
  • Максимальная просадка: -14%
  • SPY(Купи-Держи): +183%

Разница в 20% может быть связана с открытием позиции в конце дня, так как тестирование проводится на минутной истории. Это же могло повлиять и на просадку. Как видно, алгоритм торгует достаточно активно, что позволяет исключить случайность получения результатов.

🎁Код в студию

Поделитесь статьей для доступа к репозиторию с исходным кодом. Вопросы по коду пишите в комментариях💬.

🏁Вывод

В этот раз стратегия по RSI оказалась более чем жизнеспособной, в сравнении с первой попыткой, описанной здесь. Удивительные результаты были получены при торговле IWM, аж в +250%.

Для справки, оптимизация стратегии проводилась в период с 2015 до 2016 гг. То есть результаты получены на OOS (Out-Of-Sample). А по-русски, вне тестового периода.

Можно ли улучшить стратегию? Легко! Идей множество. Например, добавить контроль и закрытие позиции при долгом нахождении в зоне перепроданности. Или фильтровать по росту волатильности (ATR). А можно поменять принцип проверки бычьего/медвежьего рынка, чтобы фильтровать резкие просадки и оперативнее разрешать торговлю.

💬В комментариях напишите, какие у вас есть идеи для улучшения результатов стратегии. Что можно добавить или убрать в условиях? Где я допустил ошибку?

Александр Румянцев aka "iamraa"
Автор Quantrum.me
Интересуетесь алготрейдингом на Python? Присоединяйтесь к команде. Пишите в личку или на email.
☝Учитесь торговать внутри дня. И делайте🎓 это вместе с профессионалами👍.