"""RN-05 v1.3: population sensitivity of an invented loss mixture. Run: python tail_sensitivity_v1_3.py > tail_sensitivity_results_v1_3.json Requires NumPy and SciPy. Reads no files or network resources. All units and probabilities are synthetic. This is not a backtest. """ import json import platform import numpy as np import scipy from scipy.integrate import quad from scipy.optimize import brentq, minimize, approx_fprime from scipy.stats import norm ALPHA, CAP = .99, .80 COMMON = .20 RESIDUAL = np.array([.35, .95, .65]) JUMP = np.array([4., 0., 1.5]) def components(w, p): sd = np.sqrt(COMMON**2 * w.sum()**2 + np.sum((RESIDUAL*w)**2)) multipliers = np.array([-p, 1-p]) return np.array([1-p, p]), multipliers*(JUMP@w), sd, multipliers def ru(x, p): w, eta = x[:3], x[3] probs, means, sd, multipliers = components(w, p) z = (eta-means)/sd sf, pdf = norm.sf(z), norm.pdf(z) value = eta + probs@(sd*pdf+(means-eta)*sf)/(1-ALPHA) dsd = (COMMON**2*w.sum() + RESIDUAL**2*w)/sd dw = ((probs*sf)@multipliers*JUMP + (probs@pdf)*dsd)/(1-ALPHA) deta = 1 - probs@sf/(1-ALPHA) return float(value), np.r_[dw, deta] def population_risk(w, p): probs, means, sd, _ = components(w, p) eta = brentq(lambda t: probs@norm.cdf((t-means)/sd)-ALPHA, min(means)-12*sd, max(means)+12*sd, xtol=1e-13) z = (eta-means)/sd es = probs@(means*norm.sf(z)+sd*norm.pdf(z))/(1-ALPHA) # Independent numerical integration of loss times the mixture density. integrated = sum(prob*quad(lambda t: t*norm.pdf((t-mean)/sd)/sd, eta, np.inf, epsabs=1e-11)[0] for prob, mean in zip(probs, means))/(1-ALPHA) assert abs(es-integrated) < 1e-8 variance = sd**2 + p*(1-p)*(JUMP@w)**2 return float(eta), float(es), float(np.sqrt(variance)), float(abs(es-integrated)) def kkt(w, gradient): interior = (w>1e-7)&(w=CAP-1e-7, np.maximum(gradient-level, 0), np.abs(gradient-level))) error = float(errors.max()) assert abs(w.sum()-1)<1e-9 and w.min()>-1e-9 and w.max()