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.