等質なCDOを評価するコードを書いてみた

金融危機時における資産価格変動の相互依存関係:コピュラに基づく評価 新谷 幸平、山田 哲也、吉羽 要直に倣って等質なCDOのスプレッドを評価してみた。このディスカッションペーパーのP23-表7を再現することが目的。コピュラって何?CDOって何?という話自体はここでは割愛。(TokyoWebmining9でその辺の話をさせてもらった際の資料はコチラ)
考えたい問題の状況設定は以下の通り。

  • 参照債務数(NUM.REFDEBT):=100
  • 満期(MATURITY):=5(年)
  • 回収率(RECOVERY.RATE):=40%(一定)
  • デフォルト確率(DEFAULT.PROBABILITY):=5%(5 年)
  • 正規コピュラのρ:=0.15
  • クレイトン・コピュラのα:=0.21

以下、実際に使用したコード(by R language)。
コピュラの生成にはcopulaパッケージを使用しているので、
install.packages("copula")としてパッケージは予めインストールしておいてください。

library(copula)
#CDOのスプレッド計算関数
SpreadOfCDO <- function(copula, default.probability, maturity,
  recovery.rate, attachment, detachment, num.path, num.refdebt)
{
  #コピュラによる乱数生成。これと倒産確率を比べて倒産判定実施
  random.copula <- rcopula(copula,num.path)
  #各パスごとのデフォルト件数
  num.default <- rowSums(random.copula < default.probability)
  #債務全体の損失率
  loss.refdebt <- (1-recovery.rate)/num.refdebt*num.default
  #トランシェの損失率
  loss.tranche <- (pmax(loss.refdebt - attachment,0)-pmax(loss.refdebt - detachment,0))/(detachment-attachment)
  #トランシェの損失率の期待値(標本ベース)
  expectation.loss.tranche <- sum(loss.tranche)/num.path
  #スプレッド
  spread <- -1/maturity*log(1-expectation.loss.tranche)
  return(spread)
}
################  main  ##################
#parameter
NUM.PATH <- 10^5
NUM.REFDEBT <- 100
DEFAULT.PROBABILITY <- 0.05
MATURITY <- 5
RECOVERY.RATE <- 0.4
#使用するコピュラオブジェクトを生成しておく
COPULA <- list(normalCopula(0.15, dim = NUM.REFDEBT),
  tCopula(0.15, dim = NUM.REFDEBT, df = 20),
  tCopula(0.15, dim = NUM.REFDEBT, df = 6),
  tCopula(0.15, dim = NUM.REFDEBT, df = 3),
  claytonCopula(0.21, dim = NUM.REFDEBT)
)
#ある程度パラメーター固定したスプレッド計算関数
SpreadOfCDOWithFixedParameter <- function(copula,attachment, detachment){
  SpreadOfCDO(copula, DEFAULT.PROBABILITY, MATURITY, 
    RECOVERY.RATE, attachment, detachment, NUM.PATH, NUM.REFDEBT)
}
result <- list()
#エクイティ
result[[1]] <- sapply(COPULA,SpreadOfCDOWithFixedParameter,0.0,0.06)
#メザニン
result[[2]] <- sapply(COPULA,SpreadOfCDOWithFixedParameter,0.06,0.18)
#シニア
result[[3]] <- sapply(COPULA,SpreadOfCDOWithFixedParameter,0.18,0.36)
#スーパーシニア
result[[4]] <- sapply(COPULA,SpreadOfCDOWithFixedParameter,0.36,1)
#行列&bp化
result <- 10^4*do.call("cbind", result) 
colnames(result) <- c("エクイティ","メザニン","シニア","スーパーシニア")
rownames(result) <- c("正規","t(20)","t(6)","t(3)","クレイトン")
result

最後の結果(result変数)を見ると。

コピュラ/トランシェ エクイティ メザニン シニア スーパーシニア
正規 1,145.42 62.49 0.52 0.000
t(20) 1,055.28 86.07 2.18 0.004
t(6) 896.74 126.44 8.56 0.044
t(3) 733.31 165.90 23.56 0.191
クレイトン 857.64 135.73 12.83 0.084

となっていて、ディスカッションペーパーの値をモンテカルロによる誤差のレベルで再現できている。
また、これを見て明らかなように正規コピュラでは金融危機のようにデフォルトが同時多発する際のシニア/スーパーシニアのリスク(スプレッド)を過小評価する可能性があることもわかる。