コード例 #1
0
 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)
コード例 #2
0
 def test_CirSimulation(self):
     r0         = 0.02
     chi_       = 0.07
     theta_     = 0.05
     sigma_     = 0.10
     modelFT = CoxIngersollRossModel(r0,chi_,theta_,sigma_,fullTruncation)
     modelLN = CoxIngersollRossModel(r0,chi_,theta_,sigma_,lognormalApproximation)
     modelQE = CoxIngersollRossModel(r0,chi_,theta_,sigma_,quadraticExponential(1.5))
     #
     dT = 5.0
     times = np.linspace(0.0, 10.0, 11)
     zcbs = np.array([ modelFT.zeroBondPrice(0.0,T + dT,r0) for T in times ])
     #
     nPaths = 2**13
     seed = 314159265359
     # risk-neutral simulation
     simFT = McSimulation(modelFT,times,nPaths,seed,showProgress=True)
     simLN = McSimulation(modelLN,times,nPaths,seed,showProgress=True)
     simQE = McSimulation(modelQE,times,nPaths,seed,showProgress=True)
     #
     zcbFT = np.mean(np.array([
         [ modelFT.zeroBond(times[t],times[t]+dT,simFT.X[p,t,:],None) / modelFT.numeraire(times[t],simFT.X[p,t,:]) for t in range(len(times)) ]
         for p in range(nPaths) ]), axis=0)
     zcbLN = np.mean(np.array([
         [ modelLN.zeroBond(times[t],times[t]+dT,simLN.X[p,t,:],None) / modelLN.numeraire(times[t],simLN.X[p,t,:]) for t in range(len(times)) ]
         for p in range(nPaths) ]), axis=0)
     zcbQE = np.mean(np.array([
         [ modelQE.zeroBond(times[t],times[t]+dT,simQE.X[p,t,:],None) / modelQE.numeraire(times[t],simQE.X[p,t,:]) for t in range(len(times)) ]
         for p in range(nPaths) ]), axis=0)
     #
     results = pd.DataFrame([ times, zcbs, zcbFT, zcbLN, zcbQE ]).T
     results.columns = ['times', 'zcbs', 'zcbFT', 'zcbLN', 'zcbQE']
     print(results)
コード例 #3
0
 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)
コード例 #4
0
 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))
コード例 #5
0
    def test_AuxilliaryStateVsQuasiGaussian(self):
        curve = YieldCurve(0.03)
        d = 3

        times = np.array([1.0, 2.0, 5.0, 10.0])
        sigma = np.array([[0.0060, 0.0070, 0.0080, 0.0100],
                          [0.0030, 0.0035, 0.0040, 0.0050],
                          [0.0025, 0.0025, 0.0025, 0.0025]])
        slope = np.zeros([3, 4])
        curve = np.zeros([3, 4])

        delta = np.array([1.0, 5.0, 20.0])
        chi = np.array([0.01, 0.05, 0.15])

        Gamma = np.array([[1.0, 0.8, 0.6], [0.8, 1.0, 0.8], [0.6, 0.8, 1.0]])
        qGmodel = QuasiGaussianModel(curve, d, times, sigma, slope, curve,
                                     delta, chi, Gamma)
        X0 = qGmodel.initialValues()
        #T = np.linspace(-1.0, 11.0, 121)
        #vols = np.array([ qGmodel.sigma_xT(t,X0) for t in T ])
        #plt.plot(T,vols[:,0,0],label='sigma[0,0]')
        vols = np.array([qGmodel.sigma_xT(t, X0) for t in times])
        #plt.plot(times,vols[:,0,0],'*',label='sigma[0,0]')
        #plt.show()
        #
        mVmodel = MarkovFutureModel(None, d, times, vols, chi)
        # we need to evolve the Quasi Gaussian model to obtain y(t)
        times = np.linspace(0.0, 11.0, 111)
        sim = McSimulation(qGmodel, times, 1, 1, showProgress=False)
        Y0 = sim.X[0, :, d:d + d * d]
        Y0.shape = [111, 3, 3]
        Y1 = np.array([mVmodel.y(t) for t in times])
        # print(np.max(np.abs(Y1[1:]/Y0[1:] - 1.0)))
        self.assertLess(np.max(np.abs(Y1[1:] / Y0[1:] - 1.0)), 6.2e-14)
