Beispiel #1
0
def get_lsmc_values(setups, nsims=5000):

    values = []
    errors = []
    for num_setting in setups:
        log_debug(num_setting, 'setting')

        ######### load setting

        ret = get_setting(num_setting)
        val_date = ret['val_date']
        dates = ret['dates']
        cons = ret['cons']
        model_params = ret['model_params']
        fwd_curve = ret['fwd_curve']
        Fc_mean = ret['Fc_mean']
        delta_F = ret['delta_F']

        Te = calcTe(val_date, dates)
        Te_ext = np.append(Te, Te[-1] + 1. / 365.)
        nTe = Te.size
        fwd_array = fwd_curve.values

        Te = calcTe(val_date, dates)
        fwd_array = fwd_curve.values

        ########## run instrinsic
        results, TP = run_one_valuation_intrinsic(Te, fwd_array, cons)

        cashflows = results['cashflows'].spot + results['cashflows'].opex
        mean_cf = cashflows.mean(axis=1)
        intr_value = mean_cf.sum()

        ########## run lsmc
        stoch_value, stoch_value_error = run_valuation_stochastic(val_date,
                                                                  dates,
                                                                  fwd_curve,
                                                                  cons,
                                                                  model_params,
                                                                  nsims=nsims)
        time_value = stoch_value - intr_value

        log_debug("stoch value = {:.4g} +- {:.4g}".format(
            stoch_value, stoch_value_error))
        log_debug("time value = {:.4g} +- {:.4g}".format(
            time_value, stoch_value_error))
        values.append(time_value)
        errors.append(stoch_value_error)
    return np.array(values), np.array(errors)
def get_lsmc_values(setups, nsims=5000):

    values = []
    errors = []
    for num_setting in setups:
        log_debug(num_setting, "setting")

        ######### load setting

        ret = get_setting(num_setting)
        val_date = ret["val_date"]
        dates = ret["dates"]
        cons = ret["cons"]
        model_params = ret["model_params"]
        fwd_curve = ret["fwd_curve"]
        Fc_mean = ret["Fc_mean"]
        delta_F = ret["delta_F"]

        Te = calcTe(val_date, dates)
        Te_ext = np.append(Te, Te[-1] + 1.0 / 365.0)
        nTe = Te.size
        fwd_array = fwd_curve.values

        Te = calcTe(val_date, dates)
        fwd_array = fwd_curve.values

        ########## run instrinsic
        results, TP = run_one_valuation_intrinsic(Te, fwd_array, cons)

        cashflows = results["cashflows"].spot + results["cashflows"].opex
        mean_cf = cashflows.mean(axis=1)
        intr_value = mean_cf.sum()

        ########## run lsmc
        stoch_value, stoch_value_error = run_valuation_stochastic(
            val_date, dates, fwd_curve, cons, model_params, nsims=nsims
        )
        time_value = stoch_value - intr_value

        log_debug("stoch value = {:.4g} +- {:.4g}".format(stoch_value, stoch_value_error))
        log_debug("time value = {:.4g} +- {:.4g}".format(time_value, stoch_value_error))
        values.append(time_value)
        errors.append(stoch_value_error)
    return np.array(values), np.array(errors)
