Пример #1
0
 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)
Пример #2
0
 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)
Пример #4
0
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)