def simulate_params_efast(NRUNS, parameter_set, fixed_parameters):
    """
    Simulate the model for different parameter sets. Record the difference in Gini inequality.
    :param NRUNS: integer amount of Monte Carlo simulations
    :param parameter_set: list of parameters which have been sampled for Sobol sensitivity analysis
    :param fixed_parameters: list of parameters which will remain fixed
    :return: numpy array of average stylized facts outcome values for all parameter combinations
    """
    gini_avs = []
    real_gini_avs = []
    palma_avs = []
    real_palma_avs = []
    av_profits = []
    av_volatilities = []

    for parameters in parameter_set:
        # combine individual parameters with fixed parameters
        params = fixed_parameters.copy()
        params.update(parameters)

        # simulate the model
        trdrs = []
        orbs = []
        for seed in range(NRUNS):
            traders, orderbook = init_objects.init_objects(params, seed)
            traders, orderbook = exuberance_inequality_model(traders,
                                                             orderbook,
                                                             params,
                                                             seed=seed)
            trdrs.append(traders)
            orbs.append(orderbook)

        mc_prices, mc_returns, mc_autocorr_returns, \
        mc_autocorr_abs_returns, mc_volatility, mc_volume, mc_fundamentals = organise_data(orbs, burn_in_period=0)

        av_volatility = mc_volatility.mean().mean()

        ginis_ot = []
        palmas_ot = []
        real_ginis_ot = []
        real_palmas_ot = []
        profits = []

        # determine the start and end wealth
        for seed, traders in enumerate(trdrs):
            money_start = np.array([x.var.money[0] for x in traders])
            stocks_start = np.array([x.var.stocks[0] for x in traders])
            wealth_start = money_start + (stocks_start *
                                          orbs[seed].tick_close_price[0])

            money_end = np.array([x.var.money[-1] for x in traders])
            stocks_end = np.array([x.var.stocks[-1] for x in traders])
            wealth_end = money_end + (stocks_end *
                                      orbs[seed].tick_close_price[-1])

            profits.append((np.array(wealth_end) - np.array(wealth_start)) /
                           np.array(wealth_start))

            wealth_gini_over_time = []
            palma_over_time = []

            real_wealth_gini_over_time = []
            real_palma_over_time = []
            for t in range(params['ticks'] - 1):
                money = np.array([x.var.money[t] for x in traders])
                stocks = np.array([x.var.stocks[t] for x in traders])
                wealth = money + (stocks * orbs[seed].tick_close_price[t])
                real_wealth = np.array([x.var.real_wealth[t] for x in traders])

                share_top_10 = sum(
                    np.sort(wealth)[int(len(wealth) * 0.9):]) / sum(wealth)
                share_bottom_40 = sum(
                    np.sort(wealth)[:int(len(wealth) * 0.4)]) / sum(wealth)
                palma_over_time.append(share_top_10 / share_bottom_40)

                real_share_top_10 = sum(
                    np.sort(real_wealth)[int(len(real_wealth) *
                                             0.9):]) / sum(real_wealth)
                real_share_bottom_40 = sum(
                    np.sort(real_wealth)[:int(len(real_wealth) *
                                              0.4)]) / sum(real_wealth)
                real_palma_over_time.append(real_share_top_10 /
                                            real_share_bottom_40)

                wealth_gini_over_time.append(gini(wealth))
                real_wealth_gini_over_time.append(gini(real_wealth))

            ginis_ot.append(wealth_gini_over_time)
            palmas_ot.append(palma_over_time)
            real_ginis_ot.append(real_wealth_gini_over_time)
            real_palmas_ot.append(real_palma_over_time)

        gini_avs.append(np.mean(ginis_ot))
        real_gini_avs.append(np.mean(real_ginis_ot))
        palma_avs.append(np.mean(palmas_ot))
        real_palma_avs.append(np.mean(real_palmas_ot))
        av_profits.append(np.mean(profits))
        av_volatilities.append(av_volatility)

    return gini_avs, real_gini_avs, palma_avs, real_palma_avs, av_profits, av_volatilities
