def test_equality_with_simm_for_irs(): irs = IRS(notional=100, timeToSwapStart=ql.Period(2, ql.Days), timeToSwapEnd=ql.Period(1, ql.Years), swapDirection=SwapDirection.RECEIVER, index=InterestRateIndex.EURIBOR6M) ois = OIS(notional=100, timeToSwapStart=ql.Period(2, ql.Days), timeToSwapEnd=ql.Period(1, ql.Years), swapDirection=SwapDirection.RECEIVER, index=InterestRateIndex.FEDFUNDS) ul_swap = IRS(notional=100, timeToSwapStart=ql.Period(1, ql.Years), timeToSwapEnd=ql.Period(2, ql.Years), swapDirection=SwapDirection.RECEIVER, index=InterestRateIndex.USDLIBOR3M) swaption = Swaption(underlyingSwap=ul_swap, optionMaturity=ql.Period(1, ql.Years)) simm = SIMM() simm.add_trades([irs, ois, ul_swap, swaption]) ccpimm = CCPIMM() ccpimm.add_trades([irs, ois, ul_swap, swaption]) assert simm.get_im_post() != 0 assert ccpimm.get_im_post() != 0 assert approx(simm.get_im_post(), rel=0.00001) == ccpimm.get_im_post() * sqrt(10 / 5)
def test_get_im_swaption(): tts = ql.Period(2, ql.Years) tte = ql.Period(10, ql.Years) swap1 = IRS(600, tts, tte, SwapDirection.RECEIVER, InterestRateIndex.USDLIBOR3M) swaption1 = Swaption(swap1, ql.Period(2, ql.Years)) simm = SIMM() simm.add_trades(swaption1) im = simm.get_im_receive() swap2 = IRS(600, tts, tte, SwapDirection.RECEIVER, InterestRateIndex.EURIBOR6M) simm.add_trades(swap2) im = simm.get_im_receive()
def test_EUR_irvol_sensi(initialize_test): tts = ql.Period(2, ql.Years) tte = ql.Period(10, ql.Years) swap1 = IRS(600, tts, tte, SwapDirection.RECEIVER, InterestRateIndex.EURIBOR6M) swaption1 = Swaption(swap1, ql.Period(2, ql.Years)) sensis1 = swaption1.get_simm_sensis_irvol() tts = ql.Period(6, ql.Months) swap2 = IRS(600, tts, tte, SwapDirection.RECEIVER, InterestRateIndex.EURIBOR6M) swaption2 = Swaption(swap2, ql.Period(6, ql.Months)) sensis2 = swaption2.get_simm_sensis_irvol() asdf = 1
def test_get_bumped_copy(): bumpsize = 0.01 option = IRS(notional = 100000, timeToSwapStart=ql.Period(1, ql.Years), timeToSwapEnd=ql.Period(5, ql.Years), swapDirection=SwapDirection.PAYER, index=InterestRateIndex.EURIBOR6M, fixed_rate=0.01) option_copy = option.get_bumped_copy(bumpsize) assert option_copy.notional == option.notional * (1 + bumpsize) assert approx(option_copy.get_price(), abs=0.000001) == option.get_price() * (1 + bumpsize) asdf = 1 for option_sensi, option_copy_sensi in zip(option.get_simm_sensis(), option_copy.get_simm_sensis()): assert approx(float(option_sensi['amountUSD']) * (1 + bumpsize), abs=0.000001) == float( option_copy_sensi['amountUSD'])
def test_EURIBOR6M_initiation(initialize_test): tts = ql.Period(2, ql.Days) tte = ql.Period(10, ql.Years) swap = IRS(100, tts, tte, SwapDirection.PAYER, InterestRateIndex.EURIBOR6M) swap.get_price() swap.get_fixed_rate() swap.get_delta()
def __init__(self, underlyingSwap: IRS = IRS(), optionMaturity: ql.Period = ql.Period(1, ql.Years), tradeDirection: TradeDirection = TradeDirection.LONG): if underlyingSwap.tradeDirection == TradeDirection.LONG: tradeType = TradeType.CALL # A swaption on a payer Swap is a Call Swaption as the call's value raises as the interest rate rises else: tradeType = TradeType.PUT # Vice versa the above self.K = underlyingSwap.ql_instrument.fixedRate() super(Swaption, self).__init__( notional=underlyingSwap.notional, currency=underlyingSwap.currency, s=underlyingSwap.s, m=underlyingSwap.e, # assuming the Swaption is physically settled t=convert_period_to_days(optionMaturity) / 360, e=underlyingSwap.e, tradeType=tradeType, tradeDirection=tradeDirection) self.underlying_swap = underlyingSwap self.ql_underlying_swap = underlyingSwap.ql_instrument self.S = self.ql_underlying_swap.fairRate() self.ql_optionMaturity = optionMaturity exerciseDate = today + optionMaturity exercise = ql.EuropeanExercise(exerciseDate) swaption = ql.Swaption(self.ql_underlying_swap, exercise) indexname = self.underlying_swap.index.name currency = IRSConventions[indexname].value['Currency'] self.currency = currency discountcuve = DiscountCurve[currency.name].value.value swaptionVol = SwaptionVolatility[currency.name].value pricer = SwaptionConventions[currency.name].value['Pricer'] real_surface_engine = pricer(discountcuve, swaptionVol) swaption.setPricingEngine(real_surface_engine) self.ql_swaption = swaption
def test_adding_and_removing_trades(): ca = CollateralAgreement(margining=Margining.MARGINED, initialMargining=InitialMargining.SIMM) ca.link_sa_ccr_instance(SA_CCR(collateralAgreement=ca)) im_model = ca.get_im_model() vm_model = ca.get_vm_model() sa_ccr_model = ca.get_sa_ccr_model() assert isinstance(im_model, SIMM) assert isinstance(vm_model, VariationMarginModel) trade = IRS(notional=100, timeToSwapStart=ql.Period(2, ql.Days), timeToSwapEnd=ql.Period(1, ql.Years), swapDirection=SwapDirection.RECEIVER, index=InterestRateIndex.EURIBOR6M) ca.add_trades(trade) assert ca.trades == [trade] assert im_model.trades == [trade] assert vm_model.trades == [trade] assert sa_ccr_model.trades == [trade] trade2 = EquityOption(maturity=ql.Period(1, ql.Years)) trade3 = EquityOption(maturity=ql.Period(2, ql.Years)) ca.add_trades(trade2) ca.add_trades(trade3) ca.remove_trades(trades=trade) assert ca.trades == [trade2, trade3] assert im_model.trades == [trade2, trade3] assert vm_model.trades == [trade2, trade3] assert sa_ccr_model.trades == [trade2, trade3]
def test_im_post_vs_receive_option(): # When setting up at the money options that expire soon enough the long side of the option should bear significant less IM than the short side swap = IRS(notional=100, timeToSwapStart=ql.Period(6, ql.Months), timeToSwapEnd=ql.Period(1, ql.Years), swapDirection=SwapDirection.RECEIVER, index=InterestRateIndex.EURIBOR6M) options = [] swaption = Swaption(underlyingSwap=swap, optionMaturity=ql.Period(6, ql.Months), tradeDirection=TradeDirection.LONG) options.append(swaption) eqOpt1 = EquityOption(maturity=ql.Period(2, ql.Months), tradeType=TradeType.CALL, tradeDirection=TradeDirection.LONG) options.append(eqOpt1) for option in options: simm = SIMM() simm.add_trades(option) im_receive = simm.get_im_receive() im_post = -1 * simm.get_im_post() assert im_post * 1.1 < im_receive eqOpt2 = EquityOption(maturity=ql.Period(2, ql.Months), tradeType=TradeType.PUT, tradeDirection=TradeDirection.SHORT) simm = SIMM() simm.add_trades(eqOpt2) im_receive = simm.get_im_receive() im_post = -1 * simm.get_im_post() assert im_receive * 1.1 < im_post
def test_setup_simm(): tts = ql.Period(2, ql.Days) tte = ql.Period(10, ql.Years) swap = IRS(100, tts, tte, SwapDirection.PAYER, InterestRateIndex.EURIBOR6M, fixed_rate=0.05) simm = SIMM() simm.add_trades(swap) swap2 = IRS(600, tts, tte, SwapDirection.RECEIVER, InterestRateIndex.USDLIBOR3M) swap3 = IRS(400, tts, tte, SwapDirection.RECEIVER, InterestRateIndex.EURIBOR6M) simm.add_trades([swap2, swap3]) yield simm
def test_EURIBOR6MSwaption(initialize_test): fw_swap = IRS(notional=1000000, timeToSwapStart=ql.Period(1, ql.Years), timeToSwapEnd=ql.Period(20, ql.Years), swapDirection=SwapDirection.PAYER, index=InterestRateIndex.EURIBOR6M) swaption = Swaption(underlyingSwap=fw_swap, optionMaturity=ql.Period(1, ql.Years), tradeDirection=TradeDirection.SHORT) print(swaption.get_price()) print(swaption.get_delta())
def test_im_post_vs_receive_linear(): # When setting up an IRS IM post should be = IM receive irs = IRS(notional=100, timeToSwapStart=ql.Period(2, ql.Days), timeToSwapEnd=ql.Period(1, ql.Years), swapDirection=SwapDirection.RECEIVER, index=InterestRateIndex.EURIBOR6M) simm = SIMM() simm.add_trades(irs) im_receive = simm.get_im_receive() im_post = simm.get_im_post() assert im_receive > 0 assert im_post < 0 assert -1 * im_receive == im_post
def test_temporarily_disable_mta(): ca_with_mta = CollateralAgreement(mta=1000000, threshold=0) ca_with_mta.link_sa_ccr_instance(SA_CCR(ca_with_mta)) ca_no_mta = CollateralAgreement(mta=0, threshold=0) ca_no_mta.link_sa_ccr_instance(SA_CCR(ca_no_mta)) trade = IRS(notional=100000000) ca_with_mta.add_trades(trade) ca_no_mta.add_trades(trade) allocator_with_mta = EulerAllocator(ca_with_mta) allocator_no_mta = EulerAllocator(ca_no_mta) with_mta = allocator_with_mta.allocate_ead()[trade] no_mta = allocator_no_mta.allocate_ead()[trade] assert pytest.approx(with_mta, rel=0.00001) == no_mta not in [None, 0]
def init_ca(): from instruments.interestRateInstrument.ois import OIS from instruments.interestRateInstrument.irs import IRS from instruments.equity_instruments.equityOption import EquityOption from collateralAgreement.collateralAgreement import CollateralAgreement from sa_ccr.sa_ccr import SA_CCR trade1 = OIS(fixed_rate=0.01) trade2 = IRS(fixed_rate=0.01) trade3 = Swaption() trade4 = EquityOption() # trade4 = EquityOption() ca = CollateralAgreement() ca.link_sa_ccr_instance(SA_CCR(ca)) ca.add_trades([trade1, trade2, trade3, trade4]) yield ca
def test_central_forward_backward_difference(): IRS1 = IRS(swapDirection=SwapDirection.PAYER) IRS2 = IRS(swapDirection=SwapDirection.RECEIVER) ca = CollateralAgreement() ca.link_sa_ccr_instance(SA_CCR(ca)) ca.add_trades([IRS1, IRS2]) allocator = EulerAllocator(ca) forward = allocator.allocate_im() allocator.fdApproach2 = FdApproach2.Forward forward2 = allocator.allocate_im() assert forward == forward2 allocator.fdApproach2 = FdApproach2.Central central = allocator.allocate_im() allocator.fdApproach2 = FdApproach2.Backward backward = allocator.allocate_im() assert approx(central[IRS1], abs=0.01) == 0 assert approx(central[IRS2], abs=0.01) == 0 assert approx(forward[IRS1], abs=0.1) != 0 assert approx(backward[IRS2], abs=0.1) != 0 assert approx(forward[IRS1], rel=0.01) == -backward[IRS1] assert approx(forward[IRS2], rel=0.01) == -backward[IRS2] asdf = 1
def test_c_calculation(): trade1 = EquityOption(maturity=ql.Period(1, ql.Years), strike=EquitySpot.ADS.value.value() - 5) trade = IRS(notional=100, timeToSwapStart=ql.Period(2, ql.Days), timeToSwapEnd=ql.Period(1, ql.Years), swapDirection=SwapDirection.RECEIVER, index=InterestRateIndex.EURIBOR6M, fixed_rate=0.00) ca_no_im = CollateralAgreement(margining=Margining.MARGINED, initialMargining=InitialMargining.NO_IM) ca_no_im.link_sa_ccr_instance(SA_CCR(collateralAgreement=ca_no_im)) ca_no_im.add_trades([trade1, trade]) assert ca_no_im.get_C() == ca_no_im.get_vm_model().get_vm() != 0 ca_simm = CollateralAgreement(margining=Margining.MARGINED, initialMargining=InitialMargining.SIMM) ca_simm.link_sa_ccr_instance(SA_CCR(collateralAgreement=ca_simm)) ca_simm.add_trades([trade1, trade]) assert 0 != ca_simm.get_C() != ca_simm.get_vm_model().get_vm() != 0 assert ca_simm.get_C() - ca_simm.get_im_model().get_im_receive( ) == ca_simm.get_vm_model().get_vm() ca_ccp = CollateralAgreement(margining=Margining.MARGINED, clearing=Clearing.CLEARED, initialMargining=InitialMargining.CCPIMM) ca_ccp.link_sa_ccr_instance(SA_CCR(collateralAgreement=ca_ccp)) ca_ccp.add_trades([trade1, trade]) assert ca_ccp.get_C() == ca_ccp.get_vm_model().get_vm() != 0 ead_no_im = ca_no_im.get_sa_ccr_model().get_ead() ead_simm = ca_simm.get_sa_ccr_model().get_ead() ead_ccp = ca_ccp.get_sa_ccr_model().get_ead() assert ead_simm < ead_ccp < ead_no_im asdf = 1
def test_adding_and_removing_trades_error_handling(): trade = IRS(notional=100, timeToSwapStart=ql.Period(2, ql.Days), timeToSwapEnd=ql.Period(1, ql.Years), swapDirection=SwapDirection.RECEIVER, index=InterestRateIndex.EURIBOR6M) trade2 = EquityOption(maturity=ql.Period(1, ql.Years)) trade3 = EquityOption(maturity=ql.Period(2, ql.Years)) ca = CollateralAgreement(margining=Margining.MARGINED, initialMargining=InitialMargining.SIMM) ca.link_sa_ccr_instance(SA_CCR(collateralAgreement=ca)) ca.add_trades(trade) with pytest.raises(Exception): ca.add_trades(trade) ca.add_trades(trade2) with pytest.raises(Exception): ca.add_trades([trade3, trade3]) ca.remove_trades(trade2) with pytest.raises(Exception): ca.add_trades([trade2, trade3, trade2]) ca.add_trades(trade2) assert [trade, trade2] == ca.trades
def get_bumped_copy(self, rel_bump_size: float = 0.00001, abs_bump_size: float = 0.01, bump_approach: FdApproach = FdApproach.Relative): if bump_approach == FdApproach.Relative: new_ul_notional = self.notional * (1 + rel_bump_size) elif bump_approach == FdApproach.Absolute: new_ul_notional = self.notional + abs_bump_size else: raise (Exception('Weird stuff is happening')) new_ul_swap = IRS( notional=new_ul_notional, timeToSwapStart=self.underlying_swap.ql_timeToSwapStart, timeToSwapEnd=self.underlying_swap.ql_timeToSwapEnd, swapDirection=self.underlying_swap.swapDirection, index=self.underlying_swap.index, fixed_rate=self.underlying_swap.get_fixed_rate(), float_spread=self.underlying_swap.float_spread) return Swaption(underlyingSwap=new_ul_swap, optionMaturity=self.ql_optionMaturity, tradeDirection=self.tradeDirection)
def test_simm_sensi(): tts = ql.Period(2, ql.Days) tte = ql.Period(10, ql.Years) swap = IRS(100, tts, tte, SwapDirection.PAYER, InterestRateIndex.EURIBOR6M, fixed_rate=0.05) sensis = swap.get_simm_sensis() asdf = 1
def test_syncing_and_desyncing(): ca = CollateralAgreement(margining=Margining.MARGINED, initialMargining=InitialMargining.SIMM) ca.link_sa_ccr_instance(SA_CCR(ca)) trade1 = EquityOption(maturity=ql.Period(1, ql.Years), strike=EquitySpot.ADS.value.value() - 5) trade2 = IRS(notional=100, timeToSwapStart=ql.Period(2, ql.Days), timeToSwapEnd=ql.Period(1, ql.Years), swapDirection=SwapDirection.RECEIVER, index=InterestRateIndex.EURIBOR6M, fixed_rate=0.00) trade3 = IRS(notional=100, timeToSwapStart=ql.Period(2, ql.Days), timeToSwapEnd=ql.Period(1, ql.Years), swapDirection=SwapDirection.RECEIVER, index=InterestRateIndex.USDLIBOR3M, fixed_rate=0.01) ca.add_trades(trade1) ca.sync_im_model = False assert ca.vm_model.trades == [trade1] assert ca.im_model.trades == [trade1] ca.add_trades(trade2) assert ca.vm_model.trades == [trade1, trade2] assert ca.im_model.trades == [trade1] ca.sync_im_model = True assert ca.im_model.trades == [trade1, trade2] ca.add_trades(trade3) assert ca.vm_model.trades == [trade1, trade2, trade3] assert ca.im_model.trades == [trade1, trade2, trade3] # now check if the calculations also add up at least for VM ca = CollateralAgreement(margining=Margining.MARGINED, initialMargining=InitialMargining.NO_IM) ca.link_sa_ccr_instance(SA_CCR(ca)) npv_1 = fxConvert(trade1.currency, Currency.USD, trade1.get_price()) npv_2 = fxConvert(trade2.currency, Currency.USD, trade2.get_price()) npv_3 = fxConvert(trade3.currency, Currency.USD, trade3.get_price()) ca.add_trades(trade1) ca.sync_vm_model = False assert ca.get_C() == ca.get_vm_model().get_vm() == npv_1 != 0 ca.add_trades(trade2) assert ca.get_C() == npv_1 ca.sync_vm_model = True assert ca.get_C() == npv_1 + npv_2 ca.add_trades(trade3) assert ca.get_C() == npv_1 + npv_2 + npv_3 # a few sanity checks for SA_CCR ca = CollateralAgreement(margining=Margining.MARGINED, initialMargining=InitialMargining.SIMM) local_sa_ccr_model = SA_CCR(ca) ca.link_sa_ccr_instance(local_sa_ccr_model) assert local_sa_ccr_model.get_ead() == 0 ca.add_trades(trade1) ca.sync_im_model = False ca.sync_vm_model = False test_value = local_sa_ccr_model.get_ead() assert test_value > 0 assert local_sa_ccr_model.trades == [trade1] ca.add_trades(trade2) test_value_2 = local_sa_ccr_model.get_ead() assert ca.vm_model.trades == [trade1] assert ca.im_model.trades == [trade1] ca.sync_vm_model = True ca.sync_im_model = True ca.sync_sa_ccr_model = True test_value_3 = local_sa_ccr_model.get_ead() assert test_value_2 != test_value_3 assert local_sa_ccr_model.trades == [trade1, trade2] assert ca.vm_model.trades == [trade1, trade2] assert ca.im_model.trades == [trade1, trade2] ca.add_trades(trade3) test_value_4 = local_sa_ccr_model.get_ead() assert test_value_4 != test_value_3 assert local_sa_ccr_model.trades == [trade1, trade2, trade3] assert ca.vm_model.trades == [trade1, trade2, trade3] assert ca.im_model.trades == [trade1, trade2, trade3]
def test_simm_sensi_ircurve(): tts = ql.Period(2, ql.Days) tte = ql.Period(10, ql.Years) swap = IRS(100, tts, tte, SwapDirection.PAYER, InterestRateIndex.EURIBOR6M) ircurve_sensis = swap.get_simm_sensis_ircurve() asdf = 1