Тази публикация ще продължи да проучва друго използване на методите на филтъра на Калман, главно като алтернатива за правене на многовариантна прогноза. Друга опция включва векторна авторегресия (VAR). Тази публикация няма да навлиза в подробности за VAR, а по-скоро ще предостави алтернатива за моделиране на многоизмерен изход, когато процесът на преход е известен. Важно е да знаете, че когато използвате филтъра на Калман, връзката между ненаблюдаваната променлива и наблюдавания изход е известна (или има разумно предположение), както и как е известно (предполага се) как ненаблюдаваната променлива преминава към следващия период на таймера. В допълнение, цялото моделиране, извършено досега, има линейно допускане, както процесът на преход, така и процесът на наблюдение са линейни.

Въведение

За тези, които не са запознати с векторните авторегресивни модели, можете да намерите подробна информация от wiki. В Python пакетът statsmodel има вградени функции за VAR, подробна употреба може да се намери в документация.

Накратко, VAR се използва, ако вярваме, че наблюдаваните променливи взаимодействат заедно. Този документ предлага PC-VAR, който е бил приложен за моделиране на много икономически серии. Бърз пример са лихвените проценти. Лихвените проценти са силно корелирани и има множество серии (от овърнайт до 30-годишни лихвени проценти), но те могат лесно да бъдат намалени до 3 измерения с помощта на анализ на главните компоненти (PCA). Първите 3 компонента на лихвения процент са добре дефинирани като „ниво“, „наклон“ и „кривина“, което би обяснило 95%+ от вариацията в лихвения процент. След това ще приложим VAR върху тези основни компоненти, ще решим едновременно коефициентите.

По отношение на PC-VAR има трансформация за превръщане на необработените лихвени проценти в основни компоненти, прилагане на VAR върху главните компоненти за изпълнение на прогноза и след това трансформиране на основните компоненти обратно в лихвени проценти. Моля, имайте предвид, че на практика съществува значителна трудност за модела да предвиди ниво (което представлява над 50% от вариацията в лихвения процент).

Многоизмерен филтър на Калман

В тази публикация ще анализираме времевата серия SP500 заедно с 2-годишния лихвен процент.

Преходната матрица е проектирана така, че

