Purpose: To instantiate a rebalance trade, which will create a rebalance instances with the proposed trades, ready for review and execution. This will cover these rebalance trade types.
- Normal Rebalance (NeedReview) – Most typical, used to reallocate the account back to tolerance with the model targets.
- Withdraw Rebalance (Withdraw) – Used to raise cash for fees, or customer withdraw requests. Sells most overweight positions first to raise the cash.
- Contribution Rebalance (Add) – Used to spend cash buying the most underweight positions first.
Simple Use Case: Firm has their own trade request portal, allowing reps or other down stream users to submit a rebalance request. The Firm can then take those requests, and translate them to actual trades in the Orion TOM application.
Scope and Outputs: This is specific to Rebalance Trades at the account level. This can also be used to trade groups of accounts, such as by Model(s), Fund Family/Custodian(s), Trade Groups(s). While the call is almost identical, this article will focus on account level, as that includes buys/sell rebalances, and the others do not.
Process Overview (3) steps:
- Optional: Get a TradeDefinition Object. This first step is to populate JSON filled in with default values. This allows the developer to start with a default object based on firm settings, then make changes specific to this rebalance instance. You can always create the rebalance body from scratch, but using this endpoint will ensure the default settings for your firm are populated.
- GenerateTrades – Call to initiate the rebalance for the specified account(s).
- Optional: Poll a status endpoint to view the status of the rebalance instance until it completes. This is optional, as a ?wait=true parameter can be used instead to make the GenerateTrades endpoint syncronous, where it will wait to respond until the instance is ready.
Process Steps
1. Optional: Get default trade definition object
This sets defaults setup in your firm for the parameters available to the rebalancer. Such as AssetValues – use pendings or not, or min trade amounts. If you will not care to use the defaults, you can skip step 1, and go straight to step 2.
GET /Trading/TradeDefinition?routine=rebalance
The response body is the default JSON you would start with for Step 2, Generate Trades.
2. Generate Trades.
The /GenerateTrades endpoint is used to generate trades. The Body Payload is described below.
Query String Parameter
Parameter | Description |
wait | Optional Query String Argument: if “wait=true” is passed as a query string parameter, the endpoint will not return a response until the rebalance completes. This is good for rebalances with 100 or less accounts. For more accounts, you may want to let the routine run on the backend and use the status endpoint to find when it completes. example: /v1/trading/generatetrades?wait=true |
Property | Description |
reason | Indicates the “type” of rebalance. * “NeedReview” – normal rebalance to bring account back to tolerance with model targets. * “Withdraw” – Raises the Amount Specified in Cash by selling overweight positions. * “Add” – Contribution, Spends the Amount Specified, buying underweight positions first. * “Withdraw100Pct” – Complete liquidation of the account, Sell all positions to 0. |
maxTrades | 1000 is most common. This is rarely used, but it will cause the rebalancer to generate trades until it reaches the max number of trades. All additional trades will be dissallowed. this value is per account, not for the entire rebalance. |
minTradePercent | 0 is most common, If this value is greater than 0, then trades where the % of the position sold is less than this value will be disallowed. |
exactTrades | false is most common. If true, then the rebalancer will try to trade the account back to the exact model targets, tolerances will not be considered. |
level | “Account” is most common. This value is used for Sleeve Trading. “Account” – Rebalance the account only. “Registration” – For Sleeve Trading, this will rebalance all the sleeves in the Registration, and get the sleeve account values back to tolerance. |
amounts | Default is empty or null. This is an array of dollar values. It is only used if the reason is “Withdraw” or “Contribution”. It will be ignored for all other rebalance reasons. This is an array of $ values to be used in the contribution or withdraw rebalances. The array positions should line up with the keys array. example: reason: “Withdraw” amounts: [100, 200, 500] keys: [1, 2, 3] In the above example, AccountID 1 will raise $100 cash, account 2 will raise $200 cash, and account 3 will raise $500 in cash. Note: For “Add” rebalances, Existing cash will be used. If the Amount is greater than the existing cash, then the accounts cash value will be increased to the Amount specified for the purpose of trade calculation. |
entity | This indicates the entity that is rebalanced. When this is set to “Account” then the keys:[] array should be account ids. If it is set to “TradeGroup”, then the keys:[] array should be trade group id’s. Use Only “Account” if doing a Add or Withdraw rebalance reason. |
keys | Array of integers indicating the keys of the entity to be rebalances. example: entity: “Account” keys: [1,2,3] this will rebalance accountId 1, accountId 2, and accountId 3. example2: entity: “ModelAgg” keys: [1,2,3] this will rebalance all accounts assigned to ModelAggs 1,2 and 3. |
routine | “Rebalance” – Indicates the trade tool used to generate the trades. For rebalances, this will always be “Rebalance” |
assetValues | Most common is “PendingTransactionsAndOrders” This indicates pending values that should be considered or not when calculating trades. PendingTransactionsAndOrders – Include Pending Transactions, and Open Orders in asset values. “Pending” – Include Pending Transactions, but not open orders in asset values. “Current” – Do not include any pending transactions or open orders. Asset values are only the completed transactions. “UseDefault” – Use the above setting designated as the default for your firm. |
minTradeAmount | Default is 0. If value is greater than 0, then any trades that are less then the minimum entered here will be disallowed. |
useProductSubstitution | Most common “Use” “Use” – the rebalancer will use any product substitution and equivalence you have configured in the accounts and models. “Ignore” – will not consider product substitution or equivalence in the rebalance. |
includeCustodialCash | Most Common “true” When true, custodial cash is concidered part of the account when calculating trades. If false, then the custodial cash in the account is ignored completely. |
notes | Optional. If included, these notes will be on the trade instance created, and visible from TOM. |
roundingLogic | Most Common “Default” Used when buying/selling equities as whole shares. In order to get to the full requested amount of the rebalance withdraw, partial equity shares will need to be rounded up or down, this allows to switch from the default behavior, to use lowest price first. “Default” – system decides what should be rounded up. “LowestPrice” – round up the lowest price equity first. “None” – Will generate partial quantity trades for equities, really should not be used. |
disableRealTimePrices | Most Common “false” When false, real time prices will be used as long as you have them enabled in your firm. When true, then real time prices will not be used, even if they are enabled for your firm. |
Sample Body
{
"reason": "Withdraw",
"minTradePercent": 0,
"maxTrades": 1000,
"exactTrades": false,
"level": "Account",
"amounts": [10000, 15000],
"roundingLogic": "Default",
"entity": "Account",
"keys": [
5412,5413
],
"routine": "Rebalance",
"nsccTransactionType": "NormalPurchase",
"assetValues": "PendingTransactionsAndOrders",
"minTradeAmount": 0,
"useProductSubstitution": "Use",
"includeCustodialCash": true,
"notes": null,
"disableRealTimePrices": false,
}
Response | Description |
Integer | If successful, the endpoint returns a 200ok and in the body is an integer holding the batch processing id. example: 25545247 The batch processingid can be used to fetch the status and error messages (if there are any) using the GET endpoints below. /Trading/TradeGenerationStatus/25545247 and/or /Trading/TradeGenerationStatus/25545245/Message |
3. Optional: Fetch Result Status
Using the response in step 2 as the batchProcessingId, use the TradeGenerationStatus to fetch the result of the rebalance.
If the ?wait=true parameter was used, then you the Instance will be completed when the the /GenerateTrades endpoint returns.
If the wait=true was not used, or false was specified, then you would need to poll this endpoint waiting for the status to be “complete” or “failed”.
Note, there are 2 endpoints here, the reason is if polling, the first endpoint is light weight/faster. It does not return details of error messages when there is an error. The second endpoint /Message will return the status along with any error messages associated with a failed rebalance.
Get the status only (no error messages), used for polling when ?wait=false is used.
GET /Trading/TradeGenerationStatus/{batchProcessingId}
Sample Failed Response:
{
"id": 25545247,
"alClientName": "Sales_Main (test)",
"status": "Failed",
"message": "Errors occurred.",
"createdBy": "benb@orion.com",
"createdDate": "2022-05-17T08:20:11.013-05:00",
"parentId": 424,
"isDone": true,
"totalItems": 1,
"itemsCompleted": 0,
"errorCount": 2,
"warningCount": 0,
"details": null
}
Sample Success Response:
{
"id": 25545245,
"alClientName": "OrionService (test)",
"status": "Complete",
"message": "",
"createdBy": "Dustin.Garrett",
"createdDate": "2022-05-17T07:51:34.557-05:00",
"parentId": null,
"isDone": true,
"totalItems": 1,
"itemsCompleted": 1,
"errorCount": 0,
"warningCount": 0,
"details": null
}
The /Message endpoint will return a severity, and the error message in the case of there was a failed rebalance.
GET /Trading/TradeGenerationStatus/{batchProcessingId}/Message
Sample Failed Response:
{
"entityId": 424,
"entityEnum": "TradeInstance",
"severity": "Failed",
"severityCode": 2,
"receivedDate": "2022-05-17T08:20:11.013-05:00",
"subject": "424: Rebalance account - (1027912)",
"message": "Errors occurred.",
"details": [
{
"severityCode": 0,
"severity": "Error",
"message": "Account: 1027912 - Account ID 1027912 does not exist (Instance ID 424). Check share class assignment, if account exists.",
"entityEnum": null,
"entityId": null
}
]
}
Sample Success Response:
{
"entityId": null,
"entityEnum": "TradeInstance",
"severity": "Complete",
"severityCode": 4,
"receivedDate": "2022-05-17T07:51:34.557-05:00",
"subject": ": ",
"message": "",
"details": []
}
Large Volume Speed Considerations
If speed is a requirement, and there is a need to rebalance a high volume of accounts, it is much more efficient to do a single rebalance request with a large number of accounts in the “keys” array. Doing multiple rebalances with 1 account will incur overhead on every request. The rebalancer is built for large batches, so the more that can be done in a single batch, the better.
For example, if you are doing an add rebalance to 5 accounts, make a single call to /GenerateTrades with keys:[1,2,3,4,5] and amounts:[100,200,300,400,500] populated for all 5 accounts. You should not make 5 individual calls as this will result in a much slower process.