Savings Plans: Recurring Investments using Workflows
Set up recurring investment schemes using workflows.
Introduction
Recurring investments are one of the pillars of investment success. In fact, it’s so popular that different regions have established totally different terms for the same thing: Dollar Cost Averaging (US) or Savings Plans (DE; Sparpläne) are popular names; however, they all share the same fundamental properties: For each of these, a fixed amount of money is invested in the same security periodically, e.g. every month.
At lemon.markets, we manage programmatic investment instructions like this using workflows. A workflow is a building block allowing automatic creation of our existing order types. As such, it complements the existing API as a pure add-on.
Create a Workflow
Let’s start by creating a workflow for the account cusa_12345
to invest 12.50 € every month into an ETF:
# curl -sS -H 'LMG-Data-Privacy-Access-Principal: backend-cusa_12345' \
-H 'LMG-Data-Privacy-Access-Justification: app.create_workflow' \
-H 'Authorization: Bearer <your-api-key>' \
-H 'Content-Type: application/json; charset: utf-8' \
'https://sandbox.api.lemon.markets/v1/accounts/cusa_12345/workflows?unified_orders=true' \
--data-binary '
{
"action": {
"type": "order.create_and_confirm",
"order": {
"amount": "12.5",
"currency": "EUR",
"fee": "0",
"instrument": "LU0290358497",
"side": "buy",
"type": "batch"
}
},
"trigger": {
"cadence": "monthly",
"type": "schedule"
}
}' | jq
As a result, you’ll see a response like this:
{
"id": "wf_c34bf754daa34de1ba7ee668a06788c9",
"trigger": {
"type": "schedule",
"cadence": "monthly"
},
"action": {
"type": "order.create_and_confirm",
"order": {
"side": "buy",
"instrument": "LU0290358497",
"amount": "12.50",
"fee": "0.00",
"currency": "EUR",
"type": "batch"
}
},
"regulatory_disclosures": {
"kid": "https://kid.dev-sandbox.lemon.markets/2023-11-17/LU0290358497-ac81558ef3e50c8eb4a01f7a68800963.pdf",
"estimated_price": "141.3010",
"estimated_quantity": "0.08846",
"estimated_amount": "12.50",
"service_costs_total": "0.00",
"service_costs_total_pct": "0.03",
"entry_costs": "0.00",
"entry_costs_pct": "0.00",
"…": "…"
},
"sca": {
"required": false,
"challenge": "aREfflZxxtFqKlxqgSAAHA=="
},
"appropriateness_consent": {
"required": false
},
"history": [
{
"status": "created",
"timestamp": "2024-04-22T14:39:34.292276+00:00"
}
]
}
Confirm a Workflow
The created workflow requires confirmation by the customer. You can confirm a workflow on the sandbox without strong customer authentication (SCA) like this:
# curl -sS -H 'LMG-Data-Privacy-Access-Principal: backend-erika.mustermann%40example.com' \
-H 'LMG-Data-Privacy-Access-Justification: create_workflow' \
-H 'Authorization: Bearer <your-api-key>' \
-H 'Content-Type: application/json; charset: utf-8' \
'https://sandbox.api.lemon.markets/v1/accounts/cusa_12345/workflows/wf_c34bf754daa34de1ba7ee668a06788c9' \
--data-binary '{}'
The response will contain the updated workflow. Information relevant for confirmation will be omitted now (regulatory disclosures, strong customer authentication, and appropriateness consent requirement). Let’s focus on the history
here to see the status being updated:
{
"…": "…",
"history": [
{
"status": "confirmed",
"timestamp": "2024-04-22T14:46:07.907882+00:00"
},
{
"status": "created",
"timestamp": "2024-04-22T14:39:34.292276+00:00"
}
]
}
Order Creation
On the next execution day, there will be two relevant points in time:
- Cut-Off Time: In the morning of the trading day, the lemon.markets platform will prepare all savings plans for execution by creating and confirming new orders. If confirmation fails (e.g. due to insufficient funds), orders will be rejected. You will see events of type
order.created
,order.confirmed
, and eitherorder.accepted
ororder.rejected
for this.- NOTE: At this point in time, cancelling a workflow will not cancel the order that was created. Instead, both the workflow and the created order have to be canceled separately.
- Execution Time: Later in the day, the orders will be executed. At that point, cancellation is no longer possible.
As the workflow captures information like regulatory disclosures, strong customer authentication and appropriateness consent, this information will not be exposed on orders created by a workflow. Instead, the order will refer to the workflow using the workflow
property:
{
"id": "bord_abd426e1a0e5478e851fca7379ea7765",
"workflow": "wf_c34bf754daa34de1ba7ee668a06788c9",
"created_at": "2024-04-23T07:00:03.740574+00:00",
"side": "buy",
"instrument": "LU0290358497",
"amount": "12.50",
"quantity": null,
"fee": "0.00",
"currency": "EUR",
"status": "accepted",
"history": [
{
"status": "accepted",
"timestamp": "2024-04-23T07:00:06.607181+00:00"
},
{
"status": "created",
"timestamp": "2024-04-23T07:00:03.740574+00:00"
}
]
}
Sequence Diagram
Current Restrictions
- Execution is restricted to a
monthly
schedule. The sandbox also provides adaily
schedule for testing. - Workflows are immutable. If the amount should be changed, cancel the old workflow and create a new one.
- Workflows can only buy shares for now. Divestment plans are not supported yet.
If your use-case exceeds these capabilities, feel free to contact us. We love expanding our product with new partners.
Updated 5 months ago