Initial commit
This commit is contained in:
parent
f20bef03fe
commit
27cfe80cbd
115
__init__.py
Normal file
115
__init__.py
Normal file
@ -0,0 +1,115 @@
|
||||
import numpy as np
|
||||
from multipolyfit import multipolyfit as mpf
|
||||
|
||||
GROSS_RENT_YIELD: float = 0.03686
|
||||
RISK_POOL_ALLOCATION: float = 0.01
|
||||
LOSS_SEVERITY: float = 0.19
|
||||
RECOVERY_RATE: float = 0.9
|
||||
|
||||
|
||||
def get_default_risk_by_fico(consumer_fico: int, loan_to_value: float) -> float:
|
||||
# remember that the credit score is the first variable and the ltv is the second
|
||||
initial_fico_ltv_risks = [
|
||||
[620, 0.01],
|
||||
[620, 0.70],
|
||||
[620, 0.85],
|
||||
[620, 0.90],
|
||||
[620, 0.95],
|
||||
[660, 0.01],
|
||||
[660, 0.70],
|
||||
[660, 0.85],
|
||||
[660, 0.90],
|
||||
[660, 0.95],
|
||||
[700, 0.01],
|
||||
[700, 0.70],
|
||||
[700, 0.85],
|
||||
[700, 0.90],
|
||||
[700, 0.95],
|
||||
[740, 0.01],
|
||||
[740, 0.70],
|
||||
[740, 0.85],
|
||||
[740, 0.90],
|
||||
[740, 0.95]
|
||||
]
|
||||
|
||||
default_rates_by_credit_score = {
|
||||
620: 0.0303,
|
||||
660: 0.0201,
|
||||
700: 0.0150,
|
||||
740: 0.0094
|
||||
}
|
||||
risk_factors_by_credit_score = {
|
||||
620: [0.20, 0.61, 1.22, 1.48, 1.80],
|
||||
660: [0.20, 0.62, 1.22, 1.48, 1.82],
|
||||
700: [0.20, 0.62, 1.22, 1.49, 1.83],
|
||||
740: [0.20, 0.63, 1.21, 1.47, 1.81]
|
||||
}
|
||||
|
||||
# We should now fill out the table of default rates with the LTV risk factors included
|
||||
initial_risk_factors_by_ltv_credit_score = []
|
||||
for fico in risk_factors_by_credit_score:
|
||||
initial_risk_factors_by_ltv_credit_score += list(np.multiply(default_rates_by_credit_score[fico],
|
||||
risk_factors_by_credit_score[fico]))
|
||||
|
||||
# Compute a line of best fit
|
||||
lobf_coefficients = mpf(initial_fico_ltv_risks, initial_risk_factors_by_ltv_credit_score, 1)
|
||||
|
||||
# the first coeffient is a constant offset, the second is the credit score factor, and the third is the ltv factor
|
||||
const_offset = lobf_coefficients[0]
|
||||
consumer_fico_factor = (lobf_coefficients[1] * consumer_fico)
|
||||
loan_to_value_factor = (lobf_coefficients[2] * loan_to_value)
|
||||
# now we just sum these up to get the result
|
||||
result = consumer_fico_factor + loan_to_value_factor + const_offset
|
||||
return result
|
||||
|
||||
def get_risk_pool_health() -> float:
|
||||
return 1.0
|
||||
|
||||
|
||||
def compute_mre(home_value: float,
|
||||
down_payment: float,
|
||||
consumer_fico: int) -> float:
|
||||
|
||||
investor_value = home_value - down_payment
|
||||
loan_to_value = float(investor_value/home_value)
|
||||
# the monthly payment is made on the value from the investors
|
||||
monthly_payment = investor_value * (GROSS_RENT_YIELD) / 12.0
|
||||
# how much is at risk if the occupant "defaults"
|
||||
at_risk_value = home_value * LOSS_SEVERITY
|
||||
# how much is expected to be recovered?
|
||||
recovery_value = at_risk_value * RECOVERY_RATE
|
||||
# get the default rate with the risk-factors dealt with
|
||||
default_rate = get_default_risk_by_fico(consumer_fico, loan_to_value)
|
||||
# get the risk pool allocation
|
||||
risk_pool_allocation = RISK_POOL_ALLOCATION * home_value
|
||||
# we should add the 4 month buffer that effectively halves the default rate,
|
||||
# this is already included in the get_default_risk_by_fico method.
|
||||
income_interruption_buffer = 4.0 * monthly_payment
|
||||
default_rate = get_default_risk_by_fico(consumer_fico, loan_to_value)
|
||||
# the expected loss to the risk pool
|
||||
default_rate_risk_pool_loss = default_rate * risk_pool_allocation
|
||||
# adjust the risk pool loss by the risk pool's health
|
||||
risk_pool_factor = get_risk_pool_health() * default_rate_risk_pool_loss
|
||||
# since we don't actually lose anything in the risk pool, it does not
|
||||
# get counted toward the loss
|
||||
|
||||
|
||||
|
||||
at_risk_value -= risk_pool_factor
|
||||
# start putting together the pieces
|
||||
mre = income_interruption_buffer
|
||||
mre += at_risk_value - recovery_value
|
||||
# make the mre a percentage of the home value
|
||||
mre /= home_value
|
||||
return mre
|
||||
|
||||
|
||||
|
||||
|
||||
#if __name__ == '__main__':
|
||||
# print('Computing risk factor for consumer with 660 FICO and 70% LTV')
|
||||
# print(f'Deault Rate: {get_default_risk_by_fico(660, 0.7)}\n')
|
||||
# print('Comuting MRE for 742,500 home with 2.5% down payment and a 680 fico')
|
||||
# print(f' MRE: {compute_mre(742500.0, 0.025*742500.0, 680)}')
|
||||
|
||||
|
||||
2
requirements.txt
Normal file
2
requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
multipolyfit==0.0.1
|
||||
numpy==2.2.4
|
||||
Loading…
Reference in New Issue
Block a user