Reference Application: Structured Products
Overview
Structured Equity Derivative Products are used to provide custom payoffs, often for Private Bank or wealth clients, who are looking to get exposure to particular underlying company performance in a way that traditional securities do not provide. For example, I may wish to receive a higher payoff if I bet the price of an underlying security trades within a particular range. Investment banks provide these products — called Structured Products — and sell them to Intermediaries, who in turn often slice up the product and offer it to their end clients.
The term of such trades can be multiple years, with defined points in time where certain parameters are measured, compared against a predefined benchmark, and a calculation made as to whether a payment should be made.
This application shows creation and subsequent event management and payment determination for two types of trades:
- Issuer vs. Intermediary
- Intermediary vs. Client
Getting Started
Installing
Disclaimer: This reference application is intended to demonstrate the capabilities of the DAML. You are recommended to consider other non-functional aspects, like security, resiliency, recoverability, etc prior to production use.
Prerequisites
Be sure you have the following installed:
- DAML SDK
- Java
- Maven
Installing Additional Tools: Telegram Installation
Telegram is used as an optional receive confirmation messages from the app. Skip these steps if you do not want to receive notification via the Telegram application.
-
Install Telegram app on your phone.
-
Set up your Telegram account by verifying with your phone number.
-
Find your Telegram chat ID:
-
Go to Chats menu in the application and find the existing bot called
@get_id_bot
by typing in its name to the search bar. -
Send the
/start
to the channel to get your Chat ID.Your Chat ID will be displayed. You can use it as CHAT ID. Its typical format is
<numbers>
-
-
Create a new bot for the application:
- Find the
@BotFather
bot as described above. - Choose start.
- Create your own bot by sending the
/newbot
message to theBotFather
. Give it a unique name ending in bot. The new bot will appear in your Telegram contact list using this name.
- Find the
-
Note the token that is displayed. This will be your bot token. The usual format is:
<numbers>:<characters>
-
Contact the new bot by sending any message to it. Otherwise it will not be allowed to relay the notifications to you.
Note: You can look up your Telegram Chat ID and Telegram Bot ID by opening the respective chats in the Telegram application:
@get_id_bot
, and@BotFather
-
Add your Telegram Chat ID and bot token id to the telegram.properties file in your Terminal by editing the file with a text editor.
-
Specify the details of your Telegram setup.
cp -n telegram.properties.sample telegram.properties
Edit this file in a plain text editor and add the values for
BOT_TOKEN
andCHAT_ID
you acquired in step 1 above.From this point, you will receive messages in Telegram.
Build with Maven
Type:
cp -n telegram.properties.sample telegram.properties
mvn clean package
Note: If you change the DAML models locally, you need to re-run this command before starting the application.
Starting the App
Note: Make sure you have built the application with Maven (see: Build with Maven).
- Start the DAML Sandbox and Navigator. Type:
The navigator will automatically open in new browser tab at http://localhost:7500.
daml start --sandbox-option --address=localhost --sandbox-option --static-time
- Start the automation logic by starting bots. Type:
java -jar target/structured-products-1.0.0-SNAPSHOT.jar
Observing Output Files
- In another terminal, first go to the folder that you started the bots from. Then list the files.
cd ./output_messages ls -l
- Print file content.
cat <file_ name>
Stopping the App
- Stop the bots by pressing Ctrl+C.
- Stop the Sandbox and the Navigator by pressing Ctrl+C in the DAML assistant.
Resetting the Prototype
Reset the application by following these steps:
- Stop the app by following the steps in Stopping the App section.
- Start the app by following the steps in Starting the App section.
Walkthrough
Logging In
As you work through the steps described in this section, log in as different users in Navigator (Issuer, Intermediary, Client, Regulator).
To log in:
- On the home screen, select the party from the list.
To switch users:
- Click the name of the current party at the top of the screen.
- On the home screen, select a different party.
Note: The Navigator for this demo has been designed with tabs that show the different types of reporting that can be done when for such a workflow in DAML. The point here is that it is very simple to pull separate information off the ledger (Sandbox).
- Market data: shows the preset market data observations for the two underlyings
- Trade details: shows trade proposals and accepted trades
- Events: shows generated events as a result of lifecycling the DCN
- Payments: shows the payments generated off the back of events (shows payer, payee, amount, currency, account details)
Demo Data
All demo data is created when the application is run, using DAML scenarios. This data includes:
- Participant roles
- Product Term Sheet
- Schedule of dates that are used during the demo
- Market data
Data is summarized here with additional information on each at the end of this document in Additional Information.
Roles
Role | Description |
Issuer | Issuer of a Digital Contract Note (DCN) |
Intermediary | Distributor of the structured products who has a contract with the Issuer |
Client | End client who has a contract with the Intermediary |
Regulator | Regulator who is entitled to see all trades, events and payments |
Term Sheet
The details of the product are pre-loaded in the demo. An auto-callable Digital Contract Note (DCN) combines a fixed income instrument (variable coupon payment) with optionality based on price of the underlyings.
Schedule
A schedule of dates that is agreed to upfront dictates on what dates market data observations will be recorded. This schedule will also define the pay date for any cash payments that are generated as a result of the market data observations.
Coupon Event
On 11 November, 2019, if the observed market price for NKY is above JPY 17359.12 AND the observed market price for INDU is above USD 20304.59, then a coupon of 5% of the notional will be paid from Issuer to Intermediary (and subsequently the Intermediary to the Client), with a payment date of 18 November, 2019.
Knockout Event
On 8 February, 2022, if the observed market price for NKY is above JPY 21687.65 AND the observed market price for INDU is above USD 25380.74, then the trade will knock out, and the full notional value will be returned to the Intermediary (by the Issuer) and to the Client (by the Intermediary).
Market Data
Structured Products normally generate events in response to market data observations (e.g., equity prices). These have been pre-loaded in the demo.
Application Steps
Note: This demo is designed to show event generation and visibility to different entities connected to the platform without any user errors or exception handling. It is also a very simplified version of a structured product and models only coupon events and one knockout event. A full production implementation would include additional features, handle errors and exceptions, and incorporate appropriate security controls.
New Trade: Issuer vs. Intermediary
Follow these steps:
-
Log in as Issuer.
-
Click on Trade Details.
You will see the pre-canned Trade Proposal between the Issuer and Intermediary and summary information: Product ID, Notional, Issuer, Buyer, Terms. Note that there is no Trade ID, as the trade has not yet been accepted by the Intermediary.
-
Click on the contract and view all the details of the Term Sheet that has been pre-canned. Note the contract id of the Trade Proposal contract.
-
Switch users and log in as Intermediary.
-
Click on Trade Details.
You will see the same Trade Proposal between the Issuer and Intermediary and summary information: Product ID, Notional, Issuer, Buyer, Terms. Note that the Trade Proposal Contract number is the same.
-
Click on the contract and view all the details of the Term Sheet that have been preset.
-
Switch users and log in as Client.
-
Click on Trade Details.
You will see a blank screen as there has been no independent trade created between the Intermediary and the Client.
-
Switch users and log in as Intermediary.
-
Click on Trade Details.
-
Click into the Proposal contract.
-
Select the Accept choice.
- Enter INTER001 as tradeid.
- Enter INTXXXABC as bic.
- Enter 1234567 as iban.
- Click Submit.
-
Go to Trade Details and see that the Proposal contract has now been replaced by Trade contract.
-
Click on Include Archived to show the now archived Proposal contract.
-
Switch users and log in as Issuer.
-
Click on Trade Details.
The Proposal contract has now been replaced by the Trade contract. The Issuer see the exact same contract as the Intermediary (can be verified by the contract id).
-
Click on Include Archived to show the now archived Proposal contract.
New Trade: Intermediary vs. Client
You now need to leverage the same business process for the trade between the Intermediary and the Client.
Follow these steps:
-
Switch users and log in as Intermediary.
-
Click on Trade Details.
-
Click on the Trade contract.
-
Copy the ContractId to the clipboard
-
Click on Trading
- Select the IntermediaryTradingRole contract
- Select the ProposeTradeToClient choice.
- Enter Client as the client.
- Enter 26000000 as notional (26 million, less than the original 50 million notional between Issuer and Intermediary).
- Paste the ContractId of the Trade from the clipboard
- Click Submit.
-
Click on Trade Details
There is now a new Proposal contract (vs. Client) as well as the Trade contract (vs. the Issuer). Note the contract # of the Proposal.
-
Switch users and log in as Client.
-
Click on Trade Details.
The contract id of the Proposal is the same as that on the Intermediary.
-
Click on the Proposal contract.
- Click Accept.
- Enter CLIENT001 as tradeid.
- Enter CLIXXXABC as bic.
- Enter 5678910 as iban.
- Click Submit.
-
Go to Trade Details and see that the Proposal contract has now been replaced by the Trade contract.
-
Click on Include Archived to show the now archived Proposal contract.
-
Switch users and log in as Issuer.
-
Click on Trade Details.
The new Trade between Intermediary and the Client is not visible.
New Trade: Regulator
Follow these steps:
-
Switch users and log in as Regulator.
-
Click on Trade Details.
Note that as the Regulator, you can see both trades.
Coupon Event: Issuer vs. Intermediary
Follow these steps:
-
Switch users and log in as Issuer.
-
Click on the Market Data tab and note that there is observed market data for 11 November, 2019, for both underlyings.
-
Click on the contract and copy its contract id.
-
Change the system date to 11 November, 2019.
-
Click on the Trade Details tab.
-
Click on Trade contract:
- Click Lifecycle.
- Enter the copied contract id as marketDataCid.
- Click Submit.
-
Click on the Events tab and note that a Coupon event has been generated that shows the relevant information: which trade it relates to, payment date, closing prices vs. strikes.
-
Click on the Payment Instructions tab and note that a Payment instruction has been generated, and the screen shows relevant information: trade it relates to, currency and amount, payment date, payer BIC and IBAN, and payee BIC and IBAN.
-
Switch users and log in as Intermediary.
-
Click on the Events tab and note that the same Coupon event has been generated and shows the relevant information: which trade it relates to, payment date, closing prices vs. strikes.
-
Click on the Payment Instructions tab. Note that the same Payment instruction has been generated, and the screen shows relevant information: trade it relates to, currency and amount, payment date, payer BIC and IBAN, and payee BIC and IBAN.
-
Switch users and log in as Client.
-
Click on Events and then the Payment Instructions tab, noting that both are blank as no events or payments have yet been generated for the Intermediary vs. Client trade.
-
Go to the
./output_messages
folder using a file browser.You will see that a sample SWIFT MT202 payment message that has been generated for the payment between the Issuer and the Intermediary. All SWIFT messages are written to this folder, which is a subfolder under the folder from which the bots were started.
-
If you have enabled the Telegram bot (search on Telegram for @DAMLBot), you will have received the event details in one message and the payment details (same MT202) in a separate message.
Coupon Event: Intermediary vs. Client
Follow these steps:
-
Go to the Intermediary window.
-
Click on the Market Data tab and note that there is observed market data for 11 November, 2019, for both underlyings.
-
Click on the contract and copy its contract id.
-
Click on the Trade Details tab.
-
Click on the Trade contract with CLIENT001 as Trade ID.
- Click Lifecycle.
- Enter the copied contract id as marketDataCid.
- Click Submit.
-
Click on the Events tab and note that a Coupon event has been generated that shows the relevant information: which trade it relates to, payment date, closing prices vs. strikes.
-
Click on the Payment Instructions tab and note that a Payment instruction has been generated, and the screen shows relevant information: trade it relates to, currency and amount, payment date, payer BIC and IBAN, and payee BIC and IBAN.
-
Switch users and log in as Client.
-
Go to the Client window and click on the Events tab and note that the same Coupon event has been generated and shows the relevant information: which trade it relates to, payment date, closing prices vs. strikes.
-
Click on the Payment Instructions tab and note that the same Payment instruction has been generated, and the screen shows relevant information: trade it relates to, currency and amount, payment date, payer BIC and IBAN, and payee BIC and IBAN.
-
Switch users and log in as Issuer.
-
Click on Events and then Payment Instructions tab.
Only one Event and one Payment Instruction are visible.
-
Go to the
./output_messages
folder using a file browser.You will see a sample SWIFT MT202 payment message that has been generated for the payment between the Issuer and the Intermediary.
-
If you have enabled the Telegram bot (search on Telegram for @DAMLBot), you will have received the event details in one message and the payment details (same MT202) in a separate message.
Knockout Event: Issuer vs. Intermediary
Follow these steps:
-
Switch users and log in as Issuer.
-
Click on the Market Data tab and note that there is observed market data for 8 February, 2022, for both underlyings.
-
Click on the contract and copy its contract id.
-
Change the system date to 8 February, 2022.
-
Click on the Trade Details tab.
-
Click on Trade contract:
- Click on Lifecycle.
- Enter the copied contract id as marketDataCid.
- Click Submit.
-
Click on the Events tab and note that now a Knockout event has been generated that shows the relevant information: which trade it relates to, payment date, closing prices vs. strikes.
-
Click on the Payment Instructions tab and note that now a Payment instruction has been generated for the full notional because the trade has knocked out. The screen shows relevant information: trade it relates to, currency and amount, payment date, payer BIC and IBAN, and payee BIC and IBAN.
-
Switch users and log in as Intermediary.
-
Click on the Events tab.
The same Knockout event has been generated that shows the relevant information: which trade it relates to, payment date, closing prices vs. strikes.
-
Click on the Payment Instructions tab and note that the same Payment instruction has been generated, and the screen shows relevant information: trade it relates to, currency and amount, payment date, payer BIC and IBAN, and payee BIC and IBAN.
-
Go to the
./output_messages
folder using a file browser.You will see a sample SWIFT MT202 payment message that has been generated for the payment between the Issuer and the Intermediary
-
If you have enabled the Telegram bot (search on Telegram for DAMLBot), you will have received the event details in one message and the payment details (same MT202) in a separate message.
Knockout Event: Intermediary vs. Client
Follow these steps:
-
Switch users and log in as Intermediary.
-
Click Refresh (this picks up the new system date).
-
Click on Market Data tab and note that there is observed market data for 8 February, 2022, for both underlyings.
-
Click on the Trade Details tab.
-
Click on Trade contract:
- Click on Lifecycle.
- Click on the contract and copy its contract id.
- Click Submit.
-
Click on the Events tab and note that now a Knockout event has been generated that shows the relevant information: which trade it relates to, payment date, closing prices vs. strikes.
-
Click on the Payment Instructions tab and note that now a Payment instruction has been generated, and the screen shows relevant information: trade it relates to, currency and amount, payment date, payer BIC and IBAN, and payee BIC and IBAN.
-
Switch users and log in as Client.
-
Go to the Client window and click on the Events tab and note that the same Knockout event has been generated that shows the relevant information: which trade it relates to, payment date, closing prices vs. strikes.
-
Click on the Payment Instructions tab and note that the same Payment instruction has been generated, and the screen shows relevant information: trade it relates to, currency and amount, payment date, payer BIC and IBAN, and payee BIC and IBAN.
-
Go to the
./output_messages
folder using a file browser.You will see a sample SWIFT MT202 payment message that has been generated for the payment between the Issuer and the Intermediary.
-
If you have enabled the Telegram bot (search on Telegram for @DAMLBot), you will have received the event details in one message and the payment details (same MT202) in a separate message.
Events and Payment Instructions - Regulator
Follow these steps:
-
Switch users and log in as Regulator.
-
Click on the Events and Payment Instructions tabs.
On each tab, all Events and Payment Instructions are visible.
Additional Information
Term Sheet
The details of the product are pre-loaded in the demo and are summarised in this table and can be observed in the DAML code.
Parameter | Detail | Notes |
Product ID | DCN | |
Notional | 50,000,000 | |
Currency | JPY | |
Issue Price Percentage | 100% | |
Underlying Index 1 | NKY | Nikkei 225 |
Underlying Index 2 | INDU | Dow Jones Industrial Average |
Trade Date | 2 November 2018 | |
Maturity Date | 16 November 2023 | |
Underlying Index 1 Coupon Strike | 17350.12 | |
Underlying Index 1 Coupon Strike CCY | JPY | |
Underlying Index 2 Coupon Strike | 20304.59 | |
Underlying Index 2 Coupon Strike CCY | USD | |
Underlying Index 1 Knockout Strike | 21687.65 | |
Underlying Index 1 Knockout Strike CCY | JPY | |
Underlying Index 2 Knockout Strike | 25380.74 | |
Underlying Index 2 Knockout Strike CCY | USD | |
Variable Interest Rate - min | 0.001 | This is the amount of interest that will be paid on the notional value if the observed market price on the observation date is < the defined coupon strike price for each underlying |
Variable Interest Rate - max | 0.05 | This is the amount of interest that will be paid on the notional value if the observed market price on the observation date is > the defined coupon strike price for each underlying |
Schedule
Coupon Observation
Dates |
NKY Coupon Strike
(JPY) |
INDU Coupon Strike
(USD) |
KO Determination
Dates |
NKY KO Price
(JPY) |
INDU KO Price
(USD) |
Interest / Redemption
Payment Dates |
(2019, Feb, 11) | 17350.12 | 20304.59 | (2019, Feb, 8) | 21687.65 | 25380.74 | (2019, Feb, 19) |
(2019, May, 9) | 17350.12 | 20304.59 | (2019, May, 9) | 21687.65 | 25380.74 | (2019, May, 16) |
(2019, Aug, 9) | 17350.12 | 20304.59 | (2019, Aug, 8) | 21687.65 | 25380.74 | (2019, Aug, 16) |
(2019, Nov, 11) | 17350.12 | 20304.59 | (2019, Nov, 11) | 21687.65 | 25380.74 | (2019, Nov, 18) |
(2020, Feb, 10) | 17350.12 | 20304.59 | (2020, Feb, 7) | 21687.65 | 25380.74 | (2020, Feb, 18) |
(2020, May, 11) | 17350.12 | 20304.59 | (2020, May, 11) | 21687.65 | 25380.74 | (2020, May, 18) |
(2020, Aug, 10) | 17350.12 | 20304.59 | (2020, Aug, 7) | 21687.65 | 25380.74 | (2020, Aug, 17) |
(2020, Nov, 9) | 17350.12 | 20304.59 | (2020, Nov, 9) | 21687.65 | 25380.74 | (2020, Nov, 16) |
(2021, Feb, 9) | 17350.12 | 20304.59 | (2021, Feb, 5) | 21687.65 | 25380.74 | (2021, Feb, 16) |
(2021, May, 10) | 17350.12 | 20304.59 | (2021, May, 10) | 21687.65 | 25380.74 | (2021, May, 17) |
(2021, Aug, 9) | 17350.12 | 20304.59 | (2021, Aug, 6) | 21687.65 | 25380.74 | (2021, Aug, 16) |
(2021, Nov, 9) | 17350.12 | 20304.59 | (2021, Nov, 9) | 21687.65 | 25380.74 | (2021, Nov, 16) |
(2022, Feb, 9) | 17350.12 | 20304.59 | (2022, Feb, 8) | 21687.65 | 25380.74 | (2022, Feb, 16) |
(2022, May, 9) | 17350.12 | 20304.59 | (2022, May, 9) | 21687.65 | 25380.74 | (2022, May, 16) |
(2022, Aug, 9) | 17350.12 | 20304.59 | (2022, Aug, 8) | 21687.65 | 25380.74 | (2022, Aug, 16) |
(2022, Nov, 9) | 17350.12 | 20304.59 | (2022, Nov, 9) | 21687.65 | 25380.74 | (2022, Nov, 16) |
(2023, Feb, 9) | 17350.12 | 20304.59 | (2023, Feb, 9) | 21687.65 | 25380.74 | (2023, Feb, 16) |
(2023, May, 9) | 17350.12 | 20304.59 | (2023, May, 9) | 21687.65 | 25380.74 | (2023, May, 16) |
(2023, Aug, 9) | 17350.12 | 20304.59 | (2023, Aug, 8) | 21687.65 | 25380.74 | (2023, Aug, 16) |
(2023, Nov, 9) | 17350.12 | 20304.59 | (2023, Nov, 9) | 21687.65 | 25380.74 | (2023, Nov, 16) |
Market Data
Underlying | Source | Publish Date | Created By | Price | Currency |
Index 1 | Reuters | 11 Nov 2019 | Issuer | 17500.25 | JPY |
Index 2 | Reuters | 11 Nov 2019 | Issuer | 20350.76 | USD |
Index 1 | Reuters | 11 May 2020 | Issuer | 17320.94 | JPY |
Index 2 | Reuters | 11 May 2020 | Issuer | 20304.59 | USD |
Index 1 | Reuters | 8 Aug 2021 | Issuer | 21687.65 | JPY |
Index 2 | Reuters | 8 Aug 2021 | Issuer | 25380.74 | USD |
Index 1 | Reuters | 8 Feb 2022 | Issuer | 22057.30 | JPY |
Index 2 | Reuters | 8 Feb 2022 | Issuer | 25402.47 | USD |
CONFIDENTIAL © 2019 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. Any unauthorized use, duplication or distribution is strictly prohibited.