Skip to content

Funding and withdrawal


There are two sorts of cash transactions: deposits (funding) and withdrawals. Depending on (1) the direction (fund, withdraw) (2) the setup with the broker (who is integrated: the Client or InvestSuite), and (3) the product (Robo Advisor or Self Investor) the Client Middleware performs several actions. These actions range from moving the money in the broker's account system, to making InvestSuite send a notification. Below we describe in detail which actions to take, and which ones InvestSuite takes depending on the scenario.

For Robo Advisor, the Funding/Withdrawal process and the Rebalancing process are closely related:

  • A funding triggers Optimizer, which will generate an Optimization, which contains orders that (during rebalancing) will invest the cash;
  • A withdrawal triggers Optimizer, which will generate an Optimization, which contains orders that (during rebalancing) will divest instruments and free up cash.

If you are looking to design/build a middleware that handles both, we recommend to have a look at our example middleware design.

For Self Investor, the Funding/Withdrawal process is more straightforward, as the Customer is responsible for investing/freeing up cash.

Funding

Broker integration by InvestSuite

Info

We assume there is an integration between the Broker/Custodian and the Core Banking System (eg. through end-of-day files), that handles the corresponding cash transfers.

  1. The Client Middleware notifies InvestSuite that the investor account at the Bank has been funded by calling POST /events/deposit/ (see here).
    • You should make sure to only call this endpoint for portfolios that have:
      • a status that is either ACTIVE or WAITING_FOR_FUNDS
      • archived field is set to false.
      • money_type is set to REAL_MONEY
  2. InvestSuite moves the cash at the broker from the bank's house account to the customer's subaccount. InvestSuite will manage keeping the Transactions, Portfolio Holdings up to date (asynchronously).
  3. If this is the first funding, InvestSuite sets the funded_since field.
  4. In case of Robo Advisor, this will (asynchronously) trigger Optimizer.
  5. InvestSuite sends a notification to the Customer.

Broker integration by the Client

Info

Applies to Robo Advisor.

Info

In case of broker integration by the client, the client can choose for an Omnibus or Segregated setup at the broker/custodian. However, InvestSuite will always act like there is a subaccount per end user at the broker/custodian. This implies that the client has to do the bookkeeping regarding the holdings of individual users itself in case of an Omnibus setup, and patch transactions/holdings to InvestSuite on portfolio level.

  1. The Client Middleware moves the cash at the broker from the bank's house account to the individual's subaccount.
  2. The Client Middleware calls POST /events/deposit/ (see here) once the Transaction is settled at the broker.
  3. InvestSuite creates an SETTLED Transaction in InvestSuite, referring to the transaction_id of the broker in the external_id field (see here).
  4. InvestSuite updates the portfolio's cash position (see here).
  5. In case of Robo Advisor, this will (asynchronously) trigger Optimizer.
  6. If the Portfolio was not yet marked as funded, the InvestSuite also sets funded_since field (see here).
  7. InvestSuite sends a notification to the Customer in case of a standalone app or sends a notification event to the Client Middleware in case of app-in-app.

CustomerCustomerInvestSuiteInvestSuiteClient MiddlewareClient MiddlewareBroker/CustodianBroker/CustodianCore Banking SystemCore Banking SystemCustomer funds his investor accountProcess cash allocation in (sub)ledgeralt[Omnibus account at broker/custodian]Move cash to omnibus accountFunding event(external_id)[Segregated account per portfolio at broker/custodian]Fund bank's house account at broker/custodianFunding event1. Move cashfrom bank's house account tocustomer's subaccountexternal_idTransaction SETTLED2. POST /events/deposit3. PATCH /portfolio/{id}/transactions/{id}/ with- status: SETTLED4. PATCH /portfolio Holdingsopt[if Robo Advisor]5. Trigger Optimizer (asynchronously)opt[if response.funded_since == null]6. PATCH /portfolio funded_sincealt[Standalone application]7. Push Notification[App-in-app]7. Notification event

Withdrawal

Robo Advisor