コード例 #6
0
 def test_MartingalePropertyTimeDependentParameters(self):
     d = 2
     times = np.array([2.0, 4.0])
     sigmaT = np.zeros([2, 2, 2])
     sigmaT[0, :, :] = np.array([[0.10, 0.15], [0.20, 0.25]])
     sigmaT[1, :, :] = np.array([[0.15, 0.20], [0.25, 0.30]])
     chi = np.array([0.1, 0.2])
     #
     model0 = MarkovFutureModel(None, d, times, sigmaT, chi)
     #
     times = np.linspace(0.0, 5.0, 6)
     nPaths = 2**10
     seed = 314159265359
     sim = McSimulation(model0,
                        times,
                        nPaths,
                        seed,
                        False,
                        showProgress=False)
     dT = np.linspace(0.0, 5.0, 3)
     for k, t_ in enumerate(times):
         for dT_ in dT:
             F = np.array([
                 model0.futurePrice(t_, t_ + dT_, X, None)
                 for X in sim.X[:, k, :]
             ])
             #print(np.abs(np.mean(F) - 1.0))
             self.assertLess(np.abs(np.mean(F) - 1.0), 0.07)
コード例 #7
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)
コード例 #8
0
 def test_KnownSimulationValues(self):
     d = 2
     times = np.array([2.0, 4.0])
     sigmaT = np.zeros([2, 2, 2])
     sigmaT[0, :, :] = np.array([[0.10, 0.15], [0.20, 0.25]]).T
     sigmaT[1, :, :] = np.array([[0.15, 0.20], [0.25, 0.30]]).T
     chi = np.array([0.1, 0.2])
     #
     model0 = MarkovFutureModel(None, d, times, sigmaT, chi)
     #
     times = np.linspace(0.0, 5.0, 6)
     nPaths = 2**3
     seed = 314159265359
     sim = McSimulation(model0,
                        times,
                        nPaths,
                        seed,
                        False,
                        showProgress=False)
     # np.set_printoptions(precision=16)
     # print(sim.X[:,-1,:])
     Xref = np.array([[-0.6000110699011598, -0.6431768273428073],
                      [0.138146279288649, 0.1270588210285978],
                      [-0.2615455421299724, -0.3054110432018231],
                      [-1.1042559026028758, -1.0151899131194109],
                      [-0.934746072227638, -1.1542393979975838],
                      [-0.0771484387711384, -0.1328561062878627],
                      [-0.5411246272833143, -0.4660671538747663],
                      [0.6805897799894314, 0.7389950985079005]])
     #print(np.max(np.abs(sim.X[:,-1,:]-Xref)))
     self.assertLess(np.max(np.abs(sim.X[:, -1, :] - Xref)), 1.2e-16)
コード例 #9
0
 def test_AmcSwapSimulation(self):
     model = HWModel()
     obsTimes = np.linspace(0.0,10.0,121)
     nPaths = 2**7
     print('')
     # calibration
     seed0 = 314159265359
     mcSim0 = McSimulation(model,obsTimes,nPaths,seed0,True)
     # simulation
     seed0 = 141592653593
     mcSim1 = McSimulation(model,obsTimes,nPaths,seed0,True)
     swap = AmcSwap(self.legs,self.pors,mcSim0,2,self.discYtsH)
     scen = swap.scenarios(obsTimes,mcSim1)
     epe = np.average(np.maximum(scen,0.0),axis=0)
     plt.plot(obsTimes,epe)
     plt.show()
コード例 #10
0
 def test_HybridModelEvolution(self):
     times = np.array([0.0])
     nPaths = 1
     seed = 314159265359
     # risk-neutral simulation
     mcSim = McSimulation(self.model,times,nPaths,seed,False)
     p = mcSim.path(0)
     #
     self.assertEqual(p.asset(0.0,'USD'),self.model.forAssetModels[0].X0)
     self.assertEqual(p.asset(0.0,'GBP'),self.model.forAssetModels[1].X0)
     self.assertEqual(p.asset(0.0,'JPY'),self.model.forAssetModels[2].X0)
     #
     self.assertEqual(p.zeroBond(0.0,5.0,'EUR'),self.model.domRatesModel.yieldCurve.discount(5.0))
     self.assertEqual(p.zeroBond(0.0,5.0,'USD'),self.model.forRatesModels[0].yieldCurve.discount(5.0))
     self.assertEqual(p.zeroBond(0.0,5.0,'GBP'),self.model.forRatesModels[1].yieldCurve.discount(5.0))
     self.assertEqual(p.zeroBond(0.0,5.0,'JPY'),self.model.forRatesModels[2].yieldCurve.discount(5.0))
