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

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

Читайте на SMART-LAB:
Фото
Разворот?
За обвалом понедельника, что в акциях, что в ОФЗ, что в ВДО, последовал отскок. Имеет ли он шансы развиться во что-то большее или...
Фото
USD/CAD: канадец неудержимо катится по наклонной
Канадский доллар после короткой консолидации в узком коридоре продолжил падать и вышел на многомесячные минимумы. Главная движущая сила в паре...
Фото
ПАО «Селигдар» проведет День инвестора на Московской бирже
Мероприятие состоится 9 июля в 11.30 в офисе Московской биржи по адресу: Большой Кисловский пер, 13, этаж 3, ауд. 0314. Спикеры...
Мой Рюкзак #65: Ставка на энергетический и продовольственный кризис из-за перекрытия проливов
Мой Рюкзак #66: Потрепанная шкура в игре, но есть ли смысл выходить по текущим? Только если ребаланс
Последний раз писал про портфель 3 месяца назад, делал ставку на энергетический и продовольственный кризис из-за перекрытия проливов Ссылка...

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

....все тэги



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