Количественные финансы. Введение в R

Салихов Марсель (marcel.salikhov@gmail.com)

2017-09-08

Цели лекции

Что такое R?

Почему именно R?

Этот график тоже построен в R

Ограничения R

R и Excel

НО:

R/Python/Matlab

Установка R

  1. Зайти на CRAN и установить R
  2. Зайти на RStudio и установить R Studio – более удобный и совершенный редактор (IDE) для R.

R можно установить и на Windows/Mac OS/ Unix – разницы в функционале не будет. + Для того, чтобы устанавливать пакеты необходимо иметь права администратора. + Не устанавливайте R в свою рабочую папку, в особенности, если вы используете имя пользователя на кириллице (для Windows)

Изучение R

Комманды в R

Базовые операции

начнем с основ:

print("Hello world")
## [1] "Hello world"

Сообщения, начинающиеся со знака # - показывают результат выывода в консоли R.

R работает и как калькулятор. Можно складывать переменные:

1+3
## [1] 4

умножать:

2*3
## [1] 6

делить:

6/2
## [1] 3

брать квадратный корень:

sqrt(5)
## [1] 2.236068

брать логарифм

log(5)
## [1] 1.609438
2^10
## [1] 1024

Типы данных

Всё в R – объекты. Объекты могут быть разных типов и классов. Узнать тип объекта можно с помощью команды type, класс объекта – командой class. R оперирует именованными структурами данным. Каждый объект имеет свое имя. Числа могут быть разных типов.

2^10
## [1] 1024

Ими могут быть, десятичные числа. Они называются numeric

x <- 10.5       # присвоить переменной x значение 10.5
x              # вывести значение x
## [1] 10.5
class(x)       # класс переменной х 
## [1] "numeric"
typeof(x)      # тип переменной X  
## [1] "double"

Команды = и <- идентичны и означают “присвоить значение”

x = 5 
x = x +5 
x 
## [1] 10

Целые числа

Тип ingeger

x = as.integer(3)       # присвоить переменной x значение 3
x              # вывести значение x
## [1] 3
class(x)       # тип переменной х 
## [1] "integer"
is.integer(x)   # является ли x целым числом?
## [1] TRUE

Логические переменные

x = 1; y = 2   # sample values 
z = x > y 
z  
## [1] FALSE
class(z)   
## [1] "logical"

логические операции

u = TRUE; v = FALSE 
u & v          # u AND v 
## [1] FALSE
u | v          # u OR v 
## [1] TRUE
!u      
## [1] FALSE
class(z)   
## [1] "logical"

Тип character

character – строковая переменная. В R объекты этого типа выделены кавычками

x = 1  # присвоить x численное значение 1 
y = '1' # присвоить y текстовое значение равное 1 
as.numeric(y) # преобразовать y в тип numeric 
## [1] 1
## попробуйте команду x + y , будет сообщение об ошибке 

Тип NA

Специальный тип для обозначения пропущенных данных (missing value)

x <- NA 
is.na(x)
## [1] TRUE
is.na(c(1, NA))
## [1] FALSE  TRUE

Вектор

Вектор – тип данных, который состоит из упорядоченного набора объектов одного типа. Вектор можно создать с помощью команды c

a <- c(1, 2, 3)
b <- c(4,5,6)
is.vector(a) ## является ли a вектором
## [1] TRUE
 n = c(2, 3, 5) 
 s = c("aa", "bb", "cc", "dd", "ee") 
 c(n, s) 
## [1] "2"  "3"  "5"  "aa" "bb" "cc" "dd" "ee"

есть и другие варианты для создания векторов:

1:10
##  [1]  1  2  3  4  5  6  7  8  9 10
seq(from = 2, to = 10, by = 2)
## [1]  2  4  6  8 10
seq(from= 1, by =2, length.out = 5)
## [1] 1 3 5 7 9
rep(1:4,2)
## [1] 1 2 3 4 1 2 3 4
rep(1:4, each = 2)
## [1] 1 1 2 2 3 3 4 4

Операции могут выполняться и с векторами разной длины. В этом случае используется выравнивание векторов (recycling rule).