def run_valuation_stochastic(val_date, dates, fwd_curve, cons, model_params, nsims=5000):
    """
    Calculate stochastic storage with simple constraints

    Parameters
    ----------
    Te  :       maturities

    fwd_array:

    cons :  tuple
        (max_inv, min_inv, start_inv, end_inv, inj_cost, rel_cost, rmin, rmax)

    Returns
    -------

    """

    max_inv = cons.max_inv
    min_inv = cons.min_inv
    start_inv = cons.start_inv
    end_inv = cons.end_inv
    inj_cost = cons.inj_cost
    rel_cost = cons.rel_cost
    rmin = cons.rmin
    rmax = cons.rmax

    sigma_1 = model_params.sigma_1
    sigma_2 = model_params.sigma_2
    alpha_1 = model_params.alpha_1
    alpha_2 = model_params.alpha_2
    rho = model_params.rho

    alphas = [alpha_1, alpha_2]
    sigmas = [sigma_1, sigma_2]

    Te = calcTe(val_date, dates)

    fc = FlowConstraint(rmin, rmax)
    flow_constraints = FlowConstraints(Te[0], fc)

    inv_constraints = InventoryConstraints(Te, start_inv, end_inv, max_inv, min_inv, [flow_constraints])
    state_object = StateObject(inv_constraints, num_levels=None)
    ls_solver_params = AttrDict(max_basis_order=4, solver="RegularisedLeastSquaresSolver")
    product = LeastSquaresMonteCarloEngine(
        state_object, StorageCashflows(Te, injection_cost=inj_cost, withdrawal_cost=rel_cost), ls_solver_params
    )

    seed = 123
    simulator = MultiFactorSimulator(alphas, sigmas, fwd_curve, rho, val_date, seed=seed)
    sims_bwd = simulator.simulate_spot(dates, nsims).values
    factors_bwd = simulator.stoch_factors
    sims_fwd = simulator.simulate_spot(dates, nsims).values
    factors_fwd = simulator.stoch_factors

    results = product.calc_extrinsic(sims_bwd, sims_fwd, factors_bwd, factors_fwd)
    cashflows = (results["cashflows"].spot + results["cashflows"].opex).sum(axis=0)
    value = cashflows.mean()
    value_std = cashflows.std()
    value_error = value_std / np.sqrt(nsims)

    return value, value_error
def get_formula_values(cut_off_params, setups):

    wmin_steps = cut_off_params["wmin_steps"]
    k_thr = cut_off_params["k_thr"]
    correction_weight = cut_off_params["correction_weight"]

    values = []
    for num_setting in setups:

        start_time0 = log_function_enter("setting {}".format(num_setting))

        ret = get_setting(num_setting)
        val_date = ret["val_date"]
        dates = ret["dates"]
        cons = ret["cons"]
        model_params = ret["model_params"]
        fwd_curve = ret["fwd_curve"]
        Fc_mean = ret["Fc_mean"]
        delta_F = ret["delta_F"]

        Te = calcTe(val_date, dates)
        Te_ext = np.append(Te, Te[-1] + 1.0 / 365.0)
        nTe = Te.size
        fwd_array = fwd_curve.values

        # estimate mean forward curve and gradient upper bound

        F0_mean = fwd_array.mean()
        dt = 1.0 / 365.0
        dFdt = np.gradient(fwd_array, dt)
        F_grad_max = abs(dFdt).max()

        results, TP = run_one_valuation_intrinsic(Te, fwd_array, cons)
        mean_actions = results.actions.mean(axis=1)

        levels = np.empty(nTe + 1, dtype=float)
        levels[0] = cons.start_inv
        levels[1:] = cons.start_inv + np.cumsum(mean_actions)

        minor_sticks = []
        for t in range(nTe)[1:]:
            if mean_actions[t] != mean_actions[t - 1]:
                minor_sticks.append(Te[t])

        triggers = calculate_trigger_prices2(TP["dVdq"], Te, fwd_array, mean_actions, cons)

        #############################################################
        if Te_ext[0] > 0:
            Num_0_Ta = Te_ext[0] * 365.0
            tenors_0_Ta = np.linspace(0.0, Te_ext[0], Num_0_Ta + 1)
            tenors_0_Tb = np.append(tenors_0_Ta, Te_ext[1:])
        else:
            tenors_0_Tb = Te_ext

        integration_dt = np.diff(tenors_0_Tb)

        triggers_matrix = np.hstack(
            (
                triggers.trigger_prices_upper.reshape(-1, 1),
                triggers.trigger_prices_lower.reshape(-1, 1),
                fwd_array.reshape(-1, 1),
            )
        )
        trigger_interpolator = Interpolate1D(Te, triggers_matrix, kind="linear")

        num_time_steps = tenors_0_Tb.size

        rmax = cons.rmax
        rmin = cons.rmin

        rmax *= 365
        rmin *= 365

        time_value1 = 0

        time_value_evolution = np.zeros(num_time_steps)

        I1_evolution1 = np.zeros(num_time_steps - 1)
        I2_evolution1 = np.zeros(num_time_steps - 1)
        mu_evolution1 = np.zeros(num_time_steps - 1)

        start_time = log_function_enter("integration time loop")
        for n in range(num_time_steps - 1):

            # log_debug('time step {} of {}'.format(n, num_time_steps - 1), std_out=False)
            t = tenors_0_Tb[n]
            tm = max(t, Te[0])
            Tb = tenors_0_Tb[-1]
            dt = 1.0 / 365.0
            num_steps = int(np.round((Tb - tm) / dt))
            num_steps *= 5.0
            tenors = np.linspace(tm, Tb, num_steps + 1)

            # log_debug(t*365., 't*365')

            C_all = trigger_interpolator.evaluate(tenors).reshape(-1, 3).T
            C_u = C_all[0]
            C_d = C_all[1]
            F0 = C_all[2]

            params = dict()
            params["n"] = n
            params["t"] = t
            params["tenors"] = tenors
            params["model_params"] = model_params
            params["C_u"] = C_u
            params["C_d"] = C_d
            params["F0"] = F0
            params["rmax"] = rmax
            params["rmin"] = rmin
            params["F0_mean"] = F0_mean
            params["F_grad_max"] = F_grad_max

            add_params = dict()
            add_params["wmin_steps"] = wmin_steps
            add_params["k_thr"] = k_thr
            add_params["correction_weight"] = correction_weight

            mu_1, I1_1, I2_1 = calculate_mu_bar(params, add_params)

            time_value1 += mu_1 * integration_dt[n]
            time_value_evolution[n + 1] = time_value1

            # log_debug(mu_1, 'mu_1')
            # log_debug(I1_1, 'I1_1')
            # log_debug(I2_1, 'I2_1')
            # log_debug(time_value1, 'time value 1')

            I1_evolution1[n] = I1_1
            I2_evolution1[n] = I2_1
            mu_evolution1[n] = mu_1

        log_function_exit("integration time loop", start_time=start_time)
        log_debug(time_value1, "final time_value")
        # print "approximated time value1 = {:.4g}".format(time_value1)
        values.append(time_value1)
        log_function_exit("setting {}".format(num_setting), start_time=start_time0)
    return np.array(values)