示例#2
0
def model_performance(input_parameters):
    """
    Simple function calibrate uncertain model parameters
    :param input_parameters: list of input parameters
    :return: cost
    """
    # set fixed parameters of integer variables & variable names
    n_runs = 1
    variable_names = ['std_noise', 'w_random']

    # update params
    uncertain_parameters = dict(zip(variable_names, input_parameters))
    params = {
        'trader_sample_size': 10,
        'n_traders': 1000,
        'init_stocks': 81,
        'ticks': 604,
        'fundamental_value': 1101.1096156039398,
        'std_fundamental': 0.036138325335996965,
        'base_risk_aversion': 0.7,
        'spread_max': 0.004087,
        'horizon': 211,
        'std_noise': 0.01,
        'w_random': 0.1,
        'mean_reversion': 0.0,
        'fundamentalist_horizon_multiplier': 1.0,
        'strat_share_chartists': 0.0,
        'mutation_intensity': 0.0,
        'average_learning_ability': 0.0,
        'trades_per_tick': 1
    }
    params.update(uncertain_parameters)

    empirical_moments = np.array([0.00283408, 0.03613833, 0.00952201])

    traders = []
    obs = []
    # run model with parameters
    for seed in range(n_runs):
        traders, orderbook = init_objects_distr(params, seed)
        traders, orderbook = volatility_inequality_model2(
            traders, orderbook, params, seed)
        traders.append(traders)
        obs.append(orderbook)

    # store simulated stylized facts
    mc_prices, mc_returns, \
    mc_autocorr_returns, mc_autocorr_abs_returns, \
    mc_volatility, mc_volume, mc_fundamentals = organise_data(obs)

    means = []
    stds = []
    first_order_autocors = []
    for col in mc_returns:
        means.append(mc_returns[col][1:].means())
        stds.append(mc_returns[col][1:].std())
        first_order_autocors.append(
            autocorrelation_returns(mc_returns[col][1:], 25))

    stylized_facts_sim = np.array([
        np.mean(means),
        np.mean(stds),
        np.mean(first_order_autocors),
    ])

    W = np.load(
        'distr_weighting_matrix.npy'
    )  #if this doesn't work, use: np.identity(len(stylized_facts_sim))

    # calculate the cost
    cost = quadratic_loss_function(stylized_facts_sim, empirical_moments, W)
    return cost
示例#3
0
def distr_model_performance(input_parameters):
    """
    Simple function calibrate uncertain model parameters
    :param input_parameters: list of input parameters
    :return: cost
    """
    # set fixed parameters of integer variables & variable names
    n_runs = 1
    variable_names = [
        'std_noise', "w_random", "strat_share_chartists", "base_risk_aversion",
        "fundamentalist_horizon_multiplier", "mutation_intensity",
        "average_learning_ability"
    ]

    # update params
    uncertain_parameters = dict(zip(variable_names, input_parameters))
    params = {
        "fundamental_value": 166,
        "trader_sample_size": 22,
        "n_traders": 1000,
        "ticks": 600,
        "std_fundamental": 0.053,
        "init_assets": 740,
        'spread_max': 0.004,
        'money_multiplier': 2.2,
        "horizon": 200,
        "std_noise": 0.049,
        "w_random": 0.08,
        "strat_share_chartists": 0.08,
        "base_risk_aversion": 1.051,
        "fundamentalist_horizon_multiplier": 3.8,
        "trades_per_tick": 1,
        "mutation_intensity": 0.0477,
        "average_learning_ability": 0.05,
        "bond_mean_reversion": 0.0,
        'cb_pf_range': 0.05,
        "qe_perc_size": 0.16,
        "cb_size": 0.02,
        "qe_asset_index": 0,
        "qe_start": 2,
        "qe_end": 598
    }
    params.update(uncertain_parameters)

    empirical_moments = np.array(
        [0.05034916, 0.06925489, 4.16055312, 0.71581425])

    traders = []
    obs = []
    # run model with parameters
    for seed in range(n_runs):
        traders, central_bank, orderbook = init_objects(params, seed)
        traders, central_bank, orderbook = qe_model(traders,
                                                    central_bank,
                                                    orderbook,
                                                    params,
                                                    scenario='None',
                                                    seed=seed)
        traders.append(traders)
        obs.append(orderbook)

    # store simulated stylized facts
    mc_prices, mc_returns, mc_autocorr_returns, mc_autocorr_abs_returns, mc_volatility, mc_volume, mc_fundamentals = organise_data(
        obs)

    autocor = []
    autocor_abs = []
    kurtosis = []
    hursts = []

    for col in mc_returns:
        autocor.append(autocorrelation_returns(mc_returns[col][1:], 25).mean())
        autocor_abs.append(
            autocorrelation_returns(mc_returns[col][1:], 25).abs().mean())
        kurtosis.append(mc_returns[col][1:].kurtosis())
        H, c, data = compute_Hc(mc_prices[col].dropna(),
                                kind='price',
                                simplified=True)
        hursts.append(H)

    stylized_facts_sim = np.array([
        np.mean(autocor),
        np.mean(autocor_abs),
        np.mean(kurtosis),
        np.mean(hursts)
    ])

    W = np.load(
        'distr_weighting_matrix.npy'
    )  #if this doesn't work, use: np.identity(len(stylized_facts_sim))

    # calculate the cost
    cost = quadratic_loss_function(stylized_facts_sim, empirical_moments, W)
    return cost