コード例 #11
0
 def test_FxSwap(self):
     today = ql.Settings.instance().getEvaluationDate()
     startDate = ql.WeekendsOnly().advance(today,ql.Period('5d'))
     endDate   = ql.WeekendsOnly().advance(today,ql.Period('1y'))
     eurLeg = ql.Leg([
         ql.SimpleCashFlow(1.0,startDate),
         ql.SimpleCashFlow(-1.0,endDate)
     ])
     usdLeg = ql.Leg([
         ql.SimpleCashFlow(1.25,startDate),
         ql.SimpleCashFlow(-1.25,endDate)
     ])
     swap = Swap([eurLeg,usdLeg],[1.0,-1.0],discYtsHs=None,currencyAliases=['EUR','USD'])
     obsTimes = np.array([0.0, 0.5, 1.1])
     timeLine = swap.timeLine(obsTimes)
     #
     print('')
     for t in timeLine:
         print('ObsTime: %.2f' % t)
         for p in timeLine[t]:
             print(p)
     #
     # we set up a very simplistic hybrid model
     eurModel = HWModel()
     usdModel = HWModel()
     fxModel  = AssetModel(1.25,0.15)
     hybModel = HybridModel('EUR',eurModel,['USD'],[fxModel],[usdModel],np.eye(3))
     mcSim    = McSimulation(hybModel,obsTimes,2,123,True)
     V = swap.scenarios(obsTimes,mcSim)
     print(V)
コード例 #12
0
 def test_QuantLibPayoff(self):
     model = self.sim.model
     simTimes = self.sim.times
     nPaths = 2**7
     seed = 3141592
     timeInterpolation = True
     sim = McSimulation(model,simTimes,nPaths,seed,timeInterpolation,False)
     qSim = QuantLibSimulation(sim) 
     #
     payoffs = self.timeline[0.0]
     scens = np.array([ [ payoff.discountedAt(path) for path in sim.paths() ]
                        for payoff in payoffs ])                           
     #
     qPayoffs = QuantLibPayoffs(payoffs)
     qScens = QuantLibDiscountedAt(qSim,qPayoffs)
     #
     self.assertAlmostEqual(np.mean(qScens),np.mean(scens),places=16)  # that's trivial at t=0
コード例 #13
0
 def test_SwapSimulation(self):
     model = HWModel()
     obsTimes = np.linspace(0.0,10.0,121)
     nPaths = 2**7
     seed = 314159265359
     print('')
     mcSim = McSimulation(model,obsTimes,nPaths,seed,True)
     swap = Swap(self.legs,self.pors,self.discYtsH)
     scen = swap.scenarios(obsTimes,mcSim)
     epe = np.average(np.maximum(scen,0.0),axis=0)
     plt.plot(obsTimes,epe)
     plt.show()
コード例 #14
0
 def test_SpreadSimulation(self):
     times = np.linspace(0.0, 10.0, 11)
     nPaths = 2**10
     seed = 1234
     # risk-neutral simulation
     print('')
     mcSim = McSimulation(self.model,times,nPaths,seed,False)
     # 
     T = 10.0
     P = Pay(Fixed(1.0),T)
     pv, err = fwd(mcSim,P)
     # domestic numeraire
     print('1.0 @ %4.1lfy %8.6lf - mc_err = %8.6lf' % (T,pv,err))
