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

Парный трейдинг: 1 из 3 способов поиска пар на Python

Первый из трех способов автоматического поиска пар на Python для торговли по стратегии «Парного трейдинга». Исходя из результатов предыдущей статьи, во всех примерах мы будем использовать только поиск коинтеграции.

Кратко о «Парном трейдинге»: в основе стратегии лежит предположение, что есть две акции, которые имеют глубокую экономическую связь друг с другом, и их цена движется в одном направлении с разной скоростью. Когда отстает акция А, мы ее покупаем и одновременно продаем в короткую акцию Б. И наоборот.

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

Подготовка к поиску

Для правильной работы необходимо соблюсти следующие условия:

  1. Истории цен должны быть равной длины. (Результат сравнения историй за 200 дней и за 20 дней может быть непредсказуем).
  2. Значения должны быть переведены в относительные величины. (Тяжело сравнивать активы за $200 и за $1).
  3. Каждая история не должна обладать стационарностью сама по себе. (Важна именно стационарность спреда пары, а не отдельного актива в ней).

Коинтеграцию каждого времянного ряда будем проверять с помощью метода Дики-Фуллера из библиотеки statsmodels. Код подготовки ниже: Исходный код на Quantrum.me.

Выбор акций для поиска

Искать пары будем среди активов торгующихся на рынке, включая ETF, ограничив следующими условиями:

  • Цена более $10.
  • Средний объем более 500 тыс. акций в день.
  • ATR за 13 дней более $0.40.

Проверяем на ликвидных активах с хорошим движением внутри дня. Из 6 тысяч американских акций, торгующихся на биржах, нам подходят ~1500 активов. Тестировать будем предыдущий год (360 календарных дней).

1 из 3: Простой коинтеграционный тест

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

Функция проверки стационарности: statsmodels.tsa.stattools.coint(X, Y)

Функция поиска пар получает словарь с историей относительного изменения цен и последовательно проверяет каждую пару. Для 1500 активов это примерно 1.1 миллиона вариантов.

Выбираем пары с оценкой ниже 5% уровня ошибки и p-значением меньше 0,001. Код поиска пар ниже: Исходный код на Quantrum.me.

На момент написания статьи тест нашел 6400 пар (~0.6%), поиск загружал 1 ядро процессора и длился порядка 45 минут. Вот первые несколько пар с наименьшим p-значением:

  • XIV, SVXY
  • IWB, SPY
  • IVV, SPY
  • DUST, GDX
  • SPY, SPXU

Видно, что это ETF на индексы и первые два действительно имеют стационарный спред, а вот начиная с IVV и SPY найти проблемы нам помогут графики.

Проверка найденных пар

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

  • XIV, SVXY
  • DUST, GDX
  • XLK, QQQ
  • PRU, C
  • TMUS, WCG

XIV, SVXY

XIV — ETN (аналог ETF) обратный индексу страха $VIX.
VSXY — ETF обратный индексу страха $VIX.

На графике история цен и сигнальная линия z-оценки. SVXY домножен на коэффициент для приведения цен к единой величине. Видно, что график хорош, но два месяца назад (ноябрь-декабрь 2016) спред уменьшился. Причина в моем поставщике данных. Ранее была бо́льшая погрешность в цене, которую нивелировали.

Парный трейдинг: 1 из 3 способов поиска пар на Python

Код z-оценки: Исходный код на Quantrum.me.

DUST, GDX

DUST — 3х-кратный обратный ETF к GDX.
GDX — ETF компаний-золотодобытчиков.

График разочаровывает и подобных графиков в результатах много. Данные активы обратно-скоррелированы — этот факт в их природе существования. Функция coint(X, Y) на вход получает два времянных ряда и сама проверяет их стационарность. Видимо эта функция использует в основе проверку корреляции и дополнительно подгоняет ряды.

Парный трейдинг: 1 из 3 способов поиска пар на Python

XLK, QQQ

XLK — ETF на индекс технологических компаний.
QQQ — ETF на индекс NASDAQ-100, где преимущественно технологические компании.

Здесь результаты лучше, но так как в QQQ также много компаний из XLV (здравоохранение), то в январе 2017 XLK сумел вырваться вперед.

Парный трейдинг: 1 из 3 способов поиска пар на Python

PRU, C

Копнем поглубже и возьмем несколько компаний.

PRU — Prudential Financials, страховая компания.
C — Citibank, банк.

Большую часть года компании шли в ногу, что не удивительно, так как обе в XLF (финансовый сектор) и обе выигрывают от роста ставок. Но за январь 2017 появилось расхождение.

