Алгоритмическая торговля

«Алгоритмическая торговля - это процесс исполнения ордеров с использованием автоматических и предварительно запрограммированных торговых инструкций для учета таких переменных, как цена, время и объем.» - Investopedia.

Основа

Алгоритмическая торговля означает, что решение о покупке или продаже финансовых ценных бумаг на бирже принимается на основе заранее определенного алгоритма. На нашей платформе алгоритм - это скрипт на python, который принимает исторические данные в качестве входных данных и дает решение о покупке/продаже акции.

Скажем, у нас есть капитал в размере $1 млн., необходимо сформировать инвестиционный портфель из трех инструментов: Apple Inc (AAPL), Alphabet Inc класса C (GOOG), Tesla Inc (TSLA). Давайте посмотрим на цену open этих акций за определенный период. Open - цена, по которой ценные бумаги впервые торгуются после открытия биржи в торговый день. Мы используем исторические данные биржи NASDAQ в качестве входных данных:

date AAPL GOOG TSLA
Mar 02, 2020 282.28 1,351.61 711.26
Mar 03, 2020 303.67 1,399.42 805.00
Mar 04, 2020 296.44 1,359.23 763.96

Таблица 1. Цена акций (в USD) на момент открытия биржи NASDAQ.

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

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

\[\label{alpha1} \frac{1}{\textbf{open}},\]

Здесь и далее мы будем выделять вектора жирным шрифтом. Если применить эту формулу к таблице 1, получится матричный вид алгоритма:

date AAPL GOOG TSLA
Mar 02, 2020 0.00354258183 0.00073985839 0.00140595562
Mar 03, 2020 0.00329304837 0.00071458175 0.00124223602
Mar 04, 2020 0.00337336391 0.00073571065 0.00130896905

Таблица 2. Матричный вид алгоритма.

Капитал распределяется пропорционально значениям матрицы. Чтобы получить доли капитала, вложенного в каждый инструмент, матрица (таблица 2) должна быть нормализована (норма \(` l_1 `\)) на единицу для каждого дня:

date AAPL GOOG TSLA
Mar 02, 2020 0.6228 0.1301 0.2472
Mar 03, 2020 0.6273 0.1361 0.2366
Mar 04, 2020 0.6226 0.1358 0.2416

Таблицы 3. Веса алгоритма (weights).

Таким образом, 2 марта 2020 года для AAPL было выделено \(` $1M \cdot 0.6228 = $622,800; `\) GOOG и TSLA получили $130,100 и $247,200 соответственно. Матричные значения (Таблица 3) называются весами (weights) алгоритма.

Длинная позиция & короткая позиция

Чтобы продать акцию, нужно просто присвоить ей отрицательный вес в алгоритме. Предположим, у вас есть следующие веса:

date AAPL GOOG TSLA
Mar 02, 2020 0.4 0.4 -0.2

Положительное значение соответствует длинной позиции (покупаем акции); отрицательное значение соответствует короткой позиции (продаем акции). Таким образом, капитал $1M будет выделен в следующих пропорциях: $400,000 для AAPL; $400,000 для GOOG; $-200,000 для TSLA.

Детали

В нашей платформе мы используем упрощенное представление короткой позиции: это обратное действие к длинной позиции. Для торговли в реальных условиях нужно помнить, что короткие позиции связаны с более высокими рисками. Инвестор, продающий акции, которыми он еще не владеет (как правило, продаёт со счета своего брокера), обязан выкупить их через некоторое время. Таким образом, инвестор ожидает падения цен и играет против рынка. Это приводит к следующим рискам:

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

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

  • Потенциальные потери при короткой позиции могут быть бесконечными, поскольку теоретически максимальная цена акций не ограничена. С другой стороны, цена акций не опустится ниже нуля, поэтому максимальная прибыль ограничена.

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

Относительная доходность

Основная информация

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

Капитал растет, если прогноз изменения цен был верен. Ежедневное изменение капитала оценивается в конце торгового дня и сильно зависит от цены close. Close - цена, по которой ценные бумаги в последний раз торговались в конкретный день.

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

pnl Рис. 1

Относительная доходность (relative returns) просто показывает как изменился капитал. Для i-ого дня мы вводим относительную доходность (rr) в долях единицы:

\[\label{equity1} \text{rr}[i] = \frac{\text{equity}[i]}{\text{equity}[i-1]} - 1,\]

Детали

Иногда важно понять, как рассчитывается совокупная прибыль (equity, PnL). Скажем, мы распределяем наш капитал пропорционально вектору weights для i-ого дня. Таким образом, мы покупаем акции по цене open и получаем следующие позиции:

\[\label{position} \textbf{pos}[i] = \left( \textbf{weights}[i]\cdot\text{equity}[i] \right)/\textbf{open}[i],\]

где переменные, выделенные жирным шрифтом, это вектора с весами для каждого инструмента в портфеле; деление производится поэлементно. На следующий день алгоритм сгенерирует новый вектор \(` \textit{weigths}[i + 1] `\), который перераспределит наш капитал на новые позиции. Перераспределение инструментов портфеля приводит к потерям капитала, связанным, главным образом, с комиссией брокера и проскальзыванием (slippage).

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

Что такое проскальзывание? Для покупки/продажи акций нужен продавец/покупатель. Если на бирже нет предложения, ордер открывается по новой цене. Таким образом, мы покупаем нужное количество акций по частям, используя предложения о покупке/продаже определенного количества акций по определенной (изменяющейся) цене. Мы вычисляем проскальзывание (slippage) по следующей формуле:

\[\label{slappage} \text{slippage}[i] = abs(\textbf{pos}[i] - \textbf{pos}[i-1])\cdot \textbf{ATR}(14) \cdot 0.05,\]

где \(` \textbf{ATR}(14) `\) - индикатор волатильности рынка. Индикатор Average True Range (\(` \textbf{ATR}(N) `\)) представляет собой скользящую среднюю (MA) значений истинного диапазона (TR) за N дней:

\[\begin{gathered} \label{ATR} \textbf{TR}[i] = max( \textbf{high}[i] - \textbf{low}[i]; \textbf{high}[i] - \textbf{close}[i-1]; \textbf{close}[i-1] - \textbf{low}[i]), \end{gathered}\]
\[\label{ATR2} \textbf{ATR}(N) = MA(\textbf{TR},N).\]

Теперь мы можем ввести формулу расчета капитала для i-ого дня:

\[\begin{split}\begin{gathered} \text{equity}[i] = \text{equity}[i - 1] + (\textbf{open}[i] - \textbf{close}[i-1]) \cdot \\ \textbf{pos}[i-1] + (\textbf{close}[i] - \textbf{open}[i]) \cdot \textbf{pos}[i] - \text{slippage}[i] \label{equity}\end{gathered}\end{split}\]

Уникальность

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

\[r_{XY} = \frac{\text{cov}_{\textbf{X}\textbf{Y}}}{\sigma_{\textbf{X}} \sigma_{\textbf{Y}}} = \frac{\sum (\textbf{X} - \overline{\textbf{X}})(\textbf{Y} - \overline{\textbf{Y}})}{\sqrt{\sum (\textbf{X} - \overline{\textbf{X}})^2(\textbf{Y} - \overline{\textbf{Y}})^2}}\]

где \(` \textbf{X}, \textbf{Y} `\) - ежедневные относительные доходы. Чем ниже корреляция, тем лучше. Согласно правилам, ваш алгоритм должен иметь коэффициент корреляции ниже 0.9 за последние 3 года; в противном случае, вам нужно иметь наибольший Sharpe ratio среди коррелирующих алгоритмов.