u = c(10, 20, 30) 
v = c(1, 2, 3, 4, 5, 6, 7, 8, 9) 
u + v 
## [1] 11 22 33 14 25 36 17 28 39

У каждого вектора есть свой индекс (порядковый номер), к которому можно обратиться с помощью имени объекта (вектора) и квадратных скобок

s = c("aa", "bb", "cc", "dd", "ee") 
s[3] 
## [1] "cc"
s[-3] # убрать третий элемент
## [1] "aa" "bb" "dd" "ee"
s[10] 
## [1] NA

Векторизация операций

a 
## [1] 1 2 3
b
## [1] 4 5 6
a+b
## [1] 5 7 9
a *b
## [1]  4 10 18
log(a)
## [1] 0.0000000 0.6931472 1.0986123

Тип data frame

data frame – это набор (коллекция) векторов, объединенных в один объект. Каждый столбец data frame – вектор. Каждая строка – наблюдение

str(mtcars) # посмотреть структуру объекта  
## 'data.frame':    32 obs. of  11 variables:
##  $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
##  $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
##  $ disp: num  160 160 108 258 360 ...
##  $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
##  $ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
##  $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
##  $ qsec: num  16.5 17 18.6 19.4 17 ...
##  $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
##  $ am  : num  1 1 1 0 0 0 0 0 0 0 ...
##  $ gear: num  4 4 4 3 3 3 3 4 4 4 ...
##  $ carb: num  4 4 1 1 2 1 4 2 2 4 ...
dim(mtcars) # размерность объекта, количество ноблюдней и переменных 
## [1] 32 11
length(mtcars) # длина -- количество переменных 
## [1] 11
head(mtcars) # первые 5 строк 
##                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
## Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
## Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
## Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
## Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1
head(mtcars, n = 2) # first 2 rows of data.frame
##               mpg cyl disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4      21   6  160 110  3.9 2.620 16.46  0  1    4    4
## Mazda RX4 Wag  21   6  160 110  3.9 2.875 17.02  0  1    4    4
tail(mtcars) # последние 5 строк 
##                 mpg cyl  disp  hp drat    wt qsec vs am gear carb
## Porsche 914-2  26.0   4 120.3  91 4.43 2.140 16.7  0  1    5    2
## Lotus Europa   30.4   4  95.1 113 3.77 1.513 16.9  1  1    5    2
## Ford Pantera L 15.8   8 351.0 264 4.22 3.170 14.5  0  1    5    4
## Ferrari Dino   19.7   6 145.0 175 3.62 2.770 15.5  0  1    5    6
## Maserati Bora  15.0   8 301.0 335 3.54 3.570 14.6  0  1    5    8
## Volvo 142E     21.4   4 121.0 109 4.11 2.780 18.6  1  1    4    2
tail(mtcars, n = 3) # last 3 rows of data.frame
##                mpg cyl disp  hp drat   wt qsec vs am gear carb
## Ferrari Dino  19.7   6  145 175 3.62 2.77 15.5  0  1    5    6
## Maserati Bora 15.0   8  301 335 3.54 3.57 14.6  0  1    5    8
## Volvo 142E    21.4   4  121 109 4.11 2.78 18.6  1  1    4    2

Существуют разные способы обратиться к элементам data frame

К примеру, к отдельной колонке (переменной) можно обратиться следующими способами:

mtcars[9] #  номер внутри двойных скобок
##                     am
## Mazda RX4            1
## Mazda RX4 Wag        1
## Datsun 710           1
## Hornet 4 Drive       0
## Hornet Sportabout    0
## Valiant              0
## Duster 360           0
## Merc 240D            0
## Merc 230             0
## Merc 280             0
## Merc 280C            0
## Merc 450SE           0
## Merc 450SL           0
## Merc 450SLC          0
## Cadillac Fleetwood   0
## Lincoln Continental  0
## Chrysler Imperial    0
## Fiat 128             1
## Honda Civic          1
## Toyota Corolla       1
## Toyota Corona        0
## Dodge Challenger     0
## AMC Javelin          0
## Camaro Z28           0
## Pontiac Firebird     0
## Fiat X1-9            1
## Porsche 914-2        1
## Lotus Europa         1
## Ford Pantera L       1
## Ferrari Dino         1
## Maserati Bora        1
## Volvo 142E           1
mtcars[[9]] #  номер внутри двойных скобок
##  [1] 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1
mtcars$am
##  [1] 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1
mtcars[, 'am']
##  [1] 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1

