@@ -50,7 +50,9 @@ def ufr_discount_factor(ufr: float, t: Union[np.ndarray, List[float]]) -> np.nda
5050 return np .exp (- ufr * t )
5151
5252
53- def wilson_function (t1 : Union [np .ndarray , List [float ]], t2 : Union [np .ndarray , List [float ]], alpha : float , ufr : float ) -> np .ndarray :
53+ def wilson_function (t1 : Union [np .ndarray , List [float ]],
54+ t2 : Union [np .ndarray , List [float ]],
55+ alpha : float , ufr : float ) -> np .ndarray :
5456 """Calculate matrix of Wilson functions
5557
5658 The Smith-Wilson method requires the calculation of a series of Wilson
@@ -95,7 +97,9 @@ def wilson_function(t1: Union[np.ndarray, List[float]], t2: Union[np.ndarray, Li
9597 return W
9698
9799
98- def fit_parameters (rates : Union [np .ndarray , List [float ]], t : Union [np .ndarray , List [float ]], alpha : float , ufr : float ) -> np .ndarray :
100+ def fit_parameters (rates : Union [np .ndarray , List [float ]],
101+ t : Union [np .ndarray , List [float ]],
102+ alpha : float , ufr : float ) -> np .ndarray :
99103 """Calculate Smith-Wilson parameter vector ζ
100104
101105 Given the Wilson-matrix, vector of discount factors and prices,
@@ -130,8 +134,10 @@ def fit_parameters(rates: Union[np.ndarray, List[float]], t: Union[np.ndarray, L
130134 return zeta
131135
132136
133- def fit_smithwilson_rates (rates_obs : Union [np .ndarray , List [float ]], t_obs : Union [np .ndarray , List [float ]],
134- t_target : Union [np .ndarray , List [float ]], ufr : float , alpha : Optional [float ] = None ) -> np .ndarray :
137+ def fit_smithwilson_rates (rates_obs : Union [np .ndarray , List [float ]],
138+ t_obs : Union [np .ndarray , List [float ]],
139+ t_target : Union [np .ndarray , List [float ]],
140+ ufr : float , alpha : Optional [float ] = None ) -> np .ndarray :
135141 """Calculate zero-coupon yields with Smith-Wilson method based on observed rates.
136142
137143 This function expects the rates and initial maturity vector to be
@@ -213,25 +219,29 @@ def fit_convergence_parameter(rates_obs: Union[np.ndarray, List[float]],
213219
214220 # Optimization function calculating the difference between UFR and forward rate at convergence point
215221 def forward_difference (alpha : float ):
216-
217222 # Fit yield curve
218- rates = fit_smithwilson_rates (rates_obs = rates_obs , # Input rates to be fitted
219- t_obs = t_obs , # Maturities of these rates
220- t_target = [convergence_t , convergence_t + 1 ], # Maturity at which curve is supposed to converge to UFR
221- alpha = alpha , # Optimization parameter
222- ufr = ufr ) # Ultimate forward rate
223+ rates = fit_smithwilson_rates (rates_obs = rates_obs , # Input rates to be fitted
224+ t_obs = t_obs , # Maturities of these rates
225+ t_target = [convergence_t , convergence_t + 1 ], # Maturity at which curve is supposed to converge to UFR
226+ alpha = alpha , # Optimization parameter
227+ ufr = ufr ) # Ultimate forward rate
223228
224229 # Calculate the forward rate at convergence maturity - this is an approximation since
225230 # according to the documentation the minimization should be based on the forward intensity, not forward rate
226- forward_rate = (1 + rates [1 ])** (convergence_t + 1 )/ (1 + rates [0 ])** (convergence_t ) - 1
231+ forward_rate = (1 + rates [1 ])** (convergence_t + 1 ) / (1 + rates [0 ])** (convergence_t ) - 1
227232
228233 # Absolute difference needs to be smaller than 1 bps
229- return - abs (forward_rate - ufr ) + 1 / 10000
234+ return - abs (forward_rate - ufr ) + 1 / 10_000
230235
231236 # Minimize alpha w.r.t. forward difference criterion
232- # root = optimize.bisect(minimize, a=0.05, b=0.5, xtol=0.00001)
233- root = optimize .minimize (lambda alpha : alpha , 0.1 , method = 'SLSQP' , bounds = [[0.05 , 1.0 ]],
234- constraints = [ {'type' :'ineq' , 'fun' : lambda alpha : forward_difference (alpha )}],
235- options = {'ftol' : 1e-10 , 'disp' : True })
237+ root = optimize .minimize (lambda alpha : alpha , x0 = 0.15 , method = 'SLSQP' , bounds = [[0.05 , 1.0 ]],
238+ constraints = [{
239+ 'type' : 'ineq' ,
240+ 'fun' : forward_difference
241+ }],
242+ options = {
243+ 'ftol' : 1e-6 ,
244+ 'disp' : True
245+ })
236246
237247 return float (root .x )
0 commit comments