From 721be0ef93e1ddcca7a72c045a8aad1247ab6941 Mon Sep 17 00:00:00 2001 From: Juan Sabuco Date: Mon, 9 Oct 2017 23:37:08 +0100 Subject: [PATCH 1/2] Basic Reinsurance implementation. Files added: reinriskmodel.py, reinsurancecontract.py , reinsurancefirm.py --- reinriskmodel.py | 68 +++++++++++++++++ reinsurancecontract.py | 29 ++++++++ reinsurancefirm.py | 162 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 259 insertions(+) create mode 100644 reinriskmodel.py create mode 100644 reinsurancecontract.py create mode 100644 reinsurancefirm.py diff --git a/reinriskmodel.py b/reinriskmodel.py new file mode 100644 index 0000000..3238156 --- /dev/null +++ b/reinriskmodel.py @@ -0,0 +1,68 @@ + +import math +import numpy as np +import sys, pdb +import scipy.stats + +class ReinriskModel(): + def __init__(self, damage_distribution, expire_immediately, cat_separation_distribution, norm_premium, \ + category_number, init_average_exposure, init_profit_estimate): + """risk_distribution is some scipy frozen rv distribution wich is bound between 0 and 1 and indicates + the share of risks suffering damage as part of any single catastrophic peril""" + self.damage_distribution = damage_distribution # TODO: separate that category wise? + self.cat_separation_distribution = cat_separation_distribution + self.norm_premium = norm_premium + self.var_tail_prob = 0.02 + self.expire_immediately = expire_immediately + self.category_number = category_number + self.init_average_exposure = init_average_exposure + self.init_profit_estimate = init_profit_estimate + + def getPPF(self, tailSize): + """Method for getting quantile function of the distribution (value at risk). + Positional arguments: + tailSize (float >=0, <=1): quantile + Returns value-at-risk.""" + return self.damage_distribution.ppf(1-tailSize) + + def evaluate(self, risks, cash): + acceptable_by_category = [] + remaining_acceptable_by_category = [] + expected_profits = 0 + necessary_liquidity = 0 + for categ_id in range(self.category_number): + # compute number of acceptable risks of this category + categ_risks = [risk for risk in risks if risk["category"]==categ_id] + if len(categ_risks) > 0: + average_exposure = np.mean([risk["excess"]-risk["deductible"] for risk in categ_risks]) + + # compute expected profits from category + mean_runtime = np.mean([risk["runtime"] for risk in categ_risks]) + if self.expire_immediately: + expected_profits += (self.norm_premium - (1 - scipy.stats.poisson(1 / self.cat_separation_distribution.mean() * \ + mean_runtime).pmf(0)) * self.damage_distribution.mean()) * average_exposure * len(categ_risks) + else: + expected_profits += (self.norm_premium - mean_runtime / self.cat_separation_distribution.mean() * self.damage_distribution.mean()) * average_exposure * len(categ_risks) + else: + average_exposure = self.init_average_exposure + expected_profits += 0 + var_per_risk = self.getPPF(self.var_tail_prob) * average_exposure + necessary_liquidity += var_per_risk * len(categ_risks) + + print("RISKMODEL: ", var_per_risk, " = PPF(0.02) * ", average_exposure, " vs. cash: ", cash, "TOTAL_RISK_IN_CATEG: ", var_per_risk * len(categ_risks)) + + try: + acceptable = int(math.floor(cash / var_per_risk)) + remaining = acceptable - len(categ_risks) + except: + print(sys.exc_info()) + pdb.set_trace() + acceptable_by_category.append(acceptable) + remaining_acceptable_by_category.append(remaining) + if necessary_liquidity == 0: + assert expected_profits == 0 + expected_profits = self.init_profit_estimate * cash + else: + expected_profits / necessary_liquidity + print("RISKMODEL returns: ", expected_profits, remaining_acceptable_by_category) + return expected_profits, remaining_acceptable_by_category diff --git a/reinsurancecontract.py b/reinsurancecontract.py new file mode 100644 index 0000000..89c1340 --- /dev/null +++ b/reinsurancecontract.py @@ -0,0 +1,29 @@ +import numpy as np + +class ReinsuranceContract(): + def __init__(self, reinsurer, reinrisk, time, premium, deductible = 0, excess = None): + self.reinsurer = reinsurer + self.properties = reinrisk + print(reinrisk["firm"]) + self.property_holder = reinrisk["firm"] + self.value = reinrisk["value"] + self.category = reinrisk["category"] + self.runtime = reinrisk["runtime"] + self.expiration = reinrisk["contract"].expiration + self.contract = reinrisk["contract"] + self.deductible = deductible + self.excess = excess if excess != None else self.value + self.property_holder.receive_obligation(premium * (self.excess - self.deductible), self.reinsurer, time) + if(len(self.property_holder.underwritten_contracts)>0): + for contract in self.property_holder.underwritten_contracts: + if contract.reinrisk!= None: + if contract.reinrisk==reinrisk["identifier"]: + contract.reinsurer = self.reinsurer + + + + def explode(self, expire_immediately, time): + if expire_immediately: + self.expiration = time + + diff --git a/reinsurancefirm.py b/reinsurancefirm.py new file mode 100644 index 0000000..62f9d4a --- /dev/null +++ b/reinsurancefirm.py @@ -0,0 +1,162 @@ +import numpy as np +import scipy.stats +from reinsurancecontract import ReinsuranceContract +import sys, pdb + + +class ReinsuranceFirm(): + def __init__(self, simulation, simulation_parameters, agent_parameters): + self.simulation = simulation + ##or: ABCE style: + # def init(self, simulation_parameters, agent_parameters): + ##note that ABCE-style cannot have a pointer to the simulation. It should deal with customers directly instead. + + self.id = agent_parameters['id'] + self.cash = agent_parameters['initial_cash'] + self.reinriskmodel = agent_parameters['reinriskmodel'] + self.premium = agent_parameters["norm_premium"] + self.profit_target = agent_parameters['profit_target'] + self.acceptance_threshold = agent_parameters['initial_acceptance_threshold'] # 0.5 + self.acceptance_threshold_friction = agent_parameters['acceptance_threshold_friction'] # 0.9 #1.0 to switch off + self.obligations_reinsurer = [] + self.rein_underwritten_contracts = [] + self.operational = True + + + def iterate(self, time): + # """realize income: not necessary""" + # pass + + """realize due payments""" + self.effect_payments(time) + print(time, ":", self.id, len(self.rein_underwritten_contracts), self.cash, self.operational) + + """mature reincontracts""" + print("Hey", len(self.rein_underwritten_contracts)) + maturing = [reincontract for reincontract in self.rein_underwritten_contracts if reincontract.expiration <= time] + for reincontract in maturing: + self.rein_underwritten_contracts.remove(reincontract) + reincontracts_dissolved = len(maturing) + + print(len(self.rein_underwritten_contracts)) + + if self.operational: + # Only for ABCE: + # """collect messages""" + # self.obligations += [obligation.content for obligation in self.get_messages('obligation')] + + """request risks to be considered for rein_underwriting in the next period and collect those for this period""" + # Non-ABCE style + new_reinrisks = self.simulation.solicit_reinsurance_requests(self.id, self.cash) + ## ABCE style + # self.message("insurancecustomer", 0, 'solicit_insurance_requests', {"number": self.posession("money")}) + # new_reinrisks = [] + # for new_reinrisks in self.get_messages('new_reinrisks') + # new_reinrisks += new_reinrisks.content + reincontracts_offered = len(new_reinrisks) + try: + assert reincontracts_offered > 2 * reincontracts_dissolved + except: + print("Something wrong; agent {0:d} receives too few new reincontracts {1:d} <= {2:d}".format(self.id, + reincontracts_offered, + 2 * reincontracts_dissolved)) + # print(self.id, " has ", len(self.rein_underwritten_contracts), " & receives ", reincontracts_offered, " & lost ", reincontracts_dissolved) + + + """make rein_underwriting decisions, category-wise""" + rein_underwritten_risks = [{"excess": reincontract.excess, "category": reincontract.category, "deductible": reincontract.deductible, \ + "runtime": reincontract.runtime} for reincontract in self.rein_underwritten_contracts] + expected_profit, acceptable_by_category = self.reinriskmodel.evaluate(rein_underwritten_risks, self.cash) + + self.acceptable_mem = acceptable_by_category + # if expected_profit * 1./self.cash < self.profit_target: + # self.acceptance_threshold = ((self.acceptance_threshold - .4) * 5. * self.acceptance_threshold_friction) / 5. + .4 + # else: + # self.acceptance_threshold = (1 - self.acceptance_threshold_friction * (1 - (self.acceptance_threshold - .4) * 5.)) / 5. + .4 + + growth_limit = max(50, 2 * len(self.rein_underwritten_contracts) + reincontracts_dissolved) + if sum(acceptable_by_category) > growth_limit: + acceptable_by_category = np.asarray(acceptable_by_category) + acceptable_by_category = acceptable_by_category * growth_limit / sum(acceptable_by_category) + acceptable_by_category = np.int64(np.round(acceptable_by_category)) + + not_accepted_reinrisks = [] + for categ_id in range(len(acceptable_by_category)): + categ_risks = [risk for risk in new_reinrisks if risk["category"] == categ_id] + new_reinrisks = [risk for risk in new_reinrisks if risk["category"] != categ_id] + i = 0 + print("InsuranceFirm rein_underwrote: ", len(self.rein_underwritten_contracts), " will accept: ", + acceptable_by_category[categ_id], " out of ", len(categ_risks), "acceptance threshold: ", + self.acceptance_threshold) + try: + while (acceptable_by_category[categ_id] > 0 and len(categ_risks) > i): # \ + # and categ_risks[i]["risk_factor"] < self.acceptance_threshold): + reincontract = ReinsuranceContract(self, categ_risks[i], time, self.simulation.get_market_premium()) + self.rein_underwritten_contracts.append(reincontract) + categ_risks[i]["contract"].reincontract = reincontract + acceptable_by_category[categ_id] -= 1 + i += 1 + print(len(self.rein_underwritten_contracts)) + except: + print(sys.exc_info()) + pdb.set_trace() + not_accepted_reinrisks += categ_risks[i:] + + # return unacceptables + # print(self.id, " now has ", len(self.rein_underwritten_contracts), " & returns ", len(not_accepted_reinrisks)) + + + self.simulation.return_reinrisks(not_accepted_reinrisks) + + + # not implemented + # """adjust liquidity, borrow or invest""" + # pass + else: + pass + # Non-ABCE style not required + # self.simulation.return_risks(self.simulation.solicit_insurance_requests(0)) + # ABCE style: + # ...requires collecting message with risks like above and sending the all back + + def enter_illiquidity(self): + self.enter_bankruptcy() + + def enter_bankruptcy(self): + self.simulation.receive(self.cash) + self.cash = 0 + self.operational = False + + def reinsurer_receive_obligation(self, amount, recipient, due_time): + obligation = {"amount": amount, "recipient": recipient, "due_time": due_time} + self.obligations_reinsurer.append(obligation) + + def effect_payments(self, time): + due = [item for item in self.obligations_reinsurer if item["due_time"] <= time] + self.obligations_reinsurer = [item for item in self.obligations_reinsurer if item["due_time"] > time] + sum_due = sum([item["amount"] for item in due]) + if sum_due > self.cash: + self.obligations_reinsurer += due + self.enter_illiquidity() + else: + for obligation in due: + self.pay(obligation["amount"], obligation["recipient"]) + + def pay(self, amount, recipient): + ## ABCE style: + # self.give(self, recipient, "cash", amount) + # Non-ABCE style: + self.cash -= amount + recipient.receive(amount) + + def receive(self, amount): + ## Not necessary in ABCE style + # pass + # Non-ABCE style + """Method to accept cash payments.""" + self.cash += amount + + def return_reinrisks(self,reinrisk): + print(self.simulation.reinrisks) + self.simulation.return_reinrisks(reinrisk) + print(self.simulation.reinrisks) From ffc94df27c9020087683d13aeaafbda80a6220fa Mon Sep 17 00:00:00 2001 From: Juan Sabuco Date: Mon, 9 Oct 2017 23:44:19 +0100 Subject: [PATCH 2/2] Files modified to implement basic reinsurance: reinsurancecontract.py, reinsurancefirmt.py, reinsurancesimulation.py, plotter.py --- insurancecontract.py | 25 +++++-- insurancefirm.py | 47 ++++++++++++- insurancesimulation.py | 155 ++++++++++++++++++++++++++++++++--------- plotter.py | 97 ++++++++++++++++---------- 4 files changed, 244 insertions(+), 80 deletions(-) diff --git a/insurancecontract.py b/insurancecontract.py index f99a65d..e51e11a 100644 --- a/insurancecontract.py +++ b/insurancecontract.py @@ -1,7 +1,8 @@ import numpy as np class InsuranceContract(): - def __init__(self, insurer, properties, time, premium, runtime, deductible = 0, excess = None): + def __init__(self, insurer, properties, time, premium, runtime, deductible=0, excess=None, reinsurance=0, + reinrisk=None): self.insurer = insurer self.risk_factor = properties["risk_factor"] self.category = properties["category"] @@ -12,19 +13,29 @@ def __init__(self, insurer, properties, time, premium, runtime, deductible = 0, self.expiration = runtime + time self.deductible = deductible self.excess = excess if excess != None else self.value + self.reinsurance = reinsurance + self.reinrisk = reinrisk + self.reinsurer = None + self.reincontract = None self.property_holder.receive_obligation(premium * (self.excess - self.deductible), self.insurer, time) - - + + def explode(self, expire_immediately, time, uniform_value, damage_extent): - #np.mean(np.random.beta(1, 1./mu -1, size=90000)) - #if np.random.uniform(0, 1) < self.risk_factor: + # np.mean(np.random.beta(1, 1./mu -1, size=90000)) + # if np.random.uniform(0, 1) < self.risk_factor: if uniform_value < self.risk_factor: - #if True: + # if True: claim = damage_extent * self.excess - self.deductible - self.insurer.receive_obligation(claim, self.property_holder, time) + if (self.reincontract != None): + self.reinsurer.reinsurer_receive_obligation(claim, self.insurer, time) + self.reincontract.explode(True, time) + self.insurer.receive_obligation(claim, self.property_holder, time + 2) if expire_immediately: self.expiration = time def mature(self): self.property_holder.return_risks([self.properties]) + def reinsure(self, percentage): + self.reinsurance = self.value * percentage/100 + diff --git a/insurancefirm.py b/insurancefirm.py index 66a98e1..cafd6b8 100644 --- a/insurancefirm.py +++ b/insurancefirm.py @@ -3,6 +3,7 @@ import scipy.stats from insurancecontract import InsuranceContract import sys, pdb +import uuid class InsuranceFirm(): def __init__(self, simulation, simulation_parameters, agent_parameters): @@ -28,6 +29,8 @@ def __init__(self, simulation, simulation_parameters, agent_parameters): def iterate(self, time): #"""realize income: not necessary""" #pass + + self.ans_reinsurance() """realize due payments""" self.effect_payments(time) @@ -62,9 +65,9 @@ def iterate(self, time): """make underwriting decisions, category-wise""" - underwritten_risks = [{"excess": contract.excess, "category": contract.category, \ + underwritten_risks = [{"excess": contract.value, "category": contract.category, \ "risk_factor": contract.risk_factor, "deductible": contract.deductible, \ - "runtime": contract.runtime} for contract in self.underwritten_contracts] + "runtime": contract.runtime} for contract in self.underwritten_contracts if contract.reincontract != None] expected_profit, acceptable_by_category = self.riskmodel.evaluate(underwritten_risks, self.cash) #if expected_profit * 1./self.cash < self.profit_target: @@ -99,6 +102,9 @@ def iterate(self, time): #return unacceptables #print(self.id, " now has ", len(self.underwritten_contracts), " & returns ", len(not_accepted_risks)) + + self.ask_reinsurance() + self.simulation.return_risks(not_accepted_risks) #not implemented @@ -149,3 +155,40 @@ def receive(self, amount): # Non-ABCE style """Method to accept cash payments.""" self.cash += amount + + def ask_reinsurance(self): + nonreinsured = [contract + for contract in self.underwritten_contracts + if contract.reinrisk == None] + counter = 0 + limitrein = 0.1 * len(nonreinsured) + for contract in nonreinsured: + if counter < limitrein: + reinvalue = 0 + risk = {"value": contract.value, "category": contract.category, "firm": self, + "identifier": uuid.uuid1(), + "runtime": contract.expiration, "contract": contract} + contract.reinsure(100) # TODO percentage to floating point number + contract.reinrisk = risk["identifier"] + self.simulation.append_reinrisks(risk) + counter += 1 + else: + break + + def ans_reinsurance(self): + to_remove = [] + print(self.simulation.reinrisks) + for rein in self.simulation.get_reinrisks(): + for contract in self.underwritten_contracts: + if (rein["identifier"] == contract.reinrisk): + contract.reinsure(0) + contract.reinrisk = None + contract.reinsurer = None + contract.reincontract = None + to_remove.append(rein) + + for item in to_remove: + self.simulation.remove_reinrisks(item) + + + diff --git a/insurancesimulation.py b/insurancesimulation.py index fdb9177..f268c2e 100644 --- a/insurancesimulation.py +++ b/insurancesimulation.py @@ -1,31 +1,35 @@ from insurancefirm import InsuranceFirm from riskmodel import RiskModel +from reinsurancefirm import ReinsuranceFirm +from reinriskmodel import ReinriskModel import numpy as np import scipy.stats import math -import matplotlib.pyplot as plt -import pdb class InsuranceSimulation(): - def __init__(self, simulation_parameters = {"no_categories": 2,\ - "no_insurancefirms": 20, \ - "no_riskmodels": 2, \ - "norm_profit_markup": 0.15, \ - "mean_contract_runtime": 30, \ - "contract_runtime_halfspread": 10, \ - "max_time": 600, \ - "money_supply": 2000000000, \ - "event_time_mean_separation": 200/1., \ - "expire_immediately": True, \ - "risk_factors_present": False, \ - "risk_factor_lower_bound": 0.4, \ - "risk_factor_upper_bound": 0.6, \ - "initial_acceptance_threshold": 0.5, \ - "acceptance_threshold_friction": 0.9, \ - "initial_agent_cash": 10000, \ - "no_risks": 20000 }): - + def __init__(self, simulation_parameters={"no_categories": 1, \ + "no_insurancefirms": 2, \ + "no_reinsurancefirms": 1, \ + "no_riskmodels": 1, \ + "no_reinriskmodels": 1, \ + "norm_profit_markup": 0.15, \ + "rein_norm_profit_markup": 0.15, \ + "mean_contract_runtime": 50, \ + "contract_runtime_halfspread": 10, \ + "max_time": 1000, \ + "money_supply": 2000000000, \ + "event_time_mean_separation": 100 / 0.3, \ + "expire_immediately": True, \ + "risk_factors_present": False, \ + "risk_factor_lower_bound": 0.4, \ + "risk_factor_upper_bound": 0.6, \ + "initial_acceptance_threshold": 0.5, \ + "acceptance_threshold_friction": 0.9, \ + "initial_agent_cash": 100000, \ + "initial_reinagent_cash": 50000, \ + "no_risks": 2000}): + # save parameters self.simulation_parameters = simulation_parameters @@ -110,16 +114,48 @@ def __init__(self, simulation_parameters = {"no_categories": 2,\ self.insurancefirms.append(insurer) self.insurancefirm_weights = [1 for i in self.insurancefirms] self.insurancefirm_new_weights = [0 for i in self.insurancefirms] + + + # set up reinsurance risk models + self.reinriskmodels = [ReinriskModel(self.damage_distribution, self.simulation_parameters["expire_immediately"], \ + self.cat_separation_distribution, self.norm_premium, + self.simulation_parameters["no_categories"], \ + risk_value_mean, \ + self.simulation_parameters["rein_norm_profit_markup"]) \ + for i in range(self.simulation_parameters["no_reinriskmodels"])] + + # set up reinsurance firms + self.reinsurancefirms = [] + for i in range(self.simulation_parameters["no_reinsurancefirms"]): + reinriskmodel = self.reinriskmodels[i % len(self.reinriskmodels)] + agent_parameters = {'id': i, 'initial_cash': simulation_parameters["initial_reinagent_cash"], \ + 'reinriskmodel': reinriskmodel, 'norm_premium': self.norm_premium, \ + 'profit_target': simulation_parameters["rein_norm_profit_markup"], \ + 'initial_acceptance_threshold': simulation_parameters["initial_acceptance_threshold"], \ + 'acceptance_threshold_friction': simulation_parameters["acceptance_threshold_friction"]} + reinsurer = ReinsuranceFirm(self, simulation_parameters, agent_parameters) + self.reinsurancefirms.append(reinsurer) + self.reinsurancefirm_weights = [1 for i in self.reinsurancefirms] + self.reinsurancefirm_new_weights = [simulation_parameters["initial_reinagent_cash"] for i in self.reinsurancefirms] + + + # some output variables self.history_total_cash = [] self.history_total_contracts = [] self.history_individual_contracts = [[] for _ in range(simulation_parameters["no_insurancefirms"])] self.history_total_operational = [] + + self.history_total_reincash = [] + self.history_total_reincontracts = [] + self.history_total_reinoperational = [] wfile = open("data/rc_event_schedule.dat","a") wfile.write(str(self.rc_event_schedule)+"\n") wfile.close() + + self.reinrisks = [] def run(self): for t in range(self.simulation_parameters["max_time"]): @@ -149,6 +185,20 @@ def run(self): [contract.explode(self.simulation_parameters["expire_immediately"], t, uniformvalues[i], damagevalues[i]) for i, contract in enumerate(affected_contracts)] else: print("Next peril ", self.rc_event_schedule[categ_id]) + + + # reset reinweights + self.reinsurancefirm_weights = np.asarray(self.reinsurancefirm_new_weights) / sum( + self.reinsurancefirm_new_weights) * len(self.reinrisks) + self.reinsurancefirm_weights = np.int64(np.floor(self.reinsurancefirm_weights)) + self.reinsurancefirm_new_weights = [0 for i in self.reinsurancefirms] + np.random.shuffle(self.reinrisks) + + # iterate reinagents + for reinagent in self.reinsurancefirms: + reinagent.iterate(t) + + # reset weights self.insurancefirm_weights = np.asarray(self.insurancefirm_new_weights) / sum(self.insurancefirm_new_weights) * len(self.risks) self.insurancefirm_weights = np.int64(np.floor(self.insurancefirm_weights)) @@ -162,23 +212,39 @@ def run(self): # collect data total_cash_no = sum([insurancefirm.cash for insurancefirm in self.insurancefirms]) total_contracts_no = sum([len(insurancefirm.underwritten_contracts) for insurancefirm in self.insurancefirms]) - individual_contracts_no = [len(insurancefirm.underwritten_contracts) for insurancefirm in self.insurancefirms] + total_reincash_no = sum([reinsurancefirm.cash for reinsurancefirm in self.reinsurancefirms]) + total_reincontracts_no = sum([len(reinsurancefirm.rein_underwritten_contracts) for reinsurancefirm in self.reinsurancefirms]) operational_no = sum([insurancefirm.operational for insurancefirm in self.insurancefirms]) + reinoperational_no = sum([reinsurancefirm.operational for reinsurancefirm in self.reinsurancefirms]) self.history_total_cash.append(total_cash_no) self.history_total_contracts.append(total_contracts_no) self.history_total_operational.append(operational_no) + self.history_total_reincash.append(total_reincash_no) + self.history_total_reincontracts.append(total_reincontracts_no) + self.history_total_reinoperational.append(reinoperational_no) + + individual_contracts_no = [len(insurancefirm.underwritten_contracts) for insurancefirm in self.insurancefirms] for i in range(len(individual_contracts_no)): self.history_individual_contracts[i].append(individual_contracts_no[i]) - wfile = open("data/two_operational.dat","a") + wfile = open("data/operational.dat","w") wfile.write(str(self.history_total_operational)+"\n") wfile.close() - wfile = open("data/two_contracts.dat","a") + wfile = open("data/contracts.dat","w") wfile.write(str(self.history_total_contracts)+"\n") wfile.close() - wfile = open("data/two_cash.dat","a") + wfile = open("data/cash.dat","w") wfile.write(str(self.history_total_cash)+"\n") wfile.close() + wfile = open("data/reinoperational.dat","w") + wfile.write(str(self.history_total_reinoperational)+"\n") + wfile.close() + wfile = open("data/reincontracts.dat","w") + wfile.write(str(self.history_total_reincontracts)+"\n") + wfile.close() + wfile = open("data/reincash.dat","w") + wfile.write(str(self.history_total_reincash)+"\n") + wfile.close() #fig = plt.figure() #ax0 = fig.add_subplot(311) @@ -194,15 +260,6 @@ def run(self): #ax2.set_xlabel("Time") #plt.show() - def return_risks(self, not_accepted_risks): - self.risks += not_accepted_risks - - def solicit_insurance_requests(self, id, cash): - self.insurancefirm_new_weights[id] = cash - risks_to_be_sent = self.risks[:self.insurancefirm_weights[id]] - self.risks = self.risks[self.insurancefirm_weights[id]:] - return risks_to_be_sent - def receive_obligation(self, amount, recipient, due_time): obligation = {"amount": amount, "recipient": recipient, "due_time": due_time} self.obligations.append(obligation) @@ -237,6 +294,38 @@ def adjust_market_premium(self): def get_market_premium(self): return self.market_premium + def append_reinrisks(self, item): + if(len(item) > 0): + self.reinrisks.append(item) + + def remove_reinrisks(self,risko): + if(risko != None): + self.reinrisks.remove(risko) + + def get_reinrisks(self): + np.random.shuffle(self.reinrisks) + return self.reinrisks + + def solicit_insurance_requests(self, id, cash): + self.insurancefirm_new_weights[id] = cash + risks_to_be_sent = self.risks[:self.insurancefirm_weights[id]] + self.risks = self.risks[self.insurancefirm_weights[id]:] + print("Number of risks", len(risks_to_be_sent)) + return risks_to_be_sent + + def return_risks(self, not_accepted_risks): + self.risks += not_accepted_risks + + def solicit_reinsurance_requests(self, id, cash): + self.reinsurancefirm_new_weights[id] = cash + reinrisks_to_be_sent = self.reinrisks[:self.reinsurancefirm_weights[id]] + self.reinrisks = self.reinrisks[self.reinsurancefirm_weights[id]:] + print("Number of risks",len(reinrisks_to_be_sent)) + return reinrisks_to_be_sent + + def return_reinrisks(self, not_accepted_risks): + self.reinrisks += not_accepted_risks + # main entry point if __name__ == "__main__": S = InsuranceSimulation() diff --git a/plotter.py b/plotter.py index 615460e..f8c4679 100644 --- a/plotter.py +++ b/plotter.py @@ -1,55 +1,76 @@ import matplotlib.pyplot as plt import numpy as np -rfile = open("data/one_contracts.dat","r") -contracts_one = [eval(k) for k in rfile] +rfile = open("data/contracts.dat","r") +contracts = [eval(k) for k in rfile] rfile.close() -rfile = open("data/two_contracts.dat","r") -contracts_two = [eval(k) for k in rfile] +rfile = open("data/operational.dat","r") +op = [eval(k) for k in rfile] rfile.close() -rfile = open("data/one_operational.dat","r") -op_one = [eval(k) for k in rfile] +rfile = open("data/cash.dat","r") +cash = [eval(k) for k in rfile] rfile.close() -rfile = open("data/two_operational.dat","r") -op_two = [eval(k) for k in rfile] +rfile = open("data/reincontracts.dat","r") +reincontracts = [eval(k) for k in rfile] rfile.close() -c_one = [] -c_two = [] - -o_one = [] -o_two = [] - -for i in range(len(contracts_one[0])): - c1 = np.mean([item[i] for item in contracts_one]) - c2 = np.mean([item[i] for item in contracts_two]) - #o1 = np.mean([item[i] for item in op_one]) - #o2 = np.mean([item[i] for item in op_two]) - #c1 = np.median([item[i] for item in contracts_one]) - #c2 = np.median([item[i] for item in contracts_two]) - o1 = np.median([item[i] for item in op_one]) - o2 = np.median([item[i] for item in op_two]) - c_one.append(c1) - c_two.append(c2) - o_one.append(o1) - o_two.append(o2) - -print(contracts_one) -print(contracts_two) -print(c_one) -print(c_two) +rfile = open("data/reinoperational.dat","r") +reinop = [eval(k) for k in rfile] +rfile.close() + +rfile = open("data/reincash.dat","r") +reincash = [eval(k) for k in rfile] +rfile.close() + +c_s = [] + +o_s = [] + +h_s = [] + +c_re = [] + +o_re= [] + +h_re = [] + +for i in range(len(contracts[0])): + cs = np.mean([item[i] for item in contracts]) + os = np.median([item[i] for item in op]) + hs = np.median([item[i] for item in cash]) + c_s.append(cs) + o_s.append(os) + h_s.append(hs) + + + cre = np.mean([item[i] for item in reincontracts]) + ore = np.median([item[i] for item in reinop]) + hre = np.median([item[i] for item in reincash]) + c_re.append(cre) + o_re.append(ore) + h_re.append(hre) fig = plt.figure() -ax0 = fig.add_subplot(211) -ax0.plot(range(len(c_one)), c_one,"r") -ax0.plot(range(len(c_two)), c_two,"b") +ax0 = fig.add_subplot(611) +ax0.plot(range(len(c_s)), c_s,"b") ax0.set_ylabel("Contracts") -ax1 = fig.add_subplot(212) -ax1.plot(range(len(o_one)), o_one,"r") -ax1.plot(range(len(o_two)), o_two,"b") +ax1 = fig.add_subplot(612) +ax1.plot(range(len(o_s)), o_s,"b") ax1.set_ylabel("Active firms (out of initially 20)") +ax0 = fig.add_subplot(613) +ax0.plot(range(len(h_s)), h_s,"b") +ax0.set_ylabel("Cash") +ax0 = fig.add_subplot(614) +ax0.plot(range(len(c_re)), c_re,"r") +ax0.set_ylabel("Contracts") +ax1 = fig.add_subplot(615) +ax1.plot(range(len(o_re)), o_re,"r") +ax1.set_ylabel("Active reinfirms (out of initially 1)") +ax0 = fig.add_subplot(616) +ax0.plot(range(len(h_re)), h_re,"r") +ax0.set_ylabel("Cash") ax1.set_xlabel("Time") plt.show()