def sim_synthetic_bubble(seed):
    """
    Simulate model once with a shock and return accompanying info on
    - bubble_type
    - bubble-episode price
    - wealth_start
    - wealth_end
    + wealth_gini_over_time
    + palma_over_time
    + twentytwenty_over_time
    """
    BURN_IN = 200
    SHOCK = 12000.0
    SHOCK_PERIOD = 400

    params = {
        "spread_max": 0.004087,
        "fundamental_value": 166,
        "fundamentalist_horizon_multiplier": 0.73132061,
        "n_traders": 500,
        "w_fundamentalists": 37.20189844,
        "base_risk_aversion": 11.65898537,
        "mutation_probability": 0.30623129,
        "init_stocks": 50,
        "trader_sample_size": 19,
        "ticks": 700,
        "std_fundamental": 0.0530163128919286,
        "std_noise": 0.29985649,
        "trades_per_tick": 5,
        "average_learning_ability": 0.57451773,
        "w_momentum": 0.01,
        "horizon": 200,
        "w_random": 1.0
    }

    # simulate model once
    obs = []
    obs_no_shock = []
    # run model with parameters
    print('Simulate once')
    traders, orderbook = init_objects_distr(params, seed)
    traders, orderbook = pb_distr_model_shock(traders, orderbook, params,
                                              SHOCK, SHOCK_PERIOD, seed)
    obs.append(orderbook)

    traders_no_shock, orderbook_no_shock = init_objects_distr(params, seed)
    traders_no_shock, orderbook_no_shock = pb_distr_model_shock(
        traders_no_shock, orderbook_no_shock, params, 0.0, SHOCK_PERIOD, seed)
    obs_no_shock.append(orderbook)

    # store simulated stylized facts
    mc_prices, mc_returns, mc_autocorr_returns, mc_autocorr_abs_returns, mc_volatility, mc_volume, mc_fundamentals = organise_data(
        obs, burn_in_period=BURN_IN)

    mc_prices_ns, mc_returns_ns, mc_autocorr_returns_ns, mc_autocorr_abs_returns_ns, mc_volatility_ns, mc_volume_ns, mc_fundamentals_ns = organise_data(
        obs_no_shock, burn_in_period=BURN_IN)

    y = pd.Series(mc_prices[0][:-1] / mc_fundamentals[0])
    y_ns = pd.Series(mc_prices_ns[0][:-1] / mc_fundamentals_ns[0])

    obs = len(y)
    r0 = 0.01 + 1.8 / np.sqrt(obs)
    swindow0 = int(math.floor(r0 * obs))
    dim = obs - swindow0 + 1
    IC = 2
    adflag = 6
    yr = 2
    Tb = 12 * yr + swindow0 - 1
    nboot = 99

    # calc bubbles
    bsadfs = PSY(y, swindow0, IC, adflag)

    quantilesBsadf = cvPSYwmboot(y, swindow0, IC, adflag, Tb, nboot=99)

    monitorDates = y.iloc[swindow0 - 1:obs].index
    quantile95 = np.dot(np.array([quantilesBsadf]).T, np.ones([1, dim]))
    ind95 = (bsadfs.T[0] > quantile95[1, ])
    periods = monitorDates[ind95]

    bubble_types = []
    bubble_prices = []
    wealth_starts = []
    wealth_ends = []
    ginis_ot = []
    palmas_ot = []
    twtws_ot = []

    bubble_prices_ns = []
    wealth_ends_ns = []
    ginis_ot_ns = []
    palmas_ot_ns = []
    twtws_ot_ns = []

    if True in ind95:
        bubbly_dates = find_sequences_ints(periods, monitorDates)
        proper_bubbles = bubbly_dates.iloc[p_bubbles(bubbly_dates)]

        # classify the bubbles
        start_dates = []
        end_dates = []

        # then add the first bubble episodes
        start_dates.append(proper_bubbles.iloc[0]['start_date'])
        end_dates.append(proper_bubbles.iloc[0]['end_date'])

        if abs(y[end_dates[0]] - y[start_dates[0]]) > y[:end_dates[0]].std():
            # classify as boom or bust
            if y[start_dates[0]] > y[end_dates[0]]:
                bubble_type = 'bust'
            else:
                bubble_type = 'boom'
        else:
            if y[start_dates[0]:end_dates[0]].mean() > y[start_dates[0]]:
                # classify as boom-bust or bust-boom
                bubble_type = 'boom-bust'
            else:
                bubble_type = 'bust-boom'
        bubble_types.append(bubble_type)

        # determine the start and end wealth of the bubble
        money_start = np.array(
            [x.var.money[BURN_IN + start_dates[0]] for x in traders])
        stocks_start = np.array(
            [x.var.stocks[BURN_IN + start_dates[0]] for x in traders])
        wealth_start = money_start + (stocks_start *
                                      mc_prices[0].iloc[start_dates[0]])

        money_end = np.array(
            [x.var.money[BURN_IN + end_dates[0]] for x in traders])
        stocks_end = np.array(
            [x.var.stocks[BURN_IN + end_dates[0]] for x in traders])
        wealth_end = money_end + (stocks_end * mc_prices[0].iloc[end_dates[0]])

        # track money + wealth no shocks  TODO check if this works
        money_end_ns = np.array(
            [x.var.money[BURN_IN + end_dates[0]] for x in traders_no_shock])
        stocks_end_ns = np.array(
            [x.var.stocks[BURN_IN + end_dates[0]] for x in traders_no_shock])
        wealth_end_ns = money_end_ns + (stocks_end_ns *
                                        mc_prices_ns[0].iloc[end_dates[0]])

        wealth_gini_over_time = []
        palma_over_time = []
        twentytwenty_over_time = []

        # also record the gini etc. over time without the shock
        wealth_gini_over_time_ns = []
        palma_over_time_ns = []
        twentytwenty_over_time_ns = []
        for t in range(BURN_IN + start_dates[0], BURN_IN + end_dates[0]):
            money = np.array([x.var.money[t] for x in traders])
            stocks = np.array([x.var.stocks[t] for x in traders])
            wealth = money + (stocks * orderbook.tick_close_price[t])

            share_top_10 = sum(
                np.sort(wealth)[int(len(wealth) * 0.9):]) / sum(wealth)
            share_bottom_40 = sum(
                np.sort(wealth)[:int(len(wealth) * 0.4)]) / sum(wealth)
            palma_over_time.append(share_top_10 / share_bottom_40)

            share_top_20 = sum(
                np.sort(wealth)[int(len(wealth) * 0.8):]) / sum(wealth)
            share_bottom_20 = sum(
                np.sort(wealth)[:int(len(wealth) * 0.2)]) / sum(wealth)
            twentytwenty_over_time.append(share_top_20 / share_bottom_20)

            wealth_gini_over_time.append(gini(wealth))

            # No shocks
            money_ns = np.array([x.var.money[t] for x in traders_no_shock])
            stocks_ns = np.array([x.var.stocks[t] for x in traders_no_shock])
            wealth_ns = money_ns + (stocks_ns *
                                    orderbook_no_shock.tick_close_price[t])

            share_top_10_ns = sum(
                np.sort(wealth_ns)[int(len(wealth_ns) *
                                       0.9):]) / sum(wealth_ns)
            share_bottom_40_ns = sum(
                np.sort(wealth_ns)[:int(len(wealth_ns) *
                                        0.4)]) / sum(wealth_ns)
            palma_over_time_ns.append(share_top_10_ns / share_bottom_40_ns)

            share_top_20_ns = np.mean(
                np.sort(wealth_ns)[int(len(wealth_ns) * 0.8):])
            share_bottom_20_ns = np.mean(
                np.sort(wealth_ns)[:int(len(wealth_ns) * 0.2)])
            twentytwenty_over_time_ns.append(share_top_20_ns /
                                             share_bottom_20_ns)

            wealth_gini_over_time_ns.append(gini(wealth_ns))

        bubble_prices.append(
            list(mc_prices[0].iloc[start_dates[0]:end_dates[0]]))
        wealth_starts.append(list(wealth_start))
        wealth_ends.append(list(wealth_end))
        ginis_ot.append(wealth_gini_over_time)
        palmas_ot.append(palma_over_time)
        twtws_ot.append(twentytwenty_over_time)

        bubble_prices_ns.append(
            list(mc_prices_ns[0].iloc[start_dates[0]:end_dates[0]]))
        wealth_ends_ns.append(list(wealth_end_ns))
        ginis_ot_ns.append(wealth_gini_over_time_ns)
        palmas_ot_ns.append(palma_over_time_ns)
        twtws_ot_ns.append(twentytwenty_over_time_ns)

    return bubble_types, bubble_prices, wealth_starts, wealth_ends, ginis_ot, palmas_ot, twtws_ot, bubble_prices_ns, wealth_ends_ns, ginis_ot_ns, palmas_ot_ns, twtws_ot_ns
