import numpy as np import matplotlib.pyplot as plt from multipolyfit import multipolyfit as mpf class ConsumerNotEligibleError(Exception): def __init__(self, reason, *args): super().__init__(args) self.reason = reason def __str__(self): return f'Consumer is ineligible due to {self.reason}' def fico_default_risk_modifier_by_lend_percent(credit_score, loan_percent): # The initial data set is organized as [{credit_score}, {loan_percent}] initial_data = [[620, 1], [620, 70], [620, 85], [620, 90], [620, 95], [660, 1], [660, 70], [660, 85], [660, 90], [660, 95], [700, 1], [700, 70], [700, 85], [700, 90], [700, 95], [740, 1], [740, 70], [740, 85], [740, 90], [740, 95]] # the default rates to use def_rate_620 = 3.03 def_rate_660 = 2.01 def_rate_700 = 1.50 def_rate_740 = 0.94 # the risk factor multiples to use risk_factor_620 = [0.20, 0.61, 1.22, 1.48, 1.80] risk_factor_660 = [0.20, 0.62, 1.22, 1.48, 1.82] risk_factor_700 = [0.20, 0.62, 1.22, 1.49, 1.83] risk_factor_740 = [0.20, 0.63, 1.21, 1.47, 1.81] net_def_risks_620 = np.multiply(def_rate_620, risk_factor_620) net_def_risks_660 = np.multiply(def_rate_660, risk_factor_660) net_def_risks_700 = np.multiply(def_rate_700, risk_factor_700) net_def_risks_740 = np.multiply(def_rate_740, risk_factor_740) initial_risk_mults = [r for r in net_def_risks_620] + [r for r in net_def_risks_660] + [r for r in net_def_risks_700] + [r for r in net_def_risks_740] x, y = zip(*initial_data) ax = plt.axes(projection='3d') ax.scatter(x, y, initial_risk_mults) coefficients = mpf(initial_data, initial_risk_mults, 1) result = np.multiply(coefficients[1], x) + np.multiply(coefficients[2], y) + coefficients[0] ax.plot3D(x, y, result) ax.set_title('Credit Score/Loan % Line of Best Fit') plt.savefig('graph.png') return coefficients[0] + coefficients[1] * credit_score + coefficients[2] * loan_percent def get_loss_severity(): return 0.19 def get_recovery_rate(): return 0.9 def get_risk_pool_allocation_percent(): return 0.01 def get_gross_rent_yield(): return 3.686 def compute_mre(home_value, down_payment_percent, consumer_fico): if not 0 <= down_payment_percent < 100: raise ValueError('Down payment percent must be contained in [0, 100)') if consumer_fico < 620: raise ConsumerNotEligibleError('Credit score too low (must be 620 or Greater)') monthly_payment = home_value * get_gross_rent_yield()/100/12 income_interruption_home_percentage = 100 * (monthly_payment * 4 / home_value) risk_pool_percent = get_risk_pool_allocation_percent() loss_severity = get_loss_severity() recovery_rate = get_recovery_rate() default_rate = fico_default_risk_modifier_by_lend_percent(consumer_fico, 100 - down_payment_percent) at_risk_value = home_value * loss_severity def_rate_mult = 100/default_rate risk_pool_allocation = risk_pool_percent * home_value denom = recovery_rate num = at_risk_value - (def_rate_mult * risk_pool_allocation) result = num/denom mre = result/home_value + income_interruption_home_percentage mre += income_interruption_home_percentage return mre if __name__ == '__main__': print(compute_mre(742500, 2.5, 680)) # print(fico_default_risk_modifier_by_lend_percent(620, 85))