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))
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))