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
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
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
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