def setUp(self): self.curve = YieldCurve(0.03) mean = 0.03 times = np.array([ 1.0, 2.0, 5.0, 10.0 ]) vols = np.array([ 0.0060, 0.0070, 0.0080, 0.0100 ]) self.modelRiskNeutral = HullWhiteModel(self.curve, mean, times, vols) self.modelDiscreteFwd = HullWhiteModelWithDiscreteNumeraire(self.curve, mean, times, vols)
def test_CreditHybridModel(self): # Rates-FX eurRates = HullWhiteModel(YieldCurve(0.015),0.03,np.array([10.0]),np.array([0.0050])) usdRates = HullWhiteModel(YieldCurve(0.015),0.03,np.array([10.0]),np.array([0.0050])) usdFx = AssetModel(1.25,0.15) hybModel = HybridModel('EUR',eurRates,['USD'],[usdFx],[usdRates],np.eye(3)) # Credit spreadLevel = 0.05 spreadCurve = YieldCurve(spreadLevel) # use 5% instantanous default probablility mean = 0.0001 # 1bp sigma = 0.0100 # 100bp skew = 0.5*sigma/spreadLevel # spreadModel = QuasiGaussianModel(spreadCurve,1,np.array([10.0]),np.array([[sigma]]), np.array([[skew]]),np.array([[-skew]]),np.array([0.01]),np.array([mean]),np.identity(1)) corr = np.eye(4) corr[1,3] = -0.85 # credit-FX corr[3,1] = -0.85 creditModel = CreditModel(hybModel,['CP'],[spreadModel],corr) # print(creditModel.factorAliases()) # obsTimes = np.linspace(0.0,10.0,3) nPaths = 2 seed = 314159265359 mcSim = McSimulation(creditModel,obsTimes,nPaths,seed,True,False)
class TestHullWhiteModel(unittest.TestCase): # set up the stage for testing the models def setUp(self): self.curve = YieldCurve(0.03) mean = 0.03 times = np.array([1.0, 2.0, 5.0, 10.0]) vols = np.array([0.0060, 0.0070, 0.0080, 0.0100]) self.model = HullWhiteModel(self.curve, mean, times, vols) def test_zeroBondPrice(self): obsTime = 10.0 matTime = 20.0 states = [-0.10, -0.05, 0.00, 0.03, 0.07, 0.12] refResult = [ # reference results checked against QuantLib 1.7178994273756056, 1.1153102854629025, 0.7240918839816156, 0.5587692049384843, 0.39550396436404667, 0.25677267968500767 ] for x, res in zip(states, refResult): self.assertEqual(self.model.zeroBondPrice(obsTime, matTime, x), res) def test_couponBondOption(self): excTime = 10.0 payTimes = [ 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 20.0 ] cashFlows = [0.025] * 10 + [1.0] # bond cash flows callOrPut = 1.0 # call strikes = [0.8, 0.9, 1.0, 1.1, 1.2] refResult = [ # reference results checked against QuantLib 0.12572604970665557, 0.07466919528750032, 0.039969719617809936, 0.019503405494683164, 0.008804423283331253 ] for strike, res in zip(strikes, refResult): self.assertEqual( self.model.couponBondOption(excTime, payTimes, cashFlows, strike, callOrPut), res)
class TestHullWhiteMonteCarlo(unittest.TestCase): # set up the stage for testing the models def setUp(self): self.curve = YieldCurve(0.03) mean = 0.03 times = np.array([ 1.0, 2.0, 5.0, 10.0 ]) vols = np.array([ 0.0060, 0.0070, 0.0080, 0.0100 ]) self.modelRiskNeutral = HullWhiteModel(self.curve, mean, times, vols) self.modelDiscreteFwd = HullWhiteModelWithDiscreteNumeraire(self.curve, mean, times, vols) def test_monteCarloSimulation(self): times = np.linspace(0.0, 10.0, 11) nPaths = 2**11 seed = 1234 # risk-neutral simulation mcSim = McSimulation(self.modelRiskNeutral,times,nPaths,seed,showProgress=False) discZeroBonds = np.array([ [ 1.0 / self.modelRiskNeutral.numeraire(t,x) for t,x in zip(times,path) ] for path in mcSim.X ]) mcZeroBondsRiskNeutral = np.average(discZeroBonds,axis=0) # discrete forward measure simulation mcSim = McSimulation(self.modelDiscreteFwd,times,nPaths,seed,showProgress=False) discZeroBonds = np.array([ [ 1.0 / self.modelDiscreteFwd.numeraire(t,x) for t,x in zip(times,path) ] for path in mcSim.X ]) mcZeroBondsDiscreteFwd = np.average(discZeroBonds,axis=0) # curve zeroBonds = np.array([ self.curve.discount(t) for t in times ]) print('') print(' T ZeroRate RiskNeutral DiscreteFwd') for k, t in enumerate(times[1:]): zeroRate = -np.log(zeroBonds[k+1])/t riskNeutral = -np.log(mcZeroBondsRiskNeutral[k+1])/t discreteFwd = -np.log(mcZeroBondsDiscreteFwd[k+1])/t print(' %4.1f %6.4lf %6.4lf %6.4lf' % (t, zeroRate, riskNeutral, discreteFwd) ) self.assertAlmostEqual(zeroRate,riskNeutral,3) self.assertAlmostEqual(zeroRate,discreteFwd,3) def test_simulationStates(self): times = np.array([0.0, 2.0, 5.0, 10.0]) nPaths = 2 seed = 1234 mcSim = McSimulation(self.modelRiskNeutral,times,nPaths,seed,False,showProgress=False) # test exact values for k, t in enumerate(times): self.assertListEqual(list(mcSim.state(0,t)),list(mcSim.X[0][k])) # now we allow interpolation/extrapolation mcSim.timeInterpolation = True # test extrapolation self.assertListEqual(list(mcSim.state(1,-0.5)),list(mcSim.X[1][0])) self.assertListEqual(list(mcSim.state(1,12.5)),list(mcSim.X[1][3])) # test interpolation self.assertListEqual(list(mcSim.state(1,1.0)),list(0.5*(mcSim.X[1][0] + mcSim.X[1][1]))) self.assertListEqual(list(mcSim.state(1,7.0)),list((0.6*mcSim.X[1][2] + 0.4*mcSim.X[1][3]))) def test_pathGeneration(self): times = np.array([0.0, 2.0, 5.0, 10.0]) nPaths = 2 seed = 1234 mcSim = McSimulation(self.modelRiskNeutral,times,nPaths,seed,True,showProgress=False) idx = 0 dT = 5.7 path = mcSim.path(idx) for t in np.linspace(-1.0, 11.0, 13): s = mcSim.state(idx,t) self.assertEqual(path.numeraire(t),mcSim.model.numeraire(t,s)) self.assertEqual(path.zeroBond(t,t+dT,None),mcSim.model.zeroBond(t,t+dT,s,None)) def test_liborPayoff(self): # Libor Rate payoff liborTimes = np.linspace(0.0, 10.0, 11) dT0 = 2.0 / 365 dT1 = 0.5 cfs = [ Pay(LiborRate(t,t+dT0,t+dT0+dT1),t+dT0+dT1) for t in liborTimes] times = set.union(*[ p.observationTimes() for p in cfs ]) times = np.array(sorted(list(times))) # nPaths = 2**11 seed = 1234 # risk-neutral simulation mcSim = McSimulation(self.modelRiskNeutral,times,nPaths,seed,showProgress=False) # cfPVs = np.array([ [ p.discountedAt(mcSim.path(idx)) for p in cfs ] for idx in range(nPaths) ]) cfPVs = np.average(cfPVs,axis=0) discounts0 = np.array([ mcSim.model.yieldCurve.discount(t+dT0) for t in liborTimes ]) discounts1 = np.array([ mcSim.model.yieldCurve.discount(t+dT0+dT1) for t in liborTimes ]) liborsCv = (discounts0/discounts1 - 1.0)/dT1 liborsMC = cfPVs / discounts1 print('') print(' T LiborRate MnteCarlo') for k,t in enumerate(liborTimes): print(' %4.1f %6.4lf %6.4lf' % (t, liborsCv[k], liborsMC[k]) ) self.assertAlmostEqual(liborsCv[k],liborsMC[k],2)
def HWModel(rate=0.01, vol=0.0050, mean=0.03): curve = YieldCurve(rate) times = np.array([ 10.0 ]) vols = np.array([ vol ]) return HullWhiteModel(curve, mean, times, vols)
def setUp(self): self.curve = YieldCurve(0.03) mean = 0.03 times = np.array([1.0, 2.0, 5.0, 10.0]) vols = np.array([0.0060, 0.0070, 0.0080, 0.0100]) self.model = HullWhiteModel(self.curve, mean, times, vols)