Александр Томтосов
Александр Томтосов личный блог
13 мая 2021, 17:42

Системно тестируем аномалии на Python. Релиз библиотеки Portfolio Quantitive Research (PQR)

Привет! Сегодня не про результаты, а про методы. Закончил писать базовый функционал библиотеки для количественных исследований. Вот что из него можно выжать:

  • Моделирование портфелей по кросс-секции и временным рядам;
  • Квантильная методика формирования портфелей в % от выборки или фиксированное число инструментов;
  • Возможность гибко задавать веса в портфеле по дополнительному фактору (почти smart beta);
  • Можно вырывать данные для аналитики на каждом промежуточном этапе: сделки, размер позиций, комиссии, доходность портфелей;
  • Возможность относительно точно учесть комиссионные расходы;
  • Пока самая простая визуализация и метрики.

Как выглядит итоговая отрисовка:
Системно тестируем аномалии на Python. Релиз библиотеки Portfolio Quantitive Research (PQR)

Небольшая предыстория или зачем писать свой тестер

 

Не являясь базовым программистом, я пользовался готовыми решениями для бэктестов и особенно долго засиживался на платформе Quantopian. В прошлом году компания не получила нового транша от инвесторов и объявила о закрытии. Вместе с ней сгинул и весь написанный код, а знания синтаксиса несуществующей платформы близки по полезности к 1С-программированию при переезде в долину.
Поработав с другими сервисами, понял, что их существенные недостатки можно разделить на 3 группы:

 

  1. Отсутствие гибкости в плане выбора параметров и получения промежуточных результатов;
  2. Работа в закрытой экосистеме из данных и тестов. Проблемно загрузить много своих альтернативных данных или существенно поменять логику тестов;
  3. Отсутствие системного тестирования рынка и работа по отдельным инструментам.

 

Последний пункт наиболее критичный. Мне хотелось тестировать технические индикаторы или отбор акций по EV/EBITDA не на выборке из 1/2/25 бумаг, а на всех 500+ акциях, которые обращались на Мосбирже или 10к+ на NYSE. Данных и идей будет много, поэтому программа должна быть умеренно быстрой. Остановился на векторных вычислениях в numpy.
Логика расчетов не убойная и ее не сложно переписать на ваш любимый язык. Пример c расчетом весов портфеля по заданному фактору. Например, это может быть рыночная капитализация:

Системно тестируем аномалии на Python. Релиз библиотеки Portfolio Quantitive Research (PQR)

Как можно тестировать свои идеи в PQR

  1. Загружаем библиотеку и смотрим примеры использования в main.py и в папке с примерами. Там ноутбуки с простыми идеями. Будут пополняться;
  2. Находим данные по ценам и факторам для множества компаний. Цена тоже может быть фактором, если ее преобразовать в изменение или другой показатель. Допустим, выбраны мультипликаторы P/E и месячные цены закрытия для 200 российских акций;
  3. Составляем одинаковые по размеру таблицы (матрицы) в экселе/csv/txt или в чем угодно, что сможете загрузить в программу. По вертикальной оси будут названия компаний, а по вертикальной временной ряд. Матрицы обязательно должны быть одинаковы по размеру;
  4. Выбираем параметры тестирования: сколько периодов мы наблюдаем за фактором перед покупкой и сколько будем держать позиции. Устанавливаем лаг, комиссии и требуемый % акций из выборки в каждом портфеле;
  5. Подаем данные по P/E в функцию get_factor и получаем готовые ряды для дальнейших тестов. Все расчеты по укрощению lookahead bias выполняются здесь. Дополнительно сдвигать ряды не нужно;
  6. Задаем фильтры (опционально). Например, выкидываем из выборки компании со среднедневным объемом торгов за прошлый месяц менее 100 млн рублей;
  7. Считаем позиции по отдельным бумагам в каждом портфеле. Эти бинарные матрицы уже почти портфели, но не хватает весов;
  8. Задаем способ расчета весов в портфеле. Если выбираете взвешенный по фактору, то этот фактор нужно загрузить, не забывая про размер матрицы;
  9. Опционально считаем комиссии;
  10. Подаем все полученные данные в последний скрипт для расчета доходности портфеля, метрик и сравнения с бенчмарком. Если есть интересная альфа – можно углубиться в отдельные портфели и подумать над усложнением стратегии. Если нет – копаем дальше.

