Source code for modeluserfunk

# -*- coding: utf-8 -*-
"""
To make userdefined function avaiable to Business logic define them here
Function names have to be all lower case !!!

Created on Fri Mar  2 14:50:18 2018

@author: hanseni
"""

try:
    from numba import jit
    
    @jit("f8(b1,f8,f8)",nopython=True)
    def recode(condition,yes,no):
        '''Function which recreates the functionality of @recode from eviews ''' 
        return yes if condition else no
except Exception as e:
    print(f' Import of numba failed {e} ')
[docs] def recode(condition,yes,no): '''Function which recreates the functionality of @recode from eviews ''' return yes if condition else no
try: from stem import ste except: pass def __pd(): ''' Returns functions translating pd to REA veights. The reason for making a closure is to avoid namespace clutter with the imported functions''' from math import isclose,sqrt,erf from math import exp, log from scipy.special import erfinv , ndtri def phi(x): ''' Cumulative normal distribution function ''' return (1.0 + erf(x / sqrt(2.0))) / 2.0 def phiinv(x): ''' inverse Cumulative normal distribution function ''' return ndtri(x) def pd_to_w(PD=0.01,LGD=0.5,cat='mrtg'): ''' based on pd,lgd and sector this function calculates the risk weigts based on Basel 3 this function is based on Marco Gross's matlab function and chekked against the results the function is Risk_weights.m and a copy is located at 'Python poc' directory This function only distinguis betwen 3 types, Alternative is to implement the parameters from BST.steet(CR_MAP) ''' NORM99 = 3.0902323061678132 # from phiinv(0.999) PD_ = 1e-10 if isclose(PD,0.0,abs_tol=1e-9) else PD if PD < -1e-9: PD_ = 1e-10 if cat == 'corp': R = 0.12*(1-exp(-50*PD_ ))/(1-exp(-50)) + 0.24* (1-(1-exp(-50*PD_ ))/(1-exp(-50))) b = (0.11852 - 0.05478*log(PD_))**2. M = 2.5; normal_dist_comp = phi(((1-R)**-0.5) *phiinv(PD_) + NORM99 * ((R /(1-R))**0.5)) K = LGD *(normal_dist_comp-PD_ ) *(1+(b*(M-2.5))) /(1- b*1.5) elif cat == 'mrtg': R = 0.15; normal_dist_comp = phi(((1-R)**-0.5)*phiinv(PD_) + NORM99 *((R/(1-R))**0.5)) K = LGD*(normal_dist_comp-PD) elif cat == 'retail': R = 0.03*(1-exp(-35*PD_))/(1-exp(-35)) + 0.16*(1-(1-exp(-35*PD_))/(1-exp(-35))); normal_dist_comp = phi(((1-R)**-0.5)*phiinv(PD_) + NORM99 * ((R/(1-R))**0.5)) K = LGD*(normal_dist_comp-PD) else: print('Major mistake. No Basel categori :',cat) return K * 12.5 def pd_to_w_corp(PD=0.01,LGD=0.5): return pd_to_w(PD,LGD,cat='corp' ) def pd_to_w_mrtg(PD=0.01,LGD=0.5): return pd_to_w(PD,LGD,cat='mrtg' ) def pd_to_w_retail(PD=0.01,LGD=0.5): return pd_to_w(PD,LGD,cat='retail' ) return pd_to_w,pd_to_w_corp,pd_to_w_mrtg,pd_to_w_retail,phi,phiinv # pd_to_w,pd_to_w_corp,pd_to_w_mrtg,pd_to_w_retail,phi,phiinv = __pd()