def test_formula(nsims=None):

    # val_date, dates, cons, model_params, fwd_curve, Fc, delta_F = setting_1()
    # val_date, dates, cons, model_params, fwd_curve, Fc, delta_F = setting_2()
    val_date, dates, cons, model_params, fwd_curve, Fc, delta_F = setting_3()

    Te = calcTe(val_date, dates)
    Te_ext = np.append(Te, Te[-1] + 1.0 / 365.0)
    nTe = Te.size
    fwd_array = fwd_curve.values

    # estimate mean forward curve and gradient upper bound

    F0_mean = fwd_array.mean()
    dt = 1.0 / 365.0
    dFdt = np.gradient(fwd_array, dt)
    F_grad_rms = rms(dFdt)
    F_grad_max = abs(dFdt).max()

    results, TP = run_one_valuation_intrinsic(Te, fwd_array, cons)

    cashflows = results["cashflows"].spot + results["cashflows"].opex
    mean_cf = cashflows.mean(axis=1)
    value = mean_cf.sum()
    mean_actions = results.actions.mean(axis=1)
    print "intrinsic value = {}".format(value)

    levels = np.empty(nTe + 1, dtype=float)
    levels[0] = cons.start_inv
    levels[1:] = cons.start_inv + np.cumsum(mean_actions)

    minor_sticks = []
    for t in range(nTe)[1:]:
        if mean_actions[t] != mean_actions[t - 1]:
            minor_sticks.append(Te[t])

    triggers = calculate_trigger_prices2(TP["dVdq"], Te, fwd_array, mean_actions, cons)
    # triggers = calculate_trigger_prices(TP['dVdq'], Te, fwd_array, mean_actions, cons)

    log_debug(Te, "Te")
    log_debug(Te * 365.0, "Te*365")
    log_debug(fwd_array, "fwd_array")
    log_debug(triggers.trigger_prices_upper, "trigger_prices_upper")
    log_debug(triggers.trigger_prices_lower, "trigger_prices_lower")
    log_debug(triggers.tt_up * 365.0, "tt_up*365")
    log_debug(triggers.tt_down * 365.0, "tt_down*365")
    log_debug(triggers.fdot_up, "fdot_up")
    log_debug(triggers.fdot_down, "fdot_down")

    if nsims is not None and nsims > 0:
        stoch_value, stoch_value_error = run_valuation_stochastic(
            val_date, dates, fwd_curve, cons, model_params, nsims=nsims
        )
        print "stoch value = {:.4g} +- {:.4g}".format(stoch_value, stoch_value_error)
        print "time value = {:.4g} +- {:.4g}".format(stoch_value - value, stoch_value_error)

    plt.close("all")
    plt.figure()
    plt.plot(Te, fwd_array, "o-", linewidth=1, markersize=2)
    plt.plot(Te_ext, levels)
    plt.plot(Te, triggers.trigger_prices, "o-", linewidth=1, markersize=2)
    plt.plot(Te, triggers.trigger_prices_upper, "--", linewidth=1)
    plt.plot(Te, triggers.trigger_prices_lower, "--", linewidth=1)
    ax = plt.gca()
    # start, end = ax.get_xlim()
    ax.xaxis.set_ticks(minor_sticks, minor=True)
    plt.grid(True)
    ax.xaxis.grid(True, which="minor")
    # plt.show()

    # return

    #############################################################
    if Te_ext[0] > 0:
        Num_0_Ta = Te_ext[0] * 365.0
        tenors_0_Ta = np.linspace(0.0, Te_ext[0], Num_0_Ta + 1)
        tenors_0_Tb = np.append(tenors_0_Ta, Te_ext[1:])
    else:
        tenors_0_Tb = Te_ext

    integration_dt = np.diff(tenors_0_Tb)

    log_debug(Te_ext * 365.0, "tenors_Ta_Tb*365")
    log_debug(tenors_0_Tb * 365.0, "tenors_0_Tb*365")

    from mkl.interpolation import Interpolate1D

    triggers_matrix = np.hstack(
        (
            triggers.trigger_prices_upper.reshape(-1, 1),
            triggers.trigger_prices_lower.reshape(-1, 1),
            fwd_array.reshape(-1, 1),
        )
    )
    trigger_interpolator = Interpolate1D(Te, triggers_matrix, kind="linear")

    num_time_steps = tenors_0_Tb.size

    rmax = cons.rmax
    rmin = cons.rmin

    rmax *= 365
    rmin *= 365

    time_value1 = 0
    time_value2 = 0
    time_value3 = 0

    time_value_evolution = np.zeros(num_time_steps)

    I1_evolution1 = np.zeros(num_time_steps - 1)
    I2_evolution1 = np.zeros(num_time_steps - 1)
    mu_evolution1 = np.zeros(num_time_steps - 1)

    I1_evolution2 = np.zeros(num_time_steps - 1)
    I2_evolution2 = np.zeros(num_time_steps - 1)
    mu_evolution2 = np.zeros(num_time_steps - 1)

    for n in range(num_time_steps - 1):
        log_function_enter("time loop")
        log_debug("time step {} of {}".format(n, num_time_steps - 1), std_out=False)
        t = tenors_0_Tb[n]
        tm = max(t, Te[0])
        Tb = tenors_0_Tb[-1]
        dt = 1.0 / 365.0
        num_steps = int(np.round((Tb - tm) / dt))
        num_steps *= 5.0
        tenors = np.linspace(tm, Tb, num_steps + 1)

        log_debug(t * 365.0, "t*365")

        C_all = trigger_interpolator.evaluate(tenors).reshape(-1, 3).T
        C_u = C_all[0]
        C_d = C_all[1]
        F0 = C_all[2]

        params = dict()
        params["n"] = n
        params["t"] = t
        params["tenors"] = tenors
        params["model_params"] = model_params
        params["C_u"] = C_u
        params["C_d"] = C_d
        params["F0"] = F0
        params["rmax"] = rmax
        params["rmin"] = rmin
        params["F0_mean"] = F0_mean
        params["F_grad_max"] = F_grad_max

        add_params = dict()
        add_params["wmin_steps"] = 10.0
        add_params["k_thr"] = 0.7
        add_params["correction_weight"] = 0.5

        mu_1, I1_1, I2_1 = calculate_mu_bar(params, add_params)
        mu_2, I1_2, I2_2 = calculate_mu_bar_2(t, model_params, rmax, rmin, triggers)

        time_value1 += mu_1 * integration_dt[n]
        time_value2 += mu_2 * integration_dt[n]
        time_value_evolution[n + 1] = time_value1

        log_debug(mu_1, "mu_1")
        log_debug(I1_1, "I1_1")
        log_debug(I2_1, "I2_1")
        log_debug(time_value1, "time value 1")

        I1_evolution1[n] = I1_1
        I2_evolution1[n] = I2_1
        mu_evolution1[n] = mu_1

        I1_evolution2[n] = I1_2
        I2_evolution2[n] = I2_2
        mu_evolution2[n] = mu_2

        log_function_exit("time loop")

    log_debug(time_value1, "final time_value")
    print "approximated time value1 = {:.4g}".format(time_value1)
    print "approximated time value2 = {:.4g}".format(time_value2)

    # plt.figure()
    # plt.plot(tenors_0_Tb, time_value_evolution)
    # plt.title('time value')
    # plt.grid(True)

    plt.figure()
    plt.plot(tenors_0_Tb[:-1], mu_evolution1, "--r", label="mu1")
    plt.plot(tenors_0_Tb[:-1], I1_evolution1, "r", label="I1_evolution_1")
    plt.plot(tenors_0_Tb[:-1], I2_evolution1, "r", label="I2_evolution_1")

    plt.plot(tenors_0_Tb[:-1], mu_evolution2, "--g", label="mu2")
    plt.plot(tenors_0_Tb[:-1], I1_evolution2, "g", linewidth=2, label="I1_evolution_2")
    plt.plot(tenors_0_Tb[:-1], I2_evolution2, "g", label="I2_evolution_2")

    plt.legend(loc="best")
    plt.grid(True)
    plt.show()
