Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
braverock
GitHub Repository: braverock/portfolioanalytics
Path: blob/master/sandbox/FFEV/HermiteGrid_CaseStudy.R
1433 views
1
# This script estimates the prior of a hedge fund return and processes extreme views on CVaR
2
# according to Entropy Pooling
3
# This script complements the article
4
# "Fully Flexible Extreme Views"
5
# by A. Meucci, D. Ardia, S. Keel
6
# available at www.ssrn.com
7
# The most recent version of this code is available at
8
# MATLAB Central - File Exchange
9
10
# IMPORTANT - This script is about the methodology, not the input data, which has been modified
11
12
xi = as.matrix( 100 * data[, 2] )
13
n = nrow(xi)
14
15
# bandwidth
16
bw = kernelbw(xi)
17
18
# weights
19
lambda = log(2) / (n / 2)
20
wi = as.matrix( exp( -lambda * ( n - seq( from=n, to=1 ) ) ) )
21
wi = as.matrix( apply( wi, 2, rev ) / sum( wi ) )
22
23
# Prior market model
24
# kernel density
25
26
market.mu = mean(xi)
27
market.pdf = function ( x ) kernelpdf( x, xi, bw, wi )
28
market.cdf = function ( x ) kernelcdf( x, xi, bw, wi )
29
market.inv = function ( x ) kernelinv( x, xi, bw, wi )
30
market.VaR95 = market.inv( c(0.05) )
31
market.CVaR95 = integrate( function( x ) x * market.pdf( x ), -100, market.VaR95 )$val / 0.05
32
33
# numerical (Gauss-Hermite grid) prior
34
tmp = ( ghqx - min( ghqx ) )/( max( ghqx ) - min( ghqx ) ) # rescale GH zeros so they belong to [0,1]
35
epsilon = 1e-10
36
Lower = market.inv( epsilon )
37
Upper = market.inv( 1 - epsilon )
38
X = Lower + tmp * ( Upper - Lower ) # rescale mesh
39
40
p = integrateSubIntervals( X , market.cdf )
41
p = normalizeProb( p )
42
J = nrow( X )
43
44
# Entropy posterior from extreme view on mean and CVaR
45
view.mu = mean( xi ) - 1.0
46
view.CVaR95 = market.CVaR95 - 1.0
47
48
# Netwton Raphson
49
emptyMatrix = matrix( ,nrow = 0, ncol = 0)
50
s = emptyMatrix
51
idx = as.matrix( cumsum(p) <= 0.05 )
52
s[1] = sum(idx)
53
posteriorEntropy = EntropyProg(p, t( idx ), as.matrix( 0.05 ), rbind( rep(1, J), t( X ), t( idx * X ) ), rbind( 1, view.mu, 0.05 * view.CVaR95) )
54
KLdiv = as.matrix( posteriorEntropy$optimizationPerformance$ml )
55
p_ = posteriorEntropy$p_
56
57
doStop = 0
58
i = 1
59
while ( !doStop ) {
60
i = i + 1
61
62
idx = cbind( matrix(1, 1, s[i - 1] ), matrix(0, 1, J - s[i-1] ) )
63
posteriorEntropy1 = EntropyProg(p, idx, as.matrix( 0.05 ), rbind( matrix(1, 1, J), t( X ), t( t(idx) * X) ), rbind( 1, view.mu, 0.05 * view.CVaR95 ) )
64
# [dummy, KLdiv_s] = optimizeEntropy(p, [idx'; (idx .* X)'], [0.05; 0.05 * view.CVaR95], [ones(1, J); X'], [1; view.mu]);
65
66
idx = cbind( matrix(1, 1, s[i - 1] + 1 ), matrix(0, 1, J - s[i - 1] - 1) )
67
posteriorEntropy2 = EntropyProg(p, idx, as.matrix( 0.05 ), rbind( matrix(1, 1, J), t( X ), t( t(idx) * X) ), rbind( 1, view.mu, 0.05 * view.CVaR95 ) )
68
# [dummy, KLdiv_s1] = optimizeEntropy(p, [idx'; (idx .* X)'], [0.05; 0.05 * view.CVaR95], [ones(1, J); X'], [1; view.mu]);
69
70
idx = cbind( matrix(1, 1, s[i - 1] + 2 ), matrix(0, 1, J - s[i - 1] - 2) )
71
posteriorEntropy3 = EntropyProg(p, idx, as.matrix( 0.05 ), rbind( matrix(1, 1, J), t( X ), t( t(idx) * X) ), rbind( 1, view.mu, 0.05 * view.CVaR95 ) )
72
# [dummy, KLdiv_s2] = optimizeEntropy(p, [idx'; (idx .* X)'], [0.05; 0.05 * view.CVaR95], [ones(1, J); X'], [1; view.mu]);
73
74
# first difference
75
DE = posteriorEntropy2$optimizationPerformance$ml - posteriorEntropy1$optimizationPerformance$ml
76
77
# second difference
78
D2E = posteriorEntropy3$optimizationPerformance$ml - 2 * posteriorEntropy2$optimizationPerformance$ml + posteriorEntropy1$optimizationPerformance$ml
79
80
# optimal s
81
s = rbind( s, round( s[i - 1] - (DE / D2E) ) )
82
83
tmp = emptyMatrix
84
idx = cbind( matrix( 1, 1, s[i] ), matrix( 0, 1, J - s[i] ) )
85
tempEntropy = EntropyProg(p, idx, as.matrix( 0.05 ), rbind( matrix(1, 1, J), t( X ), t( t(idx) * X) ), rbind( 1, view.mu, 0.05 * view.CVaR95 ) )
86
# [tmp.p_, tmp.KLdiv] = optimizeEntropy(p, [idx'; (idx .* X)'], [0.05; 0.05 * view.CVaR95], [ones(1, J); X'], [1; view.mu]);
87
p_ = cbind( p_, tempEntropy$p_ )
88
KLdiv = rbind( KLdiv, tempEntropy$optimizationPerformance$ml ) #ok<*AGROW>
89
90
# if change in KLdiv less than one percent, stop
91
if( abs( ( KLdiv[i] - KLdiv[i - 1] ) / KLdiv[i - 1] ) < 0.01 ) { doStop = 1 }
92
}
93
94
plot( t(X), p )
95
plot( t(X), p_[,ncol(p_)])
96