コード例 #15
0
 def test_ModelSetup(self):
     baseModel = HWModel()
     name1Model = HWModel(0.03, 0.0100, 0.10)
     name2Model = DcfModel(YieldCurve(0.02))
     name2Model.domAlias = 'Two'
     corr = np.identity(2)
     model = CreditModel(baseModel,['One', 'Two'],[name1Model,name2Model],corr)
     # basic tests
     self.assertEqual(model.size(),4)
     self.assertEqual(model.factors(),2)
     self.assertListEqual(model.stateAliases(),['x', 's', 'One_x', 'One_s'])  # no state for DCF model
     self.assertListEqual(model.factorAliases(),['x', 'One_x'])  # no state for DCF model
     #
     times = np.array([0.0, 5.0])
     nPaths = 1
     seed = 314159265359
     # risk-neutral simulation
     mcSim = McSimulation(model,times,nPaths,seed,False,False)
     p = mcSim.path(0)
     #
     self.assertEqual(p.zeroBond(0.0, 10.0, None), baseModel.yieldCurve.discount(10.0) )
     #
     self.assertEqual(p.hazardProcess(0.0,'One'), 1.0)
     self.assertAlmostEqual(p.hazardRate(0.0,'One'),0.03,13)
     self.assertEqual(p.survivalProb(0.0,10.0,'One'),name1Model.yieldCurve.discount(10.0))
     #
     self.assertEqual(p.hazardProcess(5.0,'Two'), name2Model.domCurve.discount(5.0))
     self.assertAlmostEqual(p.hazardRate(5.0,'Two'),0.02,13)
     self.assertEqual(p.survivalProb(5.0,10.0,'Two'),
         name2Model.domCurve.discount(10.0) / name2Model.domCurve.discount(5.0))
     # evolve manually
     X0 = baseModel.initialValues()
     X1 = np.array(X0)
     baseModel.evolve(0.0,X0,5.0,mcSim.dW[0,0,0:1],X1)
     self.assertTrue(np.allclose(X1,mcSim.X[0,1,:2],rtol=0.0,atol=1.0e-14))
     X0 = name1Model.initialValues()
     X1 = np.array(X0)
     name1Model.evolve(0.0,X0,5.0,mcSim.dW[0,0,1:2],X1)
     self.assertTrue(np.allclose(X1,mcSim.X[0,1,2:],rtol=0.0,atol=1.0e-14))
コード例 #16
0
 def test_CompareWithMarkovModel(self):
     kappa       = 1.35
     sigma_0     = 0.50
     sigma_infty = 0.17
     rho_infty   = 0.50
     model0 = AndersenFutureModel(None,kappa,sigma_0,sigma_infty,rho_infty)
     #
     def sigmaT(sigma_0, sigma_infty, rho_infty):
         h1 = -sigma_infty + rho_infty * sigma_0
         h2 = sigma_0 * np.sqrt(1.0 - rho_infty**2)
         hi = sigma_infty
         return np.array([ [h1, h2], [hi, 0.0] ])
     #
     def chi(kappa):
         return np.array([ kappa, 0.0 ])
     #
     sigmaT_ = sigmaT(sigma_0,sigma_infty,rho_infty)
     chi_    = chi(kappa)
     #
     d = 2
     times = np.array([0.0])
     model1 = MarkovFutureModel(None,d,times,np.array([ sigmaT_ ]),chi_)
     #
     times = np.linspace(0.0, 5.0, 3)
     nPaths = 2**3
     seed = 14159265359
     #
     sim0 = McSimulation(model0,times,nPaths,seed,False,showProgress=False)
     sim1 = McSimulation(model1,times,nPaths,seed,False,showProgress=False)
     #
     for idx in range(1,times.shape[0]):
         t = times[idx]
         for dT in [ 0.0, 1.0, 2.0, 5.0, 10.0]:
             T = t + dT
             F0 = np.array([ model0.futurePrice(t,T,X,None) for X in sim0.X[:,idx,:] ])
             F1 = np.array([ model1.futurePrice(t,T,X,None) for X in sim1.X[:,idx,:] ])
             # print(F0-F1)
             self.assertLess(np.max(np.abs(F0-F1)),3.0e-16)
