uralpro
uralpro личный блог
23 апреля 2015, 10:12

Линейная регрессия с использованием фильтра Калмана

price_corr

Линейная регрессия часто используется для вычисления пропорции хеджирования в парном трейдинге. В идеальной ситуации коэффициенты этой регрессии — наклон линии регрессии и свободный член (пересечение) остаются всегда постоянными. Однако в реальности все, конечно, не так радужно, и значения этих параметров постоянно меняются во времени. Как правильно вычислять коэффициенты регрессии, чтобы избежать подгонки к текущей ситуации, рассматривается в статье "Online Linear Regression using a Kalman Filter". Для этой цели в данной публикации используется фильтр Калмана. 

Для тестирования берутся исторические цены закрытия двух биржевых фондов ETF — австралийского EWA и канадского EWC с 2010 по 2014 год. Динамика цен этих фондов показывает взаимосвязь, что продемонстрировано на  диаграмме рассеивания в заглавии поста. Однако по этому же графику видно, что эту взаимосвязь невозможно описать с помощью линейной регрессии с постоянными коэффициентами. 

Приведем сначала уравнение линейной регрессии:

a_k=\beta b_k+\alpha

где ak, bk- приведенные цены фондов EWC и EWA соответственно, а β, α- коэффициенты регрессии — угол наклона и пересечение соответственно. Перепишем уравнение в матричной форме:

a_k=\beta B_k

\beta=[\beta\;\alpha]

B_k=\begin{bmatrix}b_k\\1\end{bmatrix}

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

x_{k+1}=A_kx_k+w_k

z_k=H_kx_k+v_k

где xk, zk- вектор скрытых состояний и вектор наблюдений в  момент времени k, Ak, Hk- матрица переходов и наблюдений соответственно, wk,vk- векторы гауссовского шума с нулевым средним.

Для наших целей предположим, что вектор состояний xk соостветствует вектору коэффициентов регрессии β. Также предположим, что угол наклона и пересечение следуют процессу случайного блуждания (random walk), тогда Ak будет равна матрице идентичности I (матрице, где на главной диагонали единицы, остальные элементы — нули). В этом случае передаточное уравнение запишется:

\beta_{k+1}=I\beta_k + w_k

то есть β в следующий момент времени равна β в текущий момент времени плюс шумовая составляющая.

На следующем шаге применим нашу модель к уравнению наблюдений фильтра Калмана. Для этого приведенные цены закрытия актива EWC обозначим как вектор наблюдений zk, и матрицу наблюдений Hk представим как вектор размерности 1х2, содержащий в первой колонке приведенные цены закрытия EWA и единицами во второй колонке, подобно нашему вектору Bk. Таким образом, это просто линейная регрессия между двумя активами. Для подпрограммы на Python - pykalman, конструирующей фильтр Калмана, матрица наблюдений obs_mat выглядит так:

obs_mat = np.vstack([data.EWA, np.ones(data.EWA.shape)]).T[:, np.newaxis]
array([[[ 19.36,   1.  ]],
       [[ 19.42,   1.  ]],
       [[ 19.49,   1.  ]],
       ..., 
       [[ 26.02,   1.  ]],
       [[ 26.24,   1.  ]],
       [[ 26.42,   1.  ]]])

Последнее, что нужно сделать — определить шумовые составляющие wk,vk. Установим ковариацию наблюдений vk, как единичный вектор. Тогда будем трактовать ковариацию переходов, wk, как настраиваемый параметр для управления скоростью изменения коэффициентов регрессии:

delta = 1e-5
trans_cov = delta / (1 - delta) * np.eye(2)

Далее установим класс фильтра Калмана KalmanFilter из модуля pykalman :

kf = KalmanFilter(n_dim_obs=1, n_dim_state=2,
                  initial_state_mean=np.zeros(2),
                  initial_state_covariance=np.ones((2, 2)),
                  transition_matrices=np.eye(2),
                  observation_matrices=obs_mat,
                  observation_covariance=1.0,
                  transition_covariance=trans_cov)

 

и вычислим средние значения и ковариацию состояний:

state_means, state_covs = kf.filter(data.EWC.values)

В итоге мы получаем графики изменений коэффициентов регресии — угла наклона (slope) и пересечения (intercept):

slope_intercept

Более наглядно можно показать, как подстраиваются коэффициенты регрессии в течение времени на диаграмме рассеивания активов EWA и EWC:

price_corr_regress

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

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

12 Комментариев
  • уважаю автора этой теории -Dr. Aidan O’Mahony за то, что он пишет на питоне. В остальном — данная теория как задание (бонус) при его резюме при устройстве на новую работу.
  • ves2010
    23 апреля 2015, 10:31
    мне никак не понять… в чем проблема то? берем 2 актива делим один на другой получаем пару… затем эту пару торгуем как и обычную цену теми же скользящими средними… и где сложности?

    вся суть парного в том, что имеем 10 активов… всего будет 50 пар… из этих 50 пар можно выбрать 2-3 стабильные торгуемые обычными скользящими средними без всякого мозготраха
      • ves2010
        23 апреля 2015, 10:43
        uralpro,
        1 скользящая средняя = ФНЧ… на любом фильтре, в том числе и калмана есть отставание… чем выше порядок фильтра тем больше отставние-задержка
        2 дык ты не вычитай один актив из другого, а дели один на другой… типа брент/голд
  • avvin
    23 апреля 2015, 10:39
    чет ниче не видно)

  • SergeyJu
    23 апреля 2015, 10:56
    Можно взять временное окно фиксированной длины и пересчитывать коэффициенты регрессии по обычному методу наименьших квадратов хоть на каждом такте.
    Что мы выигрываем по описанному автором методу по сравнению с подходом " в лоб"? Ну, кроме скорости вычислений, которая, имхо, не особо напрягает всех, кроме высокочастотников.
  • ch5oh
    23 апреля 2015, 12:18
    В чем картинки рисуете? Очень интересное решение с раскраской в зависимости от возраста точки… Только за это можно плюсануть топик! =)
  • Vona
    23 апреля 2015, 12:39
    Сделай проверку остатков по этому фильтру и обычным МНК, сильно удивишься.

    Удачи!
  • vlad1024
    23 апреля 2015, 14:39
    спреды только с таким подходом достаточно тяжко торговать, потому что сам видишь, что коэфициент «пляшет», соответственно, непонятно как постоянно корректировать позицию, чтобы это все еще и прибыль приносило. (тоесть понятно что мы поменяли расхождение спреда, на коэфициент который всегда можно «подогнать», соответсвенно надо либо прогнозировать его динамику, либо не понятно где здесь edge)

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

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