Давайте попробуем разобраться в машинах опорных векторов и в том, как их внедрить на финансовых рынках.

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

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

Классификатор максимальной маржи

Алгоритм машины опорных векторов исходит из классификатора максимальной маржи. Классификатор максимальной маржи использует расстояние от заданной границы решения для классификации входных данных. Чем больше расстояние или поле, тем лучше классификатор обрабатывает данные. На декартовой плоскости границу можно представить как линию. В трехмерном пространстве это самолет, но после этого его становится трудно осмыслить. Эту границу лучше рассматривать как гиперплоскость, в частности, как одну из размеров p-1, где p - размер точки данных.
Наша граница, или гиперплоскость, известна как разделяющая гиперплоскость, потому что она используется для разделения точек данных на требуемые категории. В общем, существует множество гиперплоскостей, которые могут разделить данный набор данных, но нас интересует гиперплоскость максимального поля или o оптимальная разделяющая гиперплоскость . Эта разделяющая гиперплоскость имеет наибольшее минимальное расстояние от каждой точки данных в обучающем наборе. Используя эту гиперплоскость для классификации точки данных из тестового набора, мы получаем классификатор максимальной маржи.

Линия на графике выше представляет гиперплоскость. Обратите внимание, что он полностью разделяет все точки в синей и фиолетовой областях графика.

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

На этом этапе вы должны рассмотреть свои варианты:

  1. Вы можете основать свой классификатор на разделяющей гиперплоскости, как объяснялось ранее. Но гиперплоскости не существует ... значит, у вас нет классификатора.
  2. Рассмотрим классификатор, который не идеален, но может работать большую часть времени.

Классификаторы опорных векторов

Мне тоже нравится второй вариант. Используя несовершенный классификатор, вы можете, по крайней мере, обработать большинство наблюдений и внести определенный уровень адаптации в модель, когда она будет представлена ​​с новыми данными.

Эта эволюция классификатора максимальной маржи известна как классификатор опорных векторов (SVC) или классификатор мягкой маржи. Вместо того, чтобы быть точным и не очень надежным в своей классификации, SVC позволяет некоторым наблюдениям быть не на той стороне поля и / или гиперплоскости (откуда взято программное обеспечение), чтобы классификация была в основном правильной.

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

Параметр настройки используется для управления компромиссом смещения и дисперсии. Когда он небольшой, классификатор хорошо подходит для данных, так как поля маленькие. Другими словами, низкая систематическая ошибка, высокая дисперсия. Чем больше параметр настройки, тем наоборот. Это позволяет большему количеству наблюдений оказаться на неправильной стороне запаса, обеспечивая высокую систематическую ошибку и низкую дисперсию.

В частности, переменные Slack - это круто. Они позволяют точкам данных располагаться сбоку от поля или гиперплоскости. Они также используются для преобразования неравенства в равенство. Значения, которые принимают значения резерва, также могут рассказать нам о поведении данной точки данных. Если переменная резерва для данной точки данных равна 0, то эта точка данных находится на правой стороне поля. Если переменная резерва больше 0, но меньше 1, точка данных находится на неправильной стороне поля, но на правой стороне гиперплоскости. Если переменная резерва больше 1, точка данных находится на неправильной стороне гиперплоскости.

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

Наконец, машины опорных векторов

Машины опорных векторов основаны на оптимизации классификаторов опорных векторов за счет увеличения пространства функций с помощью ядер.

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

Существует множество различных ядер, включая ядро ​​RBF, ядра графов, линейное ядро, полиномиальное ядро. Например, линейное ядро ​​сравнивает пару точек данных, используя их двумерную корреляцию. Ядро полинома пытается уместить SVC в пространстве более высокой размерности. Классификатор опорных векторов аналогичен использованию SVM с полиномиальным ядром степени 1.

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

Машины опорных векторов для торговли

Прежде чем я перейду к этому приложению, это ни в коем случае не совет о том, как и чем вам следует торговать. Это тебе.

Начнем со сбора данных.

Мы будем использовать период времени, равный примерно пяти годам, с 28 октября 2014 г. по 28 октября 2019 г. Акции, по которым мы получим данные, являются компонентами промышленного индекса Доу-Джонса.

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

Первым делом мы импортируем все необходимые пакеты.

Затем мы воспользуемся пакетом запросов для очистки содержимого этой страницы в Yahoo Finance. На странице указаны названия компаний, входящих в промышленный индекс Доу-Джонса, а также их тикеры. Затем мы воспользуемся BeautifulSoup4, чтобы сделать информацию в Dow_Content доступной для поиска.

Строки выше анализируют данные, собранные с веб-страницы, и ищут фрагмент HTML-кода, соответствующий таблице на странице. Это можно найти, щелкнув правой кнопкой мыши в области страницы, проверив элемент, и после небольшого исследования вы можете найти имя класса, использованное выше.

Будет обнаружено два типа строк:

  1. Строки, содержащие тикер
  2. Строки, содержащие название компании без тикера

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

