def forecast(getfit_data, stoc_simulate_data, itime=0, N=5000, delphi=False): #%% Restruct stochastic scenarios nlag = stoc_simulate_data['nlag'] nTime = getfit_data['fit_par'].shape[0] i_par = list(range(nTime - nlag - itime, nTime - itime)) #t1 fit_par1 = copy.deepcopy(getfit_data['fit_par'].iloc[i_par]) fit_par1[3] = np.log(fit_par1[3]) #t1 + 1 day forcast if delphi: fit_par2 = np.sum([ np.dot(stoc_simulate_data['Var_Betas'][i], fit_par1.iloc[-(i + 1)]) + stoc_simulate_data['Var_C'] for i in range(stoc_simulate_data['nlag']) ], axis=0) Var_fit_par = fit_par2 + stoc_simulate_data['Var_Rand'] else: fit_par2 = np.array(fit_par1.iloc[-1]) Var_fit_par = fit_par2 + stoc_simulate_data['Var_Rand'] #Transform back fit_par1[3] = np.exp(fit_par1[3]) fit_par2[3] = np.exp(fit_par2[3]) Var_fit_par[:, 3] = np.exp(Var_fit_par[:, 3]) #extract yield curve tfit = np.linspace(0, 30, 100) fit_par1 = fit_par1.iloc[-1] yfit_t1 = NelsonSiegelCurve(fit_par1[0], fit_par1[1], fit_par1[2], fit_par1[3])(tfit) yfit_t2 = NelsonSiegelCurve(fit_par2[0], fit_par2[1], fit_par2[2], fit_par2[3])(tfit) yfit_t2_stochastic = np.array([ NelsonSiegelCurve(Var_fit_par[i][0], Var_fit_par[i][1], Var_fit_par[i][2], Var_fit_par[i][3])(tfit) for i in range(N) ]) return { 'tfit': tfit, 'yfit_t1': yfit_t1, 'yfit_t2': yfit_t2, 'yfit_t2_stochastic': yfit_t2_stochastic, 'Var_fit_par': Var_fit_par, 'fit_par': fit_par2 }
class TestNelsonSiegelCurveImplementation(unittest.TestCase): '''Tests for Nelson-Siegel curve implementation''' def setUp(self): self.y = NelsonSiegelCurve(0.017, -0.023, 0.24, 2.2) def test_curve_init(self): NelsonSiegelCurve(0, 0, 0, 0) def test_nelson_siegel_curve_array_vs_individual(self): '''Test curve evaluation on array vs individual elements''' t = np.linspace(0, 10, 11) y_array = self.y(t) y_individual = np.array([self.y(t_i) for t_i in t]) self.assertTrue(np.allclose(y_array, y_individual), 'array valued yields differ from individual ones') def test_nelson_siegel_at_0(self): '''Test curve evaluation at time 0''' y = self.y y_actual = y(0.0) # float time self.assertEqual(y.beta0 + y.beta1, y_actual) y_actual = y(0) # int time self.assertEqual(y.beta0 + y.beta1, y_actual) y_actual = y(np.array([0.0])) # array time self.assertEqual(y.beta0 + y.beta1, y_actual[0]) def test_forward_against_zero_curve(self): '''Test forward against zero curve implementation by integrating''' t = np.linspace(0.001, 25, 500) dt = t[1] - t[0] y_by_fw_integration = np.cumsum(self.y.forward(t)) * dt / t y_actual = self.y(t) self.assertTrue( np.allclose(y_actual[100:], y_by_fw_integration[100:], atol=1e-3)) # todo: numerical issue closer to 0? def test_factor_matrix(self): '''Test shape of factor matrix''' n = 50 t = np.linspace(0, 25, n) fmat = self.y.factor_matrix(t) self.assertEqual((n, 3), fmat.shape) self.assertEqual((3, ), self.y.factor_matrix(0.123).shape)
def PV_cashflow(cf, t, fit_ns): ns_yieldcurve = NelsonSiegelCurve(fit_ns[0], fit_ns[1], fit_ns[2], fit_ns[3]) interest = (ns_yieldcurve(t)) / 100 PV_cf = [ cf[i] * np.exp(-interest[i] * (i + 1)) for i in range(len(interest)) ] PV = np.sum(PV_cf) dur = np.dot(PV_cf / PV, t) #y = -np.log(PV/np.sum(cf))/t[-1] return PV, dur
def setUp(self): self.y1 = NelsonSiegelCurve(0.017, -0.023, 0.24, 2.2) self.y2 = NelsonSiegelSvenssonCurve(0.017, -0.023, 0.24, 0.1, 2.2, 3.1) self.t = [ 0.0, 0.5, 1.0, 2.0, 3.0, 4.0, 5.0, 10.0, 15.0, 20.0, 25.0, 30.0 ] self.y = [ 0.01, 0.011, 0.013, 0.016, 0.019, 0.021, 0.026, 0.03, 0.035, 0.037, 0.038, 0.04 ] self.runner = CliRunner()
def yfit_beta(tfit, fit_par): yfit = NelsonSiegelCurve(fit_par[0], fit_par[1], fit_par[2], fit_par[3]) c_z = yfit(tfit) return c_z
def setUp(self): self.y = NelsonSiegelCurve(0.017, -0.023, 0.24, 2.2)
def test_curve_init(self): NelsonSiegelCurve(0, 0, 0, 0)