How to use the Structured Product Instrument package

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 Instrument/StructuredProduct/Test/BarrierReverseConvertible.daml , 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.

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.