Development Guides

Focused Rebalance (Sleeved Portfolios)

A focused rebalance generates trades for only part of a sleeved portfolio. Holdings outside the focus are left as they are.

This is the same URL as a standard sleeve rebalance. The run is treated as focused when you send rebalanceType: “Focused Rebalance” and tradeInstanceSubType: 4 and exactly one focus identifier.

Do not mix this recipe with the standard sleeve recipe (tradeInstanceSubType: 14) — subtype 14 runs a full-portfolio sleeve rebalance, not a focused one.


MethodPOST
URLhttps://www.orioneclipse.com/v1/tradetool/rebalancer/action/generatetrade

Headers

HeaderValue
AuthorizationSession <access_token>
Content-Typeapplication/json

To kick off a focused sleeve rebalance, you need three things:

  1. A valid session token
  2. The portfolioId of the parent sleeved portfolio
  3. A POST request with the body below, using the focus identifier that matches what you want to rebalance

Choose one focus identifier

Send exactly one of these — never more than one per call.

If you want to rebalance…SendTypeScope
Every sleeve that shares a sleeve strategysleeveStrategyIdsstring array, e.g. [“11”]Those sleeves only. Others are skipped.
Every sleeve that uses a sleeve modelsleeveModelIdsinteger array, e.g. [1414]Those sleeves only. Others are skipped.
Specific nodes inside one sleeve’s modelmodelTypeIdsinteger array, e.g. [16905]Those nodes in that one sleeve. All other holdings in the sleeve, and all other sleeves, are left alone.

JSON typing matters. sleeveStrategyIds values must be strings. sleeveModelIds and modelTypeIds values must be integers. Sending the wrong type may silently fail to resolve the focus.

Quick Start template

Copy this template exactly, replace portfolioIds and the focus identifier, and send it. The fields you may want to customize are covered in §3.2 — all others should be sent as shown.

For a sleeve model, replace “sleeveStrategyIds”: [“11”] with “sleeveModelIds”: [1414]. For a security-set run, replace it with “modelTypeIds”: [16905].


3.1 Required identifiers & metadata

FieldTypeValueNotes
portfolioIdsint[]e.g. [3555]Parent sleeved portfolio. One-element array for a single portfolio.
One of sleeveStrategyIds / sleeveModelIds / modelTypeIdssee §2see §2Exactly one. Never send two focus identifiers on one call.
tradeInstanceTypeint6Portfolio rebalance.
tradeInstanceSubTypeint4Focused rebalance. 14 is a full sleeve rebalance — a different operation.
tradeToolSelectionint10From the rebalance tool.
rebalanceTypestring“Focused Rebalance”Triggers the focused flow.

You do not send tradeInstanceId. The backend creates the trade instance and returns its id in the response.

Extra rule for modelTypeIds: all values must belong to the same sleeve model and the same level of that model tree. The sleeve is inferred from the nodes.

3.2 Fields you may want to customize

FieldTypeRecommendedNotes
useDefaultPreferencebooltrueUse the firm’s saved rebalance preferences. Strongly recommended. When true, allowWashSale, allowShortTermGain, and maxGainAmount are ignored and the firm’s saved values are used instead.
isViewOnlybool | nulltrue for the first calltrue = preview only (will not flow to execution). null or false = committable trades.
reasonstring | nullnullOptional free-text reason logged on the trade instance.
minimumTradeAmount{ type, amount }{ “type”: “$”, “amount”: null }Minimum trade amount. amount: null uses the firm’s default. If type: “%”, amount must be ≤ 100.
maxGainAmountdecimal | nullnullCap on the total realized gain produced by this run. null = no override (uses firm default). Only honored when useDefaultPreference: false.
allowWashSalebool | nullnullOverride the firm’s wash-sale rule. null = use the firm’s saved value. Only honored when useDefaultPreference: false.
allowShortTermGainstring | nullnullOverride the firm’s short-term-gain rule. null = use the firm’s saved value. Accepted values: “Allow”, “Full Position Disallow”, “TaxLot Disallow”. Only honored when useDefaultPreference: false.

All other fields in the Quick Start template should be sent exactly as shown.


A successful call returns 200 OK.

4.1 Sample response

An empty trades: [] array is success, not failure. It means either the focused sleeves/nodes were already in tolerance, or (on a security-set run) the targeted sleeve is not eligible for this operation. See §4.4.

4.2 Top-level fields

FieldTypeDescription
tradeInstanceIdlongServer-generated id for this run. Save it — it’s how you’ll find or reconcile the trades downstream.
instanceIdlongSame value as tradeInstanceId. Both are returned for backward compatibility.
isViewOnlyboolEchoes the resolved value. Confirms whether trades were saved as preview or committable.
shouldUseV2PostTradeProcessbooltrue when the run used the current post-trade pipeline.
tradesTrade[]Every trade saved against this instance. May include JOURNAL IN / JOURNAL OUT rows on strategy/model runs — see §4.3 and §4.4.

4.3 Trade object fields (response only)

Each entry in the trades[] array is generated by the rebalancer — none of these fields are set by the caller. The list below covers the fields most external consumers use.

Identity