Broker integration by InvestSuite

Info

We assume there is an integration between the Broker/Custodian and the Core Banking System (eg. through end-of-day files), which is master of the counter_account and handles the corresponding cash transfers.

  1. A withdrawal is triggered:
    1. Either by the Customer, through the InvestSuite app. The app sets the divest_amount on the Portfolio object.
    2. Either by the Client Middleware, by setting the divest_amount on the Portfolio (see here).
  2. InvestSuite asynchronously runs Optimizer, resulting in an Optimization which, during the next rebalancing, will free up cash.
  3. In case of an advisory mandate the Customer confirms the Optimizaton. The confirmation is registered in the owner_choice field of the Optimization object.
  4. If there is sufficient cash in the Portfolio:
    1. InvestSuite moves the cash at the broker from the customer's subaccount to the bank's house account. InvestSuite will manage keeping the Transactions, Portfolio Holdings and the divest_amount up to date (asynchronously).
    2. The Core Banking System transfers the cash to the customer's counter_account.
    3. The Client Middleware notifies InvestSuite that the payment has occurred (see here).
    4. InvestSuite sends a notification to the Customer in case of a standalone app or sends a notification event to the Client Middleware in case of app-in-app.
  5. If not, the withdrawal will be handled by the Client Middleware at a later time (after the the rebalancing process or the process that handles executed or settled transactions from the broker has run. See the Example Middleware Design).

CustomerCustomerInvestSuiteInvestSuiteClient MiddlewareClient MiddlewareBroker/CustodianBroker/CustodianCore Banking SystemCore Banking Systemalt[InvestSuite App]1a. Request withdrawal[Middleware]1b. Request withdrawal2. Trigger Optimizer (asynchronously)opt[if Advisory mandate and insufficient cash]3. Confirm Optimization4. Get available cash in Portfolioalt[Sufficient Cash (divest_amount <= cash>)]5a. Move cash from customer's subaccount to bank's house accountopt[This depends on how the Bank and the Broker are integrated]Respond to cash movements5b. Execute cash transferto the Customer's counter accountCash transfer EXECUTED5c. POST /events/withdrawalt[Standalone application]5d. Push Notification[App-in-app]5d. Notification event[Insufficient Cash]6. The withdrawal will be handled at a later time,by the rebalancing process or the process thathandles executed or settled transactions from the broker.

Broker integration by the Client (Event driven)

  1. A withdrawal is triggered:
    1. Either by the Customer, through the InvestSuite app. The app sets the divest_amount on the Portfolio object.
    2. Either by the Client Middleware, by setting the divest_amount on the Portfolio (see here).
  2. InvestSuite asynchronously runs Optimizer, resulting in an Optimization which, during the next rebalancing, will free up cash.
  3. In case of an advisory mandate and insufficient cash, the Customer confirms the Optimization. The confirmation is registered in the owner_choice field of the Optimization object.
  4. The portfolio.withdrawal-request event is fired (see here).
  5. If there is sufficient cash in the Portfolio (get this from the Core Banking System or from the Portfolio object):
    1. The Client Middleware instructs the Core Banking System to execute the cash transfer.
    2. The Client Middleware creates a Transaction, type CASH, status SETTLED, and a negative quantity (see here).
    3. The Client Middleware sets the divest_amount to 0, indicating there is no more cash to divest (see here).
    4. The Client Middleware updates the Portfolio Holdings with decreased cash (see here).
    5. The Client Middleware informs InvestSuite that the withdrawal has executed by calling POST /events/withdraw/ (see here).
    6. InvestSuite sends a notification to the Customer in case of a standalone app or sends a notification event to the Client Middleware in case of app-in-app.
  6. If not, the withdrawal will be handled by the Client Middleware at a later time, by the rebalancing process or the process that handles executed or settled transactions from the broker. See the Example Middleware Design.

