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

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

Осцилляторы - это большая вещь - от стохастического осциллятора до MACD и Осциллятора Чайкина, который был разработан в 1970-х Марком Чайкиным (и является лишь одним из многих индикаторов, которые он изобрел). Вот формула осциллятора Чайкина, который измеряет колебания денежных потоков, поступающих и исходящих из капитала:

Эта формула принимает во внимание C (цена закрытия), H (высокая цена), L (низкая цена) и V (объем) и может работать, если не для прогнозирования движения цены, то, по крайней мере, для подтверждения или опровержения существования Тенденция.

В большинстве случаев анализ проводится в виде линий. То есть мы используем человеческий глаз и мозг, чтобы различать закономерности и прогнозировать на основе опыта. Это правила, которые трейдеры используют для генерации сигналов. А если речь идет о быке или медведе, покупке или продаже, вы можете автоматизировать этот процесс. Например, если вы зайдете на tradingview.com, вы можете взять любой капитал или любую валюту и увидеть эту панель инструментов, которая суммирует то, что нам говорят технические характеристики.

Индикаторов и средних даже больше, чем в той шапке экрана. Каждый из них можно свести к покупке, продаже или нейтрали, и окончательное «совокупное» решение - это то, что вы видите вверху в сводке. В этом случае каждый показатель или среднее значение получает 1 «голос», поэтому, если у вас нет никаких предубеждений или предпочтений, вы можете просто посчитать и посмотреть, выиграет ли покупка, продажа или удержание.

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

Настройка

dim = 100 #derivation window                    
forecast = 50 #length of forecast window
skip = 5 #days between "today" and the start of the forecast window

Вероятно, вы захотите использовать входные данные, которые в 2 или 3 раза превышают окно прогноза. Это проблема предсказания последовательности для последовательности, поэтому ожидайте, что RNN и CNN будут в центре внимания. Я использовал временные сверточные сети. Этот эксперимент в основном опирался на следующие библиотеки:

!pip install git+https://github.com/manu-mannattil/nolitsa.git
!pip install yfinance --upgrade --no-cache-dir
!pip install keras-tcn
!pip install ta
!pip install finta

nolitsa - для нелинейного анализа временных рядов, yfinance - для загрузки финансовых данных, keras-tcn - для временных сверточных сетей, а finta и ta для технического анализа (индикаторы, средние значения и т. д.).

Я пробовал различные комбинации технических индикаторов, от MACD до Awesome Oscillator и Money Flow Index, осциллятора Чайкина, среднего истинного диапазона и т.д. как здесь, так и в академических статьях это делают, то есть бросить все и посмотреть, что прилипнет - что в некотором смысле является роскошью, которую дает нам глубокое обучение, но с практической точки зрения вы должны начать с нескольких хороших функций и сделать что-то экономное и посмотри, как это работает.

После большого количества проб и (в основном) ошибок я остановился на денежном потоке Чайкина и TRIX (тройное сглаженное экспоненциальное среднее значение ROC за 1 день) , используя диапазоны 10,20 и 50 дней - поскольку мое окно прогноза равно 50. Идея заключалась в том, что CHAIK50 и TRIX50 были бы «базой», сглаживая шум, но что индикаторы из 10- дневной и 20-дневный уровни дали бы немного больше «деталей». Вот как выглядели 6 функций для SPY.

Вы заметите, насколько плавный TRIX - это потому, что это тройное сглаженное экспоненциальное скользящее среднее, которое затем используется для создания однопериодного осциллятора ROC (скорости изменения). Другими словами, сгладьте данные о ценах, а затем найдите производную. Это заставляет меня задуматься, нельзя ли просто использовать Савицкого-Голея с большим окном и просто вычислить производную с самого начала (вы можете сделать это в scipy). Вы можете получить что-то примерно похожее.

Что касается цели - я использовал EMA (5) или EMA (12) - экспоненциальную скользящую среднюю с 5 или 12 периодами цены закрытия, а НЕ фактическую цену закрытия. Я также масштабировал каждое 50-дневное окно в диапазоне (0,1) (в scipy это minmax_scale, axis = 1), что исключает волатильность. Это означает, что я могу предсказывать закономерности только так, как вы можете смотреть на спарклайн . У вас есть временной ряд, который "колеблется" между 0 и 1, хотя вы не знаете, насколько велик был разрыв между 0 и 1 в исходном ценовом измерении.