к строкам можно обратиться следующими способами:

mtcars[24,] # индекс по номеру 
##             mpg cyl disp  hp drat   wt  qsec vs am gear carb
## Camaro Z28 13.3   8  350 245 3.73 3.84 15.41  0  0    3    4
mtcars[c(3, 24),] 
##             mpg cyl disp  hp drat   wt  qsec vs am gear carb
## Datsun 710 22.8   4  108  93 3.85 2.32 18.61  1  1    4    1
## Camaro Z28 13.3   8  350 245 3.73 3.84 15.41  0  0    3    4
L = mtcars$am == 0 
L
##  [1] FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [12]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE
## [23]  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 mtcars[L,] 
##                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## Merc 240D           24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## Merc 230            22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
## Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
## Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## Toyota Corona       21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
## AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
## Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2

Тип Date

Тип Date представляет календарные даты. Финансовые серии как правило представляют собой временный ряд, упорядоченный во времени.

date()
## [1] "Fri Sep 08 16:29:43 2017"
today <- Sys.Date()
today
## [1] "2017-09-08"
format(today, "%d %b %Y")  # with month as a word
## [1] "08 сен 2017"
seq(today, length.out=10, by="1 week")
##  [1] "2017-09-08" "2017-09-15" "2017-09-22" "2017-09-29" "2017-10-06"
##  [6] "2017-10-13" "2017-10-20" "2017-10-27" "2017-11-03" "2017-11-10"
weekdays(today)
## [1] "пятница"
months(today)
## [1] "Сентябрь"

можно делать конвертацию между типами character и Date c помощью функций as.Date и as.character

Тип xts – временной ряд

В R есть несколько специальных типов данных для работы с временными рядами. Один из них – xts (extentible time series)

#install.packages(xts) # установать пакет 
library(xts) #  загрузить пакет
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
data(sample_matrix)

df_xts <- as.xts(as.data.frame(sample_matrix),
                 important='very important info!')
str(df_xts)
## An 'xts' object on 2007-01-02/2007-06-30 containing:
##   Data: num [1:180, 1:4] 50 50.2 50.4 50.4 50.2 ...
##  - attr(*, "dimnames")=List of 2
##   ..$ : NULL
##   ..$ : chr [1:4] "Open" "High" "Low" "Close"
##   Indexed by objects of class: [POSIXct,POSIXt] TZ: 
##   xts Attributes:  
## List of 1
##  $ important: chr "very important info!"
xts(1:10, Sys.Date()+1:10)
##            [,1]
## 2017-09-09    1
## 2017-09-10    2
## 2017-09-11    3
## 2017-09-12    4
## 2017-09-13    5
## 2017-09-14    6
## 2017-09-15    7
## 2017-09-16    8
## 2017-09-17    9
## 2017-09-18   10
head(index(df_xts))
## [1] "2007-01-02 MSK" "2007-01-03 MSK" "2007-01-04 MSK" "2007-01-05 MSK"
## [5] "2007-01-06 MSK" "2007-01-07 MSK"
head(coredata(df_xts))
##          Open     High      Low    Close
## [1,] 50.03978 50.11778 49.95041 50.11778
## [2,] 50.23050 50.42188 50.23050 50.39767
## [3,] 50.42096 50.42096 50.26414 50.33236
## [4,] 50.37347 50.37347 50.22103 50.33459
## [5,] 50.24433 50.24433 50.11121 50.18112
## [6,] 50.13211 50.21561 49.99185 49.99185

основное удобство работы с объектами типа xts – удобные способы получать срезы исходных данных:

df_xts['2007-01-06'] # отдельная дата 
##                Open     High      Low    Close
## 2007-01-06 50.24433 50.24433 50.11121 50.18112
df_xts['2007-03'] # отдельный месяц 
##                Open     High      Low    Close
## 2007-03-01 50.81620 50.81620 50.56451 50.57075
## 2007-03-02 50.60980 50.72061 50.50808 50.61559
## 2007-03-03 50.73241 50.73241 50.40929 50.41033
## 2007-03-04 50.39273 50.40881 50.24922 50.32636
## 2007-03-05 50.26501 50.34050 50.26501 50.29567
## 2007-03-06 50.27464 50.32019 50.16380 50.16380
## 2007-03-07 50.14458 50.20278 49.91381 49.91381
## 2007-03-08 49.93149 50.00364 49.84893 49.91839
## 2007-03-09 49.92377 49.92377 49.74242 49.80712
## 2007-03-10 49.79370 49.88984 49.70385 49.88698
## 2007-03-11 49.83062 49.88295 49.76031 49.78806
## 2007-03-12 49.82763 49.90311 49.67049 49.74033
## 2007-03-13 49.69628 49.70863 49.37924 49.37924
## 2007-03-14 49.36270 49.53735 49.30746 49.53735
## 2007-03-15 49.57374 49.62310 49.39876 49.49600
## 2007-03-16 49.44900 49.65285 49.42416 49.59500
## 2007-03-17 49.55666 49.55666 49.33564 49.34714
## 2007-03-18 49.29778 49.67857 49.29778 49.65463
## 2007-03-19 49.62747 49.65407 49.51604 49.54590
## 2007-03-20 49.59529 49.62003 49.42321 49.50690
## 2007-03-21 49.49765 49.53961 49.41610 49.51807
## 2007-03-22 49.42306 49.42306 49.31184 49.39687
## 2007-03-23 49.27281 49.27281 48.93095 48.93095
## 2007-03-24 48.86635 48.86635 48.52684 48.52684
## 2007-03-25 48.50649 48.50649 48.33409 48.33973
## 2007-03-26 48.34210 48.44637 48.28969 48.28969
## 2007-03-27 48.25248 48.41572 48.23648 48.30851
## 2007-03-28 48.33090 48.53595 48.33090 48.53595
## 2007-03-29 48.59236 48.69988 48.57432 48.69988
## 2007-03-30 48.74562 49.00218 48.74562 48.93546
## 2007-03-31 48.95616 49.09728 48.95616 48.97490
df_xts['/2007-01-07'] # Extract all the data from the beginning through January 7, 2007.
##                Open     High      Low    Close
## 2007-01-02 50.03978 50.11778 49.95041 50.11778
## 2007-01-03 50.23050 50.42188 50.23050 50.39767
## 2007-01-04 50.42096 50.42096 50.26414 50.33236
## 2007-01-05 50.37347 50.37347 50.22103 50.33459
## 2007-01-06 50.24433 50.24433 50.11121 50.18112
## 2007-01-07 50.13211 50.21561 49.99185 49.99185
df_xts['2007-06-25/'] #Extract all the data from June 25, 2007 through the end.
##                Open     High      Low    Close
## 2007-06-25 47.20471 47.42772 47.13405 47.42772
## 2007-06-26 47.44300 47.61611 47.44300 47.61611
## 2007-06-27 47.62323 47.71673 47.60015 47.62769
## 2007-06-28 47.67604 47.70460 47.57241 47.60716
## 2007-06-29 47.63629 47.77563 47.61733 47.66471
## 2007-06-30 47.67468 47.94127 47.67468 47.76719

Построение графиков

x = 1:100
y = rnorm(100)

plot(x = x,y =y , type = 'l')

hist(rnorm(100))

Пример визуализации финансовых данных

require(quantmod)
## Loading required package: quantmod
## Loading required package: TTR
## Version 0.4-0 included new data defaults. See ?getSymbols.
AAPL = getSymbols("AAPL", src = 'google', 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.
chartSeries(AAPL, theme = 'white') 

chartSeries(AAPL['2017::'], theme = 'white')

plot(diff(log(Cl(AAPL))), type = 'l', main = 'Лог-доходность акций AAPL, 2007-2017 ')