コード例 #17
0
 def test_HybridSimulation(self):
     times = np.concatenate([np.linspace(0.0, 10.0, 11), [10.5]])
     nPaths = 2**13
     seed = 314159265359
     # risk-neutral simulation
     print('')
     mcSim = McSimulation(self.model, times, nPaths, seed, False)
     #
     T = 10.0
     P = Pay(Fixed(1.0), T)
     fw, err = fwd(mcSim, P)
     # domestic numeraire
     print('1.0   @ %4.1lfy %8.6lf - mc_err = %8.6lf' % (T, fw, err))
     # foreign assets
     for k, alias in enumerate(self.model.forAliases):
         p = Asset(T, alias)
         xT = self.model.forAssetModels[k].X0 * \
             self.model.forRatesModels[k].yieldCurve.discount(T) / \
             self.model.domRatesModel.yieldCurve.discount(T)
         fw, err = fwd(mcSim, p)
         print(alias +
               '   @ %4.1lfy %8.6lf vs %8.6lf (curve) - mc_err = %8.6lf' %
               (T, fw, xT, err))
     # domestic Libor rate
     Tstart = 10.0
     Tend = 10.5
     L = Pay(LiborRate(T, Tstart, Tend, alias='EUR'), Tend)
     fw, err = fwd(mcSim, L)
     Lref = (mcSim.model.domRatesModel.yieldCurve.discount(Tstart) /    \
             mcSim.model.domRatesModel.yieldCurve.discount(Tend) - 1) / \
            (Tend - Tstart)
     print('L_EUR @ %4.1lfy %8.6lf vs %8.6lf (curve) - mc_err = %8.6lf' %
           (T, fw, Lref, err))
     # foreign Lbor rates
     for k, alias in enumerate(self.model.forAliases):
         L = Pay(
             LiborRate(T, Tstart, Tend, alias=alias) * Asset(Tend, alias),
             Tend)
         fw, err = fwd(mcSim, L)
         fw *= mcSim.model.domRatesModel.yieldCurve.discount(Tend) / \
               mcSim.model.forRatesModels[k].yieldCurve.discount(Tend) / \
               mcSim.model.forAssetModels[k].X0
         err *= mcSim.model.domRatesModel.yieldCurve.discount(Tend) / \
                mcSim.model.forRatesModels[k].yieldCurve.discount(Tend) / \
                mcSim.model.forAssetModels[k].X0
         Lref = (mcSim.model.forRatesModels[k].yieldCurve.discount(Tstart) /    \
                 mcSim.model.forRatesModels[k].yieldCurve.discount(Tend) - 1) / \
                (Tend - Tstart)
         print('L_%s @ %4.1lfy %8.6lf vs %8.6lf (curve) - mc_err = %8.6lf' %
               (alias, T, fw, Lref, err))
コード例 #18
0
 def test_AmcSwapSetup(self):
     model = HWModel()
     obsTimes = np.array([0.0])
     nPaths = 1
     seed = 1
     print('')
     mcSim = McSimulation(model,obsTimes,nPaths,seed,True)
     swap = AmcSwap(self.legs,self.pors,mcSim,2,self.discYtsH)
     #swap.cashFlows(8.1)
     timeLine = swap.timeLine([1.0, 2.0, 3.0])
     #
     for t in timeLine:
         print('ObsTime: %.2f' % t)
         for p in timeLine[t]:
             print(p)
コード例 #19
0
 def test_QuantLibSimulation(self):
     model = self.sim.model
     simTimes = self.sim.times
     nPaths = 2**7
     seed = 314159
     timeInterpolation = True
     sim = McSimulation(model,simTimes,nPaths,seed,timeInterpolation,False)
     #
     qSim = QuantLibSimulation(sim)                                   # just copy
     #
     simTimes = np.array([0.0, 1.0, 2.0])
     nPaths = 2
     seed = 112
     timeInterpolation = False
     qSim = QuantLibSimulation(sim,nPaths=nPaths,times=simTimes,seed=seed,timeInterpolation=timeInterpolation)  # adjust simulation details
     self.assertEqual(qSim.nPaths(),nPaths)
     self.assertEqual(np.max(np.abs(qSim.simTimes() - simTimes)), 0.0)