def sim_bubble_info(seed):
    """
    Simulate model once and return accompanying info on
    Inequality:
    - bubble_type
    - bubble-episode price
    - wealth_start
    - wealth_end
    + wealth_gini_over_time
    + palma_over_time
    + twentytwenty_over_time

    Information on agent characteristics
    - risk aversion
    - horizon
    - learning ability
    - chartist expectation
    - fundamentalist expectation
    """
    BURN_IN = 400
    with open('parameters.json', 'r') as f:
        params = json.loads(f.read())
    # simulate model once
    #traders = []
    obs = []
    # run model with parameters
    print('Simulate once')
    traders, orderbook = init_objects_distr(params, seed)
    traders, orderbook = pb_distr_model(traders, orderbook, params, seed)
    #traders.append(traders)
    obs.append(orderbook)

    # store simulated stylized facts
    mc_prices, mc_returns, mc_autocorr_returns, mc_autocorr_abs_returns, mc_volatility, mc_volume, mc_fundamentals = organise_data(
        obs, burn_in_period=BURN_IN)

    y = pd.Series(mc_prices[0][:-1] / mc_fundamentals[0])

    obs = len(y)
    r0 = 0.01 + 1.8 / np.sqrt(obs)
    swindow0 = int(math.floor(r0 * obs))
    dim = obs - swindow0 + 1
    IC = 2
    adflag = 6
    yr = 2
    Tb = 12 * yr + swindow0 - 1
    nboot = 99

    # calc bubbles
    bsadfs = PSY(y, swindow0, IC, adflag)

    quantilesBsadf = cvPSYwmboot(y, swindow0, IC, adflag, Tb, nboot=99)

    monitorDates = y.iloc[swindow0 - 1:obs].index
    quantile95 = np.dot(np.array([quantilesBsadf]).T, np.ones([1, dim]))
    ind95 = (bsadfs.T[0] > quantile95[1, ])
    periods = monitorDates[ind95]

    bubble_types = []
    bubble_prices = []
    wealth_starts = []
    wealth_ends = []
    ginis_ot = []
    palmas_ot = []
    twtws_ot = []
    risk_aversions = []
    horizons = []
    learning_abilities = []
    chartist_expectations = []
    fundamentalist_expectations = []

    if True in ind95:
        bubbly_dates = find_sequences_ints(periods, monitorDates)
        proper_bubbles = bubbly_dates.iloc[p_bubbles(bubbly_dates)]

        # classify the bubbles
        start_dates = []
        end_dates = []

        # add bubble episodes
        for l in range(len(proper_bubbles)):
            start_dates.append(proper_bubbles.iloc[l]['start_date'])
            end_dates.append(proper_bubbles.iloc[l]['end_date'])

            if abs(y[end_dates[l]] -
                   y[start_dates[l]]) > y[:end_dates[l]].std():
                # classify as boom or bust
                if y[start_dates[l]] > y[end_dates[l]]:
                    bubble_type = 'bust'
                else:
                    bubble_type = 'boom'
            else:
                if y[start_dates[l]:end_dates[l]].mean() > y[start_dates[l]]:
                    # classify as boom-bust or bust-boom
                    bubble_type = 'boom-bust'
                else:
                    bubble_type = 'bust-boom'
            bubble_types.append(bubble_type)

            # determine the start and end wealth of the bubble
            money_start = np.array(
                [x.var.money[BURN_IN + start_dates[l]] for x in traders])
            stocks_start = np.array(
                [x.var.stocks[BURN_IN + start_dates[l]] for x in traders])
            wealth_start = money_start + (stocks_start *
                                          mc_prices[0].iloc[start_dates[l]])

            money_end = np.array(
                [x.var.money[BURN_IN + end_dates[l]] for x in traders])
            stocks_end = np.array(
                [x.var.stocks[BURN_IN + end_dates[l]] for x in traders])
            wealth_end = money_end + (stocks_end *
                                      mc_prices[0].iloc[end_dates[l]])

            # determine characteristics of the agents
            risk_aversions.append([x.par.risk_aversion for x in traders])
            horizons.append([x.par.horizon for x in traders])
            learning_abilities.append(
                [x.par.learning_ability for x in traders])
            chartist_expectations.append([
                list(
                    np.array(x.var.weight_chartist)[BURN_IN +
                                                    start_dates[l]:BURN_IN +
                                                    end_dates[l]] *
                    x.var.forecast_adjust) for x in traders
            ])
            fundamentalist_expectations.append([
                list(
                    np.array(x.var.weight_fundamentalist)
                    [BURN_IN + start_dates[l]:BURN_IN + end_dates[l]] *
                    x.var.forecast_adjust) for x in traders
            ])

            wealth_gini_over_time = []
            palma_over_time = []
            twentytwenty_over_time = []
            for t in range(BURN_IN + start_dates[l], BURN_IN + end_dates[l]):
                money = np.array([x.var.money[t] for x in traders])
                stocks = np.array([x.var.stocks[t] for x in traders])
                wealth = money + (stocks * orderbook.tick_close_price[t])

                share_top_10 = sum(
                    np.sort(wealth)[int(len(wealth) * 0.9):]) / sum(wealth)
                share_bottom_40 = sum(
                    np.sort(wealth)[:int(len(wealth) * 0.4)]) / sum(wealth)
                palma_over_time.append(share_top_10 / share_bottom_40)

                share_top_20 = np.mean(
                    np.sort(wealth)[int(len(wealth) * 0.8):])
                share_bottom_20 = np.mean(
                    np.sort(wealth)[:int(len(wealth) * 0.2)])
                twentytwenty_over_time.append(share_top_20 / share_bottom_20)

                wealth_gini_over_time.append(gini(wealth))

            bubble_prices.append(
                list(mc_prices[0].iloc[start_dates[l]:end_dates[l]]))
            wealth_starts.append(list(wealth_start))
            wealth_ends.append(list(wealth_end))
            ginis_ot.append(wealth_gini_over_time)
            palmas_ot.append(palma_over_time)
            twtws_ot.append(twentytwenty_over_time)

    return bubble_types, bubble_prices, wealth_starts, wealth_ends, ginis_ot, palmas_ot, twtws_ot, risk_aversions, horizons, learning_abilities, chartist_expectations, fundamentalist_expectations
