Простой бэктестинг Rate-of-Change (ROC) на Python

Данная статья продолжает цикл анализа простых стратегий со стандартными индикаторами. Тестируем стратегии в Quantopian, а пишем на Python🐍. В этот раз мы сравним индикатор Rate-of-Change (ROC) и популярное пересечение скользящих средних SMA(50) и SMA(200).

Дополнительно рассмотрим подход быстрого получения доходности📈 и просадки📉 простых стратегий в блокноте Jupyter.

Индикатор ROC показывает процент изменения текущей цены относительно  прошлого значения. Параметр индикатора — кол-во дней, между которыми сравниваем цены. Формула:

ROC(200)=(\frac{close}{close[-200]}-1)*100

Значение индикатора находится вокруг нуля.

✊Купи и держи по ROC(200)

Проверять будем на NYSE:SPY, но помним, что все активы ведут себя по разному. Условия:

  • Период: 2004-2018.
  • Время сделки: за 1 час до закрытия рынка.
  • Капитал: $100K.
  • Покупка, когда ROC(200) >= 0.
  • Продажа, когда ROC(200) < 0.

Код условия на Quantopian:

Результаты ROC(200) и сравнение с пересечением SMA(50) и SMA(200):

С 2004 год SPY вырос на +230% имея просадку в 2008 году около -55%. Рядом с этим показателем только пересечение SMA(50) и SMA(200) с меньшей просадкой. ROC(200) оказался даже хуже пересечения цены и SMA(200), показав чуть меньшее количество сделок за весь период. Внизу показан результат сглаженного ROC по формуле из этой статьи, который показал наихудший результат.

🔬Как получить результаты без бэктеста?

Тесты дают более точную картину и это актуально при сложных стратегиях. Но для стратегий с редкими ребалансировками, где можно использовать цену закрытия, мы получим максимально приближенные результаты используя Jupyter, pandas и numpy.

Получение доходности

Получая итоговую доходность для серии pandas, мы проходим следующие шаги:

  1. Получаем ежедневную доходность chg=prices/prices.shift(1).
  2. Устанавливаем первое значение chg.iloc[0]=1.
  3. При необходимости применяем фильтр и смещаем условия на один день (сделка проходит после получения сигнала)  sma200=chg[(df.close>sma200).shift(1)]. Это важно запомнить, чтобы не заглядывать в будущее.
  4. Считаем доходность перемножив все значения result=np.prod(sma200) .

Код есть в telegram: @quantiki.

Получение просадки

Получить максимальную просадку можно так:

  1. Получаем ежедневную доходность chg=prices/prices.shift(1).
  2. Получаем доходность на каждый день
    series.rolling(total, min_periods=1).apply(np.prod).
  3. Получаем абсолютный максимум на каждый день
    series.rolling(total, min_periods=1).max().
  4. Получаем просадку на каждый день относительно последнего максимума series/rolling_max - 1.0.
  5. Получаем максимальную просадку на каждый день daily_drawdown.rolling(total, min_periods=1).min().

В итоге имеем следующий код для расчёта простых стратегий и их просадки:

Результаты выглядят следующим образом:

  • bench — бенчмарк, результат удержания актива в течение всего времени.
  • * dd — максимальная просадка при каждом условии.
  • roc200 — удержание при ROC(200) больше нуля.
  • roc200s — использование сглаженного ROC(200).
  • s200 — пересечение цены и SMA(200).
  • s50x200 — пересечение SMA(50) и SMA(200).

Сравнив результаты с тестами на Quantopian видна разница, которой можно принебречь для принятия первичных решений. В некоторых случаях разница в доли процентов. Высока вероятность, что расхождение связано со временем ребалансировки стратегий (за 1 час до закрытия рынка). Мы же делаем расчёт по цене закрытия.

🏁Вывод

Мы увидели, что использование ROC(200), как фильтра трендов, является невыгодным. Также научились быстро получать доходность и просадку для простых стратегий, достаточные для принятия решений, а работающие на порядок быстрее.

В следующий раз мы ещё немного помучаем ROC. Проверим доходность, используя силу тренда, пересечение разных периодов ROC и создадим индикатор Know Sure Thing (KST), созданный Мартином Прингом на основе ROC.

💬В комментариях пишите, ваши вопросы по тесту и коду. Запрашивайте полный код стратегии и блокнота.

Александр Румянцев
Автор на Quantrum.me
Подписывайтесь на telegram-канал📣: @quantiki

Интересуетесь алготрейдингом на Python? Присоединяйтесь к команде.
📈 Участвуйте в IPO американских компаний c United Traders👍.

Исходные коды