Введение

Все ведь знают, что инвестировать в портфель выгоднее и безопаснее, чем в отдельную акцию? Сегодня мы узнаем, почему так происходит и научимся моделировать риски для целых портфелей ценных бумаг.

Две бумаги против отдной

Начнем как обычно: quantmod, getSymbols только теперь получим две котировки:

library(quantmod)
getSymbols("YNDX", from="2012-01-01", to="2015-01-01")
## [1] "YNDX"
getSymbols("GOGL", from="2012-01-01", to="2015-01-01")
## [1] "GOGL"
plot(Ad(YNDX))

plot(Ad(GOGL))

prices1 <- as.numeric(Ad(YNDX))
prices2 <- as.numeric(Ad(GOGL))
ret1 <- diff(prices1)/head(prices1, -1)
ret2 <- diff(prices2)/head(prices2, -1)

И посмотрим на базовые характеристики наших векторов цен и доходностей:

length(ret1) == length(ret2) # Они хотя бы одинаковой длины? Вопрос: почему могут отличаться?
## [1] TRUE
mean(ret1)
## [1] 0.0002489355
mean(ret2)
## [1] -0.0005305659
sd(ret1)
## [1] 0.02730779
sd(ret2)
## [1] 0.03363116
cor(ret1, ret2)
## [1] 0.2325816
cor.test(ret1, ret2)
## 
##  Pearson's product-moment correlation
## 
## data:  ret1 and ret2
## t = 6.5535, df = 751, p-value = 1.044e-10
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.1638586 0.2990580
## sample estimates:
##       cor 
## 0.2325816

Собираем оптимальный портфель

Сначала немного забежим вперед (у вас курс по финансовым рынкам будет весной). Если есть два актива \(x\) и \(y\) (доходности), каждый со своим средним доходом \(E(x) = \mu_x, E(y) = \mu_y\) и со своим средним стандартным отклонением дохода: \(V(x) = \sigma_x^2, V(y) = \sigma_y^2\), то ставится задача оптимального распределения капитала между этими двумя активами. Что значит оптимального?

  1. Максимальная доходность.
  2. Минимальный риск.
  3. Максимизация какой-либо метрики, объединяющей доходность и риск. Ex: коэффициент Шарпа.

Пусть мы вкладываем \(\gamma\) в актив \(x\) и \(1-\gamma\) в \(y\). Тогда ожидаемая доходность равна: \(\mu = \gamma\mu_x + (1-\gamma)\mu_y\). И тут даже обсуждать не интересно. А ожидаемая дисперсия равна: \(\sigma^2 = \gamma^2*\sigma_x^2 + (1-\gamma)^2\sigma_y^2 + 2\gamma(1-\gamma) cov(x, y)\).

Построим график?

gammas <- seq(0,1,0.001)
var <- var(ret1)*gammas^2 + var(ret2)*(1-gammas)^2 + 2*cov(ret1, ret2)*gammas*(1-gammas)
optimal <- (var(ret2) - cov(ret1, ret2))/(var(ret1) + var(ret2) - 2*cov(ret1, ret2))
optimal
## [1] 0.6329153
plot(gammas, var, type="l")
abline(v = optimal, col = 2)

Теперь соберем портфель для дальнейшего исследования:

prt <- optimal*ret1 + (1-optimal)*ret2
mean(prt)
## [1] -3.720754e-05
sd(prt)
## [1] 0.02346027

Для интереса: график коэффициента Шарпа:

variance <- var(ret1)*gammas^2 + var(ret2)*(1-gammas)^2 + 2*cov(ret1, ret2)*gammas*(1-gammas)
plot(gammas, (gammas*mean(ret1) + (1-gammas)*mean(ret2))/variance, type="l")

Как моделировать портфель?

Почему нельза просто отдельно моделировать риски каждой бумаги?

Многомерные распределения

Как вариант – использовать многомерные распределения:

library(ghyp)
## Loading required package: numDeriv
## Loading required package: gplots
## 
## Attaching package: 'gplots'
## 
## The following object is masked from 'package:stats':
## 
##     lowess
rets <- cbind(ret1, ret2)
head(rets)
##              ret1         ret2
## [1,] -0.029888551  0.027941113
## [2,]  0.007310757  0.037196031
## [3,] -0.035251424 -0.029655263
## [4,]  0.006448092  0.041222459
## [5,]  0.006940790  0.013651933
## [6,]  0.018027571 -0.005387156
model <- fit.tmv(rets, silent=TRUE)