コード例 #20
0
 def setUp(self):
     today     = ql.Date(5,ql.October,2020)
     ql.Settings.instance().evaluationDate = today
     #
     discYtsH   = ql.YieldTermStructureHandle(
                      ql.FlatForward(today,0.015,ql.Actual365Fixed()))
     projYtsH   = ql.YieldTermStructureHandle(
                      ql.FlatForward(today,0.020,ql.Actual365Fixed()))
     index      = ql.Euribor6M(projYtsH)
     startDate  = ql.Date(12,ql.October,2020)
     endDate    = ql.Date(12,ql.October,2030)
     calendar   = ql.TARGET()
     fixedTenor = ql.Period('1y')
     floatTenor = ql.Period('6m')
     fixedSchedule = ql.MakeSchedule(startDate,endDate,tenor=fixedTenor,calendar=calendar)
     floatSchedule = ql.MakeSchedule(startDate,endDate,tenor=floatTenor,calendar=calendar)
     couponDayCount = ql.Thirty360()
     notional   = 1.0
     fixedRate  = 0.02
     fixedLeg   = ql.FixedRateLeg(fixedSchedule,couponDayCount,[notional],[fixedRate])
     floatingLeg = ql.IborLeg([notional],floatSchedule,index)
     #
     swap = Swap([fixedLeg,floatingLeg],[1.0,-1.0],discYtsH)
     #
     observationTimes = np.linspace(0.0,10.0,11)
     self.timeline = swap.timeLine(observationTimes)
     #
     yc = YieldCurve(0.02)
     d = 2
     times = np.array(  [ 1.0,    5.0,   10.0    ])
     sigma = np.array([ [ 0.0050, 0.0060, 0.0070 ],
                        [ 0.0050, 0.0060, 0.0070 ] ])
     slope = np.array([ [ 0.0100, 0.0100, 0.0100 ],
                        [ 0.0200, 0.0200, 0.0200 ] ])
     curve = np.array([ [ 0.0000, 0.0000, 0.0000 ],
                        [ 0.0000, 0.0000, 0.0000 ] ])
     delta = np.array(  [ 1.0,  20.0 ])
     chi   = np.array(  [ 0.01, 0.15 ])
     Gamma = np.identity(2)        
     model = QuasiGaussianModel(yc,d,times,sigma,slope,curve,delta,chi,Gamma)
     #
     nPaths = 1
     simTimes = observationTimes
     seed = 314159265359
     timeInterpolation = True
     self.sim = McSimulation(model,simTimes,nPaths,seed,timeInterpolation,False)
コード例 #21
0
 def test_HybridVolAdjusterCalculation(self):
     model = copy.deepcopy(self.model)
     # model = copy.deepcopy(self.gaussianModel)
     hybVolAdjTimes = np.linspace(0.0, 20.0, 21)
     model.recalculateHybridVolAdjuster(hybVolAdjTimes)
     plt.plot(model.hybAdjTimes, model.hybVolAdj[0], 'r*', label='USD')
     plt.plot(model.hybAdjTimes, model.hybVolAdj[1], 'b*', label='GBP')
     plt.legend()
     #
     times = np.linspace(0.0, 20.0, 101)
     plt.plot(times, [model.hybridVolAdjuster(0, t) for t in times], 'r-')
     plt.plot(times, [model.hybridVolAdjuster(1, t) for t in times], 'b-')
     plt.show()
     #
     # return
     times = np.linspace(0.0, 10.0, 11)
     nPaths = 2**13
     seed = 314159265359
     # risk-neutral simulation
     print('')
     mcSim = McSimulation(model, times, nPaths, seed, False)
     #
     T = 10.0
     for k, alias in enumerate(model.forAliases):
         # ATM forward
         xT = model.forAssetModels[k].X0 * \
              model.forRatesModels[k].yieldCurve.discount(T) / \
              model.domRatesModel.yieldCurve.discount(T)
         K = Fixed(xT)
         Z = Fixed(0.0)
         C = Pay(Max(Asset(T, alias) - K, Z), T)
         fw, err = fwd(mcSim, C)
         vol = BlackImpliedVol(fw, xT, xT, T, 1.0)
         vega = BlackVega(xT, xT, vol, T)
         err /= vega
         volRef = model.forAssetModels[k].sigma
         print('C_%s @ %4.1lfy %8.6lf vs %8.6lf (curve) - mc_err = %8.6lf' %
               (alias, T, vol, volRef, err))
         P = Pay(Max(K - Asset(T, alias), Z), T)
         fw, err = fwd(mcSim, P)
         vol = BlackImpliedVol(fw, xT, xT, T, -1.0)
         vega = BlackVega(xT, xT, vol, T)
         err /= vega
         volRef = model.forAssetModels[k].sigma
         print('P_%s @ %4.1lfy %8.6lf vs %8.6lf (curve) - mc_err = %8.6lf' %
               (alias, T, vol, volRef, err))