В папке examples на Гитхабе есть ноутбук с примером расчета небольших портфелей из FAANG и анти-FAANG акций. Пример ознакомительный и по понятным причинам выкладывать большие массивы вендоров в открытый доступ не могу.

Почему квантильная методика так важна

Количество акций в отдельные периоды на ЕМ сильно отличается, особенно если используете фильтры по ликвидности. Количество бумаг на нашей бирже в 1997 и 2021 не подлежит сравнению. 10 портфелей по 5 ликвидных (относительно) акций это очень много для того периода и мало для текущего. Квантильный способ удобен тем, что мы всегда берем одинаковый относительный охват рынка и получаем полную картину на каждый период.

Интересно наблюдать, как меняется результативность портфеля от первых 10% с наименьшим P/E, затем следующим 10% и т.д. Если альфа ломается при малейших изменениях параметров – тревожный признак. U-образная доходность портфелей – уже интереснее.

Что будет и чего не будет в будущих версиях

  1. Расширю количество метрик и графиков, добавлю мультифакторные стратегии и способы расчета бенчмарка
  2. Возможно будет коллаборация с подгрузкой данных из бесплатных источников;
  3. Больше статистики и аналитики по карте портфелей;
  4. Точно не будет всего что касается исполнения ордеров, производных инструментов и микроструктуры рынка. Это инструмент для первых прогонок стратегий. Копать дальше и торговать лучше более подходящим инструментом.

Ссылку на гитхаб с программой выложил в телеге :) https://t.me/sentimetrica

В следующий раз разберу принцип работы на конкретных примерах по нашему рынку. Идеи и пожелания по инструменту @atomtosov

