v8 Framework
Search…
⌃K

Asset swaps

Primer on asset swap structured instrument

Introduction

The purpose of this primer is to show how to create and work with Matched Maturity Asset Swaps.

Environment

Setting up your environment takes three steps:
  • Import the relevant internal and external libraries
  • Configure the environment parameters
  • Initialise the environment
import sigtech.framework as sig
from sigtech.framework.instruments.ir_otc import IRSwapMarket
import datetime as dtm
import pandas as pd
import numpy as np
import seaborn as sns
sns.set(rc={'figure.figsize': (18,6)})
env = sig.config.init()

Asset Swap Structure

The asset swap structure is formed by two instruments which are referred to as legs. One of the legs are a financial asset, in this case a government bond, whereas the other leg is an interest rate swap. Asset Swaps are used to transform cashflow characteristics from fix to floating payments with the intention of hedging credit risk.

Bond Leg

Below we are selecting an US government bond to form the first leg of the Asset Swap.
bond = sig.obj.get('US 2.5 2025/01/31 GOVT')
The static data and characteristics related to the bond can be viewed via the .treasury_info as shown in below code block:
Python
Output
bond.bond_info()
{'name': 'US9128283V09',
'coupon_amount': 0.025,
'day_count': 'ACT/ACT',
'maturity': datetime.date(2025, 1, 31),
'interest_acrrue_date': datetime.date(2018, 1, 31),
'calculation_type': 1,
'calendar': 'UST CALENDAR',
'first_coupon_date': datetime.date(2018, 7, 31),
'coupon_frequency': 'SEMI_ANNUAL',
'redemption_amount': 100.0,
'isin': 'US9128283V09',
'bond_ticker': 'US 2.5 2025/01/31 GOVT',
'first_settlement_date': datetime.date(2018, 1, 31),
'issue_date': datetime.date(2018, 1, 31),
'days_to_settle': 1}

Asset Swap Building Block

The AssetSwap class returns a Matched-Maturity Asset Swap strategy; buying a fixed-coupon bond and selling a receiver swap.
Python
Output
mm_asw = sig.AssetSwap(bond_name=bond.name,
currency='USD',
notional=100,
trade_date=dtm.date(2019,3,1),
include_trading_costs=False, # exclude trading cost
total_return=False, # exclude cash accrual
reinvest_coupon=True,
direction='long')
mm_asw.history().plot()
We can explore the bond and swap constituent by calling the method structure_instruments
Python
Output
mm_asw.structure_instruments()
[('USD US 2.5 2025/01/31 GOVT 5255CDE1 LONG SBS STRATEGY', 1.0),
('USD LIBOR SEMI_ANNUAL3M 0.025 2019-03-01 2019-03-05X2025-01-31 FLT_SPRD 0.003488 FIX_DC ACT/ACT IRS',
-100.0)]

Custom Asset Swap Structure

We can build any Asset Swap Structure by holding a bond and a swap simultaneously. In order to hold the treasury we use the building block SingleBondStrategy
Python
Output
bond_holding = sig.SingleBondStrategy(
currency=bond.currency,
start_date=bond.issue_date,
bond_name=bond.name,
reinvest_coupon=False,
initial_cash=100,
)
bond_holding.history().plot(
title="NAV of $100 notional of bond with reinvested coupons")

Swap Leg: Constructing Matching Maturity Swap

To create a matching swap to replicate the treasury leg cashflows we need to override a number of default arguments
overrides = {
'fixed_day_count': 'ACT/ACT', # bond.day_count is ACT/ACT
'float_day_count': 'ACT/ACT', # bond.day_count is ACT/ACT
'float_frequency': '6M', # bond.coupon_frequency is SEMI_ANNUAL
'forecast_curve': 'USD.F6M CURVE', # bond.coupon_frequency is SEMI_ANNUAL
'fixes_index': 'US0006M INDEX', # bond.coupon_frequency is SEMI_ANNUAL
}
We can now create the swap with the overrides above
swap = sig.InterestRateSwap(
currency=bond.currency,
trade_date=bond.issue_date,
start_date=bond.issue_date,
tenor=bond.maturity_date,
fixed_rate=bond.coupon / 100.,
spread=bond.asw_spread(bond.issue_date) / 100.,
overrides=overrides,
)
We verify the swap set up by matching the treasury information
Python
Output
swap.swap_info_from_currency(
env,
bond.issue_date,
bond.maturity_date,
bond.currency,
bond.coupon / 100,
bond.asw_spread(bond.issue_date) / 100,
overrides=overrides,
)
{'start_date': datetime.date(2018, 1, 31),
'end_date': datetime.date(2025, 1, 31),
'fixed_rate': 0.025,
'fixed_rate_frequency': 'S',
'fixed_day_count': 'ACT/ACT',
'fixed_business_convention': 'MOD_FOL',
'float_tenor': '6M',
'float_day_count': 'ACT/ACT',
'float_business_convention': 'MOD_FOL',
'currency': 'USD',
'calendar': 'FEDFUND, LONDONB CALENDAR',
'fixing_object_name_override': 'US0006M INDEX',
'spread': -0.013583813878239516}
We can compare now the swaps and treasury cashflows to ensure they match
Python
Output
swap.swap_details(bond.issue_date)['fixed_flows'], bond.cashflows(bond.issue_date)
([datetime.date(2018, 7, 31),
datetime.date(2019, 1, 31),
datetime.date(2019, 7, 31),
datetime.date(2020, 1, 31),
datetime.date(2020, 7, 31),
datetime.date(2021, 1, 29),
datetime.date(2021, 7, 30),
datetime.date(2022, 1, 31),
datetime.date(2022, 7, 29),
datetime.date(2023, 1, 31),
datetime.date(2023, 7, 31),
datetime.date(2024, 1, 31),
datetime.date(2024, 7, 31),
datetime.date(2025, 1, 31)],
array([[datetime.date(2018, 7, 31), 1.2499999999999956, 0.0],
[datetime.date(2019, 1, 31), 1.2499999999999956, 0.0],
[datetime.date(2019, 7, 31), 1.2499999999999956, 0.0],
[datetime.date(2020, 1, 31), 1.2499999999999956, 0.0],
[datetime.date(2020, 7, 31), 1.2499999999999956, 0.0],
[datetime.date(2021, 2, 1), 1.2499999999999956, 0.0],
[datetime.date(2021, 8, 2), 1.2499999999999956, 0.0],
[datetime.date(2022, 1, 31), 1.2499999999999956, 0.0],
[datetime.date(2022, 8, 1), 1.2499999999999956, 0.0],
[datetime.date(2023, 1, 31), 1.2499999999999956, 0.0],
[datetime.date(2023, 7, 31), 1.2499999999999956, 0.0],
[datetime.date(2024, 1, 31), 1.2499999999999956, 0.0],
[datetime.date(2024, 7, 31), 1.2499999999999956, 0.0],
[datetime.date(2025, 1, 31), 1.2499999999999956, 100.0]],
dtype=object))

Asset Swap Structure

Below, the two legs of the asset swap structure are combined:
class AssetSwapStrategy(sig.DailyStrategy):
def strategy_initialization(self, dt):
pass
asw = AssetSwapStrategy(
currency=bond.currency,
start_date=bond.issue_date,
# as an Asset Swap buyer we are long the swap and short the bond
additional_initial_holdings=[
(bond_holding.name, 1.0),
(swap.name, - bond_holding.initial_cash)
],
initial_cash=0,
include_trading_costs=False,
total_return=False,
)
The below code block will create a performance report of the asset swap strategy:
Python
Output
sig.PerformanceReport(asw).report()