Beispiel #6
0
def get_formula_values(cut_off_params, setups):

    wmin_steps = cut_off_params['wmin_steps']
    k_thr = cut_off_params['k_thr']
    correction_weight = cut_off_params['correction_weight']

    values = []
    for num_setting in setups:

        start_time0 = log_function_enter('setting {}'.format(num_setting))

        ret = get_setting(num_setting)
        val_date = ret['val_date']
        dates = ret['dates']
        cons = ret['cons']
        model_params = ret['model_params']
        fwd_curve = ret['fwd_curve']
        Fc_mean = ret['Fc_mean']
        delta_F = ret['delta_F']

        Te = calcTe(val_date, dates)
        Te_ext = np.append(Te, Te[-1] + 1. / 365.)
        nTe = Te.size
        fwd_array = fwd_curve.values

        # estimate mean forward curve and gradient upper bound

        F0_mean = fwd_array.mean()
        dt = 1. / 365.
        dFdt = np.gradient(fwd_array, dt)
        F_grad_max = abs(dFdt).max()

        results, TP = run_one_valuation_intrinsic(Te, fwd_array, cons)
        mean_actions = results.actions.mean(axis=1)

        levels = np.empty(nTe + 1, dtype=float)
        levels[0] = cons.start_inv
        levels[1:] = cons.start_inv + np.cumsum(mean_actions)

        minor_sticks = []
        for t in range(nTe)[1:]:
            if mean_actions[t] != mean_actions[t - 1]:
                minor_sticks.append(Te[t])

        triggers = calculate_trigger_prices2(TP['dVdq'], Te, fwd_array,
                                             mean_actions, cons)

        #############################################################
        if Te_ext[0] > 0:
            Num_0_Ta = Te_ext[0] * 365.
            tenors_0_Ta = np.linspace(0., Te_ext[0], Num_0_Ta + 1)
            tenors_0_Tb = np.append(tenors_0_Ta, Te_ext[1:])
        else:
            tenors_0_Tb = Te_ext

        integration_dt = np.diff(tenors_0_Tb)

        triggers_matrix = np.hstack(
            (triggers.trigger_prices_upper.reshape(-1, 1),
             triggers.trigger_prices_lower.reshape(-1, 1),
             fwd_array.reshape(-1, 1)))
        trigger_interpolator = Interpolate1D(Te,
                                             triggers_matrix,
                                             kind='linear')

        num_time_steps = tenors_0_Tb.size

        rmax = cons.rmax
        rmin = cons.rmin

        rmax *= 365
        rmin *= 365

        time_value1 = 0

        time_value_evolution = np.zeros(num_time_steps)

        I1_evolution1 = np.zeros(num_time_steps - 1)
        I2_evolution1 = np.zeros(num_time_steps - 1)
        mu_evolution1 = np.zeros(num_time_steps - 1)

        start_time = log_function_enter('integration time loop')
        for n in range(num_time_steps - 1):

            # log_debug('time step {} of {}'.format(n, num_time_steps - 1), std_out=False)
            t = tenors_0_Tb[n]
            tm = max(t, Te[0])
            Tb = tenors_0_Tb[-1]
            dt = 1. / 365.
            num_steps = int(np.round((Tb - tm) / dt))
            num_steps *= 5.
            tenors = np.linspace(tm, Tb, num_steps + 1)

            # log_debug(t*365., 't*365')

            C_all = trigger_interpolator.evaluate(tenors).reshape(-1, 3).T
            C_u = C_all[0]
            C_d = C_all[1]
            F0 = C_all[2]

            params = dict()
            params['n'] = n
            params['t'] = t
            params['tenors'] = tenors
            params['model_params'] = model_params
            params['C_u'] = C_u
            params['C_d'] = C_d
            params['F0'] = F0
            params['rmax'] = rmax
            params['rmin'] = rmin
            params['F0_mean'] = F0_mean
            params['F_grad_max'] = F_grad_max

            add_params = dict()
            add_params['wmin_steps'] = wmin_steps
            add_params['k_thr'] = k_thr
            add_params['correction_weight'] = correction_weight

            mu_1, I1_1, I2_1 = calculate_mu_bar(params, add_params)

            time_value1 += mu_1 * integration_dt[n]
            time_value_evolution[n + 1] = time_value1

            # log_debug(mu_1, 'mu_1')
            # log_debug(I1_1, 'I1_1')
            # log_debug(I2_1, 'I2_1')
            # log_debug(time_value1, 'time value 1')

            I1_evolution1[n] = I1_1
            I2_evolution1[n] = I2_1
            mu_evolution1[n] = mu_1

        log_function_exit('integration time loop', start_time=start_time)
        log_debug(time_value1, 'final time_value')
        # print "approximated time value1 = {:.4g}".format(time_value1)
        values.append(time_value1)
        log_function_exit('setting {}'.format(num_setting),
                          start_time=start_time0)
    return np.array(values)