def simulate_individual_nmr(individual):
    """Function to simulate one individual per core for the no mean reversion model"""
    # combine individual parameters with fixed parameters
    parameters = individual.parameters.copy()
    params = fixed_parameters_nmr.copy()
    params.update(parameters)

    # simulate the model
    obs = []
    for seed in range(NRUNS):
        traders, orderbook = init_objects.init_objects(params, seed)
        traders, orderbook = simfinmodel.sim_fin_model(traders, orderbook, params, seed)
        obs.append(orderbook)

    # store simulated stylized facts
    mc_prices, mc_returns, mc_autocorr_returns, mc_autocorr_abs_returns, mc_volatility, mc_volume, mc_fundamentals = organise_data(
        obs)

    first_order_autocors = []
    autocors1 = []
    autocors5 = []
    mean_abs_autocor = []
    kurtoses = []
    spy_abs_auto10 = []
    spy_abs_auto25 = []
    spy_abs_auto50 = []
    spy_abs_auto100 = []
    cointegrations = []
    for col in mc_returns:
        first_order_autocors.append(autocorrelation_returns(mc_returns[col][1:], 25))
        autocors1.append(mc_returns[col][1:].autocorr(lag=1))
        autocors5.append(mc_returns[col][1:].autocorr(lag=5))
        mean_abs_autocor.append(autocorrelation_abs_returns(mc_returns[col][1:], 25))
        kurtoses.append(mc_returns[col][2:].kurtosis())
        spy_abs_auto10.append(mc_returns[col][1:].abs().autocorr(lag=10))
        spy_abs_auto25.append(mc_returns[col][1:].abs().autocorr(lag=25))
        spy_abs_auto50.append(mc_returns[col][1:].abs().autocorr(lag=50))
        spy_abs_auto100.append(mc_returns[col][1:].abs().autocorr(lag=100))
        cointegrations.append(cointegr(mc_prices[col][1:], mc_fundamentals[col][1:])[0])

    stylized_facts_sim = np.array([
        np.mean(first_order_autocors),
        np.mean(autocors1),
        np.mean(autocors5),
        np.mean(mean_abs_autocor),
        np.mean(kurtoses),
        np.mean(spy_abs_auto10),
        np.mean(spy_abs_auto25),
        np.mean(spy_abs_auto50),
        np.mean(spy_abs_auto100),
        np.mean(cointegrations)
    ])

    # create next generation individual
    cost = quadratic_loss_function(stylized_facts_sim, empirical_moments, W)
    next_gen_individual = Individual(parameters, stylized_facts_sim, cost)

    return next_gen_individual
