Александр Румянцев
Александр Румянцев личный блог
21 марта 2017, 23:46

Бэктестинг: купи и держи со скользящими средними

В этот раз «подкрутим» стратегию «купи и держи» с помощью скользящих средних на основе этой статьи. Там говорится, что при входе выше 200-дневной средней и выходе под ней, мы можем получить аналогичную доходность и сократить просадки. Дополнительно появляется возможность припарковать свободный капитал, например, в банк.

Будет приведено несколько алгоритмов:

  • пересечение SMA200 и цены;
  • пересечение SMA200 и SMA10;
  • пересечение SMA200 и SMA50;
  • пересечение EMA200 и EMA50;
  • пересечение EMA200 и EMA50 плюс покупка облигаций.

Все происходит на платформе Quantopian, о которой я подробнее пишу в этом посте. Период тестирования для всех алгоритмов — с 01.01.2014 до 29.12.2016. Связано это с тем, что у EMA есть нестабильный период, который необходимо пропустить. 

 

«Купи и держи» за выбранный период

Для наглядности размещу здесь результат стратегии «Купи и держи». Можно заметить, что результат хуже бенчмарка на ~3%, что связано с механизмом просадок и комиссий, используемым по умолчанию в платформе. Об этом поговорим в отдельном обзоре.

Бэктестинг: купи и держи со скользящими средними

Внизу видно, что было много транзакций — это связано с реинвестированием дивидендов.

 

Пересечение SMA200 и цены

Бэктестинг: купи и держи со скользящими среднимиСправа на картинке не впечатляющие результаты тестирования. Мы входим над 200-дневной скользящей средней и выходим, когда цена опускается под нее. Внизу видно увеличившееся число произведенных транзакций, которые с аппетитом поедали средства на комиссии и проскальзывания. За 50% доходности мы получили сокращение на 22% времени удержания позиции и уменьшение просадки до -22%, что положительно скажется на нервах. Результаты всех измерений доступны в конце статьи, в таблице.

Внизу видно, что транзакции на покупку и продажу сконцентрированы в нескольких местах. Объясняется это тем, что цена очень часто колеблется вокруг 200-дневной средней, являющейся очень сильным уровнем поддержки или сопротивления. Для сокращения колебаний воспользуемся второй короткой средней, SMA(10), и будем входить когда она над длинной, а выходить — наоборот.

Ниже размещен код на Python. Все последующие тесты используют этот же код с минимальными изменениями, которые будут показаны без повторения нетронутых строк. Исходный код на Quantrum.me.

Для использования этого кода, перейдите на страницу своих алгоритмов, нажмите кнопку «New Algorithm», в названии укажите «Buy and hold SMA200» и нажмите «OK». Скопируйте текущий код и на открывшейся странице вставьте его в левое поле, стерев предварительно все что там было. Для запуска алгоритма нажмите «Build Algorithm».

 

Пересечение SMA200 и SMA10

Бэктестинг: купи и держи со скользящими средними
В этот раз удалось отыграть 20% доходности и сократить просадку до -19%.

В следующем тесте проведем проверку с пересечением SMA(50) и SMA(200). Данное пересечение является фактом долгосрочного бычьего или медвежьего трендов. По этому пересечению многие трейдеры держат консервативную часть своего капитала в индексах широкого рынка, таких как S&P 500 (SPY).

В коде тестирования SMA(200) X SMA(10) были поменяны только три строчки, которые представлены ниже: Исходный код на Quantrum.me.

 

Пересечение SMA200 и SMA50

 Бэктестинг: купи и держи со скользящими средними

Результаты стали значительно лучше. Не хватает только 9% доходности, а на другой чаше весов сокращение времени удержания позиции на 23%, сокращение просадки на 35% и даже сокращение количества сделок.

В следующем тесте попробуем заменить обычные на экспоненциальные скользящие средние. Ведь они быстрее реагируют на изменения цены, что может позволить нам улучшить результаты теста.

Изменения кода SMA(200) X SMA(50): Исходный код на Quantrum.me

 

Пересечение EMA200 и EMA50

Бэктестинг: купи и держи со скользящими средними

За последние 12 лет грааль вроде найден и содержит он простое пересечение EMA(50) и EMA(200). Нам удалось обыграть рынок на 2%, сократить просадку до 18%, сократить количество сделок и сократить время удержания на 18%. И это при учете проскальзываний и комиссий (об этом подробнее в будущих статьях), которые автоматически учитываются на Quantopian.

Изменения кода EMA(200) X EMA(50):

<code class=" language-python">    ...
    ma_long = talib.EMA(price_hist, timeperiod=200)[-1]
    ma_short = talib.EMA(price_hist, timeperiod=50)[-1]
    ...</code>

Помня, что в первый час открытия рынка торговать не рекомендуется из-за повышенной волатильности, мы установим условие, что на рынок будем выходить спустя 1 (один) час после открытия. Данный не хитрый способ позволил нам отыграть еще 4%. Код изменения ниже:

<code class=" language-python">    ...
    schedule_function(rebalance, date_rules.every_day(), time_rules.market_open(hours=1))
    ...</code>

