示例#1
0
    def test_value_at_risk_lognormal(self):
        mu, sigma = 0, 1

        def f(x):
            return np.exp(x).T

        def VaR(p):
            return np.exp(mu + sigma * np.sqrt(2) * erfinv(2 * p - 1))

        mean = np.exp(mu + sigma**2 / 2)

        def CVaR(p):
            return mean * stats.norm.cdf(
                (mu + sigma**2 - np.log(VaR(p))) / sigma) / (1 - p)

        weights = None
        alpha = 0.8
        num_samples = int(1e6)
        samples = f(np.random.normal(0, 1, num_samples))
        xx = np.sort(samples)
        empirical_VaR, __ = value_at_risk(xx,
                                          alpha,
                                          weights,
                                          samples_sorted=True)
        # print(VaR(alpha),empirical_VaR)
        assert np.allclose(VaR(alpha), empirical_VaR, 1e-2)
示例#2
0
def conditional_value_at_risk_subgradient(samples,
                                          alpha,
                                          weights=None,
                                          samples_sorted=False):
    assert samples.ndim == 1 or samples.shape[1] == 1
    samples = samples.squeeze()
    num_samples = samples.shape[0]
    if weights is None:
        weights = np.ones(num_samples) / num_samples
    assert np.allclose(weights.sum(), 1)
    assert weights.ndim == 1 or weights.shape[1] == 1
    if not samples_sorted:
        II = np.argsort(samples)
        xx, ww = samples[II], weights[II]
    else:
        xx, ww = samples, weights
    VaR, index = value_at_risk(xx, alpha, ww, samples_sorted=True)
    grad = np.empty(num_samples)
    grad[:index] = 0
    grad[index] = 1 / (1 - alpha) * (weights[:index + 1].sum() - alpha)
    grad[index + 1:] = 1 / (1 - alpha) * weights[index + 1:]
    if not samples_sorted:
        # grad is for sorted samples so revert to original ordering
        grad = grad[np.argsort(II)]
    return grad
示例#3
0
    def test_weighted_value_at_risk_normal(self):
        mu, sigma = 1, 1
        # bias_mu,bias_sigma=1.0,1
        bias_mu, bias_sigma = mu, sigma

        from scipy.special import erf

        def VaR(alpha):
            return stats.norm.ppf(alpha, loc=mu, scale=sigma)

        def CVaR(alpha):
            vals = 0.5 * mu
            vals -= 0.5*mu*erf((VaR(alpha)-mu)/(np.sqrt(2)*sigma)) -\
                sigma*np.exp(-(mu-VaR(alpha))**2/(2*sigma**2))/np.sqrt(2*np.pi)
            vals /= (1 - alpha)
            return vals

        alpha = 0.8

        print(CVaR(alpha),
              cvar_gaussian_variable(stats.norm(loc=mu, scale=sigma), alpha))
        assert np.allclose(
            CVaR(alpha),
            cvar_gaussian_variable(stats.norm(loc=mu, scale=sigma), alpha))

        num_samples = int(1e5)
        samples = np.random.normal(bias_mu, bias_sigma, num_samples)
        target_pdf_vals = stats.norm.pdf(samples, loc=mu, scale=sigma)
        bias_pdf_vals = stats.norm.pdf(samples, loc=bias_mu, scale=bias_sigma)
        II = np.where(bias_pdf_vals < np.finfo(float).eps)[0]
        assert np.all(target_pdf_vals[II] < np.finfo(float).eps)
        J = np.where(bias_pdf_vals >= np.finfo(float).eps)[0]
        weights = np.zeros_like(target_pdf_vals)
        weights[J] = target_pdf_vals[J] / bias_pdf_vals[J]
        weights /= weights.sum()

        empirical_VaR, __ = value_at_risk(samples,
                                          alpha,
                                          weights,
                                          samples_sorted=False)
        # print('VaR',VaR(alpha),empirical_VaR)
        assert np.allclose(VaR(alpha), empirical_VaR, rtol=1e-2)

        empirical_CVaR = conditional_value_at_risk(samples, alpha, weights)
        # print('CVaR',CVaR(alpha),empirical_CVaR)
        assert np.allclose(CVaR(alpha), empirical_CVaR, rtol=1e-2)