CustomerCustomerInvestSuiteInvestSuiteClient MiddlewareClient MiddlewareBroker/CustodianBroker/CustodianCore Banking SystemCore Banking Systemalt[InvestSuite App]1a. Request withdrawal[Middleware]1b. Request withdrawal2. Trigger Optimizer (asynchronously)opt[if Advisory mandate and insufficient cash]3. Confirm Optimization4. portfolio.withdrawal event(NOTE this actually happens in parallel with #2)Contains divest_amount5. Get available cash in Portfolioalt[Sufficient Cash (divest_amount <= cash>)]5a. Execute cash transfer5b. Create cash transactionPOST /portfolios/{id}/transaction with- Type CASH- Status SETTLED- Quantity <05c. Set the divest_amount to 0PATCH /portfolios with- divest_amount 05d. Update Portfolio holdingsPATCH /portfolios5e. POST /events/withdrawalt[Standalone application]5f. Push Notification[App-in-app]5f. Notification event[Insufficient Cash]6. The withdrawal will be handled at a later time,by the rebalancing process or the process thathandles executed or settled transactions from the broker.

Broker integration by the Client (Batch process)

  1. A withdrawal is triggered:
    1. Either by the Customer, through the InvestSuite app. The app sets the divest_amount on the Portfolio object.
    2. Either by the Client Middleware, by setting the divest_amount on the Portfolio (see here).
  2. InvestSuite asynchronously runs Optimizer, resulting in an Optimization which, during the next rebalancing, will free up cash.
  3. In case of an advisory mandate and insufficient cash, the Customer confirms the Optimization. The confirmation is registered in the owner_choice field of the Optimization object.
  4. In a batch process, the Client Middleware gets all portfolios with pending withdrawals (see here).
  5. If there is sufficient cash in the Portfolio (get this from the Core Banking System or from the Portfolio object):
    1. The Client Middleware instructs the Core Banking System to execute the cash transfer.
    2. The Client Middleware creates a Transaction, type CASH, status SETTLED, and a negative quantity (see here).
    3. The Client Middleware sets the divest_amount to 0, indicating there is no more cash to divest (see here).
    4. The Client Middleware updates the Portfolio Holdings with decreased cash (see here).
    5. The Client Middleware informs InvestSuite that the withdrawal has executed by calling POST /events/withdraw/ (see here).
    6. InvestSuite sends a notification to the Customer.
  6. If not, the withdrawal will be handled by the Client Middleware at a later time, during the next batch job run, by the rebalancing process or the process that handles executed or settled transactions from the broker. See the Example Middleware Design.

CustomerCustomerInvestSuiteInvestSuiteClient MiddlewareClient MiddlewareBroker/CustodianBroker/CustodianCore Banking SystemCore Banking Systemalt[InvestSuite App]1a. Request withdrawal[Middleware]1b. Request withdrawal2. Trigger Optimizer (asynchronously)opt[if Advisory mandate and insufficient cash]3. Confirm sellloop[Batch process (eg. nightly)]4. Get portfolios withpending withdrawalsGET /portfolios?query=...5. Get available cash in Portfolioalt[Sufficient Cash (divest_amount <= cash>)]5a. Execute cash transfer5b. Create cash transactionPOST /portfolios/{id}/transaction with- Type CASH- Status SETTLED- Quantity <05c. Set the divest_amount to 0PATCH /portfolios with- divest_amount 05d. Update Portfolio holdingsPATCH /portfolios5e. POST /events/withdraw5f. Notification[Insufficient Cash]6. The withdrawal will be handled at a later time,by the rebalancing process or the process thathandles executed or settled transactions from the broker.

Self Investor

Broker integration by InvestSuite

Info

We assume there is an integration between the Broker/Custodian and the Core Banking System (eg. through end-of-day files), which is master of the counter_account and handles the corresponding cash transfers.

  1. The Client issues a withdrawal in the app.
  2. InvestSuite moves the cash at the broker from the customer's subaccount to the bank's house account. InvestSuite will manage keeping the Transactions and Portfolio Holdings up to date (asynchronously). When this process completes, InvestSuite sends a notification to the Customer.
  3. The Core Banking System transfers the cash to the customer's counter_account.