Блог им. Quantrum

Простой бэктестинг 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)

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

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

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

# получаем цены и рассчитываем ROC(200)
price_hist = data.history(context.asset, 'close', 400, '1d')
roc = talib.ROC(price_hist, timeperiod=200)

# сигнал на значении выше нуля
allow = roc[-1] >= 0

# ...

if data.can_trade(context.asset):
    if allow:
        # покупаем актив на 100% портфеля, если разрешено
        order_target_percent(context.asset, 1.)
    else:
        # закрываем позицию при запрете
        order_target_percent(context.asset, 0.)

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

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

С 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().

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

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

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

  • 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? Присоединяйтесь к команде.

Данная публикация является личным мнением автора. Мнение владельца сайта может не совпадать с мнением автора.
| ★10
2 комментария
Интересно. Как раз учу питон.
avatar

Читайте на SMART-LAB:
Фото
Рынок акций 6—10 июля: снижение доходностей не оказало поддержки
Фото
Выплатим 246,88 рубля на каждую акцию нашим акционерам уже в августе
Напоминаем, 17 июля – последний день для покупки акций с дивидендами. Лайк — если уже планируете реинвестировать дивиденды в акции ДОМ.PФ
Чек честнее инфляции?
В открытой студии ТРЕЙДЕР ТВ на Smart-Lab Conf 2026 — КОТ ФИНАНС. Повод для разговора — статья, которая начинается с обычной покупки...
Мой Рюкзак #66: Потрепанная шкура в игре, но есть ли смысл выходить по текущим? Только если ребаланс
Мой Рюкзак #67: Стратегическое плечо под дивиденды
Последний раз писал пост 23 июня smart-lab.ru/company/mozgovik/blog/1319727.php Счет продолжает растворяться в жерле Мосбиржи, было 21,5...

теги блога Александр Румянцев

....все тэги



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