modelflowib 2.73__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
modeluserfunk.py ADDED
@@ -0,0 +1,97 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ To make userdefined function avaiable to Business logic define them here
4
+ Function names have to be all lower case !!!
5
+
6
+ Created on Fri Mar 2 14:50:18 2018
7
+
8
+ @author: hanseni
9
+ """
10
+
11
+ try:
12
+ from numba import jit
13
+
14
+ @jit("f8(b1,f8,f8)",nopython=True)
15
+ def recode(condition,yes,no):
16
+ '''Function which recreates the functionality of @recode from eviews '''
17
+ return yes if condition else no
18
+ except Exception as e:
19
+ print(f' Import of numba failed {e} ')
20
+ def recode(condition,yes,no):
21
+ '''Function which recreates the functionality of @recode from eviews '''
22
+ return yes if condition else no
23
+
24
+
25
+ try:
26
+ from stem import ste
27
+ except:
28
+ pass
29
+
30
+ def __pd():
31
+ ''' Returns functions translating pd to REA veights.
32
+
33
+ The reason for making a closure is to avoid namespace clutter with the imported functions'''
34
+
35
+
36
+ from math import isclose,sqrt,erf
37
+ from math import exp, log
38
+ from scipy.special import erfinv , ndtri
39
+
40
+
41
+ def phi(x):
42
+ ''' Cumulative normal distribution function '''
43
+ return (1.0 + erf(x / sqrt(2.0))) / 2.0
44
+
45
+ def phiinv(x):
46
+ ''' inverse Cumulative normal distribution function '''
47
+ return ndtri(x)
48
+
49
+
50
+
51
+ def pd_to_w(PD=0.01,LGD=0.5,cat='mrtg'):
52
+ ''' based on pd,lgd and sector this function calculates the risk weigts based on Basel 3
53
+ this function is based on Marco Gross's matlab function and chekked against the results
54
+ the function is Risk_weights.m and a copy is located at 'Python poc' directory
55
+ This function only distinguis betwen 3 types,
56
+ Alternative is to implement the parameters from BST.steet(CR_MAP) '''
57
+ NORM99 = 3.0902323061678132
58
+ # from phiinv(0.999)
59
+
60
+ PD_ = 1e-10 if isclose(PD,0.0,abs_tol=1e-9) else PD
61
+ if PD < -1e-9:
62
+ PD_ = 1e-10
63
+
64
+ if cat == 'corp':
65
+ R = 0.12*(1-exp(-50*PD_ ))/(1-exp(-50)) + 0.24* (1-(1-exp(-50*PD_ ))/(1-exp(-50)))
66
+ b = (0.11852 - 0.05478*log(PD_))**2.
67
+ M = 2.5;
68
+ normal_dist_comp = phi(((1-R)**-0.5) *phiinv(PD_) + NORM99 * ((R /(1-R))**0.5))
69
+ K = LGD *(normal_dist_comp-PD_ ) *(1+(b*(M-2.5))) /(1- b*1.5)
70
+ elif cat == 'mrtg':
71
+ R = 0.15;
72
+ normal_dist_comp = phi(((1-R)**-0.5)*phiinv(PD_) + NORM99 *((R/(1-R))**0.5))
73
+ K = LGD*(normal_dist_comp-PD)
74
+ elif cat == 'retail':
75
+ R = 0.03*(1-exp(-35*PD_))/(1-exp(-35)) + 0.16*(1-(1-exp(-35*PD_))/(1-exp(-35)));
76
+ normal_dist_comp = phi(((1-R)**-0.5)*phiinv(PD_) + NORM99 * ((R/(1-R))**0.5))
77
+ K = LGD*(normal_dist_comp-PD)
78
+ else:
79
+ print('Major mistake. No Basel categori :',cat)
80
+
81
+ return K * 12.5
82
+
83
+
84
+ def pd_to_w_corp(PD=0.01,LGD=0.5):
85
+ return pd_to_w(PD,LGD,cat='corp' )
86
+
87
+
88
+ def pd_to_w_mrtg(PD=0.01,LGD=0.5):
89
+ return pd_to_w(PD,LGD,cat='mrtg' )
90
+
91
+
92
+ def pd_to_w_retail(PD=0.01,LGD=0.5):
93
+ return pd_to_w(PD,LGD,cat='retail' )
94
+
95
+ return pd_to_w,pd_to_w_corp,pd_to_w_mrtg,pd_to_w_retail,phi,phiinv
96
+
97
+ # pd_to_w,pd_to_w_corp,pd_to_w_mrtg,pd_to_w_retail,phi,phiinv = __pd()