diff --git a/ensemble.py b/ensemble.py index 95ea6cb..ca80b54 100644 --- a/ensemble.py +++ b/ensemble.py @@ -90,14 +90,15 @@ def rake(hostname): wfile_11 = open(os.getcwd() + "/data/" + str(nums[str(counter)]) + "_premium.dat", "w") wfile_12 = open(os.getcwd() + "/data/" + str(nums[str(counter)]) + "_reinpremium.dat", "w") wfile_13 = open(os.getcwd() + "/data/" + str(nums[str(counter)]) + "_cumulative_bankruptcies.dat", "w") - wfile_14 = open(os.getcwd() + "/data/" + str(nums[str(counter)]) + "_cumulative_unrecovered_claims.dat", "w") - wfile_15 = open(os.getcwd() + "/data/" + str(nums[str(counter)]) + "_cumulative_claims.dat", "w") - wfile_16 = open(os.getcwd() + "/data/record_" + str(nums[str(counter)]) + "_insurance_firms_cash.dat", "w") - wfile_17 = open(os.getcwd() + "/data/record_" + str(nums[str(counter)]) + "_reinsurance_firms_cash.dat", "w") - wfile_18 = open(os.getcwd() + "/data/" + str(nums[str(counter)]) + "_market_diffvar.dat", "w") - wfile_19 = open(os.getcwd() + "/data/" + str(counter) + "_rc_schedule.dat", "w") - wfile_20 = open(os.getcwd() + "/data/" + str(counter) + "_rc_damage.dat", "w") - + wfile_14 = open(os.getcwd() + "/data/" + str(nums[str(counter)]) + "_cumulative_market_exits", "w") + wfile_15 = open(os.getcwd() + "/data/" + str(nums[str(counter)]) + "_cumulative_unrecovered_claims.dat", "w") + wfile_16 = open(os.getcwd() + "/data/" + str(nums[str(counter)]) + "_cumulative_claims.dat", "w") + wfile_17 = open(os.getcwd() + "/data/record_" + str(nums[str(counter)]) + "_insurance_firms_cash.dat", "w") + wfile_18 = open(os.getcwd() + "/data/record_" + str(nums[str(counter)]) + "_reinsurance_firms_cash.dat", "w") + wfile_19 = open(os.getcwd() + "/data/" + str(nums[str(counter)]) + "_market_diffvar.dat", "w") + wfile_20 = open(os.getcwd() + "/data/" + str(counter) + "_rc_schedule.dat", "w") + wfile_21 = open(os.getcwd() + "/data/" + str(counter) + "_rc_damage.dat", "w") + wfile_22 = open(os.getcwd() + "/data/" + str(counter) + "_no_riskmodels.dat", "w") """Here the results of the simulations (typically run in the cloud) are collected""" @@ -136,6 +137,10 @@ def rake(hostname): wfile_18.write(str(result[i][18]) + "\n") wfile_19.write(str(result[i][19]) + "\n") wfile_20.write(str(result[i][20]) + "\n") + wfile_21.write(str(result[i][21]) + "\n") + wfile_22.write(str(result[i][22]) + "\n") + + @@ -162,6 +167,8 @@ def rake(hostname): wfile_18.close() wfile_19.close() wfile_20.close() + wfile_21.close() + wfile_22.close() counter =counter + 1 diff --git a/insurancesimulation.py b/insurancesimulation.py index a652ac7..7857f10 100644 --- a/insurancesimulation.py +++ b/insurancesimulation.py @@ -276,6 +276,7 @@ def iterate(self, t): # adjust market premiums sum_capital = sum([agent.get_cash() for agent in self.insurancefirms]) #TODO: include reinsurancefirms self.adjust_market_premium(capital=sum_capital) + sum_capital = sum([agent.get_cash() for agent in self.reinsurancefirms]) # TODO: include reinsurancefirms self.adjust_reinsurance_market_premium(capital=sum_capital) # pay obligations @@ -397,6 +398,7 @@ def save_data(self): current_log['market_premium'] = self.market_premium current_log['market_reinpremium'] = self.reinsurance_market_premium current_log['cumulative_bankruptcies'] = self.cumulative_bankruptcies + current_log['cumulative_market_exits'] = self.cumulative_market_exits current_log['cumulative_unrecovered_claims'] = self.cumulative_unrecovered_claims current_log['cumulative_claims'] = self.cumulative_claims #Log the cumulative claims received so far. @@ -526,16 +528,47 @@ def shuffle_risks(self): np.random.shuffle(self.risks) def adjust_market_premium(self, capital): - self.market_premium = self.norm_premium * (self.simulation_parameters["upper_price_limit"] - capital / (self.simulation_parameters["initial_agent_cash"] * self.damage_distribution.mean() * self.simulation_parameters["no_risks"])) + """Adjust_market_premium Method. + Accepts arguments + capital: Type float. The total capital (cash) available in the insurance market (insurance only). + No return value. + This method adjusts the premium charged by insurance firms for the risks covered. The premium reduces linearly + with the capital available in the insurance market and viceversa. The premium reduces until it reaches a minimum + below which no insurer is willing to reduce further the price. This method is only called in the self.iterate() + method of this class.""" + self.market_premium = self.norm_premium * (self.simulation_parameters["upper_price_limit"] - self.simulation_parameters["premium_sensitivity"] * capital / (self.simulation_parameters["initial_agent_cash"] * self.damage_distribution.mean() * self.simulation_parameters["no_risks"])) if self.market_premium < self.norm_premium * self.simulation_parameters["lower_price_limit"]: self.market_premium = self.norm_premium * self.simulation_parameters["lower_price_limit"] def adjust_reinsurance_market_premium(self, capital): - self.reinsurance_market_premium = self.market_premium + """Adjust_market_premium Method. + Accepts arguments + capital: Type float. The total capital (cash) available in the reinsurance market (reinsurance only). + No return value. + This method adjusts the premium charged by reinsurance firms for the risks covered. The premium reduces linearly + with the capital available in the reinsurance market and viceversa. The premium reduces until it reaches a minimum + below which no reinsurer is willing to reduce further the price. This method is only called in the self.iterate() + method of this class.""" + self.reinsurance_market_premium = self.norm_premium * (self.simulation_parameters["upper_price_limit"] - self.simulation_parameters["reinpremium_sensitivity"] * capital / (self.simulation_parameters["initial_agent_cash"] * self.damage_distribution.mean() * self.simulation_parameters["no_risks"])) + if self.reinsurance_market_premium < self.norm_premium * self.simulation_parameters["lower_price_limit"]: + self.reinsurance_market_premium = self.norm_premium * self.simulation_parameters["lower_price_limit"] def get_market_premium(self): + """Get_market_premium Method. + Accepts no arguments. + Returns: + self.market_premium: Type float. The current insurance market premium. + This method returns the current insurance market premium.""" return self.market_premium + def get_market_reinpremium(self): + """Get_market_reinpremium Method. + Accepts no arguments. + Returns: + self.reinsurance_market_premium: Type float. The current reinsurance market premium. + This method returns the current reinsurance market premium.""" + return self.reinsurance_market_premium + def get_reinsurance_premium(self, np_reinsurance_deductible_fraction): # TODO: cut this out of the insurance market premium -> OBSOLETE?? # TODO: make premiums dependend on the deductible per value (np_reinsurance_deductible_fraction) -> DONE. @@ -682,7 +715,7 @@ def insurance_firm_market_entry(self, prob=-1, agent_type="InsuranceFirm"): def record_bankruptcy(self): """Record_bankruptcy Method. - Accepts no arguments: + Accepts no arguments. No return value. This method is called when a firm files for bankruptcy. It is only called from the method dissolve() from the class metainsuranceorg.py after the dissolution of the firm.""" @@ -690,7 +723,7 @@ class metainsuranceorg.py after the dissolution of the firm.""" def record_market_exit(self): """Record_market_exit Method. - Accepts no arguments: + Accepts no arguments. No return value. This method is used to record the firms that leave the market due to underperforming conditions. It is only called from the method dissolve() from the class metainsuranceorg.py after the dissolution of the firm.""" @@ -787,7 +820,7 @@ def reinsurance_capital_entry(self): #This method determines the capital mar def reset_pls(self): """Reset_pls Method. - Accepts no arguments: + Accepts no arguments. No return value. This method reset all the profits and losses of all insurance firms, reinsurance firms and catbonds.""" for insurancefirm in self.insurancefirms: diff --git a/isleconfig.py b/isleconfig.py index 0060e9c..f284c5e 100644 --- a/isleconfig.py +++ b/isleconfig.py @@ -41,6 +41,9 @@ "capacity_target_increment_threshold": 1.2, "capacity_target_decrement_factor": 24/25., "capacity_target_increment_factor": 25/24., + #Premium sensitivity parameters + "premium_sensitivity": 8, #This parameter represents how sensitive is the variation of the insurance premium with respect of the capital of the market. Higher means more sensitive. + "reinpremium_sensitivity": 8, #This parameter represents how sensitive is the variation of the reinsurance premium with respect of the capital of the market. Higher means more sensitive. #Balanced portfolio parameters "insurers_balance_ratio": 0.1, # This ratio represents how low we want to keep the standard deviation of the cash reserved below the mean for insurers. Lower means more balanced. "reinsurers_balance_ratio": 20, # This ratio represents how low we want to keep the standard deviation of the cash reserved below the mean for reinsurers. Lower means more balanced. (Deactivated for the moment) diff --git a/logger.py b/logger.py index cb32b63..e83b271 100644 --- a/logger.py +++ b/logger.py @@ -31,6 +31,7 @@ def __init__(self, no_riskmodels=None, rc_event_schedule_initial=None, rc_event_ self.history_logs['total_contracts'] = [] self.history_logs['total_operational'] = [] self.history_logs['cumulative_bankruptcies'] = [] # TODO: should we not have that for both insurance firms and reinsurance firms? + self.history_logs['cumulative_market_exits'] = [] # TODO: should we not have that for both insurance firms and reinsurance firms? self.history_logs['cumulative_claims'] = [] #Here are stored the total cumulative claims received by the whole insurance sector until a certain time. self.history_logs['cumulative_unrecovered_claims'] = [] @@ -89,14 +90,15 @@ def obtain_log(self): #This function allows to return in a list all the data g [11]: 'market_premium' [12]: 'market_reinpremium' [13]: 'cumulative_bankruptcies' - [14]: 'cumulative_unrecovered_claims' - [15]: 'cumulative_claims' - [16]: 'insurance_firms_cash' - [17]: 'reinsurance_firms_cash' - [18]: 'market_diffvar' - [19]: rc_event_schedule_initial - [20]: rc_event_damage_initial - [21]: number_riskmodels + [14]: 'cumulative_market_exits' + [15]: 'cumulative_unrecovered_claims' + [16]: 'cumulative_claims' + [17]: 'insurance_firms_cash' + [18]: 'reinsurance_firms_cash' + [19]: 'market_diffvar' + [20]: rc_event_schedule_initial + [21]: rc_event_damage_initial + [22]: number_riskmodels """ log = [] @@ -115,6 +117,7 @@ def obtain_log(self): #This function allows to return in a list all the data g log.append(self.history_logs['market_premium']) log.append(self.history_logs['market_reinpremium']) log.append(self.history_logs['cumulative_bankruptcies']) + log.append(self.history_logs['cumulative_market_exits']) log.append(self.history_logs['cumulative_unrecovered_claims']) log.append(self.history_logs['cumulative_claims']) log.append(self.history_logs['insurance_firms_cash']) @@ -169,14 +172,15 @@ def restore_logger_object(self, log): self.history_logs['market_premium'] = log [11] self.history_logs['market_reinpremium'] = log [12] self.history_logs['cumulative_bankruptcies'] = log [13] - self.history_logs['cumulative_unrecovered_claims'] = log [14] - self.history_logs['cumulative_claims'] = log [15] - self.history_logs['insurance_firms_cash'] = log [16] - self.history_logs['reinsurance_firms_cash'] = log [17] - self.history_logs['market_diffvar'] = log [18] - self.rc_event_schedule_initial = log[19] - self.rc_event_damage_initial = log[20] - self.number_riskmodels = log[21] + self.history_logs['cumulative_market_exits'] = log[14] + self.history_logs['cumulative_unrecovered_claims'] = log [15] + self.history_logs['cumulative_claims'] = log [16] + self.history_logs['insurance_firms_cash'] = log [17] + self.history_logs['reinsurance_firms_cash'] = log [18] + self.history_logs['market_diffvar'] = log [19] + self.rc_event_schedule_initial = log[20] + self.rc_event_damage_initial = log[21] + self.number_riskmodels = log[22] def save_log(self, background_run):