示例#4
0
 def test_value_at_risk_normal(self):
     weights = None
     alpha = 0.8
     num_samples = int(1e2)
     samples = np.random.normal(0, 1, num_samples)
     # [np.random.permutation(num_samples)]
     samples = np.arange(1, num_samples + 1)
     # xx = np.sort(samples)
     # VaR,VaR_index = value_at_risk(xx,alpha,weights,samples_sorted=True)
     xx = samples
     VaR, VaR_index = value_at_risk(xx,
                                    alpha,
                                    weights,
                                    samples_sorted=False)
     sorted_index = int(np.ceil(alpha * num_samples) - 1)
     II = np.argsort(samples)
     index = II[sorted_index]
     print(index, VaR_index)
     assert np.allclose(VaR_index, index)
     assert np.allclose(VaR, xx[index])
    def help_check_smooth_conditional_value_at_risk(self, smoother_type, eps,
                                                    alpha):
        samples = np.linspace(-1, 1, 11)
        t = value_at_risk(samples, alpha)[0]
        x0 = np.hstack((samples, t))[:, None]
        errors = check_gradients(
            lambda xx: smooth_conditional_value_at_risk(
                smoother_type, eps, alpha, xx),
            lambda xx: smooth_conditional_value_at_risk_gradient(
                smoother_type, eps, alpha, xx), x0)
        assert errors.min() < 1e-6

        weights = np.random.uniform(1, 2, samples.shape[0])
        weights /= weights.sum()
        errors = check_gradients(
            lambda xx: smooth_conditional_value_at_risk(
                smoother_type, eps, alpha, xx, weights),
            lambda xx: smooth_conditional_value_at_risk_gradient(
                smoother_type, eps, alpha, xx, weights), x0)
        assert errors.min() < 1e-6
示例#6
0
def plot_lognormal_example_exact_quantities(
        num_samples=int(2e5), plot=False, mu=0, sigma=1):
    num_vars = 1
    if plot:
        assert num_samples <= 1e5
    else:
        assert num_samples >= 1e4

    f, f_cdf, f_pdf, VaR, CVaR, ssd, ssd_disutil = \
        get_lognormal_example_exact_quantities(mu, sigma)
    from pyapprox.low_discrepancy_sequences import transformed_halton_sequence
    # samples = np.random.normal(mu,sigma,(num_vars,num_samples))
    # values = f(samples)[:,0]
    samples = transformed_halton_sequence(
        [partial(stats.norm.ppf, loc=mu, scale=sigma)], num_vars, num_samples)
    values = f(samples)[:, 0]

    if plot:
        import matplotlib.pyplot as plt
        fig, axs = plt.subplots(1, 6, sharey=False, figsize=(16, 6))
        # from pyapprox.density import EmpiricalCDF
        ygrid = np.linspace(-1, 5, 100)
        # ecdf = EmpiricalCDF(values)
        # axs[0].plot(ygrid,ecdf(ygrid),'-')
        axs[0].plot(ygrid, f_cdf(ygrid), '--')
        # axs[0].set_xlim(ygrid.min(),ygrid.max())
        axs[0].set_title('CDF')
        # ecdf = EmpiricalCDF(-values)
        # axs[0].plot(-ygrid,ecdf(-ygrid),'-')

        ygrid = np.linspace(-1, 20, 100)
        # axs[1].hist(values,bins='auto',density=True)
        axs[1].plot(ygrid, f_pdf(ygrid), '--')
        axs[1].set_xlim(ygrid.min(), ygrid.max())
        axs[1].set_title('PDF')

    pgrid = np.linspace(1e-2, 1 - 1e-2, 100)
    evar = np.array([value_at_risk(values, p)[0] for p in pgrid])
    # print(np.linalg.norm(evar.squeeze()-VaR(pgrid),ord=np.inf))
    if plot:
        axs[2].plot(pgrid, evar, '-')
        axs[2].plot(pgrid, VaR(pgrid), '--')
        axs[2].set_title('VaR')
    else:
        assert np.allclose(evar.squeeze(), VaR(pgrid), atol=2e-1)

    pgrid = np.linspace(1e-2, 1 - 1e-2, 100)
    ecvar = np.array([conditional_value_at_risk(values, y) for y in pgrid])
    # print(np.linalg.norm(ecvar.squeeze()-CVaR(pgrid).squeeze(),ord=np.inf))
    print(CVaR(0.8))
    if plot:
        axs[3].plot(pgrid, ecvar, '-')
        axs[3].plot(pgrid, CVaR(pgrid), '--')
        axs[3].set_xlim(pgrid.min(), pgrid.max())
        axs[3].set_title('CVaR')
    else:
        assert np.allclose(ecvar.squeeze(), CVaR(pgrid).squeeze(), rtol=4e-2)

    # ygrid = np.linspace(-1,10,100)
    ygrid = np.linspace(stats.lognorm.ppf(0.0, np.exp(mu), sigma),
                        stats.lognorm.ppf(0.9, np.exp(mu), sigma), 101)
    essd = compute_conditional_expectations(ygrid, values, False)
    # print(np.linalg.norm(essd.squeeze()-ssd(ygrid),ord=np.inf))
    if plot:
        axs[4].plot(ygrid, essd, '-')
        axs[4].plot(ygrid, ssd(ygrid), '--')
        axs[4].set_xlim(ygrid.min(), ygrid.max())
        axs[4].set_title(r'$E[(\eta-Y)^+]$')
        axs[4].set_xlabel(r'$\eta$')
    else:
        assert np.allclose(essd.squeeze(), ssd(ygrid), atol=1e-3)

    # zoom into ygrid over high probability region of -Y
    ygrid = -ygrid[::-1]
    disutil_essd = compute_conditional_expectations(ygrid, values, True)
    assert np.allclose(disutil_essd,
                       compute_conditional_expectations(ygrid, -values, False))
    # print(np.linalg.norm(disutil_essd.squeeze()-ssd_disutil(ygrid),ord=np.inf))
    if plot:
        axs[5].plot(ygrid, disutil_essd, '-', label='Empirical')
        axs[5].plot(ygrid, ssd_disutil(ygrid), '--', label='Exact')
        axs[5].set_xlim((ygrid).min(), (ygrid).max())
        axs[5].set_title(r'$E[(\eta-(-Y))^+]$')
        axs[5].set_xlabel(r'$\eta$')
        axs[5].plot([0], [np.exp(mu + sigma**2 / 2)], 'o')
        axs[5].legend()
        plt.show()
    else:
        assert np.allclose(disutil_essd.squeeze(),
                           ssd_disutil(ygrid),
                           atol=1e-3)