コード例 #22
0
 def test_ModelEvolution(self):
     model = self.model
     #
     times = np.linspace(0.0, 10.0, 11)
     nPaths = 2**3
     seed = 314159265359
     # risk-neutral simulation
     mcSim = McSimulation(model, times, nPaths, seed, showProgress=False)
     #
     T = 10
     P10 = np.array(
         [1.0 / model.numeraire(T, x) for x in mcSim.X[:, -1, :]])
     #print(np.mean(P10))
     #print(model.zeroBondPrice(0.0,10.0,model.r0))
     self.assertAlmostEqual(np.mean(P10), 0.6480670673701923, 12)
     self.assertAlmostEqual(model.zeroBondPrice(0.0, 10.0, model.r0),
                            0.5997174951900259, 12)
コード例 #23
0
 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])))
コード例 #24
0
 def test_MartingaleProperty(self):
     kappa       = 1.35
     sigma_0     = 0.50
     sigma_infty = 0.17
     rho_infty   = 0.50
     model = AndersenFutureModel(None,kappa,sigma_0,sigma_infty,rho_infty)
     #
     times = np.linspace(0.0, 5.0, 3)
     nPaths = 2**13
     seed = 14159265359
     sim = McSimulation(model,times,nPaths,seed,False,showProgress=False)
     #
     for idx in range(1,times.shape[0]):
         t = times[idx]
         for dT in [ 0.0, 1.0, 2.0, 5.0, 10.0]:
             T = t + dT
             F = np.array([ model.futurePrice(t,T,X,None) for X in sim.X[:,idx,:] ])
             Fav = np.mean(F)
             sigma = np.std(F) / np.sqrt(t)
             # print('t: %6.2f, T: %6.2f, F: %6.4f, sigma: %6.4f' % (t,T,Fav,sigma) )
             # print(np.abs(Fav - 1.0))
             self.assertLess(np.abs(Fav - 1.0),0.0026)
コード例 #25
0
 def test_HybridVolAdjusterCalculation(self):
     # we set up a hybrid model consistent to QuantLib
     domAlias = 'EUR'
     domModel = HWModel(0.01, 0.0050, 0.01)
     forAliases = ['USD', 'GBP']
     forAssetModels = [AssetModel(1.0, 0.30), AssetModel(2.0, 0.15)]
     forRatesModels = [
         HWModel(0.02, 0.0060, 0.02),
         HWModel(0.02, 0.0070, 0.03)
     ]
     corr = np.identity(2 * len(forAliases) + 1)
     # [ EUR, USD-EUR, USD, GBP-EUR, GBP ]
     #   0    1        2    3        4
     # USD-EUR - EUR
     corr[0, 1] = 0.5
     corr[1, 0] = 0.5
     # USD-EUR - USD
     corr[1, 2] = -0.5
     corr[2, 1] = -0.5
     # EUR - USD
     corr[0, 2] = -0.5
     corr[2, 0] = -0.5
     # GBP-EUR - EUR
     corr[0, 3] = -0.5
     corr[3, 0] = -0.5
     # GBP-EUR - GBP
     corr[3, 4] = 0.5
     corr[4, 3] = 0.5
     # EUR - GBP
     corr[0, 4] = -0.8
     corr[4, 0] = -0.8
     # USD - GBP
     corr[2, 4] = 0.0
     corr[4, 2] = 0.0
     # overwrtite
     # corr = np.identity(2 * len(forAliases) + 1)
     # print(corr-corr.transpose())
     model = HybridModel(domAlias, domModel, forAliases, forAssetModels,
                         forRatesModels, corr)
     hybVolAdjTimes = np.linspace(0.0, 20.0, 21)
     model.recalculateHybridVolAdjuster(hybVolAdjTimes)
     #plt.plot(model.hybAdjTimes,model.hybVolAdj[0], 'r*')
     #plt.plot(model.hybAdjTimes,model.hybVolAdj[1], 'b*')
     #
     #times = np.linspace(0.0,20.0,101)
     #plt.plot(times,[ model.hybridVolAdjuster(0,t) for t in times ]  , 'r-')
     #plt.plot(times,[ model.hybridVolAdjuster(1,t) for t in times ]  , 'b-')
     # plt.show()
     #
     times = np.linspace(0.0, 10.0, 11)
     nPaths = 2**13
     seed = 314159265359
     # risk-neutral simulation
     print('')
     mcSim = McSimulation(model, times, nPaths, seed, False)
     #
     T = 10.0
     for k, alias in enumerate(model.forAliases):
         # ATM forward
         xT = model.forAssetModels[k].X0 * \
              model.forRatesModels[k].yieldCurve.discount(T) / \
              model.domRatesModel.yieldCurve.discount(T)
         K = Fixed(xT)
         Z = Fixed(0.0)
         C = Pay(Max(Asset(T, alias) - K, Z), T)
         fw, err = fwd(mcSim, C)
         vol = BlackImpliedVol(fw, xT, xT, T, 1.0)
         vega = BlackVega(xT, xT, vol, T)
         err /= vega
         volRef = model.forAssetModels[k].sigma
         print('C_%s @ %4.1lfy %8.6lf vs %8.6lf (curve) - mc_err = %8.6lf' %
               (alias, T, vol, volRef, err))
         P = Pay(Max(K - Asset(T, alias), Z), T)
         fw, err = fwd(mcSim, P)
         vol = BlackImpliedVol(fw, xT, xT, T, -1.0)
         vega = BlackVega(xT, xT, vol, T)
         err /= vega
         volRef = model.forAssetModels[k].sigma
         print('P_%s @ %4.1lfy %8.6lf vs %8.6lf (curve) - mc_err = %8.6lf' %
               (alias, T, vol, volRef, err))
