CrossCurrencySwap

CrossCurrencySwap#

class sigtech.framework.instruments.xccy_swap.CrossCurrencySwap

Baseclasses: OTCInstrumentWithPeriodicFlows

Vanilla cross currency swap 'FloatFloat' receiving main currency currency and paying pay_currency with zero spread on receiving leg.

The swap type is inferred from fixed_rate field. If a fixed_rate is set, the swap type will default in 'FixedFloat'. This can be overridden by setting swap_type parameter.

The receiving leg is fixed in FixedFloat case

Keyword arguments:

  • currency: Currency of the swap and the receiving leg

  • pay_currency: Currency of the paying leg

  • tenor: Tenor (e.g. 5Y) or maturity date (e.g. dtm.date(2025,1,3)) of the swap

  • trade_date: Trade date of the swap. Used for starting the history and inferring un-supplied parameters.

  • start_date: Start date of the swap, or tenor for forward starting swap (e.g. '1Y' for swap starting in 1 year). If no date or tenor is given, T+2 is used

  • pay_notional: Notional of the paying leg. Notional of the receiving leg is always assumed 1. If no value is passed, the start_date FX forward on the trade_date is used

  • fixed_rate: Fixed rate (of the receiving leg) in case of fixed-floating swap. Will be set to the fair rate if left None, and swap_type is set to 'FixedFloat'. Expected in decimal format, e.g. 0.05 for 5%

  • spread: Spread (of the pay leg). In case of floating-floating swap, if left blank, fair spread will be set. Expected in the decimal format, e.g. 0.002 for 20bp

  • fixed_frequency: Fixed leg frequency ('Q', 'SA', or 'A') in case of fixed-floating swap quarterly if left blank (used only in 'FixedFloat' swap case)

  • receive_tenor: Receiving floating leg tenor ('1M', '3M', '6M', '1Y') in case of floating-floating swap. '3M' if left blank (used only in 'FloatFloat' swap case)

  • pay_tenor: Paying floating leg tenor ('1M', '3M', '6M', '1Y') . '3M' if left blank

  • receive_daycount: day count of the receiving leg (e.g. '30/360'). Currency interest rate swap default is used if left blank

  • pay_daycount: Day count of the paying leg (e.g. '30/360'). Currency interest rate swap default is used if left blank

  • swap_type: 'FixedFloat' or 'FloatFloat' to specify explicitly the type of swap (e.g. if fixed rate is not input and has to be inferred as the market fair rate)

  • pay_fixes_index: Optional override for default floating index fixing object of the pay leg

  • receive_fixes_index: Optional override for default floating index fixing object of the receive leg in 'FloatFloat' swap case

  • is_ois: Optional flag to use OIS floating leg(s) instead of IBOR if True. (Default swaps are IBOR swaps).

  • ois_params: Optional dictionary of OIS swap additional parameters overrides. Supported parameters are 'fixing_lag', 'pay_delay', 'pay_fixing_lag', 'rec_fixing_lag', 'ois_legs' - fixing_lag can be set for both floating legs via 'fixing_lag', or for each leg individually via 'pay_fixing_lag' and 'rec_fixing_leg' correspondingly, if both legs are floating OIS legs. 'ois_legs' is an optional parameter to allow only one of the legs be ois based, while the second - IBOR based. Allowed values are 'both' (default), 'pay' or 'rec'.

  • use_notional_reset: Optional flag to reset receiving leg notional to fair fx equivalent of the pay leg notional at each coupon end date. (Also known as MTM swaps). (False by default, i.e. notionals are fixed through life of the swap).

  • ignore_future_notional_reset: Optional flag for the resettable notional case. If True, only actually happened notional resets are taken into account, and legs are assumed bullet for the remaining life for valuation purposes - this reduces the valuation time without much sacrifice in precision as effect of proper future resets is minimal (True by default).

Example object creation:

swap = sig.CrossCurrencySwap(
            currency='USD',
            pay_currency='EUR',
            tenor=dtm.date(2025, 7, 5),
            pay_notional=0.89,
            start_date=dtm.date(2021, 7, 5),
            fixed_rate=0.0132)