示例#7
0
def plot_truncated_lognormal_example_exact_quantities(num_samples=int(1e5),
                                                      plot=False,
                                                      mu=0,
                                                      sigma=1):
    if plot:
        assert num_samples <= 1e5

    lb, ub = -1, 3

    f, f_cdf, f_pdf, VaR, CVaR, ssd, ssd_disutil = \
        get_truncated_lognormal_example_exact_quantities(lb, ub, mu, sigma)
    # lb,ub passed to stats.truncnorm are defined for standard normal.
    # Adjust for mu and sigma using
    alpha, beta = (lb - mu) / sigma, (ub - mu) / sigma
    samples = stats.truncnorm.rvs(alpha, beta, mu, sigma,
                                  size=num_samples)[np.newaxis, :]
    values = f(samples)[:, 0]

    ygrid = np.linspace(np.exp(lb) - 1, np.exp(ub) * 1.1, 100)
    if plot:
        import matplotlib.pyplot as plt
        fig, axs = plt.subplots(1, 6, sharey=False, figsize=(16, 6))
        from pyapprox.density import EmpiricalCDF
        ecdf = EmpiricalCDF(values)
        axs[0].plot(ygrid, ecdf(ygrid), '-')
        axs[0].plot(ygrid, f_cdf(ygrid), '--')
        axs[0].set_xlim(ygrid.min(), ygrid.max())
        axs[0].set_title('CDF')

    if plot:
        ygrid = np.linspace(np.exp(lb) - 1, np.exp(ub) * 1.1, 100)
        axs[1].hist(values, bins='auto', density=True)
        axs[1].plot(ygrid, f_pdf(ygrid), '--')
        axs[1].set_xlim(ygrid.min(), ygrid.max())
        axs[1].set_title('PDF')

    pgrid = np.linspace(0.01, 1 - 1e-2, 10)
    evar = np.array([value_at_risk(values, p)[0] for p in pgrid]).squeeze()
    if plot:
        axs[2].plot(pgrid, evar, '-')
        axs[2].plot(pgrid, VaR(pgrid), '--')
        axs[2].set_title('VaR')
    else:
        assert np.allclose(evar, VaR(pgrid), rtol=2e-2)

    pgrid = np.linspace(0, 1 - 1e-2, 100)
    ecvar = np.array([conditional_value_at_risk(values, p) for p in pgrid])
    # CVaR for alpha=0 should be the mean
    assert np.allclose(ecvar[0], values.mean())
    if plot:
        axs[3].plot(pgrid, ecvar, '-')
        axs[3].plot(pgrid, CVaR(pgrid), '--')
        axs[3].set_xlim(pgrid.min(), pgrid.max())
        axs[3].set_title('CVaR')
    else:
        assert np.allclose(ecvar.squeeze(), CVaR(pgrid).squeeze(), rtol=1e-2)

    ygrid = np.linspace(np.exp(lb) - 10, np.exp(ub) + 1, 100)
    essd = compute_conditional_expectations(ygrid, values, False)
    if plot:
        axs[4].plot(ygrid, essd, '-')
        axs[4].plot(ygrid, ssd(ygrid), '--')
        axs[4].set_xlim(ygrid.min(), ygrid.max())
        axs[4].set_title(r'$E[(\eta-Y)^+]$')
        axs[5].set_xlabel(r'$\eta$')
    else:
        assert np.allclose(essd.squeeze(), ssd(ygrid), rtol=2e-2)

    # zoom into ygrid over high probability region of -Y
    ygrid = -ygrid[::-1]
    disutil_essd = compute_conditional_expectations(ygrid, values, True)
    assert np.allclose(disutil_essd,
                       compute_conditional_expectations(ygrid, -values, False))
    # print(np.linalg.norm(disutil_essd.squeeze()-ssd_disutil(ygrid),ord=np.inf))
    if plot:
        axs[5].plot(ygrid, disutil_essd, '-', label='Empirical')
        axs[5].plot(ygrid, ssd_disutil(ygrid), '--', label='Exact')
        axs[5].set_xlim(ygrid.min(), ygrid.max())
        axs[5].set_title(r'$E[(\eta-(-Y))^+]$')
        axs[5].set_xlabel(r'$\eta$')
        axs[5].legend()

        plt.show()