Пробелы в пьесах

Джон Ф. Картер в книге Освоение сделки описывает простейшую из своих схем как игру с гэпами, когда он торгует с гэпами, возникающими при открытии акции и фиксируют прибыль по мере их закрытия. Я попытаюсь воссоздать этот разрыв, используя простые методы классификации и регрессии. Торговый жаргон будет широко использоваться, но, если повезет, это не умалит сути этого поста. Однако, если вы хотите всегда быть в курсе событий, this - хорошее начало кроличьей норе, которая объясняет здесь все элементарные концепции.

Установка

Установка Картера включает «уменьшение» разрыва в цене акции. Он делает это на дневном таймфрейме и использует общий объем перед рынком по определенному набору акций, которые он называет «громкими именами дня», которые обеспечивают обзор состояния рынка в этот день. Его установка состоит из пороговых значений, основанных на эвристике, которую он определяет на основе опыта на премаркете объемов этих репрезентативных запасов. Он основывает значения пороговых объемов на значении индикатора $ VIX.

Настройка (без жаргона)

Схема Картера предполагает зарабатывание денег на разнице в курсах акций, возникающей в течение дня. Если, например, при открытии рынка сегодня акция торгуется по цене ниже, чем та, по которой торговались, когда рынок закрылся вчера, то на основе определенных показателей Картер покупает акции этой акции и продает их, когда “ разрыв » в ценах при сегодняшнем открытии и закрытии вчерашнего дня. Что это за индикаторы? Картер использует данные об объеме торгов незадолго до открытия рынка определенного набора выбранных им акций и определяет пороговые значения этих объемов, на основании которых он принимает решение о покупке / продаже. Эти пороговые значения определяются на основе другого индикатора, называемого $ VIX, значение которого определяет, какими должны быть эти пороговые значения. Это не ракетостроение (или, по крайней мере, мне так не кажется), это установка, созданная на основе опыта.

Моя цель - воссоздать эту установку, используя базовые методы машинного обучения. Я обучу два вида предикторов: регрессор, чтобы предсказать, какой процент пробела будет заполнен, и классификатор, чтобы предсказать, закроется пробел или нет. Однако в этом посте я подробно расскажу о результатах только для классификатора.

Данные

По моим данным, я получил 15-минутные внутридневные данные для всех акций NIFTY с 01.01.2019 по 17.07.2020. Данные доступны в виде файлов CSV, и я отфильтровываю предпродажные данные из более крупного набора данных. Это выполняется путем поиска соответствующей временной отметки 09: 00–09: 15 (время предмаркетной сессии для NSE) по всем данным по всем акциям и сбора их в матрицу данных.

Модель предоставит прогнозы для пробелов в NIFTY (Картер использует S&P, DOW), и поэтому для меток истинности (независимо от того, закрыт пробел или нет), я использую ежедневные данные для NIFTY (а также $ INDIAVIX) в тот же диапазон, что и раньше. Затем я просматриваю данные и формирую необходимые метки для определения того, закрылись ли пробелы в NIFTY или нет, используя OHLC предыдущего дня и сегодняшнего.

# NIFTY OHLC data is in nifty_data
# truth labels
binary_labels = []
for i in range(nifty_data.shape[0]-1):
    yday_close = nifty_data[i, CLOSE]
    today_open = nifty_data[i+1, OPEN]
    today_low = nifty_data[i+1, LOW]
    today_high = nifty_data[i+1, HIGH]
# gap at open, and gap at its smallest
if today_open > yday_close:
    gap = today_open - yday_close
    gap_close = today_low - yday_close
elif today_open < yday_close:
    gap = yday_close - today_open
    gap_close = yday_close - today_high
# did the gap close?
if gap_close <= 0:
    binary_labels.append([i,1])
else:
    binary_labels.append([i,0])

Наивный исходный уровень

Сразу же мы сталкиваемся с затруднительным положением: недостаточно данных. Источник, из которого я получил свои исторические данные, предоставляет данные только за 01.01.2019, что дает 350 точки данных. Поскольку у нас нет данных, давайте воспользуемся простой моделью логистической регрессии в качестве первоначальной наивной основы.

clf = LogisticRegression()

Использование K-кратного метода перекрестной проверки с 4 разделениями дает ужасные результаты:

Class   Metric     Score
0       Recall     0.064
1       Precision  0.67
--------------------------
Accuracy = 0.66

Примечание. Нас интересует оценка отзыва для гэпа, остающегося открытым (класс 0), поскольку последствия занятия позиции с неверным прогнозом закрытия гэпа (ложноотрицательные) очень серьезны. Точно так же точность закрытия разрыва (класс 1) имеет большее значение, поскольку нам нужно как можно больше правильных прогнозов для закрытия разрыва (истинное положительное значение), и мы просто не будем входить в позицию, если прогноз был открыт с разрывом (ложное положительное ).

Если мы немного изменим модель:

clf = LogisticRegression(class_weight='balanced')

Тогда результаты более обнадеживающие:

Class   Metric     Score
0       Recall     0.45
1       Precision  0.70
--------------------------
Accuracy = 0.59

Похоже, мы достигли гораздо лучшего показателя отзыва (45%) при незначительном улучшении точности до 70% за счет общей точности, которая снизилась с 66% до 59%. Однако общая точность здесь не имеет большого значения. Чтобы понять почему, вот график всего набора данных:

Имеется значительно большее количество точек «закрытия разрыва», чем «открытия разрыва», только 1/3 данных соответствует «открытию разрыва» очков. Это означает, что вы можете получить точность 66%, просто всегда прогнозируя, что разрыв будет сокращаться, что является точностью, которую дает первая базовая модель. Параметр class_weight = «сбалансированный» позволяет нам компенсировать этот дисбаланс в данных, и результаты очевидны.

Вывод

Совершенно ненужный для науки о данных эквивалент игры с пробелами Джона Ф. Картера возможен при использовании классификатора логистической регрессии, обученного на данных за полтора года. Кроме того, интересно отметить, что можно было заработать деньги (тоже много потерять, но, в конце концов, получить прибыль), просто всегда открывая позицию, предполагая, что разрыв закроется.