Салихов Марсель (marcel.salikhov@gmail.com)
2017-12-01
Для облигации с номиналом в 1000 рублей номинальная стоимость равняется:
\[ = \frac{1000}{(1+i)^n} \]
Предположим, что \(i = 10%\), тогда стоимость однолетней бумаги:
\[ = \frac{1000}{(1+0,1)^1} = 909,09 \]
стоимость 6-месячной бумаги равна:
\[ = \frac{1000}{(1+0,1)^{1/2}} = 953,46 \]
Стоимость 10-летней бумаги будет равна:
\[ = \frac{1000}{(1+0,1)^{10}} = 385,54 \]
Эмитент облигации обещает осуществить серию периодических купонных платежей, а также вернуть номинал в дату погашению.
\[ P_{cb} = \frac{Coupon}{(1+i)^1} + \frac{Coupon}{(1+i)^2} + ... + \frac{Coupon}{(1+i)^n} + \frac{FaceValue}{(1+i)^n} \]
К примеру, для 1-летней облигации с купоном в 5%:
\[ Price = \frac{50}{(1+i)} + \frac{1000}{(1+i)} \]
Оценим связь между ценой облигации и процентными ставками в R.
\[\frac{40}{1.05} + \frac{1040}{1.06^2} = 38,10 + 925,60 = 963,70 \]
\[\frac{40}{y+1} + \frac{1040}{(1+y)^2} = 963,70 \] Решение этого уравнение \(y = 6,3\) (полугодовая доходность). Годовая доходность будет равна 12,99%.
Инструменты с фиксированной доходностью меняются в цене при изменении процентных ставок. Поэтому управление процентным риском является важной частью управления портфелем облигаций.
Оценка дюрации позволяет оценить чувствителность облигации к изменению процентных ставок. Стратегии immunization (выстраивание портфеля таким образом, чтобы дюрации активов и обязательств совпадали) позволяют снизить влияние процентного риска.
Дюрация Макколея - средневзвешенный срок потока платежей, где весами выступают дисконтированные стоимости платежей.
\[ MacalayD = \frac{\sum\limits_{t=1}^T{PV(CF_t)}}{P} \] где \(PV(CF)_t\) – дисконтированный денежный поток в период времени t, \(Price\) – текущая цена облигации.
Дюрация будет всегда меньше или равна сроку до погашению облигации, при этом дюрация будет равна сроку до погашения только бескупонных облигаций.
Дюрация денежного потока зависит не только от его структуры, но и от текущей процентной ставки. Чем выше ставка, тем меньше стоимость дальних выплат по сравнению с короткими и тем меньше дюрация, и наоборот, чем меньше ставка, тем больше дюрация потока платежей.
Фраза «дюрация облигации составляет 3 года» означает, что рассматриваемая облигация имеет такую же чувствительность цены к колебаниям процентных ставок, как 3-летняя бескупонная облигация.
Другая интерпретация дюрации – среднее средневзвешенное количество лет, которое инвестор должен держать облигацию для того, чтобы дисконтированная стоимость денежных потоков облигации не сравнялась с той ценой, которую заплатил инвестор.
Модифицированная дюрация Макколея – показатель, характеризующий реакцию цены облигации на изменение доходности к погашению.
\[ MD = \frac{MacalayD}{1+YTM}\]
при малых величинах будет выполняться равенство
\[ \frac{\Delta P }{P} \approx -MD * \Delta r\] Пример. пусть модифицированная дюрация равна 4, облигация торгуется по цене 90% с доходность 8%. НКД равен 0. Как изменится цена, если доходность вырастет до 8.5% (изменение на 0.005).
Изменение цены можно будет вычислить следующим образом: \(-4 * 0.005 * 90=-1.8\). Цена облигации снизится на 1.8, до 88.2% номинала.
Накопленный купонный доход (accrued interest) – величина, измеряемая в денежных единицах, и характеризующая ту часть купонного дохода, которая «накоплена» с начала текущего купонного периода.
Купон по облигациям платится периодически, обычно 1 раз в квартал, полгода или год. Соответственно, после того, как очередной купон выплачен и начался новый купонный период, купон начинает «накапливаться».
Важность учета НКД обусловлена тем, что на большинстве рынков облигаций они торгуются по т.н. «чистой цене», не включающей в себя НКД. Для того, чтобы получить полную цену, которую покупатель облигации заплатит продавцу (ее также называют «грязной» ценой), надо к чистой цене прибавить НКД.
\[НКД = Coupon \frac{t_0 - t_{c-1}}{t_c - t_{c-1}} \] где \(t_0\) -– текущая дата, \(t_{с-1}\) – дата начала купонного периода, \(t_{с}\) – дата дата выплаты ближайшего купона.
К примеру, если размер очередного купона по облигации составляет 50 рублей, дата начала купонного периода – 01.04, дата окончания купонного периода (выплаты купона) – 01.10, то на момент 01.09 НКД составит 50*153/183=41.80 рублей.
Эмпирические наблюдения процентных ставок:
Временная структура процентных ставок до \(n\) лет погашению может описываться любым из следующих параметров:
Пусть у нас есть следующие данные по форвардным ставкам:
** Таблица. Форвардные процентные ставки на 3 года **
Год | Процентная ставка |
---|---|
1 | 6 |
2 | 7 |
3 | 8 |
Тогда 1-летняя бумага будет иметь цену, равную:
\[\frac{1000}{1+r_1} = \frac{1000}{1,06} = 943,40 = P(1) \]
2-летняя:
\[\frac{1000}{(1+r_1)(1+r_2)} = \frac{1000}{(1,06)(1,07)} = 881,68 = P(2) \]
3-летняя:
\[\frac{1000}{(1+r_1)(1+r_2)(1+r_3)} = \frac{1000}{(1,06)(1,07)(1,08)} = 816,37 = P(3) \]
Доходность к погашению будет определяться по традиционной формуле:
\[\frac{1000}{1+y_1} = 943,40 \] то есть \(y_1 = 0,06\)
Для двухлетней бумаги:
\[\frac{1000}{(1+y_1)^2} = 881,68 \]
\[ y=\sqrt{\frac{1000}{881,68}}=0,065 \] \(y_3 = 0,07\). Проверьте!
Общая формула для определения форвардных ставок из спотовых:
\[ r_1 = y_1 \]
и
\[r_n = \frac{(1+y_n)^n}{(1+y_{n-1})^{n-1})}-1 \]
Пусть у нас имеется следующая информация по ценам на облигации с нулевым купоном:
Погашение, лет | Цена, рублей |
---|---|
1 | 920 |
2 | 830 |
3 | 760 |
Тогда доходности к погашению будут определяться как:
\[y_1 = \frac{1000}{920} = 0,087 \] \[ y_2 = \{\frac{1000}{830}\}^{1/2} = 0,0976\] \[ y_3 = \{\frac{1000}{760}\}^{1/3} = 0,096\] Тогда используя формулу:
\[r_1 = y_1 = 0,087\] \[r_2 = \frac{(1+y_2)^2}{1+y_1}-1=\frac{1,0976^2}{1,0876}-1 =0,108 \] \[r_3 = \frac{(1+y_3)^3}{(1+y_2)^2}-1=\frac{1,096^3}{1,0976^2}-1 =0,092 \]
Таким образом, общая формула будет иметь вид:
\[r_n = \frac{P(n-1)}{P(n)}-1 \]
Ставка 1y1y - форвардная ставка на 1 год через 1 год, то есть это текущие ожидаемое значение ставки на 1 год через 1 год.
curve_new <- GCurve('2017-03-10')
spot_curve <- (curve_new$val+100)/100
fwd_curve <- c(spot_curve[1], rep(0,29))
for(i in 2:30){
fwd_curve[i] = (spot_curve[i]^i)/spot_curve[i-1]^(i-1)
}
plot(1:30, fwd_curve, type='l', xlab="лет", ylab="%", main = 'Кривая доходностей рынка ОФЗ (10 марта 2017 г.)')
lines(spot_curve, col = 'red')
legend("topright",legend=c("Спотовая кривая","Форвардная кривая"),
col=c(1,2),lty=1)
На графике приведены формы кривой доходности ОФЗ в период 2012-2017 гг. Как видно, форма кривой может быть различной.
Пусть у нас вложение 1000 рублей, которое принесет 10% через год. Как сумма полученных средств зависит от скорости начисления процента?
Начисление | Платежей | % за период |
---|---|---|
Ежегодно | 1 | 0.1 |
Полгода | 2 | 0.05 |
Квартал | 4 | 0.025 |
Месяц | 12 | 0.0083 |
Неделя | 52 | \(\frac{0.1}{52}\) |
День | 365 | \(\frac{0.1}{365}\) |
\(\infty\) | \(\infty\) |
\[ 1105.517 = 1000 e^{0.1} \] Мы можем выразить наоборот: какова текущая величина инвестициии, которая позволит получить нам 1000 рублей при непрерывном начислении доходности:
\[1000 e^{-0.1} = 904.84 \]
\[P(n) = \frac{1000}{exp(r_1 + r_2 + \ldots + r_n)} \] \[\frac{P(n-1)}{P(n)} = \frac{exp(r_1 + r_2 + \ldots + r_n)}{exp(r_1 + r_2 + \ldots + r_{n-1})} = exp(r_n)\] \[log(\frac{P(n-1)}{P(n)})= r_n \] Доходность к погашению n-летней облигации (\(y_n\)) с нулевым купоном решает уравнение:
\[P(n) = \frac{1000}{exp(n y_n)}\] тогда
\[y_n = \frac{(r_1 + r_2+ \ldots + r_n)}{n} \] Соответственно можно выразить форвардную ставку как:
\[r_n = n y_n - (n-1)y_{n-1} \]
\[ D(T) = exp(- \int_{0}^{T}r(t)dt \]
\(D(T)\) называется дисконтной функцией. Цена любой облигации с нулевым купоном будет определяться как:
\[ P(T) = PAR \times D(T) \] где \(PAR\) – номинальная стоимость к погашению.
\[log(P(t)) = log(PAR)- \int_{0}^{T}r(t)dt\]
y = as.numeric((last(gcurve)[-1]+100)/100)
y
[1] 1.090359 1.085586 1.084297 1.082588 1.082047 1.082050 1.082154
[8] 1.082295 1.082456 1.082627 1.082801 1.082974 1.083142 1.083304
[15] 1.083457 1.083602 1.083738 1.083866 1.083985 1.084096 1.084199
[22] 1.084296 1.084385 1.084469 1.084547 1.084620 1.084688 1.084752
[29] 1.084811 1.084867
d <- rep(0,30)
for(i in 1:30){
d[i] = 1/y[i]^i
}
plot(1:30, d, type = 'l', main = 'Пример расчета дисконтной функции', xlab = 'лет до погашения', ylab='')
Предположим, что существует несколько типов облигаций с нулевой доходностью номиналом в 1000 рублей с несколькими разными сроками до погашения (\(T_i\).
Дходность к погашению для всех этих облигаций одинаковая и равна \(r\).
C условием постоянной величины \(r\) для разных типов облигаций:
\[ P_i = 1000 exp(-r T_i) \]
где \(i\) – определяет разные выпуски облигаций.
Так существует определенная вариация в наблюдаемых ценах на облигации, то можно включить случайную компоненту:
\[ P_i = 1000 exp(-r T_i) + \epsilon_i\]
Величину \(r\) можно определить с помощью МНК, минимизируя сумму квадратов
\[\sum_{i=1}^n \{ P_i - exp(-r T_i) \} \]
nls
, но необходимо задать начальное значение (мы задали 0,04)#bondprices_df <- read.table("lectures/data/bondprices.txt",header=T)
bondprices_df
maturity price
1 0.75 967.26
2 2.50 834.21
3 3.00 810.52
4 5.00 769.30
5 7.50 656.64
6 7.90 639.71
7 8.00 604.61
8 12.00 502.11
9 16.00 393.38
fit = nls(data = bondprices_df, price ~ 1000*exp(-r*maturity),start=list(r=.04))
summary(fit)
Formula: price ~ 1000 * exp(-r * maturity)
Parameters:
Estimate Std. Error t value Pr(>|t|)
r 0.058498 0.001488 39.31 1.93e-10 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 19.6 on 8 degrees of freedom
Number of iterations to convergence: 4
Achieved convergence tolerance: 5.528e-08
par(mfrow=c(1,1))
plot(bondprices_df$maturity,bondprices_df$price,pch="*",cex = 2, xlab = 'срок до погашения', ylab = 'цена P')
grid = seq(0, 20, length=201)
price_grid = 1000*exp(-0.0585*grid)
lines(grid,price_grid, lwd = 2, col = "red")
\[ y_T(\beta) = T^{-1} \int_o^T r(t;\beta) dt \]
\[P_t(\beta) = exp \{-T y_T (\beta) \} = exp \int_o^T r(t;\beta) dt \]
\[r(t; \beta) = \beta_0 + (\beta_1 + \beta_2 t) e^{(-\lambda t)} \]
Мы загрузим данные кривой бескупонной доходности с сайта Банка России (предварительно сохраненные)
#gcurve <- read.csv("lectures/data/gcurve.csv")
#gcurve <- tail(gcurve,100)
tail(gcurve)
date X1 X2 X3 X4 X5 X6
1295 2017-03-02 8.918567 8.529273 8.497813 8.333247 8.272291 8.268537
1296 2017-03-03 8.989110 8.563316 8.500615 8.332923 8.271080 8.265414
1297 2017-03-06 9.022121 8.514530 8.451944 8.304479 8.249609 8.246006
1298 2017-03-07 8.973115 8.506906 8.421690 8.255603 8.198997 8.197915
1299 2017-03-09 9.006285 8.531892 8.427208 8.266444 8.215443 8.217659
1300 2017-03-10 9.035880 8.558589 8.429702 8.258808 8.204673 8.205020
X7 X8 X9 X10 X11 X12 X13
1295 8.275205 8.285508 8.297932 8.311516 8.325583 8.339670 8.353464
1296 8.270404 8.279367 8.290730 8.303474 8.316880 8.330447 8.343835
1297 8.252502 8.262844 8.275475 8.289381 8.303849 8.318385 8.332657
1298 8.207044 8.219777 8.234568 8.250427 8.266662 8.282797 8.298518
1299 8.229522 8.244684 8.261641 8.279432 8.297392 8.315070 8.332173
1300 8.215438 8.229470 8.245550 8.262668 8.280118 8.297415 8.314240
X14 X15 X16 X17 X18 X19 X20
1295 8.366764 8.379448 8.391449 8.402740 8.413322 8.423212 8.432439
1296 8.356818 8.369256 8.381066 8.392212 8.402683 8.412488 8.421653
1297 8.346445 8.359618 8.372099 8.383857 8.394888 8.405208 8.414844
1298 8.313622 8.327990 8.341560 8.354311 8.366249 8.377400 8.387798
1299 8.348517 8.364002 8.378579 8.392240 8.405004 8.416906 8.427988
1300 8.330387 8.345736 8.360226 8.373839 8.386582 8.398484 8.409583
X21 X22 X23 X24 X25 X26 X27
1295 8.441039 8.449052 8.456517 8.463475 8.469965 8.476024 8.481687
1296 8.430207 8.438186 8.445627 8.452570 8.459050 8.465103 8.470763
1297 8.423831 8.432210 8.440020 8.447304 8.454100 8.460447 8.466380
1298 8.397486 8.406510 8.414917 8.422752 8.430059 8.436881 8.443257
1299 8.438303 8.447901 8.456835 8.465156 8.472912 8.480150 8.486912
1300 8.419925 8.429559 8.438535 8.446901 8.454705 8.461992 8.468801
X28 X29 X30
1295 8.486985 8.491948 8.496604
1296 8.476061 8.481027 8.485686
1297 8.471933 8.477136 8.482019
1298 8.449222 8.454811 8.460053
1299 8.493237 8.499160 8.504717
1300 8.475174 8.481145 8.486747
используем пакет termstr
require(termstrc)
yields <- as.matrix(gcurve[,2:31])
dates <- as.Date(gcurve$date)
datazeroyields <- zeroyields(maturities, yields, dates) # сконструриуем объектов со ставками
datazeroyields
This is a data set of zero-coupon yields.
Maturities range from 0.0833333333333333 to 12 years.
There are 100 observations between 2016-10-18 and 2017-03-10 .
ns_res <- estim_nss(datazeroyields, "ns", tauconstr = c(0.2, 6, 0.1), optimtype = "allglobal")
ns_res
---------------------------------------------------
Estimated Nelson/Siegel parameters:
---------------------------------------------------
Number of oberservations: 100
[[1]]
beta_0 beta_1 beta_2 tau_1
Min. :8.208 Min. :-0.201577 Min. :-1.32840 Min. :0.2000
1st Qu.:8.445 1st Qu.:-0.001164 1st Qu.:-0.84943 1st Qu.:0.2865
Median :8.538 Median : 0.116940 Median :-0.56691 Median :0.5027
Mean :8.555 Mean : 0.114837 Mean :-0.51094 Mean :0.6947
3rd Qu.:8.634 3rd Qu.: 0.215026 3rd Qu.:-0.04093 3rd Qu.:0.5902
Max. :8.934 Max. : 0.452412 Max. : 0.30425 Max. :5.9001
plot(param(ns_res))
Loading required package: YieldCurve
TRADEDATE SECID YIELD PREV_YIELD TREND CALCVALUE SPREAD
35 2017-03-10 SU25080RMFS1 9.85 9.85 0.00 9.77 -0.08
34 2017-03-10 SU26206RMFS1 9.74 9.74 0.00 9.69 -0.05
33 2017-03-10 SU24018RMFS2 9.24 9.21 0.03 9.55 0.31
32 2017-03-10 SU25081RMFS9 9.14 9.11 0.03 9.14 0.00
31 2017-03-10 SU26204RMFS6 9.03 9.00 0.03 9.08 0.05
30 2017-03-10 SU46021RMFS0 8.95 8.92 0.03 9.36 0.41
29 2017-03-10 SU46014RMFS5 8.86 8.83 0.03 8.15 -0.71
28 2017-03-10 SU46005RMFS3 8.91 8.88 0.03 NA NA
26 2017-03-10 SU46019RMFS4 8.73 8.71 0.02 8.91 0.18
27 2017-03-10 SU26208RMFS7 8.58 8.56 0.02 8.49 -0.09
25 2017-03-10 SU26216RMFS0 8.56 8.54 0.02 8.60 0.04
24 2017-03-10 SU26210RMFS3 8.49 8.48 0.01 8.47 -0.02
23 2017-03-10 SU29011RMFS2 8.48 8.48 0.00 10.06 1.58
22 2017-03-10 SU26214RMFS5 8.41 8.41 0.00 8.35 -0.06
21 2017-03-10 SU26205RMFS3 8.29 8.29 0.00 8.33 0.04
20 2017-03-10 SU26217RMFS8 8.26 8.27 -0.01 8.29 0.03
19 2017-03-10 SU46018RMFS6 8.33 8.33 0.00 8.71 0.38
18 2017-03-10 SU26209RMFS5 8.24 8.25 -0.01 8.25 0.01
17 2017-03-10 SU26220RMFS2 8.24 8.25 -0.01 8.32 0.08
16 2017-03-10 SU26211RMFS1 8.24 8.25 -0.01 8.34 0.10
15 2017-03-10 SU46022RMFS8 8.23 8.24 -0.01 8.81 0.58
14 2017-03-10 SU26215RMFS2 8.24 8.25 -0.01 8.29 0.05
13 2017-03-10 SU29006RMFS2 8.26 8.27 -0.01 10.29 2.03
12 2017-03-10 SU46011RMFS1 8.26 8.27 -0.01 NA NA
11 2017-03-10 SU46023RMFS6 8.31 8.32 -0.01 NA NA
10 2017-03-10 SU26219RMFS4 8.27 8.28 -0.01 8.28 0.01
9 2017-03-10 SU26207RMFS9 8.27 8.29 -0.02 8.13 -0.14
8 2017-03-10 SU29007RMFS0 8.28 8.29 -0.01 10.46 2.18
7 2017-03-10 SU26212RMFS9 8.28 8.30 -0.02 8.26 -0.02
6 2017-03-10 SU46012RMFS9 8.29 8.31 -0.02 NA NA
5 2017-03-10 SU29008RMFS8 8.30 8.31 -0.01 10.49 2.19
4 2017-03-10 SU26218RMFS6 8.32 8.33 -0.01 8.31 -0.01
3 2017-03-10 SU29009RMFS6 8.32 8.34 -0.02 10.61 2.29
2 2017-03-10 SU29010RMFS4 8.34 8.35 -0.01 10.53 2.19
1 2017-03-10 SU46020RMFS2 8.35 8.37 -0.02 8.50 0.15
MATDATE MATPERIOD month
35 19.04.2017 0.11 1
34 14.06.2017 0.26 3
33 27.12.2017 0.80 10
32 31.01.2018 0.89 11
31 15.03.2018 1.01 12
30 08.08.2018 1.41 17
29 29.08.2018 1.47 18
28 09.01.2019 1.83 22
26 20.03.2019 2.03 24
27 27.02.2019 1.97 24
25 15.05.2019 2.18 26
24 11.12.2019 2.75 33
23 29.01.2020 2.89 35
22 27.05.2020 3.21 39
21 14.04.2021 4.10 49
20 18.08.2021 4.44 53
19 24.11.2021 4.71 57
18 20.07.2022 5.36 64
17 07.12.2022 5.75 69
16 25.01.2023 5.88 71
15 19.07.2023 6.36 76
14 16.08.2023 6.44 77
13 29.01.2025 7.89 95
12 20.08.2025 8.45 101
11 23.07.2026 9.37 112
10 16.09.2026 9.52 114
9 03.02.2027 9.91 119
8 03.03.2027 9.98 120
7 19.01.2028 10.87 130
6 05.09.2029 12.50 150
5 03.10.2029 12.57 151
4 17.09.2031 14.53 174
3 05.05.2032 15.16 182
2 06.12.2034 17.75 213
1 06.02.2036 18.92 227