Ето кода: Обърнете внимание, че курсът на хазната е от Министерство на финансите на САЩ.

    n_train = int(len(data) * 0.9)
    n_test = len(data) - n_train
    result_set = {}
    graph_text = ""
    filter_input = np.concatenate([sp_return.T, interest_rate], axis=1)

    kf = KalmanFilter(transition_matrices=[1], observation_matrices=[1],
                      transition_covariance=np.array([[1]]), observation_covariance=1,
                      n_dim_obs=1)
    kf_mean, filtered_std = kf.filter(filter_input[:n_train,0])
    kf_pred = np.array([1]) * np.power(np.array([1]), np.arange(n_test-1)) * kf_mean[-1]
    result_set = {'kf-1 state': np.append(kf_mean[5:], kf_pred.reshape(-1,1))}
    graph_text = "kf-1 rmse: " + "{:.4f}".format(rmse(filter_input[n_train:,0],kf_pred))


    n_season = 5
    F = np.zeros((n_season + 1, n_season + 1))
    F[0,0] = 1
    F[1, 1:-1] = [-1.0] * (n_season - 1)
    F[2:,1:-1] = np.eye(n_season - 1)
    H = np.array([1, 1, 0, 0, 0, 0])
    P_init = np.eye(n_season + 1) * 0
    P_init[:2,:2] = np.eye(1) * Q
    kf = KalmanFilter(transition_matrices=F, observation_matrices=H,
                      transition_covariance=P_init, observation_covariance=1,
                      n_dim_obs=1)
    kf_1, filtered_std = kf.filter(filter_input[:n_train,0])
    filtered_obs = kf_1.dot(H)
    filtered_pred = forecast_kf(n_test-1, kf_1[-1], F, H.reshape(1,-1))
    graph_text += "\nkf_5 rmse: " + "{:.4f}".format(rmse(filter_input[n_train:,0],filtered_pred))
    result_set['kf_5_2'] = np.append(filtered_obs[5:], filtered_pred.reshape(-1,1))

    n_int=2
    F = np.zeros((n_season + 1 + n_int, n_season + 1 + n_int))
    F[0,0] = 1
    F[0,-2:] = [-1, 1]
    F[1, 1:n_season] = [-1.0] * (n_season - 1)
    F[2:n_season+1,1:n_season] = np.eye(n_season - 1)
    F[-2,-2] = 1
    F[-1,-2] = 1
    H = np.array([[1, 1, 0, 0, 0, 0, 0, 0],[0,0,0,0,0,0,1,0]])
    P_init = np.eye(n_season + 1 + n_int) * 0
    P_init[:2,:2] = np.eye(2) * Q
    P_init[-2:,-2:] = np.eye(2) * Q
    R = np.eye(2) * R
    X_0 = np.zeros(n_season + 1 + n_int)
    kf = KalmanFilter(transition_matrices=F, observation_matrices=H,
                      transition_covariance=P_init, observation_covariance=R,
                      initial_state_mean=X_0, initial_state_covariance=P_init,
                      n_dim_state=8
                      )
    mean_, std_ = kf.filter(filter_input[:n_train,:])


    filtered_pred = forecast_kf(n_test-1, mean_[-1], F, H)
    fitted_value = np.dot(mean_,H.T)
    result_set['SPY Kalman with Treasury'] = np.append(fitted_value.T[0,5:], filtered_pred[0,:])
    graph_text += "\nSPY Kalman with Treasury rmse: " + "{:.4f}".format(rmse(filter_input[n_train:,0], filtered_pred[0,:]))
    ## VAR
    model = VAR(filter_input[:n_train,:])
    results = model.fit(1)
    filtered_pred = results.forecast(filter_input[n_train-1:n_train,:], n_test-1)
    result_set['SPY VAR(1)'] = np.append(results.fittedvalues[4:,0], filtered_pred[:,0])
    graph_text += "\nSPY VAR(1) rmse: " + "{:.4f}".format(rmse(filter_input[n_train:,0], filtered_pred[:,0]))

    results = model.fit(5)
    filtered_pred = results.forecast(filter_input[n_train - 5:n_train, :], n_test - 1)
    result_set['SPY VAR(5)'] = np.append(results.fittedvalues[:, 0], filtered_pred[:, 0])
    graph_text += "\nSPY VAR(5) rmse: " + "{:.4f}".format(rmse(filter_input[n_train:, 0], filtered_pred[:, 0]))

Резултатът е както следва, моля, имайте предвид, че в графиката по-долу той разглежда само прогнозата за възвращаемост на SP500, игнорира резултата за прогнозата за лихвения процент, за да бъде в съответствие с другите публикации. Силата на модела е, че прогнозира и двете серии.

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

Има малка разлика между филтъра на Калман с цикличен термин от последната публикация (назован kf_5 тук и kf_5_2 по-рано, най-вече втората гърбица е по-слабо изразена с включването на съкровищния курс).

Заключение

Разглеждайки го внимателно, забелязахме, че въпреки че има леко намаление на RMSE с включването на съкровищницата, точността на насочване леко спада. Можем да подобрим набора от модели, като се вдъхновим от модела PC-VAR, за да включим допълнителни серии на лихвените проценти (първо прилагане на PCA за намаляване на размерността) и/или бихме могли да включим друга възвръщаемост на капитала (DJ) или серии, като например индекс на волатилност.

Неща, които трябва да имате предвид

Досега сме направили някои силни предположения (линейност) и нямаме неизвестен параметър в модела на прехода и наблюдението. В много случаи на употреба това не е истина. В бъдещите публикации ще проучим как да се справим с нелинейния преходен модел и как да оценим параметрите.

Моля, следвайте и се абонирайте, ако проявявате интерес към бъдещи публикации по темата.