Я согласен с этим - я хотел посмотреть, могу ли я моделировать закономерности, и я знал, что временной ряд с 50 периодами, если его сглаживать, примет только несколько основных паттернов, так что это казалось приемлемым.

Архитектура представляет собой обычную временную свертку из библиотеки keras-tcn (и большое спасибо Филиппу Реми за создание этой библиотеки). Временная свертка имеет расширенные ядра, которые позволяют воспринимающему полю почти достигать 100, что позволяет выполнять свертку по широкому диапазону входных данных, сохраняя при этом меньшее количество весов и вычислительную сложность. За ним следует полностью связанный плотный (регрессионный) слой с активацией ReLU. Я не использовал никаких специальных инициализаций или мер регуляризации. Оптимизатором был Адам со скоростью обучения 1e-3. Довольно стандартно.

i = Input((dim,nf)) #dim = 100 and nf is number of features (eg 6)
o = TCN(nb_filters = 64, 
        kernel_size = 9,
        use_skip_connections = False,
        nb_stacks = 1,
        dilations = [2,4,8],
        dropout_rate = 0.10, 
        return_sequences = False)(i)
oo = Dense(trainY.shape[-1], activation = 'relu')(o)
model = Model(inputs = [i], outputs = oo)
model.reset_states()
model.compile(loss = "mean_absolute_error", metrics = [], 
              optimizer = Adam(lr = 1e-3))

Примерно после 120 эпох обучения, со снижением скорости обучения и ранней остановкой для предложения регуляризации, вы получаете ошибки в зоне 0,05 - это признак того, что ваша модель может быть не только пригодной к эксплуатации, но даже… хорошей?

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

Вот как выглядит пара случайного предсказания и достоверности из набора для проверки. Они довольно плотно прилипают друг к другу!

Вот два примерных прогноза из набора испытаний / испытаний, прилипание не так хорошо, но общая тенденция верна:

Очевидно, что с таким маленьким набором задержек (23 точки) данные не сильно различаются. По сути, он охватывает диапазон ~ 73 дней, в течение которых был в основном простой медвежий, а затем бычий разворот, поэтому в этом смысле может быть сложно полностью его испортить.

Заключение

Я не уверен, насколько все это полезно для реальных трейдеров и финансистов (я всего лишь обычный розничный инвестор, к тому же работающий неполный рабочий день). Однако с помощью этой модели вы сможете хотя бы почувствовать форму в течение следующих 50 дней - и, возможно, вы не будете так сильно паниковать, если увидите, что она идет вниз, поскольку она может просто развернуться и подняться через 20 дней. Возможно, вы откроете короткую или ликвидируете свою длинную позицию, потому что некоторое время видите, что она снижается.

Кроме того, вы можете сказать, что эта модель не является обобщающей, поскольку она была обучена 1. только на данных за 10 лет 2. только на одной конкретной акции. Однако на это уходит так мало времени, что вы можете переучивать свою модель каждый день, черт возьми, переобучать, и просто надеяться, что она выучила достаточно, чтобы сделать «обоснованное» предположение о том, что произойдет с одним предсказанием, которое вам небезразлично. большинство - то, что вы делаете сегодня, в будущее, которое вы не видите. Другие газеты добавили кучу ETF типа Vanguard, чтобы пополнить данные. Я думаю, что это может сработать, хотя будет проще, если вы затем отнесетесь к этому как к задаче классификации, когда вы помечаете цель {1,0, -1} для бычьего, нейтрального и медвежьего. Если только акции не сильно коррелированы («клоны»), мне интересно, какая часть того, что модель «узнает» о денежных потоках TRIX и Чайкина, специфична для исследуемых акций, а какая - «универсальна».

Я потратил на это месяц или два и до сих пор не уверен, является ли это интересным или плодотворным направлением для дальнейших исследований. Легко заблудиться в методологии и просто убедиться, что вы не делаете фальшивых математических ошибок и не делаете ложных прогнозов. Если у вас есть предложения или идеи по этому поводу, дайте мне знать. Плохие модели, которые не работают, - это одно, а выкопать не то дерево совсем - еще хуже. Я хотел бы получить советы и спасибо за чтение!