alpha = np.random.uniform(0, 1) beta = np.random.uniform(0, 1, size=n_) gamma = np.random.uniform(0, 1, size=(n_, n_)) gamma = (gamma + gamma.T) / 2 # make gamma symmetric and positive (semi)definite mu = np.random.uniform(0, 1, size=n_) sigma = np.random.uniform(0, 1, size=(n_, n_)) sigma2 = sigma @ sigma.T # make sigma2 positive definite # ## [Step 1](https://www.arpm.co/lab/redirect.php?permalink=s_saddle_point_vs_mcfp_quadn-implementation-step01): Generate quadratic-normal scenarios y, p_ = simulate_quadn(alpha, beta, gamma, mu, sigma2, j_) # ## [Step 2](https://www.arpm.co/lab/redirect.php?permalink=s_saddle_point_vs_mcfp_quadn-implementation-step02): Compute the saddle point approximation of the pdf y_grid = np.linspace(quantile_sp(0.001, y, p_), quantile_sp(0.999, y, p_), 500) cdf, pdf = saddle_point_quadn(y_grid, alpha, beta, gamma, mu, sigma2) # ## [Step 3](https://www.arpm.co/lab/redirect.php?permalink=s_saddle_point_vs_mcfp_quadn-implementation-step03): Compute Calculate the heights and bin centers of the normalized empirical histogram f_hat, grid = histogram_sp(y, p=p_, k_=200) # ## Plots # + plt.style.use('arpm') darkred = [.9, 0, 0] lightgrey = [.8, .8, .8] plt.figure() mydpi = 72.0 f = plt.figure(figsize=(1280.0 / mydpi, 720.0 / mydpi), dpi=mydpi)
# ## [Step 2](https://www.arpm.co/lab/redirect.php?permalink=s_checklist_scenariobased_step04-implementation-step02): Projection of invariants # + epsi_proj = np.zeros((j_, m_, i_)) for m in range(m_): # copula scenarios # simulate standardized invariants scenarios for copula epsi_tilde_proj = simulate_t(np.zeros(i_), rho2_copula, nu_copula, j_) # generate invariants scenarios # invariants modeled nonparametrically for i in ind_nonparametric: # project t-copula standardized invariants scenarios u_proj = tstu.cdf(epsi_tilde_proj[:, i], nu_copula) epsi_proj[:, m, i] = quantile_sp(u_proj, epsi[:, i], p_marginal[:, i]) # invariants modeled parametrically (estimated as Student t distributed) for i in ind_parametric: # project t-copula standardized invariants scenarios u_proj = tstu.cdf(epsi_tilde_proj[:, i], nu_copula) mu_marg = db_estimation_parametric.loc['mu', str(i)] sig2_marg = db_estimation_parametric.loc['sig2', str(i)] nu_marg = db_estimation_parametric.loc['nu', str(i)] epsi_proj[:, m, i] = mu_marg + np.sqrt(sig2_marg) * tstu.ppf( u_proj, nu_marg) # - # ## [Step 3](https://www.arpm.co/lab/redirect.php?permalink=s_checklist_scenariobased_step04-implementation-step03): Projection of risk drivers # + x_proj = np.zeros((j_, m_ + 1, d_))
# ## [Step 1](https://www.arpm.co/lab/redirect.php?permalink=s_evaluation_cornishfisher_stocks-implementation-step01): Ex ante P&L mean, standard deviation and skewness mu_pl_h, sd_pl_h, sk_pl_h = moments_logn(h, mu_pl, sig2_pl, v_tnow) # ## [Step 2](https://www.arpm.co/lab/redirect.php?permalink=s_evaluation_cornishfisher_stocks-implementation-step02): Cornish-Fisher approximation q_cf = cornish_fisher(mu_pl_h, sd_pl_h, sk_pl_h, 1 - c) # ## [Step 3](https://www.arpm.co/lab/redirect.php?permalink=s_evaluation_cornishfisher_stocks-implementation-step03): Scenario-probability quantile # + # Monte carlo scenarios for the portfolio's P&L pl_h = h @ pl.T # scenario-probability quantile q_sp = quantile_sp(1 - c, pl_h) # - # ## Plots # + plt.style.use('arpm') lgray = [.8, .8, .8] # light gray dgray = [.7, .7, .7] # dark gray fig = plt.figure() # histogram of the portfolio's ex-ante P&L j_ = pl_h.shape[0] n_bins = np.round(10 * np.log(j_)) # number of histogram bins y_hist, x_hist = histogram_sp(pl_h, p=1 / j_ * np.ones(j_), k_=n_bins)
# language: python # name: python3 # --- # # s_scen_prob_quantile [<img src="https://www.arpm.co/lab/icons/icon_permalink.png" width=30 height=30 style="display: inline;">](https://www.arpm.co/lab/redirect.php?code=s_scen_prob_quantile&codeLang=Python) # For details, see [here](https://www.arpm.co/lab/redirect.php?permalink=eb-univ-fpcase-stud). # + import numpy as np from arpym.statistics import quantile_sp # - # ## [Input parameters](https://www.arpm.co/lab/redirect.php?permalink=s_scen_prob_quantile-parameters) # + k_ = 99 x = np.array([1, 2, 0]) p = np.array([0.31, 0.07, 0.62]) c_ = np.linspace(0.01, 0.99, k_) # - # ## [Step 1](https://www.arpm.co/lab/redirect.php?permalink=s_scen_prob_quantile-implementation-step01): Compute quantile q_x_c = quantile_sp(c_, x, p) # ## [Step 2](https://www.arpm.co/lab/redirect.php?permalink=s_scen_prob_quantile-implementation-step02): Compute the median med_x = quantile_sp(0.5, x, p)
# number of grid points i_ = 50 # grid points r_sandp_min, r_sandp_max = r_sandp.min(), r_sandp.max() z_grid = np.linspace(r_sandp_min, r_sandp_max, i_) # kernel bandwidth h = (r_sandp_max - r_sandp_min)/100 # smoothing parameter gamma = 2 # compute quantile regression predictor on the grid q_r_call_tnow_thor_given_z_grid = np.ones(i_)*np.nan for i, z_i in enumerate(z_grid): # smooth kernel conditional probabilities p_given_z_i = smooth_kernel_fp(r_sandp,z_i,h,gamma) # compute the quantile of the conditioned distribution q_r_call_tnow_thor_given_z_grid[i] = quantile_sp(np.array([c]), r_call, p_given_z_i) # compute quantile regression predictor as piecewise linear interpolation through def chi(z): return np.interp(z, z_grid, q_r_call_tnow_thor_given_z_grid) # - # ## [Step 3](https://www.arpm.co/lab/redirect.php?permalink=s_call_quant_regression-implementation-step03): Evaluate prediction and residuals r_bar_call = chi(r_sandp) # prediction u = r_call-r_bar_call # residuals # ## [Step 4](https://www.arpm.co/lab/redirect.php?permalink=s_call_quant_regression-implementation-step04): Compute payoff at t_end and current value of the call option as a function of the underlying S&P500 # + i_ = 50
return -np.exp(-lam * y) # inverse exponential utility function def ce_f(z, lam): return -(1 / lam) * np.log(-z) utility_r_h = exp_utility_f(r_h, lam_2) # utility mu_utility = utility_r_h @ p # expected utility computation cert_eq_r_h = ce_f(mu_utility, lam_2) # certainty-equivalent] # - # ## [Step 5](https://www.arpm.co/lab/redirect.php?permalink=s_evaluation_satis_scenprob-implementation-step05): Compute the quantile (VaR) q_r_h = quantile_sp(1 - c, r_h, p=p) # ## [Step 6](https://www.arpm.co/lab/redirect.php?permalink=s_evaluation_satis_scenprob-implementation-step06): Compute the Expected shortfall # + # compute expected shortfall using spectral_index # indicator function def indicator(x): return (0 <= x and x <= 1 - c) # spectrum function def spectr_es(x): return (1 / (1 - c)) * indicator(x)
# - # ## [Step 1](https://www.arpm.co/lab/redirect.php?permalink=s_checklist_scenariobased_step07-implementation-step01): Calculate certainty equivalent satisfaction measure # + # expected utility expected_utility = p @ (-np.exp(-lam * y_h)) # expected utility computation # certainty equivalent satisfaction measure cert_eq_yh = -(1 / lam) * np.log(-expected_utility) # - # ## [Step 2](https://www.arpm.co/lab/redirect.php?permalink=s_checklist_scenariobased_step07-implementation-step02): Quantile satisfaction measure # quantile q_yh = quantile_sp(1 - c_quantile, y_h, p, method='kernel_smoothing') # ## [Step 3](https://www.arpm.co/lab/redirect.php?permalink=s_checklist_scenariobased_step07-implementation-step03): Expected shortfall satisfaction measure # + # indicator function def indicator(x): return (0 <= x and x <= 1 - c_es) # spectrum function def spectr_es(x): return (1 / (1 - c_es)) * indicator(x)