每周有效地為息票債券定價
我有一張息票債券 $ NV=20 000 000 $ 和優惠券 $ 4% p.a. $ ,假設優惠券每年支付一次(我沒有明確說明)。我們假設,開始日期是 27.4.2015,所以第一張優惠券將在明年支付。我的目標是從開始之日起每週為該債券定價,給定 $ 1Y,3Y $ 和 $ 10Y $ 零利率:
Date EUR1Y EUR3Y EUR10Y 1 2015-04-27 -0.27 -0.14 0.15 2 2015-05-04 -0.24 0.01 0.40 3 2015-05-11 -0.24 0.08 0.60 4 2015-05-18 -0.24 0.09 0.67 5 2015-05-25 -0.24 0.00 0.53 6 2015-06-01 -0.24 0.00 0.53
我知道,會有很多插值和混亂的日期計數,我不知道如何在 R 中有效地進行:
nv <- 20000000 c <- nv*0.04 coupons <- rep(c,10) payments <- seq.Date(as.Date("2015-04-27"),as.Date("2025-04-27"), by='year') payments2 <- bizdays::adjust.previous(payments, 'weekends')[2:10]
注意:在本文中,我不會涉及骯髒與清潔價格的話題。曲線構造的工作日調整均不存在。
定義
債券的現值或其淨價可以定義為
$$ P(t) = \sum_i^ncD(t,T_i)+D(T_n) $$ 在哪裡 $ c $ 是債券的息票(可能按正確的支付頻率調整), $ D(t,T) $ 是現金流量的折現因子 $ T $ , 按日期估值 $ t $ .
實際上,您的問題“歸結為”曲線構造練習。
曲線構造
您的債券估值歸結為貼現曲線的定義和重複校準/應用。從這裡開始,我假設您引用的零利率被“引用”為實際/365 連續複利。首先,我們需要一個函式,在給定零利率和期限的情況下返回“校準”貼現曲線。為此,讓
discount_factor_generator <- function(nodes, rates){ function(t){exp( -t * approxfun(x = nodes, y = rates,rule = 2)(t))} }
這個函式接受節點
c(1,3,10)
和零利率c(-0.0027, -0.0014, 0.0015)
並返回一個函式f(t)
。該函式f(t)
將產生現金流量的貼現因子 $ t $ ,在速率之間進行線性插值。假設您將費率儲存在一個名為的表中,好吧,
rates
每行索引 1 週,並且您的日期儲存在第一列中(如您的範例中所示)然後:
sapply(1:nrow(rates),function(i){ ttm <- as.numeric(pmax(payment_dates - rates[i,1],0)/365) dfs <- discount_factor_generator(c(1,3,10),current_rates <- rates[i,-1])(ttm) sum(schedule * (payment_dates>=rates[i,1]) * dfs) })
將產生一個 PV 列表,每個估值日期都有一個。
說明:
date_diffs
以年分數的形式儲存直到每個現金流量的剩餘時間。一旦付款日期過去,它將在每個點保持零。dfs
持有現金流日期對應向量的貼現因子值。最終,該notional * sum(...)
期限產生所有未來息票支付的現值和到期時 100% 的最終支付。高溫高壓
工作範例:
discount_factor_generator <- function(nodes, rates){ function(t){exp( -t * approxfun(x = nodes, y = rates,rule = 2)(t))} } payment_dates <- seq.Date(as.Date("2015-04-27"),as.Date("2025-04-27"), by='year') coupon <- 0.04 notional <- 20000000 schedule <- notional * c(rep(coupon,length(payment_dates)-1),1+coupon) rates <- data.frame( Date = seq.Date(as.Date("2015-04-27"),as.Date("2015-06-01"),by="week"), EUR1Y = c( -0.27, -0.24, -0.24, -0.24, -0.24, -0.24)/100, EUR3Y = c( -0.14, 0.01, 0.08, 0.09, 0.00, 0.00)/100, EUR10Y = c( 0.15, 0.40, 0.60, 0.67, 0.53, 0.53)/100) sapply(1:nrow(rates),function(i){ ttm <- as.numeric(pmax(payment_dates - rates[i,1],0)/365) dfs <- discount_factor_generator(c(1,3,10),current_rates <- rates[i,-1])(ttm) sum(schedule * (payment_dates>=rates[i,1]) * dfs) })
帶輸出
[1] 28491519 27119430 26684695 26541992 26858125 26863656