def simulate_individual2(individual):
    """Function to simulate one individual per core"""
    parameters = individual.parameters.copy()
    params = fixed_parameters_no_mean_reversion.copy()
    params.update(parameters)

    stylized_facts = {
        'autocorrelation': np.inf,
        'kurtosis': np.inf,
        'autocorrelation_abs': np.inf,
        'hurst': np.inf,
        'av_dev_from_fund': np.inf
    }

    # simulate the model
    obs = []
    for seed in range(NRUNS):
        traders, orderbook = init_objects.init_objects(params, seed)
        traders, orderbook = simfinmodel.sim_fin_model(traders, orderbook,
                                                       params, seed)
        obs.append(orderbook)

    # store simulated stylized facts
    mc_prices, mc_returns, mc_autocorr_returns, mc_autocorr_abs_returns, mc_volatility, mc_volume, mc_fundamentals = organise_data(
        obs)
    mc_dev_fundamentals = (mc_prices - mc_fundamentals) / mc_fundamentals

    mean_autocor_abs = []
    mean_kurtosis = []
    long_memory = []
    av_deviation_fundamental = []
    for col in mc_returns:
        mean_autocor_abs.append(np.mean(mc_autocorr_abs_returns[col][1:]))
        mean_kurtosis.append(mc_returns[col][2:].kurtosis())
        long_memory.append(hurst(mc_prices[col][2:]))
        av_deviation_fundamental.append(np.mean(mc_dev_fundamentals[col][1:]))

    stylized_facts['kurtosis'] = np.mean(mean_kurtosis)
    stylized_facts['autocorrelation_abs'] = np.mean(mean_autocor_abs)
    stylized_facts['hurst'] = np.mean(long_memory)
    stylized_facts['av_dev_from_fund'] = np.mean(av_deviation_fundamental)

    cost = cost_function(stylized_facts_spy, stylized_facts)
    next_gen_individual = Individual(parameters, stylized_facts, cost)

    return next_gen_individual