Beispiel #7
0
def test_formula(nsims=None):

    # val_date, dates, cons, model_params, fwd_curve, Fc, delta_F = setting_1()
    # val_date, dates, cons, model_params, fwd_curve, Fc, delta_F = setting_2()
    val_date, dates, cons, model_params, fwd_curve, Fc, delta_F = setting_3()

    Te = calcTe(val_date, dates)
    Te_ext = np.append(Te, Te[-1] + 1. / 365.)
    nTe = Te.size
    fwd_array = fwd_curve.values

    # estimate mean forward curve and gradient upper bound

    F0_mean = fwd_array.mean()
    dt = 1. / 365.
    dFdt = np.gradient(fwd_array, dt)
    F_grad_rms = rms(dFdt)
    F_grad_max = abs(dFdt).max()

    results, TP = run_one_valuation_intrinsic(Te, fwd_array, cons)

    cashflows = results['cashflows'].spot + results['cashflows'].opex
    mean_cf = cashflows.mean(axis=1)
    value = mean_cf.sum()
    mean_actions = results.actions.mean(axis=1)
    print "intrinsic value = {}".format(value)

    levels = np.empty(nTe + 1, dtype=float)
    levels[0] = cons.start_inv
    levels[1:] = cons.start_inv + np.cumsum(mean_actions)

    minor_sticks = []
    for t in range(nTe)[1:]:
        if mean_actions[t] != mean_actions[t - 1]:
            minor_sticks.append(Te[t])

    triggers = calculate_trigger_prices2(TP['dVdq'], Te, fwd_array,
                                         mean_actions, cons)
    # triggers = calculate_trigger_prices(TP['dVdq'], Te, fwd_array, mean_actions, cons)

    log_debug(Te, 'Te')
    log_debug(Te * 365., 'Te*365')
    log_debug(fwd_array, 'fwd_array')
    log_debug(triggers.trigger_prices_upper, 'trigger_prices_upper')
    log_debug(triggers.trigger_prices_lower, 'trigger_prices_lower')
    log_debug(triggers.tt_up * 365., 'tt_up*365')
    log_debug(triggers.tt_down * 365., 'tt_down*365')
    log_debug(triggers.fdot_up, 'fdot_up')
    log_debug(triggers.fdot_down, 'fdot_down')

    if nsims is not None and nsims > 0:
        stoch_value, stoch_value_error = run_valuation_stochastic(val_date,
                                                                  dates,
                                                                  fwd_curve,
                                                                  cons,
                                                                  model_params,
                                                                  nsims=nsims)
        print "stoch value = {:.4g} +- {:.4g}".format(stoch_value,
                                                      stoch_value_error)
        print "time value = {:.4g} +- {:.4g}".format(stoch_value - value,
                                                     stoch_value_error)

    plt.close('all')
    plt.figure()
    plt.plot(Te, fwd_array, 'o-', linewidth=1, markersize=2)
    plt.plot(Te_ext, levels)
    plt.plot(Te, triggers.trigger_prices, 'o-', linewidth=1, markersize=2)
    plt.plot(Te, triggers.trigger_prices_upper, '--', linewidth=1)
    plt.plot(Te, triggers.trigger_prices_lower, '--', linewidth=1)
    ax = plt.gca()
    # start, end = ax.get_xlim()
    ax.xaxis.set_ticks(minor_sticks, minor=True)
    plt.grid(True)
    ax.xaxis.grid(True, which='minor')
    # plt.show()

    # return

    #############################################################
    if Te_ext[0] > 0:
        Num_0_Ta = Te_ext[0] * 365.
        tenors_0_Ta = np.linspace(0., Te_ext[0], Num_0_Ta + 1)
        tenors_0_Tb = np.append(tenors_0_Ta, Te_ext[1:])
    else:
        tenors_0_Tb = Te_ext

    integration_dt = np.diff(tenors_0_Tb)

    log_debug(Te_ext * 365., 'tenors_Ta_Tb*365')
    log_debug(tenors_0_Tb * 365., 'tenors_0_Tb*365')

    from mkl.interpolation import Interpolate1D
    triggers_matrix = np.hstack(
        (triggers.trigger_prices_upper.reshape(-1, 1),
         triggers.trigger_prices_lower.reshape(-1,
                                               1), fwd_array.reshape(-1, 1)))
    trigger_interpolator = Interpolate1D(Te, triggers_matrix, kind='linear')

    num_time_steps = tenors_0_Tb.size

    rmax = cons.rmax
    rmin = cons.rmin

    rmax *= 365
    rmin *= 365

    time_value1 = 0
    time_value2 = 0
    time_value3 = 0

    time_value_evolution = np.zeros(num_time_steps)

    I1_evolution1 = np.zeros(num_time_steps - 1)
    I2_evolution1 = np.zeros(num_time_steps - 1)
    mu_evolution1 = np.zeros(num_time_steps - 1)

    I1_evolution2 = np.zeros(num_time_steps - 1)
    I2_evolution2 = np.zeros(num_time_steps - 1)
    mu_evolution2 = np.zeros(num_time_steps - 1)

    for n in range(num_time_steps - 1):
        log_function_enter('time loop')
        log_debug('time step {} of {}'.format(n, num_time_steps - 1),
                  std_out=False)
        t = tenors_0_Tb[n]
        tm = max(t, Te[0])
        Tb = tenors_0_Tb[-1]
        dt = 1. / 365.
        num_steps = int(np.round((Tb - tm) / dt))
        num_steps *= 5.
        tenors = np.linspace(tm, Tb, num_steps + 1)

        log_debug(t * 365., 't*365')

        C_all = trigger_interpolator.evaluate(tenors).reshape(-1, 3).T
        C_u = C_all[0]
        C_d = C_all[1]
        F0 = C_all[2]

        params = dict()
        params['n'] = n
        params['t'] = t
        params['tenors'] = tenors
        params['model_params'] = model_params
        params['C_u'] = C_u
        params['C_d'] = C_d
        params['F0'] = F0
        params['rmax'] = rmax
        params['rmin'] = rmin
        params['F0_mean'] = F0_mean
        params['F_grad_max'] = F_grad_max

        add_params = dict()
        add_params['wmin_steps'] = 10.
        add_params['k_thr'] = 0.7
        add_params['correction_weight'] = 0.5

        mu_1, I1_1, I2_1 = calculate_mu_bar(params, add_params)
        mu_2, I1_2, I2_2 = calculate_mu_bar_2(t, model_params, rmax, rmin,
                                              triggers)

        time_value1 += mu_1 * integration_dt[n]
        time_value2 += mu_2 * integration_dt[n]
        time_value_evolution[n + 1] = time_value1

        log_debug(mu_1, 'mu_1')
        log_debug(I1_1, 'I1_1')
        log_debug(I2_1, 'I2_1')
        log_debug(time_value1, 'time value 1')

        I1_evolution1[n] = I1_1
        I2_evolution1[n] = I2_1
        mu_evolution1[n] = mu_1

        I1_evolution2[n] = I1_2
        I2_evolution2[n] = I2_2
        mu_evolution2[n] = mu_2

        log_function_exit('time loop')

    log_debug(time_value1, 'final time_value')
    print "approximated time value1 = {:.4g}".format(time_value1)
    print "approximated time value2 = {:.4g}".format(time_value2)

    # plt.figure()
    # plt.plot(tenors_0_Tb, time_value_evolution)
    # plt.title('time value')
    # plt.grid(True)

    plt.figure()
    plt.plot(tenors_0_Tb[:-1], mu_evolution1, '--r', label='mu1')
    plt.plot(tenors_0_Tb[:-1], I1_evolution1, 'r', label='I1_evolution_1')
    plt.plot(tenors_0_Tb[:-1], I2_evolution1, 'r', label='I2_evolution_1')

    plt.plot(tenors_0_Tb[:-1], mu_evolution2, '--g', label='mu2')
    plt.plot(tenors_0_Tb[:-1],
             I1_evolution2,
             'g',
             linewidth=2,
             label='I1_evolution_2')
    plt.plot(tenors_0_Tb[:-1], I2_evolution2, 'g', label='I2_evolution_2')

    plt.legend(loc='best')
    plt.grid(True)
    plt.show()