Yahoo Finance использует метку времени Unix в своем URL-адресе, поэтому мы используем пакет time для преобразования наших дат начала и окончания в желаемый формат. Он может принимать либо struct_time (подробнее об этом здесь), либо кортеж из 9 временных аргументов. На самом деле нас здесь не волнует ни о чем после свидания.

Функция ScrapeYahoo принимает четыре аргумента:

  1. data_df, ваша назначенная структура данных для хранения вывода
  2. тикер, строка, представляющая данную акцию.
  3. start, отметка времени Unix, представляющая дату начала
  4. end, метка времени Unix, представляющая текущий день.

Он объединяет их с базовым URL-адресом Yahoo Finance и получает данные с нужной веб-страницы. Вместо того, чтобы обрабатывать его, как мы делали ранее, мы анализируем данные JSON со страницы. Yahoo Finance теперь использует файлы cookie, и простое использование HTML-кода приведет к ошибке.

Строки после синтаксического анализа содержимого данных JSON. Когда я изначально изучал набор данных, мне очень помог метод keys () для словарей Python. Это значительно упростило просмотр данных JSON. Вы можете прочитать об этом здесь"

Словарь Stock_Data будет содержать наши проанализированные данные. Ключи в словаре будут тикером данной акции. Для каждой акции функция ScrapeYahoo создаст рамку даты, содержащую данные открытия, максимума, минимума, закрытия и объема.

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

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

Прежде чем двигаться дальше, следует обратить внимание на одну очень важную вещь: предвзятость в прогнозе. У нас уже есть все данные закрытия, которые мы будем использовать для расчетов. В реальном сценарии максимум, что у вас есть, - это закрытие предыдущего дня. Мы должны убедиться, что наши расчеты не учитывают данные, которые технически еще не были получены. Для этого мы будем лагать данные. То есть сдвинуть наши данные на один день назад.

Технический анализ

Мы воспользуемся библиотекой talib для выполнения расчетов технического анализа.

Мы будем использовать столбец доходности для расчета нашей метки на каждый торговый день. Если доходность равна 0 или положительна, она будет помечена как 1, в противном случае она будет помечена как 0. Обратите внимание, что в столбце доходности используются цены открытия, а не цены закрытия, чтобы избежать предвзятости прогноза.

Обучение модели

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

Мы использовали MaxAbsScaler, который масштабирует каждую функцию по ее максимальному абсолютному значению.

Затем мы создали словарь для хранения данных обучения и тестирования. Если значения NaN не отброшены, модель не запустится. Переменная X будет содержать все функции модели, которые затем будут масштабированы. Важно убрать столбцы "Сигнал" и "Возвраты". Мы прогнозируем сигнал, если он сохранится, модель будет почти идеальной. Если мы сохраним столбец «Возврат», это тоже будет слишком сильно влиять на модель. Помните, что столбец «Сигнал» изначально рассчитывался с использованием рассчитанной доходности. Y - это то, что мы хотим предсказать, поэтому мы назначаем его столбцу, содержащему сигналы.

Наша модель будет использовать 70% данных для обучения и 30% для тестирования, как показано в строке 11.

Модель определяется переменной model (на случай, если вы запутались). Я оставил различные конфигурации ядра в приведенном ниже блокноте, с которыми вы можете поиграть. Модель соответствует обучающим данным и используется для прогнозирования значений в столбце «Сигнал».

Наконец, мы добавляем точность, точность и отзывчивость в наш модельный словарь для каждой акции.

Почти готово! Следующий бит кода вычисляет возврат, используя сигналы из модели SVM. Используя метод iloc для фреймов данных Pandas, гораздо проще добавлять сигналы в конец, чем мы делали это раньше.

Мы рассчитаем доходность относительно динамики рынка и будем использовать ее в качестве ориентира. Эффективность портфеля оценивается с помощью коэффициента Шарпа.

Наконец, построим графики результатов прогнозов.

Вот несколько примеров вывода:

Заключение

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

  1. Используйте технические индикаторы для создания сигналов, а не только для доходности
  2. Адаптируйте модель для длинных / коротких сценариев
  3. Используйте разные технические индикаторы
  4. Создайте портфель, включая размер позиции, транзакционные издержки, проскальзывание и т. Д.

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

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

Я надеюсь, что это было полезно в вашем понимании опорных векторных машин!

использованная литература

[1] Р. Росилло, Дж. Гинер, Д. Де ла Фуэнте и Р. Пино, Торговая система, основанная на машинах опорных векторов в индексе S&P 500 (2012 г.), Труды Международной конференции по искусственному интеллекту 2012 г., ICAI 2012 г.

[2] Б. Энрике, В. Собрейро и Х. Кимура, Прогнозирование цен на акции с использованием регрессии опорных векторов по дневным ценам и с точностью до минут (2018), The Journal of Finance and Data Science

[3] X. Di, Прогнозирование тренда акций с помощью технических индикаторов с использованием SVM (2014)

[4] Дж. Джеймс, Д. Виттен, Т. Хасти и Р. Тибширани, Введение в статистическое обучение с приложениями на R (2017).

Код Python

РЕДАКТИРОВАТЬ: исправлена ​​проблема с использованием «сдвига» в различных частях кода. Спасибо тем, кто это назвал, я ценю отзывы.