Structured Product¶
To follow the script used in this tutorial, you can clone the Daml Finance repository. In particular, the Structured Product test folder Instrument/StructuredProduct/Test/ is the starting point of this tutorial.
How to create a Structured Product Instrument¶
In order to create a structured product instrument, you first have to decide what type of payoff you need. The structured product instrument packages currently supports the following types of payoffs:
Barrier Reverse Convertible¶
The BarrierReverseConvertible instrument models cash-settled, auto-exercising barrier reverse convertible (BRC) instruments. It can be seen as a long fixed coupon bond and a short Down-And-In put option.
For example, consider a BRC that pays a fixed 5% coupon rate and has a barrier level of 30 USD. If the underlying ever trades below this level, the put option is knocked in (activated). This would reduce the redemption amount if the underlying closes below the strike price at expiry.
This example is taken from the BarrierReverseConvertible.daml test file , where all the details are available.
You start by defining the terms:
barrier = 30.0
barrierStartDate = date 2019 Jan 16
strike = 40.0
expiryDate = date 2019 May 15
referenceAssetId = "AAPL-CLOSE"
couponRate = 0.05
issueDate = date 2019 Jan 16
firstCouponDate = date 2019 Feb 15
maturityDate = date 2019 May 15
Now that the terms have been defined, you can create the BRC instrument:
let
instrument = InstrumentKey with
issuer
depository
id = Id label
version = "0"
holdingStandard
cid <- submitMulti [issuer] [publicParty] do
exerciseCmd brcFactoryCid BarrierReverseConvertibleFactory.Create with
barrierReverseConvertible = BarrierReverseConvertible with
instrument
description
expiryDate
strike
barrier
barrierStartDate
referenceAssetId
couponRate
periodicSchedule
holidayCalendarIds
calendarDataProvider
dayCountConvention
notional
currency
lastEventTimestamp
prevEvents = []
observers = Map.fromList observers
Once this is done, you can create a holding on it using Account.Credit.
This BRC instrument is automatically exercised. This means that the decision whether or not to exercise the embedded option is done automatically by comparing observations of the underlying to the strike and barrier level of the instrument. For this to work, you need to define an Observation as well:
let
observations = Map.fromList
[ (dateToDateClockTime $ date 2019 Feb 13, 28.78)
, (dateToDateClockTime $ date 2019 Feb 15, 39.78)
, (dateToDateClockTime $ date 2019 May 15, 38.78)
, (dateToDateClockTime $ date 2019 May 16, 18.78)
, (dateToDateClockTime $ date 2019 May 17, 38.78)
]
observableCid <- toInterfaceContractId <$> submit issuer do
createCmd Observation with
provider = issuer; id = Id referenceAssetId; observations; observers = mempty
Since this option instrument is cash-settled, the underlying asset will not change hands. Instead, the cash value of the payoff is paid to the BRC holder.
Auto-Callable¶
The AutoCallable instrument models a single-underlying auto-callable note that pays a conditional coupon.
Coupon payment¶
The conditional coupon is paid in every period unless the coupon barrier is hit at the end of the period. There is no coupon memory – coupons missed due to barrier hits are not repaid in future periods.
Early redemption¶
If the underlying asset closes above the call barrier on an observation date, the instrument is automatically redeemed early at the end of that period.
Redemption at maturity (if not redeemed early)¶
At maturity, the principal amount is repaid unless a final barrier has been breached on the last observation date (in which case the performance of the underlying asset is paid). In other words, this instrument models an AutoCallable Barrier Reverse Convertible where the knock-in put is struck at 100% and the barrier is observed at maturity.
Example¶
For example, consider an auto-callable yield note that pays a conditional 5% coupon. (For more details, see the AutoCallable.daml test file for this example.)
Start by defining the terms:
putStrike = 1.00 -- 100% of the underlying closing price on the initial fixing date
couponBarrier = 0.65 -- 65% of the underlying closing price on the initial fixing date
callBarrier = 1.00
finalBarrier = 0.875
referenceAssetId = "AAPL-CLOSE"
couponRate = 0.05
dayCountConvention = Basis1 -- coupon rate is paid each period, not per annum.
businessDayConvention = Following
couponPeriod = M
couponPeriodMultiplier = 3
initialFixingDate = date 2024 Jan 10
issueDate = date 2024 Jan 16
firstRegularObervationDate = date 2024 Mar 28
firstCouponDate = date 2024 Apr 2
secondCouponDate = date 2024 Jul 2
expiryDate = date 2024 Sep 28
maturityDate = date 2024 Oct 2
Note that the Basis1 day-count convention specifies that the 5% coupon is paid in every coupon period (not per annum).
Now that the terms have been defined, you can create the AutoCallable instrument:
let
instrument = InstrumentKey with
issuer
depository
id = Id label
version = "0"
holdingStandard
cid <- submitMulti [issuer] [publicParty] do
exerciseCmd factoryCid AutoCallableFactory.Create with
autoCallable = AutoCallable with
instrument
description
putStrike
couponBarrier
callBarrier
finalBarrier
referenceAssetId
couponRate
observationSchedule
periodicSchedule
holidayCalendarIds
calendarDataProvider
dayCountConvention
notional
currency
lastEventTimestamp
prevEvents = []
observers = Map.fromList observers
Then you can create a holding on it using Account.Credit.
This instrument is automatically called. This means that the decision whether or not to exercise the embedded option is done automatically using the observations of the underlying asset.
Because this option instrument is cash-settled, the underlying asset does not change hands. Instead, the cash value of the payoff is paid to the holder.
Frequently Asked Questions¶
How do I calculate settlement payments for a structured product?¶
Similar to a fixed coupon bond, a BRC instrument needs to be lifecycled on the coupon dates and at expiry, in order to calculate the corresponding payments. This is described in the Lifecycling tutorial. In addition, if the instrument has a barrier (which is the case for a BRC), it needs to be lifecycled regularly during its lifetime to record any barrier breach, which would impact the redemption payment.