Beispiel #8
0
def run_valuation_stochastic(val_date,
                             dates,
                             fwd_curve,
                             cons,
                             model_params,
                             nsims=5000):
    """
    Calculate stochastic storage with simple constraints

    Parameters
    ----------
    Te  :       maturities

    fwd_array:

    cons :  tuple
        (max_inv, min_inv, start_inv, end_inv, inj_cost, rel_cost, rmin, rmax)

    Returns
    -------

    """

    max_inv = cons.max_inv
    min_inv = cons.min_inv
    start_inv = cons.start_inv
    end_inv = cons.end_inv
    inj_cost = cons.inj_cost
    rel_cost = cons.rel_cost
    rmin = cons.rmin
    rmax = cons.rmax

    sigma_1 = model_params.sigma_1
    sigma_2 = model_params.sigma_2
    alpha_1 = model_params.alpha_1
    alpha_2 = model_params.alpha_2
    rho = model_params.rho

    alphas = [alpha_1, alpha_2]
    sigmas = [sigma_1, sigma_2]

    Te = calcTe(val_date, dates)

    fc = FlowConstraint(rmin, rmax)
    flow_constraints = FlowConstraints(Te[0], fc)

    inv_constraints = InventoryConstraints(Te, start_inv, end_inv, max_inv,
                                           min_inv, [flow_constraints])
    state_object = StateObject(inv_constraints, num_levels=None)
    ls_solver_params = AttrDict(max_basis_order=4,
                                solver='RegularisedLeastSquaresSolver')
    product = LeastSquaresMonteCarloEngine(
        state_object,
        StorageCashflows(Te, injection_cost=inj_cost,
                         withdrawal_cost=rel_cost), ls_solver_params)

    seed = 123
    simulator = MultiFactorSimulator(alphas,
                                     sigmas,
                                     fwd_curve,
                                     rho,
                                     val_date,
                                     seed=seed)
    sims_bwd = simulator.simulate_spot(dates, nsims).values
    factors_bwd = simulator.stoch_factors
    sims_fwd = simulator.simulate_spot(dates, nsims).values
    factors_fwd = simulator.stoch_factors

    results = product.calc_extrinsic(sims_bwd, sims_fwd, factors_bwd,
                                     factors_fwd)
    cashflows = (results['cashflows'].spot +
                 results['cashflows'].opex).sum(axis=0)
    value = cashflows.mean()
    value_std = cashflows.std()
    value_error = value_std / np.sqrt(nsims)

    return value, value_error