示例#8
0
def distr_model_performance(input_parameters):
    """
    Simple function calibrate uncertain model parameters
    :param input_parameters: list of input parameters
    :return: cost
    """
    # set fixed parameters of integer variables & variable names
    n_runs = 1
    integer_var_locations = [0, 5, 7]
    variable_names = [
        'trader_sample_size', 'std_noise', 'w_fundamentalists', 'w_momentum',
        'base_risk_aversion', 'horizon', "fundamentalist_horizon_multiplier",
        "trades_per_tick", "mutation_probability", "average_learning_ability"
    ]

    # convert relevant parameters to integers
    new_input_params = []
    for idx, par in enumerate(input_parameters):
        if idx in integer_var_locations:
            new_input_params.append(int(par))
        else:
            new_input_params.append(par.item())

    # update params
    uncertain_parameters = dict(zip(variable_names, new_input_params))
    params = {
        "ticks": 500,
        "fundamental_value": 166,
        'n_traders': 500,
        'std_fundamental': 0.0530163128919286,
        'spread_max': 0.004087,
        "w_random": 1.0,
        "init_stocks": 50
    }  #TODO make ticks: 2516 * 10
    params.update(uncertain_parameters)

    empirical_moments = np.array([
        -7.91632942e-03, -6.44109792e-02, -5.17149408e-02, 2.15757804e-01,
        4.99915089e+00, 2.29239806e-01, 1.36705815e-01, 8.99171488e-02,
        3.97109985e-02, 4.56905198e-02, 3.40685479e-03
    ])

    traders = []
    obs = []
    # run model with parameters
    for seed in range(n_runs):
        traders, orderbook = init_objects_distr(params, seed)
        traders, orderbook = pb_distr_model(traders, orderbook, params, seed)
        traders.append(traders)
        obs.append(orderbook)

    # store simulated stylized facts
    mc_prices, mc_returns, mc_autocorr_returns, mc_autocorr_abs_returns, mc_volatility, mc_volume, mc_fundamentals = organise_data(
        obs)

    first_order_autocors = []
    autocors1 = []
    autocors5 = []
    mean_abs_autocor = []
    kurtoses = []
    spy_abs_auto10 = []
    spy_abs_auto25 = []
    spy_abs_auto50 = []
    spy_abs_auto100 = []
    spy_abs_auto150 = []
    spy_abs_auto200 = []
    for col in mc_returns:
        first_order_autocors.append(
            autocorrelation_returns(mc_returns[col][1:], 25))
        autocors1.append(mc_returns[col][1:].autocorr(lag=1))
        autocors5.append(mc_returns[col][1:].autocorr(lag=5))
        mean_abs_autocor.append(
            autocorrelation_abs_returns(mc_returns[col][1:], 25))
        kurtoses.append(mc_returns[col][2:].kurtosis())
        spy_abs_auto10.append(mc_returns[col][1:].abs().autocorr(lag=10))
        spy_abs_auto25.append(mc_returns[col][1:].abs().autocorr(lag=25))
        spy_abs_auto50.append(mc_returns[col][1:].abs().autocorr(lag=50))
        spy_abs_auto100.append(mc_returns[col][1:].abs().autocorr(lag=100))
        spy_abs_auto150.append(mc_returns[col][1:].abs().autocorr(lag=150))
        spy_abs_auto200.append(mc_returns[col][1:].abs().autocorr(lag=200))

    stylized_facts_sim = np.array([
        np.mean(first_order_autocors),
        np.mean(autocors1),
        np.mean(autocors5),
        np.mean(mean_abs_autocor),
        np.mean(kurtoses),
        np.mean(spy_abs_auto10),
        np.mean(spy_abs_auto25),
        np.mean(spy_abs_auto50),
        np.mean(spy_abs_auto100),
        np.mean(spy_abs_auto150),
        np.mean(spy_abs_auto200)
    ])

    W = np.load(
        'distr_weighting_matrix.npy'
    )  #if this doesn't work, use: np.identity(len(stylized_facts_sim))

    # calculate the cost
    cost = quadratic_loss_function(stylized_facts_sim, empirical_moments, W)
    return cost