19 Комментариев
  • Ынвестор
    13 мая 2021, 17:53
    По России интересно. По Штатам все уже придумано в лучшем виде.
  • Михаил Дунаев
    13 мая 2021, 17:58
    Для анализа можно использовать готовую довольно мощную либу pyfolio от quantopian, может работать изолированно без экосистемы quantopian
    Так же можно использовать zipline локально
    Есть еще альтернатива с quantconnect, тоже доступна для локальной работы

    Понимаю, что свой велосипед приятнее и роднее )
    Но все же рекомендую глянуть на готовые решения, если вдруг пока не довелось, возможно, они закроют большую часть потребностей
      • Александр Томтосов, отбор акций и формирование портфелей по фундаментальным показателям возможен на квантконекте, без танцев с бубном над подготовкой выборок и тд. 
        • broker25
          15 мая 2021, 16:46
          Dancing Orange Hyena, отбор по фундаменталу? То есть можно с квантконнекта качать годовые и квартальные прибыли и цены с глубиной? А как насчет делистингованных компаний?
          • broker25, приветствую. Делистингованные компании тоже есть(свойство delisting) Вот ссылка на доку по ресерчу. www.quantconnect.com/docs/research/fundamental-data
            Качать данные… наверно можно исхитрится, чтобы отправлять себе почту. Но по сути это ненужно.
            Вот пример кода по отбору и сделкам на основе балансовой стоимости. Пример на питоне. На С# переключать не стал, так как сейчас идет бектест, чтобы ничего не сломалось. Но старожилы квантконекта рекомендуют использовать С#, так как бектесты работают в десятки раз быстрее. К сожалению отступы не копируются на смарт лабе. Но зная вас, думаю общее впечатление себе вы сможете составить.
            _________________________________

            from datetime import timedelta
            from QuantConnect.Data.UniverseSelection import *
            from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel

            class LiquidValueStocks(QCAlgorithm):

            def Initialize(self):
            self.SetStartDate(2017, 5, 15)
            self.SetEndDate(2017, 7, 15)
            self.SetCash(100000)
            self.UniverseSettings.Resolution = Resolution.Hour
            self.AddUniverseSelection(LiquidValueUniverseSelectionModel())

            #1. Create and instance of the LongShortEYAlphaModel
            self.AddAlpha(LongShortEYAlphaModel())

            self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())
            self.SetExecution(ImmediateExecutionModel())

            class LiquidValueUniverseSelectionModel(FundamentalUniverseSelectionModel):

            def __init__(self):
            super().__init__(True, None, None)
            self.lastMonth = -1

            def SelectCoarse(self, algorithm, coarse):
            if self.lastMonth == algorithm.Time.month:
            return Universe.Unchanged
            self.lastMonth = algorithm.Time.month

            sortedByDollarVolume = sorted([x for x in coarse if x.HasFundamentalData],
            key=lambda x: x.DollarVolume, reverse=True)

            return [x.Symbol for x in sortedByDollarVolume[:100]]

            def SelectFine(self, algorithm, fine):
            sortedByYields = sorted(fine, key=lambda f: f.ValuationRatios.EarningYield, reverse=True)
            universe = sortedByYields[:10] + sortedByYields[-10:]
            return [f.Symbol for f in universe]

            # Define the LongShortAlphaModel class
            class LongShortEYAlphaModel(AlphaModel):

            def __init__(self):
            self.lastMonth = -1

            def Update(self, algorithm, data):
            insights = []

            #2. If else statement to emit signals once a month
            if self.lastMonth == algorithm.Time.month:
            return insights
            self.lastMonth = algorithm.Time.month

            #3. For loop to emit insights with insight directions
            # based on whether earnings yield is greater or less than zero once a month
            for security in algorithm.ActiveSecurities.Values:
            direction = 1 if security.Fundamentals.ValuationRatios.EarningYield > 0 else -1
            insights.append(Insight.Price(security.Symbol, timedelta(28), direction))
            return insights

            • broker25
              15 мая 2021, 17:40
              Dancing Orange Hyena, спасибо, интересно. Возможно, качну, проверю. На самом деле у меня не было особых проблем со скоростью Питона при тесте фундаментала. А вот с тиками он явно не справится, даже минутки под вопросом
              • broker25, а ничего качать не надо. Там же webIDE. При бектестах дается бесплатная виртуалка. Все деплоится нажатием кнопки. Раздел рисерч предназначен для быстрого поиска идей(я новенький в квантконекте, по этому не разобрался нафиг он нужен когда есть webIDE, аж с двумя подходами: класcическим и на основе нового фремворка).  Я пока пытаюсь разобраться с классическим подходом. Там вобще все просто относительно. Но я не профессиональный прогер, поэтому иногда возникают глупые затыки. Но если уж такой тупень как я, смог начать в этом потихоньку разбираться, то вы разберетесь очень быстро.

                 

              • broker25, а еще там есть опционы
    • broker25
      15 мая 2021, 16:48
      Михаил Дунаев, а в zipline правда лежат исторические цены акций с таймфреймом минута?
      • Михаил Дунаев
        15 мая 2021, 17:04
        broker25, если говорить про локальное использование, то зависит от того, какие данные туда положишь, можно и дневные и минутные
  • Артур
    13 мая 2021, 19:31
    а panda не изучвли?
  • Артур
    13 мая 2021, 19:32
     как вообще начали питон осваивать. мне 31 год и я вообще не шарю в программировании. хочу на досуге питон начать учить, но так лень.
    • Виталий
      14 мая 2021, 09:02
      Артур, в инете полно уроков, начните с малого и шаг за шагом…
    • Михаил Дунаев
      15 мая 2021, 17:05
      Артур, рекомендую платформу stepic, там есть бесплатные курсы и для начинающих и для продвинутых
  • broker25
    15 мая 2021, 17:02
    Это все прекрасно, но у вас цены с яху, а фундаментал вообще не качается. Будете добавлять из открытых источников?? А они такие есть в принципе? И это противоречит идее тестирования без ошибки выжившего
    • Михаил Дунаев
      15 мая 2021, 17:11
      broker25, фундаментал нормально можно вытащить с яху.финанс, там есть апи для этого
      В открытых источниках есть проблема с компаниями которые больше не торгуются, но есть недорогие платные, например, tiingo за 10$ /мес
      Есть еще market-archive.appspot.com, не проверял лично, но на сайте указано, что за 60$ можно получить дневки по всем акциям, в том числе и снятым с листинга
      • broker25
        15 мая 2021, 17:18
        Михаил Дунаев, то есть на сайте yahoo.finance все закрыто, кроме последних лет, а в апи они дают к данным доступ? Может быть, конечно, но предполагаю, что как на сайте
        • Михаил Дунаев
          15 мая 2021, 18:37
          broker25, да, подзабыл я этот момент, на яху только недавние данные отдаются, как на сайте
          Ковырял тут otcmarkets, на удивление, там можно вытащить историю не только по otc рынку, но и по основному
          Подергал недокументированное апи на счет всяких эплов и фэйсбуков
          Годовые отчеты есть до 96 года, квартальные только до 2015

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

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