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))
예제 #2
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)
 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))
 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))
    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
        ]

        curve = YieldCurve(0.03)
        path = DcfModel(curve).path()

        cfPVs = np.array([p.discountedAt(path) for p in cfs])
        discounts0 = np.array([curve.discount(t + dT0) for t in liborTimes])
        discounts1 = np.array(
            [curve.discount(t + dT0 + dT1) for t in liborTimes])
        liborsCv = (discounts0 / discounts1 - 1.0) / dT1
        liborsMC = cfPVs / discounts1
        print('')
        print('  T     LiborRate  ModelLibor')
        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 test_payoffTimes(self):
     L1 = LiborRate(1.0, 1.0, 1.5)
     L2 = LiborRate(2.0, 3.0, 3.5)
     P = Pay(L1 + L2 + 1.0, 5.0)
     self.assertListEqual(list(P.observationTimes()), [0.0, 1.0, 2.0, 5.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))