def test_cache_subset(mocker): set_session() ir_swap = IRSwap('Pay', '10y', 'DKK') values = [ {'date': '2019-10-07', 'value': 0.01}, {'date': '2019-10-08', 'value': 0.01} ] mocker.return_value = [[values]] dates = (dt.date(2019, 10, 7), dt.date(2019, 10, 8)) with HistoricalPricingContext(dates=dates, use_cache=True) as hpc: pricing_key = hpc.pricing_key price_f = ir_swap.price() price_f.result() cached = PricingCache.get(ir_swap, risk.Price, pricing_key) assert len(cached) == len(dates) cached_scalar = PricingCache.get(ir_swap, risk.Price, PricingContext(pricing_date=dates[0]).pricing_key) assert isinstance(cached_scalar, float) dates = dates + (dt.date(2019, 10, 9),) pricing_key = HistoricalPricingContext(dates=dates).pricing_key cached2 = PricingCache.get(ir_swap, risk.Price, pricing_key) assert cached2 is None cached3 = PricingCache.get(ir_swap, risk.Price, pricing_key, return_partial=True) assert len(cached3) < len(dates) values = [ {'date': '2019-10-07', 'marketDataType': 'IR', 'assetId': 'USD', 'pointClass': 'Swap', 'point': '1y', 'value': 0.01}, {'date': '2019-10-07', 'marketDataType': 'IR', 'assetId': 'USD', 'pointClass': 'Swap', 'point': '2y', 'value': 0.015}, {'date': '2019-10-08', 'marketDataType': 'IR', 'assetId': 'USD', 'pointClass': 'Swap', 'point': '1y', 'value': 0.01}, {'date': '2019-10-08', 'marketDataType': 'IR', 'assetId': 'USD', 'pointClass': 'Swap', 'point': '2y', 'value': 0.015}, {'date': '2019-10-09', 'marketDataType': 'IR', 'assetId': 'USD', 'pointClass': 'Swap', 'point': '1y', 'value': 0.01}, {'date': '2019-10-09', 'marketDataType': 'IR', 'assetId': 'USD', 'pointClass': 'Swap', 'point': '2y', 'value': 0.015} ] mocker.return_value = [[values]] with HistoricalPricingContext(dates=dates, use_cache=True) as hpc: pricing_key = hpc.pricing_key risk_f = ir_swap.calc(risk.IRDelta) risk_frame = risk_f.result() assert isinstance(risk_frame, pd.DataFrame) assert len(risk_frame.index.unique()) == len(dates) cached4 = PricingCache.get(ir_swap, risk.IRDelta, pricing_key) assert len(cached4.index.unique()) == len(dates) cached5 = PricingCache.get(ir_swap, risk.IRDelta, PricingContext(pricing_date=dates[0]).pricing_key) assert len(cached5.index.unique()) == len(cached5)
def test_backtothefuture_pricing(mocker): with MockCalc(mocker): swap1 = IRSwap('Pay', '10y', 'USD', fixed_rate=0.01, name='swap1') swap2 = IRSwap('Pay', '10y', 'USD', fixed_rate=0.02, name='swap2') swap3 = IRSwap('Pay', '10y', 'USD', fixed_rate=0.03, name='swap3') portfolio = Portfolio((swap1, swap2, swap3)) pricing_date = dt.date(2021, 2, 10) with PricingContext(pricing_date=pricing_date): with BackToTheFuturePricingContext(dates=business_day_offset( pricing_date, [-1, 0, 1], roll='forward')) as hpc: risk_key = hpc._PricingContext__risk_key( risk.DollarPrice, swap1.provider) results = portfolio.calc(risk.DollarPrice) expected = risk.SeriesWithInfo( pd.Series( data=[-22711963.80864744, -22655907.930484552, -21582551.58922608], index=business_day_offset(pricing_date, [-1, 0, 1], roll='forward')), risk_key=historical_risk_key(risk_key), ) actual = results[risk.DollarPrice].aggregate() assert actual.equals(expected)
def test_exit_action_bytradename(mocker): with MockCalc(mocker): start_date = date(2021, 12, 6) end_date = date(2021, 12, 10) # Define trade irswap1 = IRSwap(PayReceive.Receive, '10y', Currency.USD, notional_amount=1e5, name='swap1') irswap2 = IRSwap(PayReceive.Pay, '5y', Currency.USD, notional_amount=1e5, name='swap2') trig_req_add = PeriodicTriggerRequirements(start_date=start_date, end_date=end_date, frequency='1b') trig_req_exit = PeriodicTriggerRequirements(start_date=start_date, end_date=end_date, frequency='2b') actions_add = AddTradeAction([irswap1, irswap2]) actions_exit = ExitTradeAction('swap1') triggers = [ PeriodicTrigger(trig_req_add, actions_add), PeriodicTrigger(trig_req_exit, actions_exit) ] strategy = Strategy(None, triggers) # run backtest daily engine = GenericEngine() # backtest = engine.run_backtest(strategy, start=start_date, end=end_date, frequency='1b', show_progress=True) backtest = engine.run_backtest(strategy, states=[ date(2021, 12, 6), date(2021, 12, 7), date(2021, 12, 8), date(2021, 12, 9), date(2021, 12, 10) ], end=end_date, show_progress=True) trade_ledger = backtest.trade_ledger().to_dict('index') assert trade_ledger['Action1_swap1_2021-12-06']['Open'] == date( 2021, 12, 6) assert trade_ledger['Action1_swap1_2021-12-06']['Close'] == date( 2021, 12, 6) assert trade_ledger['Action1_swap1_2021-12-07']['Open'] == date( 2021, 12, 7) assert trade_ledger['Action1_swap1_2021-12-07']['Close'] == date( 2021, 12, 8) assert trade_ledger['Action1_swap2_2021-12-06']['Status'] == 'open' assert trade_ledger['Action1_swap2_2021-12-07']['Status'] == 'open' assert trade_ledger['Action1_swap2_2021-12-10']['Status'] == 'open'
def test_duplicate_instrument(mocker): set_session() dollar_price_values = [[[{ '$type': 'Risk', 'val': 0.01 }], [{ '$type': 'Risk', 'val': 0.02 }], [{ '$type': 'Risk', 'val': 0.03 }]]] mocker.return_value = [dollar_price_values] swap1 = IRSwap('Pay', '10y', 'USD', fixed_rate=0.01, name='swap1') swap2 = IRSwap('Pay', '10y', 'USD', fixed_rate=0.02, name='swap2') swap3 = IRSwap('Pay', '10y', 'USD', fixed_rate=0.03, name='swap3') portfolio = Portfolio((swap1, swap2, swap3, swap1)) assert portfolio.index('swap1') == (0, 3) assert portfolio.index('swap2') == 1 prices: PortfolioRiskResult = portfolio.dollar_price() assert tuple(prices) == (0.01, 0.02, 0.03, 0.01) assert round(prices.aggregate(), 2) == 0.07 assert prices[swap1] == (0.01, 0.01)
def test_historical_pricing(mocker): with MockCalc(mocker): swap1 = IRSwap('Pay', '10y', 'USD', fixed_rate='ATM+1', name='10y@a+1') swap2 = IRSwap('Pay', '10y', 'USD', fixed_rate='ATM+2', name='10y@a+2') swap3 = IRSwap('Pay', '10y', 'USD', fixed_rate='ATM+3', name='10y@a+3') portfolio = Portfolio((swap1, swap2, swap3)) dates = (dt.date(2021, 2, 9), dt.date(2021, 2, 10), dt.date(2021, 2, 11)) with HistoricalPricingContext(dates=dates) as hpc: risk_key = hpc._PricingContext__risk_key(risk.DollarPrice, swap1.provider) results = portfolio.calc((risk.DollarPrice, risk.IRDelta)) expected = risk.SeriesWithInfo( pd.Series( data=[-580316.7895084377, -580373.4091600645, -580811.1441974249], index=[dt.date(2021, 2, 9), dt.date(2021, 2, 10), dt.date(2021, 2, 11)] ), risk_key=historical_risk_key(risk_key), ) assert results.dates == dates actual = results[risk.DollarPrice].aggregate() assert actual.equals(expected) assert (results[dt.date(2021, 2, 9)][risk.DollarPrice]['10y@a+1'] == results[risk.DollarPrice][dt.date(2021, 2, 9)]['10y@a+1']) assert (results[dt.date(2021, 2, 9)][risk.DollarPrice]['10y@a+1'] == results[risk.DollarPrice]['10y@a+1'][dt.date(2021, 2, 9)]) assert (results[dt.date(2021, 2, 9)][risk.DollarPrice]['10y@a+1'] == results['10y@a+1'][risk.DollarPrice][dt.date(2021, 2, 9)]) assert (results[dt.date(2021, 2, 9)][risk.DollarPrice]['10y@a+1'] == results['10y@a+1'][dt.date(2021, 2, 9)][risk.DollarPrice]) assert (results[dt.date(2021, 2, 9)][risk.DollarPrice]['10y@a+1'] == results[dt.date(2021, 2, 9)]['10y@a+1'][risk.DollarPrice])
def test_backtothefuture_pricing(mocker): with MockCalc(mocker): swap1 = IRSwap('Pay', '10y', 'USD', fixed_rate=0.01, name='swap1') swap2 = IRSwap('Pay', '10y', 'USD', fixed_rate=0.02, name='swap2') swap3 = IRSwap('Pay', '10y', 'USD', fixed_rate=0.03, name='swap3') portfolio = Portfolio((swap1, swap2, swap3)) pricing_date = dt.date(2020, 10, 7) with PricingContext(pricing_date=pricing_date): with BackToTheFuturePricingContext(dates=business_day_offset( pricing_date, [-1, 0, 1], roll='forward')) as hpc: risk_key = hpc._PricingContext__risk_key( risk.DollarPrice, swap1.provider) results = portfolio.calc(risk.DollarPrice) expected = risk.SeriesWithInfo( pd.Series( data=[-35280379.86540368, -35348910.76427929, -30830994.939595155], index=business_day_offset(pricing_date, [-1, 0, 1], roll='forward')), risk_key=risk_key.ex_date_and_market, ) actual = results[risk.DollarPrice].aggregate() assert actual.equals(expected)
def test_clone(): old_p = Portfolio( (IRSwap(name='c'), Portfolio((IRSwap(name='a'), IRSwap(name='b'))))) old_p.priceables[1].instruments[0].name = 'changed_name' new_p = old_p.clone() assert old_p['changed_name'] == () assert new_p['changed_name'] == IRSwap(name='changed_name')
def test_cache_addition_removal(): # Don't use a mocker here as it will hold refs to things and break the cache removal test set_session() p1 = IRSwap('Pay', '10y', 'DKK') with PricingContext(use_cache=True): market_data_location = PricingContext.current.market_data_location pricing_date = PricingContext.current.pricing_date p1.price() assert PricingCache.get(p1, market_data_location, risk.Price, pricing_date) assert not PricingCache.get(p1, market_data_location, risk.IRDelta, pricing_date) # Assert that deleting the cached instrument removes it from the PricingCache # N.B, this may not work when debugging tests del p1 p2 = IRSwap('Pay', '10y', 'DKK') assert not PricingCache.get(p2, market_data_location, risk.Price, pricing_date) with PricingContext(use_cache=True): p2.price() assert PricingCache.get(p2, market_data_location, risk.Price, pricing_date) # Change a property and assert that p2 is no longer cached p2.notional_currency = 'EUR' assert not PricingCache.get(p2, market_data_location, risk.Price, pricing_date)
def test_cache_subset(mocker): set_session() ir_swap = IRSwap('Pay', '10y', 'DKK') values = [{'$type': 'Risk', 'val': 0.01}] mocker.return_value = [[[values]], [[values]]] dates = (dt.date(2019, 10, 7), dt.date(2019, 10, 8)) with HistoricalPricingContext(dates=dates, use_cache=True): price_f = ir_swap.price() price_f.result() for date in dates: risk_key = PricingContext(pricing_date=date)._PricingContext__risk_key( risk.Price, ir_swap.provider) cached_scalar = PricingCache.get(risk_key, ir_swap) assert cached_scalar assert isinstance(cached_scalar, float) risk_key = PricingContext( pricing_date=dt.date(2019, 10, 9))._PricingContext__risk_key( risk.Price, ir_swap.provider) cached2 = PricingCache.get(risk_key, ir_swap) assert cached2 is None values = [{ '$type': 'RiskVector', 'asset': [0.01, 0.015], 'points': [{ 'type': 'IR', 'asset': 'USD', 'class_': 'Swap', 'point': '1y' }, { 'type': 'IR', 'asset': 'USD', 'class_': 'Swap', 'point': '2y' }] }] # Check that we can return the same values from the cache, after calculating once (with return values set to None) for return_values in ([[[values]], [[values]], [[values]]], None): mocker.return_value = return_values with HistoricalPricingContext(dates=dates, use_cache=True): risk_f = ir_swap.calc(risk.IRDelta) risk_frame = risk_f.result() assert isinstance(risk_frame, pd.DataFrame) assert len(risk_frame.index.unique()) == len(dates)
def test_backtothefuture_pricing(mocker): set_session() day1 = [ [ [{'$type': 'Risk', 'val': 0.01}], [{'$type': 'Risk', 'val': 0.02}], [{'$type': 'Risk', 'val': 0.03}], ] ] day2 = [ [ [{'$type': 'Risk', 'val': 0.011}], [{'$type': 'Risk', 'val': 0.021}], [{'$type': 'Risk', 'val': 0.031}], ] ] day3 = [ [ [{'$type': 'Risk', 'val': 0.012}], [{'$type': 'Risk', 'val': 0.022}], [{'$type': 'Risk', 'val': 0.032}], ] ] mocker.return_value = [day1, day2, day3] swap1 = IRSwap('Pay', '10y', 'USD', fixed_rate=0.01, name='swap1') swap2 = IRSwap('Pay', '10y', 'USD', fixed_rate=0.02, name='swap2') swap3 = IRSwap('Pay', '10y', 'USD', fixed_rate=0.03, name='swap3') portfolio = Portfolio((swap1, swap2, swap3)) with BackToTheFuturePricingContext(dates=business_day_offset(dt.datetime.today().date(), [-1, 0, 1], roll='forward')) as hpc: risk_key = hpc._PricingContext__risk_key(risk.DollarPrice, swap1.provider) results = portfolio.calc(risk.DollarPrice) expected = risk.SeriesWithInfo( pd.Series( data=[0.06, 0.063, 0.066], index=business_day_offset(dt.datetime.today().date(), [-1, 0, 1], roll='forward') ), risk_key=risk_key.ex_date_and_market,) actual = results[risk.DollarPrice].aggregate() assert actual.equals(expected)
def test_duplicate_instrument(mocker): with MockCalc(mocker): swap1 = IRSwap('Pay', '1y', 'EUR', name='EUR1y') swap2 = IRSwap('Pay', '2y', 'EUR', name='EUR2y') swap3 = IRSwap('Pay', '3y', 'EUR', name='EUR3y') portfolio = Portfolio((swap1, swap2, swap3, swap1)) assert portfolio.paths('EUR1y') == (PortfolioPath(0), PortfolioPath(3)) assert portfolio.paths('EUR2y') == (PortfolioPath(1), ) with PricingContext(pricing_date=dt.date(2020, 10, 15)): fwds: PortfolioRiskResult = portfolio.calc(risk.IRFwdRate) assert tuple(map(lambda x: round(x, 6), fwds)) == (-0.005378, -0.005224, -0.00519, -0.005378) assert round(fwds.aggregate(), 6) == -0.02117 assert round(fwds[swap1], 6) == -0.005378
def test_construction(): swap1 = IRSwap('Pay', '10y', 'USD') swap2 = IRSwap('Pay', '5y', 'USD') my_list = [swap1, swap2] my_tuple = (swap1, swap2) my_np_arr = np.array((swap1, swap2)) p1 = Portfolio(my_list) p2 = Portfolio(my_tuple) p3 = Portfolio(my_np_arr) assert len(p1) == 2 assert len(p2) == 2 assert len(p3) == 2 assert p1 == p2 assert p2 == p3
def test_date_trigger(): # Test DateTrigger action = AddTradeAction(IRSwap()) trigger = DateTrigger( DateTriggerRequirements([ dt.date(2021, 11, 9), dt.date(2021, 11, 10), dt.date(2021, 11, 11) ]), [action]) assert not trigger.has_triggered(dt.datetime(2021, 11, 10, 14, 0)) assert trigger.has_triggered(dt.date(2021, 11, 10)) trigger = DateTrigger( DateTriggerRequirements([ dt.datetime(2021, 11, 9, 14, 0), dt.datetime(2021, 11, 10, 14, 0), dt.datetime(2021, 11, 11, 14, 0) ]), [action]) assert trigger.has_triggered(dt.datetime(2021, 11, 10, 14, 0)) assert not trigger.has_triggered(dt.date(2021, 11, 10)) trigger = DateTrigger( DateTriggerRequirements([ dt.datetime(2021, 11, 9, 14, 0), dt.datetime(2021, 11, 10, 14, 0), dt.datetime(2021, 11, 11, 14, 0) ], entire_day=True), [action]) assert trigger.has_triggered(dt.datetime(2021, 11, 10, 14, 0)) assert trigger.has_triggered(dt.date(2021, 11, 10))
def test_aggregate_triggger(): # Test Aggregate Trigger action_1 = AddTradeAction(IRSwap()) action_2 = AddTradeAction(IRSwaption()) trigger_1 = DateTrigger( DateTriggerRequirements([ dt.date(2021, 11, 9), dt.date(2021, 11, 10), dt.date(2021, 11, 11) ]), [action_1]) trigger_2 = DateTrigger( DateTriggerRequirements([ dt.date(2021, 11, 8), dt.date(2021, 11, 10), dt.date(2021, 11, 12) ]), [action_2]) agg_trigger = AggregateTrigger( AggregateTriggerRequirements([trigger_1, trigger_2], aggregate_type=AggType.ALL_OF)) assert not agg_trigger.has_triggered(dt.date(2021, 11, 9)) assert agg_trigger.has_triggered(dt.date(2021, 11, 10)) assert len(agg_trigger.actions) == 2 agg_trigger = AggregateTrigger( AggregateTriggerRequirements([trigger_1, trigger_2], aggregate_type=AggType.ANY_OF)) assert agg_trigger.has_triggered(dt.date(2021, 11, 8)) assert isinstance(agg_trigger.actions[0].priceables[0], IRSwaption) assert agg_trigger.has_triggered(dt.date(2021, 11, 10)) assert len(agg_trigger.actions) == 2
def test_from_frame(): swap = IRSwap('Receive', '3m', 'USD', fixed_rate=0, notional_amount=1) swaption = IRSwaption(notional_currency='GBP', expiration_date='10y', effective_date='0b') portfolio = Portfolio((swap, swaption)) port_df = portfolio.to_frame() new_port_df = Portfolio.from_frame(port_df) assert new_port_df[swap] == swap assert new_port_df[swaption] == swaption
def test_historical_pricing(mocker): with MockCalc(mocker): swap1 = IRSwap('Pay', '10y', 'USD', fixed_rate='ATM+1', name='10y@a+1') swap2 = IRSwap('Pay', '10y', 'USD', fixed_rate='ATM+2', name='10y@a+2') swap3 = IRSwap('Pay', '10y', 'USD', fixed_rate='ATM+3', name='10y@a+3') portfolio = Portfolio((swap1, swap2, swap3)) dates = (dt.date(2019, 10, 7), dt.date(2019, 10, 8), dt.date(2019, 10, 9)) with HistoricalPricingContext(dates=dates) as hpc: risk_key = hpc._PricingContext__risk_key(risk.DollarPrice, swap1.provider) results = portfolio.calc((risk.DollarPrice, risk.IRDelta)) expected = risk.SeriesWithInfo( pd.Series(data=[ -564854.3640043903, -565604.2636791412, -564751.5121349357 ], index=[ dt.date(2019, 10, 7), dt.date(2019, 10, 8), dt.date(2019, 10, 9) ]), risk_key=risk_key.ex_date_and_market, ) assert results.dates == dates actual = results[risk.DollarPrice].aggregate() assert actual.equals(expected) assert (results[dt.date(2019, 10, 9)][risk.DollarPrice]['10y@a+1'] == results[risk.DollarPrice][dt.date(2019, 10, 9)]['10y@a+1']) assert (results[dt.date(2019, 10, 9)][risk.DollarPrice]['10y@a+1'] == results[risk.DollarPrice]['10y@a+1'][dt.date(2019, 10, 9)]) assert (results[dt.date(2019, 10, 9)][risk.DollarPrice]['10y@a+1'] == results['10y@a+1'][risk.DollarPrice][dt.date(2019, 10, 9)]) assert (results[dt.date( 2019, 10, 9)][risk.DollarPrice]['10y@a+1'] == results['10y@a+1'][dt.date( 2019, 10, 9)][risk.DollarPrice]) assert (results[dt.date( 2019, 10, 9)][risk.DollarPrice]['10y@a+1'] == results[dt.date( 2019, 10, 9)]['10y@a+1'][risk.DollarPrice])
def test_portfolio(mocker): with MockCalc(mocker): with PricingContext(pricing_date=dt.date(2020, 10, 15)): swap1 = IRSwap('Pay', '10y', 'USD', fixed_rate=0.001, name='swap_10y@10bp') swap2 = IRSwap('Pay', '10y', 'USD', fixed_rate=0.002, name='swap_10y@20bp') swap3 = IRSwap('Pay', '10y', 'USD', fixed_rate=0.003, name='swap_10y@30bp') portfolio = Portfolio((swap1, swap2, swap3)) prices: PortfolioRiskResult = portfolio.dollar_price() result = portfolio.calc((risk.DollarPrice, risk.IRDelta)) assert tuple(sorted(map(lambda x: round(x, 0), prices))) == (4439478.0, 5423405.0, 6407332.0) assert round(prices.aggregate(), 2) == 16270214.48 assert round(prices[0], 0) == 6407332.0 assert round(prices[swap2], 0) == 5423405.0 assert round(prices['swap_10y@30bp'], 0) == 4439478.0 assert tuple(map(lambda x: round(x, 0), result[risk.DollarPrice])) == (6407332.0, 5423405.0, 4439478.0) assert round(result[risk.DollarPrice].aggregate(), 0) == 16270214.0 assert round(result[risk.DollarPrice]['swap_10y@30bp'], 0) == 4439478.0 assert round(result[risk.DollarPrice]['swap_10y@30bp'], 0) == round(result['swap_10y@30bp'][risk.DollarPrice], 0) assert round(result[risk.IRDelta].aggregate().value.sum(), 0) == 278977.0 prices_only = result[risk.DollarPrice] assert tuple(map(lambda x: round(x, 0), prices)) == tuple(map(lambda x: round(x, 0), prices_only)) swap4 = IRSwap('Pay', '10y', 'USD', fixed_rate=-0.001, name='swap_10y@-10bp') portfolio.append(swap4) assert len(portfolio.instruments) == 4 extracted_swap = portfolio.pop('swap_10y@20bp') assert extracted_swap == swap2 assert len(portfolio.instruments) == 3 swap_dict = {'swap_5': swap1, 'swap_6': swap2, 'swap_7': swap3} portfolio = Portfolio(swap_dict) assert len(portfolio) == 3
def test_single_instrument(mocker): with MockCalc(mocker): swap1 = IRSwap('Pay', '10y', 'USD', fixed_rate=0.0, name='10y@0') portfolio = Portfolio(swap1) assert portfolio.paths('10y@0') == (PortfolioPath(0), ) with PricingContext(pricing_date=dt.date(2020, 10, 15)): prices: PortfolioRiskResult = portfolio.dollar_price() assert tuple(map(lambda x: round(x, 0), prices)) == (7391258.0, ) assert round(prices.aggregate(), 0) == 7391258.0 assert round(prices[swap1], 0) == 7391258.0
def test_single_instrument_new_mock(mocker): with MockCalc(mocker): with PricingContext(pricing_date=dt.date(2020, 10, 15)): swap1 = IRSwap('Pay', '10y', 'USD', name='swap1') portfolio = Portfolio(swap1) fwd: PortfolioRiskResult = portfolio.calc(risk.IRFwdRate) assert portfolio.paths('swap1') == (PortfolioPath(0), ) assert tuple(map(lambda x: round(x, 6), fwd)) == (0.007512, ) assert round(fwd.aggregate(), 2) == 0.01 assert round(fwd[swap1], 6) == 0.007512
def test_portfolio_overrides(mocker): swap_1 = IRSwap("Pay", "5y", "EUR", fixed_rate=-0.005, name="5y") swap_2 = IRSwap("Pay", "10y", "EUR", fixed_rate=-0.005, name="10y") swap_3 = IRSwap("Pay", "5y", "GBP", fixed_rate=-0.005, name="5y") swap_4 = IRSwap("Pay", "10y", "GBP", fixed_rate=-0.005, name="10y") eur_port = Portfolio([swap_1, swap_2], name="EUR") gbp_port = Portfolio([swap_3, swap_4], name="GBP") # override instruments after portfolio construction for idx in range(len(eur_port)): eur_port[idx].fixed_rate = eur_port[idx].fixed_rate - 0.0005 assert eur_port[swap_1] is not None with MockCalc(mocker): # override instruments after portfolio construction and resolution gbp_port.resolve() for idx in range(len(gbp_port)): gbp_port[idx].notional_amount = gbp_port[idx].notional_amount - 1 with PricingContext(dt.date(2020, 1, 14)): r1 = eur_port.calc(risk.Price) r2 = eur_port.calc((risk.Price, risk.DollarPrice)) r3 = gbp_port.calc(risk.Price) r4 = gbp_port.calc((risk.DollarPrice, risk.Price)) assert gbp_port[swap_3] is not None assert r1[eur_port[0]] is not None assert r1['5y'] is not None assert r1.to_frame() is not None assert r2[eur_port[0]] is not None assert r2[risk.Price][0] is not None assert r2[0][risk.Price] is not None assert r3[gbp_port[0]] is not None assert r3.to_frame() is not None assert r4[gbp_port[0]] is not None assert r4[risk.DollarPrice][0] is not None assert r4[0][risk.DollarPrice] is not None
def test_single_instrument(mocker): set_session() mocker.return_value = [[[[{'$type': 'Risk', 'val': 0.01}]]]] swap1 = IRSwap('Pay', '10y', 'USD', fixed_rate=0.01, name='swap1') portfolio = Portfolio(swap1) assert portfolio.index('swap1') == 0 prices: PortfolioRiskResult = portfolio.dollar_price() assert tuple(prices) == (0.01, ) assert round(prices.aggregate(), 2) == 0.01 assert prices[swap1] == 0.01
def test_not_triggger(): # Test Not Trigger action = AddTradeAction(IRSwap()) not_action = AddTradeAction(IRSwaption()) trigger = DateTrigger( DateTriggerRequirements([ dt.date(2021, 11, 9), dt.date(2021, 11, 10), dt.date(2021, 11, 11) ]), [action]) not_trigger = NotTrigger(NotTriggerRequirements(trigger), [not_action]) assert not_trigger.has_triggered(dt.date(2021, 11, 8)) assert isinstance(not_trigger.actions[0].priceables[0], IRSwaption) assert not not_trigger.has_triggered(dt.date(2021, 11, 10))
def test_from_dict(): swap = IRSwap('Receive', '3m', 'USD', fixedRate=0, notionalAmount=1) properties = swap.as_dict() new_swap = Instrument.from_dict(properties) assert swap == new_swap # setting a datetime.date should work in a dictionary swap = IRSwap('Receive', dt.date(2030, 4, 11), 'USD', fixedRate='atm+5', notionalAmount=1) properties = swap.as_dict() new_swap = Instrument.from_dict(properties) assert swap == new_swap
def test_nested_portfolios(mocker): swap1 = IRSwap('Pay', '10y', 'USD', name='USD-swap') swap2 = IRSwap('Pay', '10y', 'EUR', name='EUR-swap') swap3 = IRSwap('Pay', '10y', 'GBP', name='GBP-swap') swap4 = IRSwap('Pay', '10y', 'JPY', name='JPY-swap') swap5 = IRSwap('Pay', '10y', 'HUF', name='HUF-swap') swap6 = IRSwap('Pay', '10y', 'CHF', name='CHF-swap') portfolio2_1 = Portfolio((swap1, swap2, swap3), name='portfolio2_1') portfolio2_2 = Portfolio((swap1, swap2, swap3), name='portfolio2_2') portfolio1_1 = Portfolio((swap4, portfolio2_1), name='portfolio1_1') portfolio1_2 = Portfolio((swap5, portfolio2_2), name='USD-swap') portfolio = Portfolio((swap6, portfolio1_1, portfolio1_2), name='portfolio') assert portfolio.paths('USD-swap') == (PortfolioPath(2), PortfolioPath((1, 1, 0)), PortfolioPath((2, 1, 0)))
def test_pricing_context(mocker): swap1 = IRSwap('Pay', '1y', 'EUR', name='EUR1y') future_date = business_day_offset(dt.date.today(), 10, roll='forward') with MockCalc(mocker): with RollFwd(date='10b', realise_fwd=True): market = swap1.market() with pytest.raises(ValueError): # cannot pass in future date into pricing context, use RollFwd instead with PricingContext(pricing_date=future_date): _ = swap1.calc(risk.Price) # cannot pass in market dated in the future into pricing context, use RollFwd instead with PricingContext(market=CloseMarket(date=future_date)): _ = swap1.calc(risk.Price) with PricingContext(market=OverlayMarket(base_market=CloseMarket(date=future_date, location='NYC'), market_data=market.result())): _ = swap1.calc(risk.Price)
def test_results_with_resolution(mocker): with MockCalc(mocker): swap1 = IRSwap('Pay', '10y', 'USD', name='swap1') swap2 = IRSwap('Pay', '10y', 'GBP', name='swap2') swap3 = IRSwap('Pay', '10y', 'EUR', name='swap3') portfolio = Portfolio((swap1, swap2, swap3)) with PricingContext(pricing_date=dt.date(2020, 10, 15)): result = portfolio.calc((risk.DollarPrice, risk.IRDelta)) # Check that we've got results assert result[swap1][risk.DollarPrice] is not None # Now resolve portfolio and assert that we can still get the result orig_swap1 = swap1.clone() with PricingContext(pricing_date=dt.date(2020, 10, 15)): portfolio.resolve() # Assert that the resolved swap is indeed different and that we can retrieve results by both assert swap1 != orig_swap1 assert result[swap1][risk.DollarPrice] is not None assert result[orig_swap1][risk.DollarPrice] is not None # Now reset the instruments and portfolio swap1 = IRSwap('Pay', '10y', 'USD', name='swap1') swap2 = IRSwap('Pay', '10y', 'GBP', name='swap2') swap3 = IRSwap('Pay', '10y', 'EUR', name='swap3') portfolio = Portfolio((swap1, swap2, swap3, swap1)) with PricingContext(dt.date(2020, 10, 14)): # Resolve under a different pricing date portfolio.resolve() assert portfolio.instruments[0].termination_date == dt.date( 2030, 10, 16) assert portfolio.instruments[1].termination_date == dt.date( 2030, 10, 14) assert round(swap1.fixed_rate, 4) == 0.0075 assert round(swap2.fixed_rate, 4) == 0.004 assert round(swap3.fixed_rate, 4) == -0.0027 # Assert that after resolution under a different context, we cannot retrieve the result try: _ = result[swap1][risk.DollarPrice] assert False except KeyError: assert True # Resolve again and check we get the same values with PricingContext(dt.date(2020, 10, 14)): # Resolve under a different pricing date portfolio.resolve() assert portfolio.instruments[0].termination_date == dt.date( 2030, 10, 16) assert portfolio.instruments[1].termination_date == dt.date( 2030, 10, 14) assert round(swap1.fixed_rate, 4) == 0.0075 assert round(swap2.fixed_rate, 4) == 0.004 assert round(swap3.fixed_rate, 4) == -0.0027
from gs_quant.api.gs.risk import GsRiskApi from gs_quant.base import Priceable from gs_quant.common import AssetClass from gs_quant.instrument import CommodSwap, EqForward, EqOption, FXOption, IRBasisSwap, IRSwap, IRSwaption, IRCap,\ IRFloor from gs_quant.markets import PricingContext from gs_quant.session import Environment, GsSession from gs_quant.target.risk import PricingDateAndMarketDataAsOf, RiskPosition, RiskRequestParameters, \ OptimizationRequest priceables = ( CommodSwap('Electricity', '1y'), EqForward('GS.N', '1y'), EqOption('GS.N', '3m', 'ATMF', 'Call', 'European'), FXOption('EUR', 'USD', '1y', 'Call', strike_price='ATMF'), IRSwap('Pay', '10y', 'USD'), IRBasisSwap('10y', 'USD'), IRSwaption('Pay', '10y', 'USD'), IRCap('10y', 'EUR'), IRFloor('10y', 'EUR') ) def set_session(): from gs_quant.session import OAuth2Session OAuth2Session.init = mock.MagicMock(return_value=None) GsSession.use(Environment.QA, 'client_id', 'secret') def structured_calc(mocker, priceable: Priceable, measure: risk.RiskMeasure): set_session()
from gs_quant.common import PayReceive, Currency # import constants from gs_quant.instrument import IRSwap # import instruments from gs_quant.session import Environment, GsSession # import sessions client_id = None # Supply your application id client_secret = None # Supply your client secret scopes = ('run_analytics',) GsSession.use(Environment.PROD, client_id, client_secret, scopes) my_swap = IRSwap(PayReceive.Pay, '5y', Currency.USD) # 5y USD payer print(my_swap.termination_date) # get value of property 'termination_date'
def test_cache_addition_removal(): set_session() p1 = IRSwap('Pay', '10y', 'DKK') with mock.patch('gs_quant.api.gs.risk.GsRiskApi._exec') as mocker: mocker.return_value = [[[[{'$type': 'Risk', 'val': 0.07}]]]] with PricingContext(use_cache=True) as pc: p1.price() price_key = pc._PricingContext__risk_key(risk.Price, p1.provider) delta_key = pc._PricingContext__risk_key(risk.IRDelta, p1.provider) assert PricingCache.get(price_key, p1) assert not PricingCache.get(delta_key, p1) # Assert that deleting the cached instrument removes it from the PricingCache # N.B, this may not work when debugging tests del p1 del mocker import gc gc.collect() p2 = IRSwap('Pay', '10y', 'DKK') p2_price_key = PricingContext.current._PricingContext__risk_key( risk.Price, p2.provider) # assert not PricingCache.get(p2_price_key) with mock.patch('gs_quant.api.gs.risk.GsRiskApi._exec') as mocker: mocker.return_value = [[[[{'$type': 'Risk', 'val': 0.07}]]]] with PricingContext(use_cache=True): p2_price = p2.price() assert PricingCache.get(p2_price_key, p2) == p2_price.result() # Assert that running under a scenario does not retrieve the base result with mock.patch('gs_quant.api.gs.risk.GsRiskApi._exec') as mocker: mocker.return_value = [[[[{'$type': 'Risk', 'val': 0.08}]]]] with risk.RollFwd(date='1m'), PricingContext(use_cache=True) as spc: # Don't want the price without the scenario scenario_risk_key = spc._PricingContext__risk_key( risk.Price, p2.provider) assert not PricingCache.get(scenario_risk_key, p2) scenario_price = p2.price() assert PricingCache.get(scenario_risk_key, p2) == scenario_price.result() with PricingContext(use_cache=True) as pc, risk.RollFwd(date='1m'): cached_scenario_price = PricingCache.get( pc._PricingContext__risk_key(risk.Price, p2.provider), p2) # Check that we get the cached scenario price assert cached_scenario_price == scenario_price.result() # Check the base result is still correct assert PricingCache.get(p2_price_key, p2) == p2_price.result() # Assert that caching respects parameters, such as csa with mock.patch('gs_quant.api.gs.risk.GsRiskApi._exec') as mocker: mocker.return_value = [[[[{'$type': 'Risk', 'val': 0.08}]]]] with PricingContext(use_cache=True, csa_term='INVALID') as pc: # Don't want the price with default csa assert not PricingCache.get( pc._PricingContext__risk_key(risk.Price, p2.provider), p2) csa_price = p2.price() with PricingContext(use_cache=True, csa_term='INVALID') as pc: cached_csa_price = PricingCache.get( pc._PricingContext__risk_key(risk.Price, p2.provider), p2) # Check that we get the cached csa price assert cached_csa_price == csa_price.result() # Check the base result is still correct assert PricingCache.get(p2_price_key, p2) == p2_price.result() # Change a property and assert that p2 is no longer cached p2.notional_currency = 'EUR' assert not PricingCache.get(p2_price_key, p2)
from gs_quant.datetime.time import to_zulu_string import gs_quant.risk as risk from gs_quant.api.gs.risk import GsRiskApi from gs_quant.base import Priceable from gs_quant.common import AssetClass from gs_quant.instrument import CommodSwap, EqForward, EqOption, FXOption, IRBasisSwap, IRSwap, IRSwaption, IRCap,\ IRFloor from gs_quant.markets import PricingContext from gs_quant.session import Environment, GsSession from gs_quant.target.risk import PricingDateAndMarketDataAsOf, RiskPosition, RiskRequestParameters, \ APEXOptimizationRequest priceables = (CommodSwap('Electricity', '1y'), EqForward('GS.N', '1y'), EqOption('GS.N', '3m', 'ATMF', 'Call', 'European'), FXOption('EUR', 'USD', '1y', 'Call', strike_price='ATMF'), IRSwap('Pay', '10y', 'USD'), IRBasisSwap('10y', 'USD'), IRSwaption('Pay', '10y', 'USD'), IRCap('10y', 'EUR'), IRFloor('10y', 'EUR')) def set_session(): from gs_quant.session import OAuth2Session OAuth2Session.init = mock.MagicMock(return_value=None) GsSession.use(Environment.QA, 'client_id', 'secret') def structured_calc(mocker, priceable: Priceable, measure: risk.RiskMeasure): set_session() values = { '$type':