コード例 #26
0
 def test_HybridModelWithDeterministicRates(self):
     curve0 = YieldCurve(0.03)
     dcfModel0 = DcfModel(curve0)
     #
     times = np.array([0.0, 1.0])
     nPaths = 1
     seed = 314159265359
     # hybrid adjuster
     hybAdjTimes = np.array([0.0, 1.0, 2.0])
     # simulate deterministic model only
     mcSim = McSimulation(dcfModel0,times,nPaths,seed,False)
     self.assertEqual(mcSim.path(0).zeroBond(1.0,10.0,None),curve0.discount(10.0)/curve0.discount(1.0))
     # simulate deterministic domestic model
     hwModel = HWModel(0.01,0.0050,0.03)
     asModel = AssetModel(1.0,0.30)
     corr = np.identity(2)
     model = HybridModel('EUR',dcfModel0,['USD'],[asModel],[hwModel],corr)
     model.recalculateHybridVolAdjuster(hybAdjTimes)
     mcSim = McSimulation(model,times,nPaths,seed,False)
     dcfModel0.domAlias = 'EUR'
     p = mcSim.path(0)
     self.assertEqual(p.asset(0.0,'USD'),self.model.forAssetModels[0].X0)
     self.assertEqual(p.zeroBond(0.0,5.0,'EUR'),curve0.discount(5.0))
     self.assertEqual(p.zeroBond(0.0,5.0,'USD'),model.forRatesModels[0].yieldCurve.discount(5.0))
     # simulate deterministic foreign model
     model = HybridModel('EUR',hwModel,['USD'],[asModel],[dcfModel0],corr)
     model.recalculateHybridVolAdjuster(hybAdjTimes)
     mcSim = McSimulation(model,times,nPaths,seed,False)
     dcfModel0.domAlias = 'USD'
     p = mcSim.path(0)
     self.assertEqual(p.asset(0.0,'USD'),self.model.forAssetModels[0].X0)
     self.assertEqual(p.zeroBond(0.0,5.0,'EUR'),model.domRatesModel.yieldCurve.discount(5.0))
     self.assertEqual(p.zeroBond(0.0,5.0,'USD'),curve0.discount(5.0))
     # simulate deterministic domestic and foreign curve
     curve1 = YieldCurve(0.05)
     dcfModel1 = DcfModel(curve1)
     corr = np.identity(1)
     model = HybridModel('EUR',dcfModel0,['USD'],[asModel],[dcfModel1],corr)
     model.recalculateHybridVolAdjuster(hybAdjTimes)
     mcSim = McSimulation(model,times,nPaths,seed,False)
     dcfModel0.domAlias = 'EUR'
     dcfModel1.domAlias = 'USD'
     p = mcSim.path(0)
     self.assertEqual(p.asset(0.0,'USD'),self.model.forAssetModels[0].X0)
     self.assertEqual(p.zeroBond(0.0,5.0,'EUR'),curve0.discount(5.0))
     self.assertEqual(p.zeroBond(0.0,5.0,'USD'),curve1.discount(5.0))