CallableBond - Issuer delays 1 day on making a decision
Hi,
What are the consequences of an issuer making a decision 1 day after the firstCoupon date (adjusted)?
In the test bellow the issuer electAndVerifyPaymentEffects 1 day after.
- The first coupon passes the test.
- The second coupon on the second coupon date fails (the instrument is not evolved)
I wonder why this happens.
Thanks
Jose
runFloating = script do
[custodian, issuer, investor, calendarDataProvider, publicParty] <-
createParties ["Custodian", "Issuer", "Investor", "Calendar Data Provider", "PublicParty"]
-- Account and holding factory
let pp = [("FactoryProvider", S.singleton publicParty)]
-- Originate commercial-bank cash
now <- getTime
cashInstrumentCid <- originate custodian issuer "USD" "US Dollar" pp now
-- Create and distribute bond
-- Libor + 0.1% coupon every 3M
-- CREATE_3M_FLOATING_CALLABLE_BOND_VARIABLES_BEGIN
let
issueDate = date 2022 Jan 15
firstCouponDate = date 2022 Apr 15
maturityDate = date 2024 Jan 15
notional = 1.0
couponRate = 0.001
capRate = None
floorRate = None
couponPeriod = M
couponPeriodMultiplier = 3
dayCountConvention = Act360
businessDayConvention = Following
referenceRateId = "USD/LIBOR/3M"
floatingRate = Some FloatingRate with
referenceRateId
resetRelativeTo = CalculationPeriodStartDate
fixingDates = FixingDates with
periodMultiplier = 0
period = D
dayType = Some Business
businessDayConvention = NoAdjustment
businessCenters = ["USD"]
-- CREATE_3M_FLOATING_CALLABLE_BOND_VARIABLES_END
observations = M.fromList
[ (dateToDateClockTime $ date 2022 Jan 17, 0.010)
, (dateToDateClockTime $ date 2022 Apr 15, 0.010)
, (dateToDateClockTime $ date 2022 Jul 15, 0.010)
]
holidayCalendarIds = ["USD"]
cal =
HolidayCalendarData with
id = "USD"
weekend = [Saturday, Sunday]
holidays = []
-- A reference data provider publishes the holiday calendar on the ledger
calendarCid <- submit calendarDataProvider do
createCmd HolidayCalendar with
provider = calendarDataProvider
calendar = cal
observers = M.fromList pp
observableCid <- toInterfaceContractId <$> submit issuer do
createCmd Observation with
provider = issuer; id = Id $ referenceRateId; observations; observers = M.empty
bondInstrument <- originateCallableBond issuer issuer "BONDTEST1" "Callable Bond" pp now
issueDate holidayCalendarIds calendarDataProvider firstCouponDate maturityDate
dayCountConvention businessDayConvention floatingRate couponRate capRate floorRate couponPeriod
couponPeriodMultiplier cashInstrumentCid notional
-- One day before the first coupon date: try to lifecycle and verify that there are no lifecycle
-- effects.
verifyNoLifecycleEffects [publicParty] (subtractDays firstCouponDate 1) bondInstrument issuer
[observableCid]
let
amount = 1.0
electorIsOwner = False
-- Coupon date 1 + 1 : Lifecycle and verify that there is an effect for one coupon.
let
expectedConsumed = []
expectedProduced = [qty 0.0026888889 cashInstrumentCid]
(Some bondInstrumentAfterCoupon1, effectCid) <- electAndVerifyPaymentEffects (date 2022 Apr 16)
amount bondInstrument electorIsOwner issuer investor [publicParty] "NOT CALLED" [observableCid]
expectedConsumed expectedProduced
-- Coupon date 2: Lifecycle and verify that there is an effect for one coupon.
let
expectedConsumed = []
expectedProduced = [qty 0.0027805556 cashInstrumentCid]
(Some bondInstrumentAfterCoupon2, effectCid) <- electAndVerifyPaymentEffects (date 2022 Jul 15)
amount bondInstrumentAfterCoupon1 electorIsOwner issuer investor [publicParty] "NOT CALLED"
[observableCid] expectedConsumed expectedProduced
pure ()
I’ve just checked that with the new version on main the result of electAndVerifyPaymentEffects 1 day after the coupon date is the following failure:
“Election not possible on this date”
which makes sense.
The question now is: If the issuer delays on making the decision, is there some way of recovering from that?
Thanks!
Jose
The election needs to be made as of at the right time for the contract to be life-cycled correctly. Specifically, this means that the Election contract needs to contain the right date (2022 Apr 15 for the first coupon).
For lifecycling purposes, it doesn’t really matter when the Election contract is created (real time), but only what date is stored in the contract.
This is to avoid cases where an instrument ends up in a “frozen state” where it can no longer be life-cycled without introducing custom lifecycling rules.
Your election workflow needs to decide how to handle the case where the issuer delays making a decision (meaning that no Election contract is created before a specified real time T). Some options are
- a default election is processed (“CALLED” or “NOT CALLED”)
- you let the issuer create an election “retroactively”, so an election for
15 Apris created on16 Apr
The nature of the delay should probably drive what behaviour is chosen.
I hope this helps,
Matteo