Парный трейдинг: 1 из 3 способов поиска пар на Python

TMUS, WCG

TMUS — T-Mobile US, американский сотовый оператор.
WCG — WellCare Health Plans, компания из сектора здравоохранения.

Связь данной пары меня удивляет, но с графиком не поспоришь, они идут нога в ногу и обладают хорошим спредом.
Парный трейдинг: 1 из 3 способов поиска пар на Python

Вывод

Данный метод имеет право на существование. Удается найти хорошие пары, которые достойны участия в бэктестинге. Но одновременно к нам приходит большое количество шлака, что заставляет отсматривать результаты вручную. Лучше себя проявил поиск с помощью метода Дики-Фуллера, о котором я буду писать в следующей статье.

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

Обучение «Парному трейдингу» у профессионалов.
31 Комментарий
  • pm
    18 апреля 2017, 22:01
    это зачет........++++++++
  • StockChart.ru
    18 апреля 2017, 23:27
    на рутикере есть парный трейдинг кстати 

  • alexKa
    18 апреля 2017, 23:38
    когда то давно тоже искал такие зависимости, но, похоже что на практике это слишком опасно применять, расходятся на длительное время и не сходятся, или в одном периоде есть зависимость, а потом пропадает, потом снова появляется, и по какой причине это происходит непонятно.
    • Андрей К
      19 апреля 2017, 00:08
      alexKa, на моих глазах так уже достаточно таких трейдеров ушли в прошлое. Порвало на парах.
  • Авентадор
    19 апреля 2017, 06:22
    Вы не могли бы добавить сравнение GDX и NUGT (Bull 3x GDX) ?

    Графики, по идее, тоже будут расходиться на средне и долгосрочном периоде, хотя и в меньшей степени… На первый взгляд это может показаться парадоксальным, но несмотря на 3-е плечо в NUGT, его график почти всегда будет под GDX.
    Впрочем, если рассмотреть изолировано период только первой половины 2016 года, то NUGT на какое-то время обгонит свою базу.

    А долгосрочное расхождение будет формироваться как раз из-за маржинальной природы NUGT, поскольку на падающих днях, особенно на падающих резко, его Net Assets Value регулярно как бы утрамбовывается, и практически уже не восстанавливается до прежних значений (что, кстати, лишний раз напоминает о пагубности плечей).
  • baron_samedi
    19 апреля 2017, 08:31
    Каким образом устанавливать стоп на сделку и стоп на стратегию?
    Какова вероятность что порвет сильнее, чем заработаешь?
      • baron_samedi
        19 апреля 2017, 13:13
        Александр Румянцев, 
        это уже растрата семени в союзе с кулачеством.
  • Vitty
    19 апреля 2017, 08:50
    надеюсь понимаете что на живых деньгах это все исключительно к убытку приведет?
  • Igr
    19 апреля 2017, 08:55
    российские бы акции 
  • RomSunZ
    19 апреля 2017, 09:32
    Бывает и рвет. Мани и риск менеджмент никто не отменял. Скрин реальной торговли на фортсе.
  • ves2010
    19 апреля 2017, 09:42
    было такое уже... 
    выкинь гадость сразу… не трать время… на дневках тестить нельзя, т.к дневки содержат сделки за пределами торговой сессии… т.е один актив не торгуется уже а по второму идут сделки… и эти сделки входят в дневные цены… ты как бы заглядываешь в будущее...
    это легко можно проверить… берешь дневки смотришь цены открытия закрыти хая и лоя… затем смотришь 15ти минутку за тот же день и смотришь что было реально внутри торговой сессии
      • ves2010
        19 апреля 2017, 11:35
        Александр Румянцев, не спорь… просто проверь… и деньги сохранишь и время
          • ves2010
            19 апреля 2017, 17:12
            Александр Румянцев, если у тя IB то делай еще проще там в настройках TWS галочка есть игнорировать данные вне торговой сессии… кстати мож она у тебя стоит… и просто смотри дневки с этой галочкой и без нее
  • Александр Муравьев
    19 апреля 2017, 10:04
    Нельзя акции из разных секторов брать, даже если у них очень красивый спред. Обязательно разорвет, убытки будут огромные.
      • Александр Муравьев
        19 апреля 2017, 12:20
        Александр Румянцев, ок,
        Допустим спред отклонился от среднего уровня на величину входа, которая у вас определена системой. Вы вошли по направлению возврата к среднему уровню. Но спред идет дальше против вашей позы. При этом вы постоянно следите за состоянием пары.
        Что будете делать в такой ситуации для минимизации убытка?

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

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