From d1dc02ef570c9f5d14bb39b8e7287e2c88526d44 Mon Sep 17 00:00:00 2001 From: Juan Sabuco Date: Fri, 30 Nov 2018 01:09:25 +0000 Subject: [PATCH 1/7] Premium sensitivity parameters included. --- isleconfig.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/isleconfig.py b/isleconfig.py index 0060e9c..b3caf20 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, + "reinpremium_sensitivity": 8, #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) From 34b26e9dd097d750c1cd5feb5f3c0d7ce664957b Mon Sep 17 00:00:00 2001 From: Juan Sabuco Date: Fri, 30 Nov 2018 01:17:39 +0000 Subject: [PATCH 2/7] Independent insurance and reinsurance market premiums. --- insurancesimulation.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/insurancesimulation.py b/insurancesimulation.py index a652ac7..ee72d7e 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 @@ -531,7 +532,9 @@ def adjust_market_premium(self, capital): 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 + self.reinsurance_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"])) + 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): return self.market_premium From a0a25da20d40ae6a855482cf025bb79529d60abf Mon Sep 17 00:00:00 2001 From: Juan Sabuco Date: Fri, 30 Nov 2018 01:21:06 +0000 Subject: [PATCH 3/7] Parametric market premium implemented. --- insurancesimulation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/insurancesimulation.py b/insurancesimulation.py index ee72d7e..7902d6c 100644 --- a/insurancesimulation.py +++ b/insurancesimulation.py @@ -527,12 +527,12 @@ 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"])) + 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.norm_premium * (self.simulation_parameters["upper_price_limit"] - capital / (self.simulation_parameters["initial_agent_cash"] * self.damage_distribution.mean() * self.simulation_parameters["no_risks"])) + 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"] From 6177731ee99fd2f73a6a0e46255fa6c1101d09ba Mon Sep 17 00:00:00 2001 From: Juan Sabuco Date: Fri, 30 Nov 2018 01:37:10 +0000 Subject: [PATCH 4/7] Premium sensitivity comments added. --- insurancesimulation.py | 16 ++++++++++++++++ isleconfig.py | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/insurancesimulation.py b/insurancesimulation.py index 7902d6c..38298db 100644 --- a/insurancesimulation.py +++ b/insurancesimulation.py @@ -527,11 +527,27 @@ def shuffle_risks(self): np.random.shuffle(self.risks) def adjust_market_premium(self, capital): + """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): + """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"] diff --git a/isleconfig.py b/isleconfig.py index b3caf20..f284c5e 100644 --- a/isleconfig.py +++ b/isleconfig.py @@ -42,8 +42,8 @@ "capacity_target_decrement_factor": 24/25., "capacity_target_increment_factor": 25/24., #Premium sensitivity parameters - "premium_sensitivity": 8, - "reinpremium_sensitivity": 8, + "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) From fd70004e35af64dd861c68336cf9cad2472b8172 Mon Sep 17 00:00:00 2001 From: Juan Sabuco Date: Fri, 30 Nov 2018 01:45:14 +0000 Subject: [PATCH 5/7] Reinsurance premium getter added. --- insurancesimulation.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/insurancesimulation.py b/insurancesimulation.py index 38298db..7dc856c 100644 --- a/insurancesimulation.py +++ b/insurancesimulation.py @@ -555,6 +555,9 @@ def adjust_reinsurance_market_premium(self, capital): def get_market_premium(self): return self.market_premium + def get_market_reinpremium(self): + 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. From 23651d55f901af167317779d44055510ba6b9852 Mon Sep 17 00:00:00 2001 From: Juan Sabuco Date: Fri, 30 Nov 2018 01:55:01 +0000 Subject: [PATCH 6/7] More premium comments added. --- insurancesimulation.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/insurancesimulation.py b/insurancesimulation.py index 7dc856c..7bbfabd 100644 --- a/insurancesimulation.py +++ b/insurancesimulation.py @@ -553,9 +553,19 @@ def adjust_reinsurance_market_premium(self, capital): 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): @@ -704,7 +714,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.""" @@ -712,7 +722,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.""" @@ -809,7 +819,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: From dfba6bb1542c30813f651d83d5f0f21fc250efa9 Mon Sep 17 00:00:00 2001 From: Juan Sabuco Date: Fri, 30 Nov 2018 02:32:51 +0000 Subject: [PATCH 7/7] Market exit log implemented. --- ensemble.py | 23 +++++++++++++++-------- insurancesimulation.py | 1 + logger.py | 36 ++++++++++++++++++++---------------- 3 files changed, 36 insertions(+), 24 deletions(-) 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 7bbfabd..7857f10 100644 --- a/insurancesimulation.py +++ b/insurancesimulation.py @@ -398,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. 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):