А дальше Монте-Карло:

N <- 1e5 # 100 тысяч
MCpoints <- rghyp(N, model)
prt_ret <- optimal*MCpoints[,1] + (1-optimal)*MCpoints[,2]
quantile(prt_ret, 0.05) # Что это?
##        5% 
## -0.037782
mean(sort(prt_ret)[1:(N*0.05)]) # А это?
## [1] -0.0563028

Но можно придумать лучше!

Копулы

Этот человек никак не связан с копулами.

Коппола

Копула (лат. Copula) — это многомерная функция распределения, определённая на n-мерном единичном кубе, такая, что каждое её маргинальное распределение равномерно на интервале [0,1]. Теми кто сразу все понял, я восхищаюсь.

Копула для многомерной функции распределения \(H(x,y)\) – это такая функция \(C\), что \(H(x,y) = C(F(x), G(y))\), где \(F(x) = H(x, \infty)\) и \(G(y) = H(\infty, y)\).

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

Копул бывает много, вот самые популярные:

  1. Нормальная копула
library(copula)
persp(normalCopula(dim=2, param = 0.9), dCopula)

contour(normalCopula(dim=2, param = 0.9), dCopula, nlevels=40)

  1. t-копула
persp(tCopula(dim=2, param = 0.2, df = 2), dCopula)

contour(tCopula(dim=2, param = 0.2, df=2), dCopula, nlevels=40)

  1. Копула Гумбеля
persp(gumbelCopula(dim=2, param = 2), dCopula)

contour(gumbelCopula(dim=2, param = 2), dCopula, nlevels=40)

  1. Копула Клейтона
persp(claytonCopula(dim=2, param = 1), dCopula)

contour(claytonCopula(dim=2, param = 1), dCopula, nlevels=40)

Нам надо взять наше эмпирическое двумерное распределение доходностей, посчитать

cdf <- pobs(rets)
plot(cdf)

И теперь замоделируем эту штуку кем-то из наших копул. Фитирование имеет особенность: мы инициализируем копулы, а потом подгоним параметры каждой.

t.cop <- tCopula(dim = 2, param = 0.5, df = 2, df.fixed = TRUE)
fit <- fitCopula(data = cdf, copula = t.cop)
summary(fit)
## $method
## [1] "maximum pseudo-likelihood"
## 
## $loglik
## [1] -7.812359
## 
## $convergence
## [1] 0
## 
## $coefficients
##        Estimate Std. Error  z value     Pr(>|z|)
## rho.1 0.2255592 0.04760094 4.738545 2.152579e-06
## 
## attr(,"class")
## [1] "summary.fitCopula"
persp(fit@copula, dCopula)

contour(fit@copula, dCopula, nlevels=10)

Моделируем риски с использованием копул

Использовать будем Монте-Карло:

N <- 1e5
points_cop <- rCopula(copula = fit@copula, N)
plot(points_cop, cex=0.2)

ret1_cop <- quantile(ret1, points_cop)
ret2_cop <- quantile(ret2, points_cop)
prt_ret <- optimal*ret1_cop + (1-optimal)*ret2_cop
quantile(prt_ret, 0.05) # Что это?
##         5% 
## -0.0492457
mean(sort(prt_ret)[1:(N*0.05)]) # А это?
## [1] -0.08286575

А кривых VaR не будет, все в домашке :)

Домашнее задание

Easy:

  1. Взять две котировки. Лучше более-менее связанные из идейных соображений.
  2. Найти оптимальный портфель с точки зрения минимизации дисперсии доходности.
  3. Построить кривую VaR с помощью использования многомерного ОГР. Проверить качество VaR.
  4. Построить кривую VaR с помощью использования копул. Проверить качество VaR.

Hard:

  1. Попробовать другие копулы, показанные в лекции. Там все аналогично.
  2. Собрать портфель из 3+ акций.

God-mode:

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

Тем кто не смотрел, посмтреть.