ブラックスワン
ナシーム・タレブ氏はブラックスワンで非常に稀な頻度で発生するインパクトの高い事象について著しています。
彼がブラックスワンの概念を世に広めてから、テイルリスクという言葉もよく知られるようになりました。
テイルは確率分布の裾の部分、正規分布のベルカーブという釣鐘型の分布曲線の両端のことを指しています。この部分の意味するところは、非常に頻度が低いことで、分布の中心部分が発生頻度が高い事象になります。多くの金融市場の期待収益は、この分布を前提にモデル化されています。ランダムウォークモデルによる効率的市場仮説(EMH)というものです。
タレブ氏は、”そうとばかりは言えないよ。ブラックスワンは分布より高い頻度で起きたりする。”と説いています。そのことを、彼の固有のアフォリズムを用いて教えてくれます。
分布のテイルにあるリスクは、もっと分厚い頻度の分布になっています。ファットテイル、あるいはヘヴィテイルというものです。
コピュラ
コプラは英語やラテン系の言語などで、二つのワードを連結して主語と述語の関係を作り出す動詞のことを言います。英語のbe動詞などを指しますが、数学の世界では接合関数と呼ばれています。
コピュラ(接合関数)という概念は、複数の対象間の従属性をフレームワークとしたモデルです。同時分布関数は、個々のリスク要因の周辺的挙動とそれらの要因間の従属構造を説明します。コピュラは二つ以上の対象のそれぞれの挙動とその従属性、極端な結果の従属性を説明するのに役立ちます。
いくつかの金融危機や経済変動において、一つの市場の挙動が他の市場に伝搬するような現象が見られます。
両者の関係は、因果推論などのフレームワークで解析することもできます。その因果性については別の機会に記すことにします。
ここではコピュラの従属性というフレームワークを用いてリスク管理に役立てます。
テイルの非対称性
コピュラはテイルの非対称性を示すケースで従属構造を記述するのに向いています。
テイルの非対称性というのは、正規分布が示すベルカーブの外形と比較して、平均値から離れた裾野の部分でプラス側とマイナス側における厚みの相違のことです。
非対称性は「ブラックスワン」の著者タレブ氏の他の著作でもよく強調される概念の一つです。
ベルカーブで示す期待収益の確率分布の曲線が、左の裾野で厚くなっているケースをテイルリスクと呼んだりします。
ベルカーブの裾野の相違、期待リターンの分布が左サイドに盛り上がった分布は、ファットテイルまたはヘヴィテイル現象です。
これは、期待収益(損失)が正規分布に比べて大きい事象の確率を示しています。
テイル従属性
テイルリスクは、下落局面での相関リスクとして捉えることができます。
ファットテイル部分での各株式、あるいは他の金融商品の価格変動でも同様の現象が見て取れます。
この現象は金融市場で取引される商品の価格変動に共通した特徴の一つです。
価格変動に関する従属性のある時系列データは、正規分布に比べて裾野の厚い(ファットテイル)な挙動を示します。
これをテイル従属性という概念で捉えてみます。
非常に低い確率で発生する挙動である市場Aの価格変動が、同時に低い確率で発生する別な市場Bの挙動として与えられます。
この条件での確率分布は、以下の式で示され、テイル従属性はこの確率分布で与えられます。
λ (p) = ( C(p,p)) / p
ケンダールの手法によりVaRを計算してみます。
ケンダールのVivariate 分布
P(C (U ,V))< t) = t - φ(t) /φ+(t) ->Kc(t)
GARCH-Copula フレームワーク
Rのパッケージでは、fGarchのパッケージを利用することができます。
fGarch, QRMから 期待ショートフォール(CVaR)を計算してみましょう。
以下のパッケージを読み込みます。
libraray(QRM)
library(fGarch)
>library(QRM)
要求されたパッケージ gsl をロード中です
要求されたパッケージ Matrix をロード中です
次のパッケージを付け加えます: ‘Matrix’
以下のオブジェクトは ‘package:tidyr’ からマスクされています:
expand, pack, unpack
要求されたパッケージ mvtnorm をロード中です
要求されたパッケージ numDeriv をロード中です
要求されたパッケージ timeSeries をロード中です
要求されたパッケージ timeDate をロード中です
次のパッケージを付け加えます: ‘timeDate’
以下のオブジェクトは ‘package:xtable’ からマスクされています:
align
次のパッケージを付け加えます: ‘timeSeries’
以下のオブジェクトは ‘package:zoo’ からマスクされています:
time<-
次のパッケージを付け加えます: ‘QRM’
以下のオブジェクトは ‘.GlobalEnv’ によってマスクされています:
DJ
以下のオブジェクトは ‘package:ismev’ からマスクされています:
gamGPDboot, gamGPDfit, GPD.predict
以下のオブジェクトは ‘package:fExtremes’ からマスクされています:
hillPlot
以下のオブジェクトは ‘package:evir’ からマスクされています:
hill
以下のオブジェクトは ‘package:base’ からマスクされています:
lbeta
メッセージが出力されることがあります。
R実行環境に多数パッケージがインストールされているため、バッティングする部分があるためです。
QRM以外のパッケージがインストールされていなければ、このメッセージは出力されません。
先に進めて次のパッケージ fGarch を読み込みます。
>
>library(fGarch)
NOTE: Packages 'fBasics', 'timeDate', and 'timeSeries' are no longer
attached to the search() path when 'fGarch' is attached.
If needed attach them yourself in your R script by e.g.,
require("timeSeries")
次のパッケージを付け加えます: ‘fGarch’
以下のオブジェクトは ‘package:TTR’ からマスクされています:
volatility
データとしてEUの市場データを使います。
data(EuStockMarkets)
loss <- as.data.frame(na.omit(-1.0 * diff(log(EuStockMarkets)) + * 100.0))
gfit <- lapply(loss,garchFit, formula = ~ garch(1,1), cond.dist = "std", trace=FALSE)
gprog <- unlist(lapply(gfit, function(x) predict(x,n.ahead=1)[3]))
gshape <- unlist(lapply(gfit, function(x) x@fit$coef[5]))
gresid <- as.matrix(data.frame(lapply(gfit, function(x) x@residuals / sqrt(x@h.t))))
U <-sapply(1:4, function(y) pt(gresid[,y], df=gshape[y]))
cop <- fit.tcopula(Udata = U, method = "Kendall")
rcop <-rcopula.t(100000, df=cop$nu,Sigma=cop$P)
qcop <- sapply(1:4, function(x) qstd(rcop[,x], nu=gshape[x]))
ht.mat <- matrix(gprog, nrow = 100000, ncol = ncol(loss), byrow = TRUE)
pf <- qcop * ht.mat
weights <- c(0.4,0.2,0.2,0.2)
pfall <- (qcop * ht.mat) %*% weights
pfall.es95 <- median(tail(sort(pfall), 5000))
pfall.es95
> data(EuStockMarkets)
> loss <- as.data.frame(na.omit(-1.0 * diff(log(EuStockMarkets))
+ * 100.0))
>
> gfit <- lapply(loss,garchFit, formula = ~ garch(1,1),
+ cond.dist = "std", trace=FALSE)
> gprog <- unlist(lapply(gfit, function(x)
+ predict(x,n.ahead=1)[3]))
> gshape <- unlist(lapply(gfit, function(x) x@fit$coef[5]))
> gresid <- as.matrix(data.frame(lapply(gfit,
+ function(x) x@residuals / sqrt(x@h.t))))
>
> U <-sapply(1:4, function(y) pt(gresid[,y], df=gshape[y]))
> cop <- fit.tcopula(Udata = U, method = "Kendall")
> rcop <-rcopula.t(100000, df=cop$nu,Sigma=cop$P)
> qcop <- sapply(1:4, function(x) qstd(rcop[,x], nu=gshape[x]))
> ht.mat <- matrix(gprog, nrow = 100000, ncol = ncol(loss),
+ byrow = TRUE)
> pf <- qcop * ht.mat
>
> weights <- c(0.4,0.2,0.2,0.2)
> pfall <- (qcop * ht.mat) %*% weights
> pfall.es95 <- median(tail(sort(pfall), 5000))
> pfall.es95
[1] 2.590697
>