1. Получить необходимые данные для работы и построить графики

require(zoo)
require(xts)
require(rusquant)


OnDate <- start.date <- as.Date('2010-01-01')
ToDate <- end.date <- Sys.Date()

ROSN <- rusquant::getSymbols.Finam('ROSN', from = start.date) # роснефть
MICEX <- rusquant::getSymbols.Finam('MICEX', from = start.date) # ммвб
 
ROSN.rtn <- diff(log(ROSN$ROSN.Close))
MICEX.rtn <- diff(log(MICEX$MICEX.Close))

plot(ROSN.rtn, main = 'Дневная доходность Роснефти ') 

plot(MICEX.rtn, main = 'Дневная доходность ММВБ')

Объединим два показателя – доходности Роснефти и ММВБ – в один объект с помощью функции merge.

Функция merge гарантирует, что будут объединены значения с одинаковыми датами.

rtns <- merge(ROSN.rtn, MICEX.rtn)
names(rtns) <- c('ROSN', 'MICEX')
rtns <- rtns[complete.cases(rtns)]
plot(x = coredata(rtns$MICEX), y = coredata(rtns$ROSN),
     xlab='Доходность ММВБ', ylab = 'Доходность ROSN')

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

Получить безрисковкую ставку (1-летние ОФЗ) с сайта Банка России (http://www.cbr.ru/scripts/Root.asp?PrtId=SEC) Посмотрите, что означает изотермный ряд бескупонной доходности (http://www.cbr.ru/gcurve/isoterm.asp)

source('https://raw.githubusercontent.com/quantviews/CBR/master/codes_new/CBR_web.R')
rf_rate <- Isoterm(start.date,end.date,I_Day = 1)
plot(rf_rate, main = 'Безрисковая ставка', ylab = '%')

rf_rate_d <- ((rf_rate+100)/100)^(1/365)-1 #посчитать дневные значения для безрисковой ставки 

3. Посчитать линейную регрессию для модели СAPM

Для того, чтобы оценить модель CAPM необходимо рассчитать риск-премии (избыточные доходности относительно безрисковой ставки)

ex_rosn_rtns <- ROSN.rtn - rf_rate_d
ex_micex_rtns <- MICEX.rtn - rf_rate_d

fit <- lm(ex_rosn_rtns ~ ex_micex_rtns)
summary(fit)
## 
## Call:
## lm(formula = ex_rosn_rtns ~ ex_micex_rtns)
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.046689 -0.006731 -0.000707  0.006008  0.060354 
## 
## Coefficients:
##                 Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   -5.588e-05  2.644e-04  -0.211    0.833    
## ex_micex_rtns  1.010e+00  2.004e-02  50.402   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.01116 on 1780 degrees of freedom
##   (1 observation deleted due to missingness)
## Multiple R-squared:  0.588,  Adjusted R-squared:  0.5878 
## F-statistic:  2540 on 1 and 1780 DF,  p-value: < 2.2e-16

Является ли константа значимой? Какая доля дисперсии доходностей бумаги объяснется доходностью индекса?

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

4. Посчитать параметры модели CAPM с помощью пакета PerformanceAnalytics

library(PerformanceAnalytics)

CAPM.beta(Ra = ROSN.rtn,Rb = MICEX.rtn,Rf = rf_rate_d)
## [1] 1.010523
CAPM.alpha(Ra = ROSN.rtn,Rb = MICEX.rtn,Rf = rf_rate_d)
## [1] -6.894596e-05
SharpeRatio.annualized(ROSN.rtn, Rf = rf_rate_d, geometric = FALSE)
##                                    ROSN.Close
## Annualized Sharpe Ratio (Rf=4.9%) -0.04276415
SharpeRatio.annualized(MICEX.rtn, Rf = rf_rate_d, geometric = FALSE)
##                                   MICEX.Close
## Annualized Sharpe Ratio (Rf=4.9%)  0.02638295

На что указывают значения показателя Шарпа для бумаги? Как показатель Шарпа для бумаги соотносится с показателем индекса?

Можно посчитать скользяющую бету и скользяющую альфу

chart.RollingRegression(Ra = ROSN.rtn,Rb = MICEX.rtn,Rf = rf_rate_d,width = 250, attribute = "Beta",
                        main = 'Скользящая бета для акций Роснефти')

chart.RollingRegression(Ra = ROSN.rtn,Rb = MICEX.rtn,Rf = rf_rate_d,width = 250, attribute = "Alpha",
                        main = 'Скользящая альфа для акций Роснефти')

Как изменялись значение альфы и беты в различные периоды времени? Являются ли значения показателей устойчивыми по времени:

5. Оценить модель CAPM для американского рынка (месячные данные)

Оценим модель CAPM для акций Google (американской рынок) на месячных данных.

Вам необходимо использовать собственный тикер (а не GOOG), который был назначен вам случайным образом

Сначала необходимо получить данные:

GOOG <- getSymbols('GOOG', src = 'yahoo',from = start.date,auto.assign = FALSE)
##     As of 0.4-0, 'getSymbols' uses env=parent.frame() and
##  auto.assign=TRUE by default.
## 
##  This  behavior  will be  phased out in 0.5-0  when the call  will
##  default to use auto.assign=FALSE. getOption("getSymbols.env") and 
##  getOptions("getSymbols.auto.assign") are now checked for alternate defaults
## 
##  This message is shown once per session and may be disabled by setting 
##  options("getSymbols.warning4.0"=FALSE). See ?getSymbols for more details.
SPX <- getSymbols('^GSPC', src = 'yahoo',from = start.date,auto.assign = FALSE)
GOOG <- to.monthly(GOOG) # преобразовать дневные данные в месячные
SPX <- to.monthly(SPX)
GOOG.rtn <- diff(log(GOOG$GOOG.Adjusted)) # посчитать доходности
SPX.rtn <- diff(log(SPX$SPX.Adjusted))
rtns <- merge(GOOG.rtn, SPX.rtn) # Объединить в единый объект
names(rtns) <- c('GOOG', 'SPX') # переименовать переменные

rf <- getSymbols('DGS3MO', src = 'FRED', auto.assign = FALSE) #скачать данные по доходностям 3-месячных US Tresuaries
rf <- aggregate(rf, as.yearmon, mean, na.rm=TRUE ) # посчитать сремесячные значения для доходностей 
rtns <- merge.xts(rtns, rf,join = 'left' )
rtns$rf <- (rtns$rf/100+1)^(1/12)-1 # преобразовать в месячные доходности 
rtns$exret <- rtns$GOOG - rtns$rf # риск-премия для бумаги
rtns$exmkt <- rtns$SPX - rtns$rf # риск-премия для индекса

построить графики полученных переменных

plot(x=coredata(SPX.rtn), y=coredata(GOOG.rtn),
     xlab = 'Месячная доходность SP500', ylab= 'Месячная доходность GOOG' )

plot(rtns$rf,
     main = 'Среднемесячные значения UST (3m)')

Посчитаем модель CAPM c помощью функции lm

options(digits = 3)
capm_fit <- lm(formula = exret ~ exmkt, data = rtns)
summary(capm_fit)
## 
## Call:
## lm(formula = exret ~ exmkt, data = rtns)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.15569 -0.03359  0.00167  0.02922  0.19457 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  0.00382    0.00644    0.59     0.56    
## exmkt        1.04183    0.17484    5.96  5.9e-08 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.0575 on 83 degrees of freedom
##   (1 observation deleted due to missingness)
## Multiple R-squared:   0.3,   Adjusted R-squared:  0.291 
## F-statistic: 35.5 on 1 and 83 DF,  p-value: 5.93e-08

Как можно интепретировать полученные результаты регрессии CAPM?

6. Оценить модель Fama-French

Для начала необходимо скачать данные по факторам Fama-French c сайта Кеннета Френча (http://mba.tuck.dartmouth.edu/pages/faculty/ken.french/index.html)

Прочитайте описание факторов, которые используются в модели и как они рассчитываются – http://mba.tuck.dartmouth.edu/pages/faculty/ken.french/Data_Library/f-f_factors.html

temp <- tempfile() #создать временный файл
download.file("http://mba.tuck.dartmouth.edu/pages/faculty/ken.french/ftp/F-F_Research_Data_Factors_CSV.zip",temp, mode="wb")
unzip(temp, "F-F_Research_Data_Factors.CSV") #разархировать файл и сохранить его в рабочую папку
ff <- read.csv(file = 'F-F_Research_Data_Factors.CSV',skip = 3, sep = ',',stringsAsFactors = FALSE) # прочитать csv-файл
names(ff)[1] <- 'date' #изменить название первого столбца
str(ff) # посмотреть структуру объекта ff
## 'data.frame':    1180 obs. of  5 variables:
##  $ date  : chr  "192607" "192608" "192609" "192610" ...
##  $ Mkt.RF: chr  "    2.96" "    2.64" "    0.36" "   -3.24" ...
##  $ SMB   : chr  "   -2.30" "   -1.40" "   -1.32" "    0.04" ...
##  $ HML   : chr  "   -2.87" "    4.19" "    0.01" "    0.51" ...
##  $ RF    : chr  "    0.22" "    0.25" "    0.23" "    0.32" ...

Переменные имеют тип character (chr) – это плохо, так как означает, что R считает их текстовыми переменными, а не числами. Необходимо преобразовать данные, чтобы с ними можно было дальше работать

ff$date <- as.yearmon(ff$date, '%Y%m') # преобразовать в месячные даты
ff$Mkt.RF <- as.numeric(ff$Mkt.RF)/100 # преобразовать в тип numeric и поделить на 100
ff$SMB <- as.numeric(ff$SMB)/100
ff$HML <- as.numeric(ff$HML)/100
ff$RF <- as.numeric(ff$RF)/100
str(ff)
## 'data.frame':    1180 obs. of  5 variables:
##  $ date  :Class 'yearmon'  num [1:1180] 1926 1927 1927 1927 1927 ...
##  $ Mkt.RF: num  0.0296 0.0264 0.0036 -0.0324 0.0253 0.0262 -0.0006 0.0418 0.0013 0.0046 ...
##  $ SMB   : num  -0.023 -0.014 -0.0132 0.0004 -0.002 -0.0004 -0.0056 -0.001 -0.016 0.0043 ...
##  $ HML   : num  -0.0287 0.0419 0.0001 0.0051 -0.0035 -0.0002 0.0483 0.0317 -0.0267 0.006 ...
##  $ RF    : num  0.0022 0.0025 0.0023 0.0032 0.0031 0.0028 0.0025 0.0026 0.003 0.0025 ...

построить графики для факторов модели FF

par(mfrow =c(4,1)) 
plot(x = ff$date, y=ff$Mkt.RF, type = 'l')
plot(x = ff$date, y=ff$SMB, type = 'l')
plot(x = ff$date, y=ff$HML, type = 'l')
plot(x = ff$date, y=ff$RF, type = 'l')

par(mfrow =c(1,1))

Как значения факторов модели FF менялись со временем?

Необходимо дальше преобразовать данные – в частности, необходимо использовать только те значения, которые находятся после start.date

ff <- ff[as.Date(ff$date) > as.Date(start.date),]
ff <- ff[complete.cases(ff),] # оставить только те значения для которых, есть значения всех переменных
ff <- xts(ff[,-1], order.by = ff[,1])

ff_rtns <- merge(ff,rtns)
tail(ff_rtns)
##           Mkt.RF     SMB     HML    RF     GOOG      SPX       rf    exret
## сен 2016  0.0025  0.0200 -0.0134 2e-04  0.01326 -0.00124 0.000245  0.01302
## окт 2016 -0.0202 -0.0441  0.0415 2e-04  0.00928 -0.01962 0.000276  0.00901
## ноя 2016  0.0486  0.0568  0.0844 1e-04 -0.03436  0.03360 0.000376 -0.03474
## дек 2016  0.0181 -0.0004  0.0352 3e-04  0.01802  0.01804 0.000426  0.01759
## янв 2017  0.0194 -0.0095 -0.0276 4e-04  0.03184  0.01773 0.000431  0.03141
## фев 2017      NA      NA      NA    NA  0.03851  0.03123 0.000441  0.03807
##             exmkt
## сен 2016 -0.00148
## окт 2016 -0.01989
## ноя 2016  0.03323
## дек 2016  0.01761
## янв 2017  0.01729
## фев 2017  0.03079

Оценить модель FF

ff_fit <- lm(exret ~ Mkt.RF + SMB + HML, data = ff_rtns)
summary(ff_fit)
## 
## Call:
## lm(formula = exret ~ Mkt.RF + SMB + HML, data = ff_rtns)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.15689 -0.03763  0.00322  0.02792  0.18790 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  8.23e-05   6.43e-03    0.01    0.990    
## Mkt.RF       1.20e+00   1.81e-01    6.61  3.9e-09 ***
## SMB         -7.74e-01   3.01e-01   -2.57    0.012 *  
## HML         -4.91e-01   2.82e-01   -1.74    0.086 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.0561 on 80 degrees of freedom
##   (2 observations deleted due to missingness)
## Multiple R-squared:  0.357,  Adjusted R-squared:  0.333 
## F-statistic: 14.8 on 3 and 80 DF,  p-value: 9.1e-08

Сравните модели CAPM и Fama-French? Оличаются ли значения beta у моделей? Отличаются ли объяснительные силы моделей?

7. Event-study приватизационной сделки Роснефти

Вечером 7 декабря Роснефть объявила о том, что проведет приватизационную сделку (http://kremlin.ru/events/president/news/53431). Объявление проозошло вечером, после закрытия рынков. Цена закрытия 7 декабря составила 356,25 рублей. Цена открытия на следующий день составила 370,70 рублей, а цена закрытия 375,85 рублей. Таким образом, за день цена акции компании выросла на 5,5%.

Проведем event-study, на сколько изменение цен на акции 8 декабря 2016 года отличается от нормальной волатильности цен на акции Роснефти.

Определим, что дата события (event) = 8 декабря.

start.date <- as.Date('2015-12-08')
end.date <- as.Date('2016-12-08')

rtns_event <- merge(ROSN.rtn, MICEX.rtn, rf_rate_d)
rtns_event <- rtns_event[paste0(start.date, '::', end.date)]

event_day <- '2016-12-08'
chartSeries(ROSN[paste0(start.date, '::', end.date)], theme='white')

tail(rtns_event)
##            ROSN.Close MICEX.Close rf_rate_d
## 2016-12-01   -0.00501     0.00803  0.000233
## 2016-12-02    0.00442     0.00335  0.000235
## 2016-12-05    0.03326     0.01369  0.000234
## 2016-12-06    0.00327    -0.00277  0.000232
## 2016-12-07    0.01016     0.00378  0.000232
## 2016-12-08    0.05356     0.02130  0.000232

посчитаем модель CAPM за предыдущий период (1 год)

rtns_event$exret <- rtns_event$ROSN.Close -  rtns_event$rf_rate_d
rtns_event$exmkt <- rtns_event$MICEX.Close -  rtns_event$rf_rate_d

capm_event <- lm(exret ~ exmkt, data = rtns_event[,-nrow(rtns_event)]) 
event_window <- rtns_event[nrow(rtns_event)]
event_window$pred.ret <- summary(capm_event)$coefficients[1]+summary(capm_event)$coefficients[2]*event_window$exmkt
event_window$ab.ret <- event_window$exret - event_window$pred.ret
event_window$tStat <- coredata(event_window$ab.ret)/summary(capm_event)$sigma
event_window$pvalue <- 2*(1-pt(abs(coredata(event_window$tStat)), df = nrow(rtns_event)-2))
event_window
##            ROSN.Close MICEX.Close rf_rate_d  exret  exmkt pred.ret ab.ret
## 2016-12-08     0.0536      0.0213  0.000232 0.0533 0.0211   0.0268 0.0265
##            tStat pvalue
## 2016-12-08  2.29 0.0227

Отличается ли изменение цен на акций Роснефти 8 декабря 2016 года от нормального уровня волатильности при общепринятых критерях статистической значимости?