This will create a swap, starting on 5-Jul-2021, ending on 5-Jul-2025, paying 3-month EURIBOR and receiving 1.32% fixed USD quarterly leg (with notional exchanges of 1 USD and 0.89 EUR at the beginning and the end)

swap = sig.CrossCurrencySwap(
            currency='USD',
            pay_currency='EUR',
            tenor='1Y',
            trade_date=dtm.date(2021, 7, 1),
        )

This will create a 1 year swap, starting on 5-Jul-2021 (\(T+2\)), paying 3-month EURIBOR plus spread (making the trade date value of the swap 0), and receiving 3-month USD LIBOR (with notional exchanges of 1 USD and spot USDEUR on 1-Jul-2021 of EUR at the beginning and the end)

swap = sig.CrossCurrencySwap(
            currency='USD',
            pay_currency='EUR',
            tenor='1Y',
            trade_date=dtm.date(2021, 7, 1),
            swap_type='FixedFloat',
        )

This will again create a 1 year swap, starting on 5-Jul-2021 (\(T+2\)), paying 3-month EURIBOR (without spread), and receiving quarterly USD fixed coupon, that makes swap value 0 on 1-Jul-2021 (with notional exchanges of 1 USD and spot USDEUR on 1-Jul-2021 of EUR at the beginning and the end).

Minor point to note - valuation data point rules for XCCY swaps is different from FXForwards - we try to always use the discounting/forecasting curve data point for FX as well, unless they are inconsistent, but even in that case, fx forward curves data points are used, even if more dense spot fx data is available (to get better overall consistency).

currency: str
execution_datetime: Optional[datetime]
fixed_frequency: Optional[Literal['Q', 'SA', 'A']]
fixed_rate: Optional[float]
ignore_future_notional_reset: Optional[bool]
is_ois: Optional[bool]
property maturity

Maturity date.

ois_params: Optional[dict]
pay_currency: str
pay_daycount: Optional[str]
pay_fixes_index: Optional[str]
pay_notional: Optional[float]
pay_tenor: Optional[Literal['1M', '3M', '6M', '1Y']]
receive_daycount: Optional[str]
receive_fixes_index: Optional[str]
receive_tenor: Optional[Literal['1M', '3M', '6M', '1Y']]
spread: Optional[float]
start_date: Optional[Union[date, str]]
swap_type: Optional[Literal['FixedFloat', 'FloatFloat']]
tenor: Union[date, str]
trade_date: Optional[date]
use_notional_reset: Optional[bool]
coupon_payment_dates() list[datetime.date]

List of all dated on which coupons are being paid.

metrics(data_dates: list[datetime.date] = None, fields: Union[str, list[str]] = None, data_point=None) DataFrame

Calculate the PV in both currency and pay_currency, fair spread/rate, pvbp of the pay leg, and fixed leg (if applicable) of this swap for given dates. Supported fields values are 'LastPrice', 'PV Pay Currency', 'FairSpread', 'FairRate', 'PayLegPvbp', 'FixedPvbp'.

static schedule_stub(currency, pay_currency)

Schedule stub for all XCCY swaps.

Parameters:
  • currency – Input receive leg currency.

  • pay_currency – Input pay leg currency.

Returns:

Schedule stub.

static spot_date(asof_date: Union[date, DatetimeIndex, ndarray], currency_par: str)

Standard swap start date if traded on asof_date. Vectorised form is also supported.

swap_details(d: date = None, as_df: bool = False) dict

Return swap info.

Parameters:

d – Reference date to return info for (env asof_date used if omitted).

Returns:

Dictionary of swap info.

swap_metrics(data_dates: list[datetime.date] = None, fields: Union[str, list[str]] = None, data_point=None) DataFrame deprecated

Deprecated method to calculate the PV in both currency and pay_currency, fair spread/rate, pvbp of the pay leg, and fixed leg (if applicable) of this swap for given dates.