Сейчас мы видим последнюю проблему, которая поражает наш алгоритм — это резкое падение, которое было в августе 2015. Есть несколько возможных решений, например:

  • Закрывать позицию при резком падении на определенное кол-во процентов от цены.
  • Оставлять допуск на разворот в области пересечения ±2%. То есть закрывать позицию, когда EMA50 на 2% ниже EMA200, а открывать, когда на 2% выше EMA200.

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

Пересечение EMA200 и EMA50, при выходе сидим в TLT

Каждый раз на слабом рынке мы выходили в кэш. А что будет, если при выходе в кэш искать возможность войти в облигации, а именно в ETF на 20-летние облигации TLT? А все будет значительно лучше, что показывают результаты в таблице ниже. Доходность вырастает до 198%, что на 40% выше эталона, а деньги находятся в рынке 94% времени.

Остаются проблемы августа 2015, решая которые можно скорее навредить, подогнав алгоритм под историю, нежели улучшить.

Бэктестинг: купи и держи со скользящими средними

Исходный код с торговлей облигациями доступен в обмен на вашу социальную активность.

Исходный код на Quantrum.me.

Результаты

Стратегия Время торгов Кол-во сделок Срок в позиции Доходность Просадки
Купи-Держи Open 53/0 99% 160.1% -54.9%
SMA200/ Цена Open 91/47 77.5% 113.9% -22%
SMA200/ SMA10 Open 56/16 78% 129.1% -19.1%
SMA200/ SMA50 Open 47/7 77% 151.1% -19.9%
EMA200/ EMA50 Open 46/4 82.5% 162.1% -18.2%
EMA200/ EMA50 Open+1 48/4 82.5% 165.9% -18.3%
EMA200/ EMA50/ TLT Open+1 71/12 94% 198% -20.8%
  • Время торгов — время, когда алгоритм начинает торговать: Open — открытие рынка, Open+1 — через 1 час после открытия рынка.
  • Кол-во сделок — количество сделок на покупку и продажу. В поле указаны Покупки/Продажи. Реинвестиция дивидендов считается отдельными сделками.
  • Срок в позиции — количество дней в позиции. В первый день мы начинаем закупаться, отсюда 99%.

Заключение

Исследование показывает, что стратегия «Купи и держи» с легкостью может быть улучшена обычными скользящими средними. При этом не надо ни ума, ни активного робота. Достаточно заглядывать на графики раз в неделю и уже только это позволит иметь приличные результаты по доходности. В следующий раз я опишу стратегии при использовании индикатора MACD.

Напишите в комментариях, что можно улучшить в данных алгоритмах. Или предложите, какие стратегии стоит рассмотреть в будущем.

22 Комментария
  • Евгений Макеев
    22 марта 2017, 00:03
    Классический пример подгона стратегии под историческую выборку! Возьмите, то что получилось в конце, и прогоните на другом временном отрезке, выбранном случайным образом. Уверен все будет не так оптимистично.
      • Евгений Макеев
        22 марта 2017, 14:20
        Александр Румянцев, нет я хорошо все прочитал,  как только увидел слово Python :)
        Вся последовательность ваших шагов в этой статье — это чистый подгон системы под исторические данные. Проверить это не сложно, просто прогоните ее на любом случайно выбранном отрезке.
          • Евгений Макеев
            22 марта 2017, 14:40
            Александр Румянцев, о чем я вам и говорю. Вы взяли определенный период и последовательно подогнали под него параметры системы. Так не делают. Сроки тут не причем. Вам нужно было просто разделить выборку на 4 отрезка. Сделать для одного из них, то что вы сделали, а потом проверить параметры на остальных трех. 
            Я собаку съел на подобных подгонах. В чем смысл того что вы нашли (подогнали) грааль для указанной выборки? Работать оно не будет. Как реклама или практика питона, да, но практического применения без теста на независимых выборках у подобных систем нет никакого. 
              • Евгений Макеев
                22 марта 2017, 18:33
                Александр Румянцев, ладно. Тестируйте как вам угодно
  • Алекс Бергманн
    22 марта 2017, 06:06
    ема 200 настолько запаздывающий показатель (его и индикатором нельзя назвать) настолько не имеющий отношения к реальной торговле, что вместо него можно было поставлять любые значения, типа — покупаем по средам.
      • Алекс Бергманн
        23 марта 2017, 03:30
        Александр Румянцев, нет. я внимательно прочитал статью. дело не в средах))  без обид! я в принципе считаю, чтоЕМА 100,200 и тп это бессмысленные уровни как для среднесрочной торговли так и для инвестирования. это как свет мертвой звезды, они показывают то, чего давно уже нет…
  • SergeyJu
    22 марта 2017, 11:11
    Для ЕМА200 выборка маловата. 
      • SergeyJu
        22 марта 2017, 14:52
        Александр Румянцев, не в этом дело. За рассматриваемый период было 2 кризиса, доткомов и ипотечный. За их счет  эта конструкция и выигрывает. То есть, по сути 2 редких события сделали систему. Я ничего не имею против обнаружения кризисов, я просто констатировал тот факт, что для такой медленной системы запас данных маловат. 
        Вы могли бы взять недельные данные за бОльший период и перейти, скажем, к 40ЕМА на недельках?
          • SergeyJu
            22 марта 2017, 16:39
            Александр Румянцев, да, точно, я недоглядел, один кризис у Вас, а не два. 

  • Arslan
    13 мая 2020, 14:43
    Можно ли рассматривать данную стратегию как позиционный трейдинг?

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

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