FieldTypeDescription
tradeIdintUnique id of this trade row.
tradeInstanceIdlongParent trade instance id.
portfolioIdintPortfolio this trade belongs to.
accountIdintAccount (sleeve) this trade belongs to.
securityIdintInternal security id.
symbolstringSecurity symbol (e.g. IBM). “CUSTODIAL_CASH” for journal rows.
securityNamestringHuman-readable security name.
securityTypestringEquity, Mutual Fund, Bond, Other.

Action

FieldTypeDescription
actionstringBUY, SELL, JOURNAL IN, or JOURNAL OUT. Journals appear only on strategy/model runs.
approvalStatusstringCurrent approval state (e.g. Approved).
rebalanceLevelstring“Sleeved Portfolio” for strategy/model runs. “Sleeve” for security-set runs.
rebalanceLevelIdint3 for strategy/model runs. 4 for security-set runs. Key off this if you need to detect the focus type from the response.
isCustodialCashint (0/1)1 on journal rows, 0 otherwise.
tradeCreatedDateISO datetimeWhen the trade was created.

Quantity & price

FieldTypeDescription
tradeSharesdecimalShares traded (rounded to final precision).
pricedecimalPer-share price used. 1 for journal rows.
tradeAmountdecimalTotal dollar value (tradeShares × price).
priceDateISO datetimeAs-of date of the price.

Cost basis & gain/loss (sells only)

FieldTypeDescription
costAmountdecimalTotal cost basis.
costPerSharedecimalPer-share cost basis.
tradeGainLossdecimalTotal realized gain or loss.
tradeSTGainLoss / tradeLTGainLossdecimalShort-term / long-term split.

Custodian & fees

FieldTypeDescription
custodianIdintInternal custodian id.
custodianstringCustodian display name.
transactionFeedecimalTransaction fee on this trade.
redemptionFeedecimalRedemption fee on this trade.

Account & tax context

FieldTypeDescription
taxableTypestringTAXABLE, TAXDEF, TAXEXMPT.
billingAccountint (0/1)1 if this is a billing account.

4.4 How to tell which focus produced the trades

Strategy / model runSecurity-set run
rebalanceLevel“Sleeved Portfolio”“Sleeve”
rebalanceLevelId34
accountId across rowsMay differ (multiple focused sleeves)Same sleeve on every row
JOURNAL IN / JOURNAL OUT rowsPossible when cash moves between focused sleevesNever

A journal row is identifiable by action of JOURNAL IN or JOURNAL OUT, isCustodialCash: 1, symbol: “CUSTODIAL_CASH”, and price: 1.


5.1 Error body

The message field (prefixed with [REBAL] : ) is the canonical signal for what went wrong. Surface it in your logs — don’t rely on the HTTP status alone.

5.2 Status codes

CodeMeaning
200 OKRun completed. Includes trades: [] (focused sleeves/nodes were in tolerance, or a security-set sleeve is ineligible — see §6).
400 Bad RequestRequest validation failed (missing portfolioIds, missing focus identifier, or missing required trade-instance metadata).
401 / 403Missing, invalid, or unauthorized token.
500 Internal Server ErrorPortfolio, sleeve, model, or preference check failed. Read the [REBAL] : message.

5.3 Common failure messages

  • [REBAL] : Invalid Portfolio/Account type sent in request parameters. — the portfolio is not sleeved. Use the non-sleeved focused rebalance guide instead.
  • [REBAL] : Total of Sleeve Targets of Sleeve Type-‘NORMAL’ must be equal to 100%. — strategy/model runs validate the whole portfolio, even outside the focus.
  • [REBAL] : Invalid Model Detail Id — a modelTypeIds value doesn’t belong to that sleeve’s model.
  • [REBAL] : Model Detail Ids are not at same level . — mixed levels in modelTypeIds.
  • [REBAL] : The selected portfolio/sleeve has a substitute on the model. Please select the substituted model for tactical rebalance. — substitute models are not supported.
  • [REBAL] : Invalid Account Id. — the resolved sleeve is not valid for this portfolio.
  • [REBAL] : Portfolio analytics are still running. — wait for post-import analysis to complete and retry.

  • Send the focused recipe completely. rebalanceType: “Focused Rebalance” + tradeInstanceSubType: 4 + exactly one focus id array. Subtype 14 is a full sleeve rebalance, not this flow.
  • Strategy ids are strings; model and security-set ids are integers. Sending the wrong JSON type may silently fail to resolve the focus.
  • Never send two focus identifiers on one call.
  • Empty trades: [] is success. On a security-set run, also confirm the targeted sleeve is NORMAL and not SMA- or Astro-enabled — an ineligible sleeve returns 200 with an empty array, not an error.
  • Save tradeInstanceId from the response. It’s how you’ll look up or reconcile the generated trades. You cannot supply it in the request — the backend always creates a new one.
  • This endpoint does not execute trades. It only generates and saves them. Execution to a custodian or broker is a separate downstream system.
  • You own idempotency, concurrency, and rate limiting. Every call creates a new trade instance and a new set of trades — the endpoint does not de-duplicate retries or block concurrent runs against the same portfolio.