Skip to main content
Glama

NexusTrade Financial MCP

update_portfolio

Deploy, undeploy, rename, delete, add/remove/replace strategies, or set deployment frequency on portfolios. rename requires a non-empty name on the operation. delete permanently removes a chat, paper, or live portfolio (archives deployed paper/live books; deleting a chat portfolio also archives linked deployments). Pass confirmLive:true only after explicit user confirmation when deleting an active live portfolio. Structured path (zero LLM cost): pass an operations array — see inputSchema. Use replaceStrategy / replaceStrategies with full {name, condition, action, orderExecution?} strategyObjects (same shape as create_portfolio). orderExecution defaults to Market; true waiting Limits use UnitPrice for shares/crypto or MinimumNetCredit/MaximumNetDebit for options, whose amount may be an indicator (such as OptionSpreadEntryPrice plus a Value) evaluated when the strategy fires. QuoteRelative normally executes immediately at the snapshotted quote. RebalanceOption: set action.positionScope to portfolio (single-book — closes/orphans all option spreads in the portfolio) or strategy (multi-strategy book).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
operationsYesArray of edit operations. Each operation needs "portfolioId" (live, paper, or chat — server resolves automatically). Supported types include "rename" (requires non-empty "name"), "delete" (permanently remove a chat/paper/live portfolio; archives deployed books; pass confirmLive:true only after explicit user confirmation when deleting an active live portfolio). DEPLOY SAFETY: deploying a chat portfolio ID creates a NEW PAPER-TRADING portfolio (simulated money, no broker order ever placed). It cannot place real-money trades. A LIVE/real-brokerage deployment only happens when the target is an EXISTING real-brokerage portfolio (re-activating it, or addStrategies/replaceStrategies on a portfolio already connected to a live broker). You cannot create a live brokerage account from a chat portfolio through this tool. Fetch the portfolio first and use strategy IDs from the returned "strategies" array for removals. To add/replace strategies, pass FINISHED strategy objects ({name, condition, action, orderExecution?} — same shape as create_portfolio.strategies) via "strategyObjects" (or "strategyObject" for replaceStrategy). These are ingested deterministically with zero LLM cost; prefer them. Optional strategy-level `orderExecution` defaults to `{type:"Market"}`. For a true waiting Limit, use `{type:"Limit",price:{type:"UnitPrice",amount:...},workingTime:{type:"Day"|"Minutes",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:"Plus",indicators:[{type:"OptionSpreadEntryPrice",underlying:"SPX",optionType:"call",direction:"long",spreadType:"vertical"},{type:"Value",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. RebalanceOption `action.positionScope`: `"portfolio"` (default for single-book portfolios — rotation-close and open-skip span all option spreads in the portfolio) or `"strategy"` (only spreads this strategy opened; use when multiple RebalanceOption strategies share one portfolio). Set on `create_portfolio` strategies[].action or on `update_portfolio` replaceStrategy/replaceStrategies `strategyObject.action`. Examples: [{"type":"deploy","portfolioId":"id"}, {"type":"undeploy","portfolioId":"id"}, {"type":"delete","portfolioId":"id"}, {"type":"addStrategies","portfolioId":"id","strategyObjects":[{"name":"...","condition":{...},"action":{...},"orderExecution":{"type":"Limit","price":{"type":"UnitPrice","amount":150},"workingTime":{"type":"Day"}}}]}, {"type":"removeStrategies","portfolioId":"id","strategyIds":["strategyId"]}, {"type":"replaceStrategy","portfolioId":"id","targetStrategyId":"strategyId","strategyObject":{"name":"...","condition":{...},"action":{"type":"RebalanceOption","positionScope":"portfolio",...}}}, {"type":"replaceStrategies","portfolioId":"id","strategyObjects":[{"name":"...","condition":{...},"action":{...}}]}, {"type":"setDeploymentFrequency","portfolioId":"id","deploymentFrequency":"Constant"}, {"type":"rename","portfolioId":"id","name":"New Portfolio Name"}]

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed6 schema fields changed
    • changedInput schema / $defs / indicator / description
      Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), MovingAverageConvergenceDivergence (MACD; needs targetAsset; optional fastLength/slowLength/signalLength defaulting to 12/26/9 with slowLength > fastLength, interval Day|Hour|Minute default Day, and line macd|signal|histogram selecting which of the three MACD outputs to emit), AverageDirectionalIndex (Wilder ADX trend-strength system 0-100; needs targetAsset+window; optional line adx|plusDi|minusDi — ADX measures strength, +DI/-DI direction), RelativeVolume (RVOL; needs targetAsset+window; current bar volume divided by the mean volume of the trailing N completed bars, ~1.0 is its recent pace), Stochastic (needs targetAsset+window; optional smoothK/smoothD defaulting to 3/3 and line k|d), CommodityChannelIndex (CCI; needs targetAsset+window; optional constant defaulting to 0.015), WilliamsR (needs targetAsset+window; −100 to 0 scale), MoneyFlowIndex (MFI; needs targetAsset+window; volume-weighted 0-100), OnBalanceVolume (OBV; needs targetAsset; optional interval default Day), AccumulationDistribution (ADL; needs targetAsset; optional interval default Day), ChaikinMoneyFlow (CMF; needs targetAsset+window; −1 to +1 scale), DonchianChannel (needs targetAsset+window; optional line upper|lower|middle default upper), KeltnerChannel (needs targetAsset+window; optional multiplier default 2 and line upper|middle|lower default middle), Supertrend (needs targetAsset+window; optional multiplier default 3 and line value|direction default value, direction reads +1 up / −1 down), IchimokuCloud (needs targetAsset+window; optional spanLength default 52 and line tenkan|kijun|senkouA|senkouB|chikou default tenkan; lines unshifted), ParabolicSar (needs targetAsset; optional interval default Day, step default 0.02, maximum default 0.2), TrueRange/AverageTrueRange (need targetAsset; ATR also window), VWAP (needs targetAsset; resets each trading day), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), Correlation (rolling Pearson of two sub-indicators' returns; needs 2 sub-indicators + window with length >= 2), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; InstitutionalHoldings (SEC Form 13F positions) needs targetAsset, metric, windowDays and optional manager, reads the latest quarter public on or before the evaluation date, never sums across quarters, and measures accumulation and crowding rather than entry timing since a 13F is long-only and up to 45 days stale; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), MovingAverageConvergenceDivergence (MACD; needs targetAsset; optional fastLength/slowLength/signalLength defaulting to 12/26/9 with slowLength > fastLength, interval Day|Hour|Minute default Day, and line macd|signal|histogram selecting which of the three MACD outputs to emit), AverageDirectionalIndex (Wilder ADX trend-strength system 0-100; needs targetAsset+window; optional line adx|plusDi|minusDi — ADX measures strength, +DI/-DI direction), RelativeVolume (RVOL; needs targetAsset+window; current bar volume divided by the mean volume of the trailing N completed bars, ~1.0 is its recent pace), Stochastic (needs targetAsset+window; optional smoothK/smoothD defaulting to 3/3 and line k|d), CommodityChannelIndex (CCI; needs targetAsset+window; optional constant defaulting to 0.015), WilliamsR (needs targetAsset+window; −100 to 0 scale), MoneyFlowIndex (MFI; needs targetAsset+window; volume-weighted 0-100), OnBalanceVolume (OBV; needs targetAsset; optional interval default Day), AccumulationDistribution (ADL; needs targetAsset; optional interval default Day), ChaikinMoneyFlow (CMF; needs targetAsset+window; −1 to +1 scale), DonchianChannel (needs targetAsset+window; optional line upper|lower|middle default upper), KeltnerChannel (needs targetAsset+window; optional multiplier default 2 and line upper|middle|lower default middle), Supertrend (needs targetAsset+window; optional multiplier default 3 and line value|direction default value, direction reads +1 up / −1 down), IchimokuCloud (needs targetAsset+window; optional spanLength default 52 and line tenkan|kijun|senkouA|senkouB|chikou default tenkan; lines unshifted), ParabolicSar (needs targetAsset; optional interval default Day, step default 0.02, maximum default 0.2), TrueRange/AverageTrueRange (need targetAsset; ATR also window), VWAP (needs targetAsset; resets each trading day), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), Correlation (rolling Pearson of two sub-indicators' returns; needs 2 sub-indicators + window with length >= 2), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
    • addedInput schema / $defs / indicator / properties / manager
      Added value: +{
      +  "description": "InstitutionalHoldings filing manager: a CIK such as 1067983 matches exactly, any other text matches a filed name containing it, and empty reads every manager. Prefer the CIK — one CIK files under as many as six spellings of its own name, and a name like 'berkshire' spans Buffett's firm, two of its insurance subsidiaries and an unrelated asset manager.",
      +  "type": "string"
      +}
    • addedInput schema / $defs / indicator / properties / memberId
      Added value: +{
      +  "description": "PoliticalTrades member bioguide id (e.g. P000197). Matches exactly and overrides filer; prefer it when known, because names collide.",
      +  "type": "string"
      +}
    • changedInput schema / $defs / indicator / properties / metric / description
      Previous value: -"PoliticalTrades: NetAmount, BuyAmount, SellAmount, BuyCount, SellCount, DistinctBuyers. Fundamental/CompoundAnnualGrowthRate: financial metric (e.g. 'peRatio'). Economic: economic indicator (e.g. 'UNRATE'). Index: index symbol (e.g. 'VIX', 'SPX'). RebalanceDecisionMetric: allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit."New value: +"PoliticalTrades: NetAmount, BuyAmount, SellAmount, BuyCount, SellCount, DistinctBuyers, Held. InstitutionalHoldings: HolderCount, TotalShares, TotalValue, ConcentrationTop5, NetShareChange, NetHolderChange, NewHolders, ClosedHolders. Fundamental/CompoundAnnualGrowthRate: financial metric (e.g. 'peRatio'). Economic: economic indicator (e.g. 'UNRATE'). Index: index symbol (e.g. 'VIX', 'SPX'). RebalanceDecisionMetric: allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit."
    • changedInput schema / $defs / indicator / properties / type / enum
      Previous value: -[
      -  "DaysSinceAgent",
      -  "MinutesSinceAgent",
      -  "DaysSinceAlert",
      -  "MinutesSinceAlert",
      -  "StockReport",
      -  "DaysUntilEarnings",
      -  "DaysSinceEarnings",
      -  "ImpliedVolatility",
      -  "IVRank",
      -  "IVPercentile",
      -  "IVHVRatio",
      -  "LastOrderPrice",
      -  "Fundamental",
      -  "Economic",
      -  "CustomIndicator",
      -  "Index",
      -  "BollingerBand",
      -  "RelativeStrengthIndex",
      -  "MovingAverageConvergenceDivergence",
      -  "AverageDirectionalIndex",
      -  "RelativeVolume",
      -  "Stochastic",
      -  "CommodityChannelIndex",
      -  "WilliamsR",
      -  "MoneyFlowIndex",
      -  "OnBalanceVolume",
      -  "AccumulationDistribution",
      -  "ChaikinMoneyFlow",
      -  "DonchianChannel",
      -  "KeltnerChannel",
      -  "Supertrend",
      -  "IchimokuCloud",
      -  "ParabolicSar",
      -  "PriceMeanAbsoluteDeviation",
      -  "ExponentialMovingAverage",
      -  "SimpleMovingAverage",
      -  "PriceStandardDeviation",
      -  "PriceRateOfChange",
      -  "MaxDrawdown",
      -  "MaxDrawup",
      -  "MinimumPrice",
      -  "MaximumPrice",
      -  "IndicatorMeanAbsoluteDeviation",
      -  "IndicatorExponentialMovingAverage",
      -  "IndicatorSimpleMovingAverage",
      -  "IndicatorStandardDeviation",
      -  "IndicatorRateOfChange",
      -  "DaysSinceOrder",
      -  "DaysSinceOptionOrder",
      -  "DaysSinceStrategyFired",
      -  "DaysSinceLastRebalanceOptionOrder",
      -  "MinutesSinceOptionOrder",
      -  "MinutesSinceOrder",
      -  "DaysSinceTransaction",
      -  "InitialValue",
      -  "BuyingPower",
      -  "PositionValue",
      -  "PositionPercentChange",
      -  "PortfolioValue",
      -  "RebalanceDecisionMetric",
      -  "Value",
      -  "Price",
      -  "Plus",
      -  "Minus",
      -  "Multiply",
      -  "Divide",
      -  "Negative",
      -  "AbsoluteValue",
      -  "SquareRoot",
      -  "Max",
      -  "Min",
      -  "Day",
      -  "Month",
      -  "Date",
      -  "Year",
      -  "CurrentTimeSeconds",
      -  "CurrentTimeMinutes",
      -  "CurrentTimeHours",
      -  "TrailingSum",
      -  "CompoundAnnualGrowthRate",
      -  "Log",
      -  "Exponentiation",
      -  "SumOrderQuantity",
      -  "SumOrderAmount",
      -  "MinutesAfterOpen",
      -  "OpeningPrice",
      -  "PreviousClosingPrice",
      -  "HighOfDay",
      -  "LowOfDay",
      -  "MinutesUntilClose",
      -  "PriceChangeSinceOpen",
      -  "GapSize",
      -  "GapPercentage",
      -  "TrueRange",
      -  "AverageTrueRange",
      -  "Volume",
      -  "VWAP",
      -  "BullishFairValueGap",
      -  "BearishFairValueGap",
      -  "IndicatorAtMinutesAfterOpen",
      -  "IndicatorWindowAgo",
      -  "IndicatorAtEntry",
      -  "IsIndexMember",
      -  "PoliticalTrades",
      -  "InsiderTrades",
      -  "IsIndustry",
      -  "IsAssetType",
      -  "IsAsset",
      -  "IsNotAsset",
      -  "CrossAbove",
      -  "CrossBelow",
      -  "Correlation",
      -  "PositionMaxDrawdown",
      -  "PositionMaxDrawup",
      -  "UnderlyingMaxDrawdown",
      -  "ConsecutiveTrue",
      -  "CountTrue",
      -  "OptionPositionValue",
      -  "OptionPositionCount",
      -  "OptionPositionPercentChange",
      -  "OptionPositionMaxDrawdown",
      -  "OptionDaysToExpiration",
      -  "OptionDaysHeld",
      -  "OptionCollateral",
      -  "OptionSpreadCount",
      -  "OptionSpreadEntryPrice",
      -  "OptionUnrealizedPnL",
      -  "OptionRealizedPnL",
      -  "OptionRealizedPremium",
      -  "OptionGrossExposurePercent"
      -]New value: +[
      +  "DaysSinceAgent",
      +  "MinutesSinceAgent",
      +  "DaysSinceAlert",
      +  "MinutesSinceAlert",
      +  "StockReport",
      +  "DaysUntilEarnings",
      +  "DaysSinceEarnings",
      +  "ImpliedVolatility",
      +  "IVRank",
      +  "IVPercentile",
      +  "IVHVRatio",
      +  "LastOrderPrice",
      +  "Fundamental",
      +  "Economic",
      +  "CustomIndicator",
      +  "Index",
      +  "BollingerBand",
      +  "RelativeStrengthIndex",
      +  "MovingAverageConvergenceDivergence",
      +  "AverageDirectionalIndex",
      +  "RelativeVolume",
      +  "Stochastic",
      +  "CommodityChannelIndex",
      +  "WilliamsR",
      +  "MoneyFlowIndex",
      +  "OnBalanceVolume",
      +  "AccumulationDistribution",
      +  "ChaikinMoneyFlow",
      +  "DonchianChannel",
      +  "KeltnerChannel",
      +  "Supertrend",
      +  "IchimokuCloud",
      +  "ParabolicSar",
      +  "PriceMeanAbsoluteDeviation",
      +  "ExponentialMovingAverage",
      +  "SimpleMovingAverage",
      +  "PriceStandardDeviation",
      +  "PriceRateOfChange",
      +  "MaxDrawdown",
      +  "MaxDrawup",
      +  "MinimumPrice",
      +  "MaximumPrice",
      +  "IndicatorMeanAbsoluteDeviation",
      +  "IndicatorExponentialMovingAverage",
      +  "IndicatorSimpleMovingAverage",
      +  "IndicatorStandardDeviation",
      +  "IndicatorRateOfChange",
      +  "DaysSinceOrder",
      +  "DaysSinceOptionOrder",
      +  "DaysSinceStrategyFired",
      +  "DaysSinceLastRebalanceOptionOrder",
      +  "MinutesSinceOptionOrder",
      +  "MinutesSinceOrder",
      +  "DaysSinceTransaction",
      +  "InitialValue",
      +  "BuyingPower",
      +  "PositionValue",
      +  "PositionPercentChange",
      +  "PortfolioValue",
      +  "RebalanceDecisionMetric",
      +  "Value",
      +  "Price",
      +  "Plus",
      +  "Minus",
      +  "Multiply",
      +  "Divide",
      +  "Negative",
      +  "AbsoluteValue",
      +  "SquareRoot",
      +  "Max",
      +  "Min",
      +  "Day",
      +  "Month",
      +  "Date",
      +  "Year",
      +  "CurrentTimeSeconds",
      +  "CurrentTimeMinutes",
      +  "CurrentTimeHours",
      +  "TrailingSum",
      +  "CompoundAnnualGrowthRate",
      +  "Log",
      +  "Exponentiation",
      +  "SumOrderQuantity",
      +  "SumOrderAmount",
      +  "MinutesAfterOpen",
      +  "OpeningPrice",
      +  "PreviousClosingPrice",
      +  "HighOfDay",
      +  "LowOfDay",
      +  "MinutesUntilClose",
      +  "PriceChangeSinceOpen",
      +  "GapSize",
      +  "GapPercentage",
      +  "TrueRange",
      +  "AverageTrueRange",
      +  "Volume",
      +  "VWAP",
      +  "BullishFairValueGap",
      +  "BearishFairValueGap",
      +  "IndicatorAtMinutesAfterOpen",
      +  "IndicatorWindowAgo",
      +  "IndicatorAtEntry",
      +  "IsIndexMember",
      +  "PoliticalTrades",
      +  "InsiderTrades",
      +  "InstitutionalHoldings",
      +  "IsIndustry",
      +  "IsAssetType",
      +  "IsAsset",
      +  "IsNotAsset",
      +  "CrossAbove",
      +  "CrossBelow",
      +  "Correlation",
      +  "PositionMaxDrawdown",
      +  "PositionMaxDrawup",
      +  "UnderlyingMaxDrawdown",
      +  "ConsecutiveTrue",
      +  "CountTrue",
      +  "OptionPositionValue",
      +  "OptionPositionCount",
      +  "OptionPositionPercentChange",
      +  "OptionPositionMaxDrawdown",
      +  "OptionDaysToExpiration",
      +  "OptionDaysHeld",
      +  "OptionCollateral",
      +  "OptionSpreadCount",
      +  "OptionSpreadEntryPrice",
      +  "OptionUnrealizedPnL",
      +  "OptionRealizedPnL",
      +  "OptionRealizedPremium",
      +  "OptionGrossExposurePercent"
      +]
    • changedInput schema / $defs / indicator / properties / windowDays / description
      Previous value: -"PoliticalTrades / InsiderTrades trailing calendar days."New value: +"PoliticalTrades / InsiderTrades trailing calendar days. InstitutionalHoldings reads a disclosed quarter only if its filing became public within this many days, so it defaults to 180 rather than 90: a 13F is quarterly plus a filing lag of up to 45 days, and 91 days can separate two filings."
  2. Changed2 schema fields changed
    • changedInput schema / $defs / indicator / description
      Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), MovingAverageConvergenceDivergence (MACD; needs targetAsset; optional fastLength/slowLength/signalLength defaulting to 12/26/9 with slowLength > fastLength, interval Day|Hour|Minute default Day, and line macd|signal|histogram selecting which of the three MACD outputs to emit), AverageDirectionalIndex (Wilder ADX trend-strength system 0-100; needs targetAsset+window; optional line adx|plusDi|minusDi — ADX measures strength, +DI/-DI direction), RelativeVolume (RVOL; needs targetAsset+window; current bar volume divided by the mean volume of the trailing N completed bars, ~1.0 is its recent pace), TrueRange/AverageTrueRange (need targetAsset; ATR also window), VWAP (needs targetAsset; resets each trading day), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), MovingAverageConvergenceDivergence (MACD; needs targetAsset; optional fastLength/slowLength/signalLength defaulting to 12/26/9 with slowLength > fastLength, interval Day|Hour|Minute default Day, and line macd|signal|histogram selecting which of the three MACD outputs to emit), AverageDirectionalIndex (Wilder ADX trend-strength system 0-100; needs targetAsset+window; optional line adx|plusDi|minusDi — ADX measures strength, +DI/-DI direction), RelativeVolume (RVOL; needs targetAsset+window; current bar volume divided by the mean volume of the trailing N completed bars, ~1.0 is its recent pace), Stochastic (needs targetAsset+window; optional smoothK/smoothD defaulting to 3/3 and line k|d), CommodityChannelIndex (CCI; needs targetAsset+window; optional constant defaulting to 0.015), WilliamsR (needs targetAsset+window; −100 to 0 scale), MoneyFlowIndex (MFI; needs targetAsset+window; volume-weighted 0-100), OnBalanceVolume (OBV; needs targetAsset; optional interval default Day), AccumulationDistribution (ADL; needs targetAsset; optional interval default Day), ChaikinMoneyFlow (CMF; needs targetAsset+window; −1 to +1 scale), DonchianChannel (needs targetAsset+window; optional line upper|lower|middle default upper), KeltnerChannel (needs targetAsset+window; optional multiplier default 2 and line upper|middle|lower default middle), Supertrend (needs targetAsset+window; optional multiplier default 3 and line value|direction default value, direction reads +1 up / −1 down), IchimokuCloud (needs targetAsset+window; optional spanLength default 52 and line tenkan|kijun|senkouA|senkouB|chikou default tenkan; lines unshifted), ParabolicSar (needs targetAsset; optional interval default Day, step default 0.02, maximum default 0.2), TrueRange/AverageTrueRange (need targetAsset; ATR also window), VWAP (needs targetAsset; resets each trading day), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), Correlation (rolling Pearson of two sub-indicators' returns; needs 2 sub-indicators + window with length >= 2), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
    • changedInput schema / $defs / indicator / properties / type / enum
      Previous value: -[
      -  "DaysSinceAgent",
      -  "MinutesSinceAgent",
      -  "DaysSinceAlert",
      -  "MinutesSinceAlert",
      -  "StockReport",
      -  "DaysUntilEarnings",
      -  "DaysSinceEarnings",
      -  "ImpliedVolatility",
      -  "IVRank",
      -  "IVPercentile",
      -  "IVHVRatio",
      -  "LastOrderPrice",
      -  "Fundamental",
      -  "Economic",
      -  "CustomIndicator",
      -  "Index",
      -  "BollingerBand",
      -  "RelativeStrengthIndex",
      -  "MovingAverageConvergenceDivergence",
      -  "AverageDirectionalIndex",
      -  "RelativeVolume",
      -  "PriceMeanAbsoluteDeviation",
      -  "ExponentialMovingAverage",
      -  "SimpleMovingAverage",
      -  "PriceStandardDeviation",
      -  "PriceRateOfChange",
      -  "MaxDrawdown",
      -  "MaxDrawup",
      -  "MinimumPrice",
      -  "MaximumPrice",
      -  "IndicatorMeanAbsoluteDeviation",
      -  "IndicatorExponentialMovingAverage",
      -  "IndicatorSimpleMovingAverage",
      -  "IndicatorStandardDeviation",
      -  "IndicatorRateOfChange",
      -  "DaysSinceOrder",
      -  "DaysSinceOptionOrder",
      -  "DaysSinceStrategyFired",
      -  "DaysSinceLastRebalanceOptionOrder",
      -  "MinutesSinceOptionOrder",
      -  "MinutesSinceOrder",
      -  "DaysSinceTransaction",
      -  "InitialValue",
      -  "BuyingPower",
      -  "PositionValue",
      -  "PositionPercentChange",
      -  "PortfolioValue",
      -  "RebalanceDecisionMetric",
      -  "Value",
      -  "Price",
      -  "Plus",
      -  "Minus",
      -  "Multiply",
      -  "Divide",
      -  "Negative",
      -  "AbsoluteValue",
      -  "SquareRoot",
      -  "Max",
      -  "Min",
      -  "Day",
      -  "Month",
      -  "Date",
      -  "Year",
      -  "CurrentTimeSeconds",
      -  "CurrentTimeMinutes",
      -  "CurrentTimeHours",
      -  "TrailingSum",
      -  "CompoundAnnualGrowthRate",
      -  "Log",
      -  "Exponentiation",
      -  "SumOrderQuantity",
      -  "SumOrderAmount",
      -  "MinutesAfterOpen",
      -  "OpeningPrice",
      -  "PreviousClosingPrice",
      -  "HighOfDay",
      -  "LowOfDay",
      -  "MinutesUntilClose",
      -  "PriceChangeSinceOpen",
      -  "GapSize",
      -  "GapPercentage",
      -  "TrueRange",
      -  "AverageTrueRange",
      -  "Volume",
      -  "VWAP",
      -  "BullishFairValueGap",
      -  "BearishFairValueGap",
      -  "IndicatorAtMinutesAfterOpen",
      -  "IndicatorWindowAgo",
      -  "IndicatorAtEntry",
      -  "IsIndexMember",
      -  "PoliticalTrades",
      -  "InsiderTrades",
      -  "IsIndustry",
      -  "IsAssetType",
      -  "IsAsset",
      -  "IsNotAsset",
      -  "CrossAbove",
      -  "CrossBelow",
      -  "PositionMaxDrawdown",
      -  "PositionMaxDrawup",
      -  "UnderlyingMaxDrawdown",
      -  "ConsecutiveTrue",
      -  "CountTrue",
      -  "OptionPositionValue",
      -  "OptionPositionCount",
      -  "OptionPositionPercentChange",
      -  "OptionPositionMaxDrawdown",
      -  "OptionDaysToExpiration",
      -  "OptionDaysHeld",
      -  "OptionCollateral",
      -  "OptionSpreadCount",
      -  "OptionSpreadEntryPrice",
      -  "OptionUnrealizedPnL",
      -  "OptionRealizedPnL",
      -  "OptionRealizedPremium",
      -  "OptionGrossExposurePercent"
      -]New value: +[
      +  "DaysSinceAgent",
      +  "MinutesSinceAgent",
      +  "DaysSinceAlert",
      +  "MinutesSinceAlert",
      +  "StockReport",
      +  "DaysUntilEarnings",
      +  "DaysSinceEarnings",
      +  "ImpliedVolatility",
      +  "IVRank",
      +  "IVPercentile",
      +  "IVHVRatio",
      +  "LastOrderPrice",
      +  "Fundamental",
      +  "Economic",
      +  "CustomIndicator",
      +  "Index",
      +  "BollingerBand",
      +  "RelativeStrengthIndex",
      +  "MovingAverageConvergenceDivergence",
      +  "AverageDirectionalIndex",
      +  "RelativeVolume",
      +  "Stochastic",
      +  "CommodityChannelIndex",
      +  "WilliamsR",
      +  "MoneyFlowIndex",
      +  "OnBalanceVolume",
      +  "AccumulationDistribution",
      +  "ChaikinMoneyFlow",
      +  "DonchianChannel",
      +  "KeltnerChannel",
      +  "Supertrend",
      +  "IchimokuCloud",
      +  "ParabolicSar",
      +  "PriceMeanAbsoluteDeviation",
      +  "ExponentialMovingAverage",
      +  "SimpleMovingAverage",
      +  "PriceStandardDeviation",
      +  "PriceRateOfChange",
      +  "MaxDrawdown",
      +  "MaxDrawup",
      +  "MinimumPrice",
      +  "MaximumPrice",
      +  "IndicatorMeanAbsoluteDeviation",
      +  "IndicatorExponentialMovingAverage",
      +  "IndicatorSimpleMovingAverage",
      +  "IndicatorStandardDeviation",
      +  "IndicatorRateOfChange",
      +  "DaysSinceOrder",
      +  "DaysSinceOptionOrder",
      +  "DaysSinceStrategyFired",
      +  "DaysSinceLastRebalanceOptionOrder",
      +  "MinutesSinceOptionOrder",
      +  "MinutesSinceOrder",
      +  "DaysSinceTransaction",
      +  "InitialValue",
      +  "BuyingPower",
      +  "PositionValue",
      +  "PositionPercentChange",
      +  "PortfolioValue",
      +  "RebalanceDecisionMetric",
      +  "Value",
      +  "Price",
      +  "Plus",
      +  "Minus",
      +  "Multiply",
      +  "Divide",
      +  "Negative",
      +  "AbsoluteValue",
      +  "SquareRoot",
      +  "Max",
      +  "Min",
      +  "Day",
      +  "Month",
      +  "Date",
      +  "Year",
      +  "CurrentTimeSeconds",
      +  "CurrentTimeMinutes",
      +  "CurrentTimeHours",
      +  "TrailingSum",
      +  "CompoundAnnualGrowthRate",
      +  "Log",
      +  "Exponentiation",
      +  "SumOrderQuantity",
      +  "SumOrderAmount",
      +  "MinutesAfterOpen",
      +  "OpeningPrice",
      +  "PreviousClosingPrice",
      +  "HighOfDay",
      +  "LowOfDay",
      +  "MinutesUntilClose",
      +  "PriceChangeSinceOpen",
      +  "GapSize",
      +  "GapPercentage",
      +  "TrueRange",
      +  "AverageTrueRange",
      +  "Volume",
      +  "VWAP",
      +  "BullishFairValueGap",
      +  "BearishFairValueGap",
      +  "IndicatorAtMinutesAfterOpen",
      +  "IndicatorWindowAgo",
      +  "IndicatorAtEntry",
      +  "IsIndexMember",
      +  "PoliticalTrades",
      +  "InsiderTrades",
      +  "IsIndustry",
      +  "IsAssetType",
      +  "IsAsset",
      +  "IsNotAsset",
      +  "CrossAbove",
      +  "CrossBelow",
      +  "Correlation",
      +  "PositionMaxDrawdown",
      +  "PositionMaxDrawup",
      +  "UnderlyingMaxDrawdown",
      +  "ConsecutiveTrue",
      +  "CountTrue",
      +  "OptionPositionValue",
      +  "OptionPositionCount",
      +  "OptionPositionPercentChange",
      +  "OptionPositionMaxDrawdown",
      +  "OptionDaysToExpiration",
      +  "OptionDaysHeld",
      +  "OptionCollateral",
      +  "OptionSpreadCount",
      +  "OptionSpreadEntryPrice",
      +  "OptionUnrealizedPnL",
      +  "OptionRealizedPnL",
      +  "OptionRealizedPremium",
      +  "OptionGrossExposurePercent"
      +]
  3. Changed2 schema fields changed
    • changedInput schema / $defs / indicator / description
      Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), MovingAverageConvergenceDivergence (MACD; needs targetAsset; optional fastLength/slowLength/signalLength defaulting to 12/26/9 with slowLength > fastLength, interval Day|Hour|Minute default Day, and line macd|signal|histogram selecting which of the three MACD outputs to emit), AverageDirectionalIndex (Wilder ADX trend-strength system 0-100; needs targetAsset+window; optional line adx|plusDi|minusDi — ADX measures strength, +DI/-DI direction), RelativeVolume (RVOL; needs targetAsset+window; current bar volume divided by the mean volume of the trailing N completed bars, ~1.0 is its recent pace), TrueRange/AverageTrueRange (need targetAsset; ATR also window), VWAP (needs targetAsset; resets each trading day), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
    • changedInput schema / $defs / indicator / properties / type / enum
      Previous value: -[
      -  "DaysSinceAgent",
      -  "MinutesSinceAgent",
      -  "DaysSinceAlert",
      -  "MinutesSinceAlert",
      -  "StockReport",
      -  "DaysUntilEarnings",
      -  "DaysSinceEarnings",
      -  "ImpliedVolatility",
      -  "IVRank",
      -  "IVPercentile",
      -  "IVHVRatio",
      -  "LastOrderPrice",
      -  "Fundamental",
      -  "Economic",
      -  "CustomIndicator",
      -  "Index",
      -  "BollingerBand",
      -  "RelativeStrengthIndex",
      -  "PriceMeanAbsoluteDeviation",
      -  "ExponentialMovingAverage",
      -  "SimpleMovingAverage",
      -  "PriceStandardDeviation",
      -  "PriceRateOfChange",
      -  "MaxDrawdown",
      -  "MaxDrawup",
      -  "MinimumPrice",
      -  "MaximumPrice",
      -  "IndicatorMeanAbsoluteDeviation",
      -  "IndicatorExponentialMovingAverage",
      -  "IndicatorSimpleMovingAverage",
      -  "IndicatorStandardDeviation",
      -  "IndicatorRateOfChange",
      -  "DaysSinceOrder",
      -  "DaysSinceOptionOrder",
      -  "DaysSinceStrategyFired",
      -  "DaysSinceLastRebalanceOptionOrder",
      -  "MinutesSinceOptionOrder",
      -  "MinutesSinceOrder",
      -  "DaysSinceTransaction",
      -  "InitialValue",
      -  "BuyingPower",
      -  "PositionValue",
      -  "PositionPercentChange",
      -  "PortfolioValue",
      -  "RebalanceDecisionMetric",
      -  "Value",
      -  "Price",
      -  "Plus",
      -  "Minus",
      -  "Multiply",
      -  "Divide",
      -  "Negative",
      -  "AbsoluteValue",
      -  "SquareRoot",
      -  "Max",
      -  "Min",
      -  "Day",
      -  "Month",
      -  "Date",
      -  "Year",
      -  "CurrentTimeSeconds",
      -  "CurrentTimeMinutes",
      -  "CurrentTimeHours",
      -  "TrailingSum",
      -  "CompoundAnnualGrowthRate",
      -  "Log",
      -  "Exponentiation",
      -  "SumOrderQuantity",
      -  "SumOrderAmount",
      -  "MinutesAfterOpen",
      -  "OpeningPrice",
      -  "PreviousClosingPrice",
      -  "HighOfDay",
      -  "LowOfDay",
      -  "MinutesUntilClose",
      -  "PriceChangeSinceOpen",
      -  "GapSize",
      -  "GapPercentage",
      -  "TrueRange",
      -  "AverageTrueRange",
      -  "Volume",
      -  "VWAP",
      -  "BullishFairValueGap",
      -  "BearishFairValueGap",
      -  "IndicatorAtMinutesAfterOpen",
      -  "IndicatorWindowAgo",
      -  "IndicatorAtEntry",
      -  "IsIndexMember",
      -  "PoliticalTrades",
      -  "InsiderTrades",
      -  "IsIndustry",
      -  "IsAssetType",
      -  "IsAsset",
      -  "IsNotAsset",
      -  "CrossAbove",
      -  "CrossBelow",
      -  "PositionMaxDrawdown",
      -  "PositionMaxDrawup",
      -  "UnderlyingMaxDrawdown",
      -  "ConsecutiveTrue",
      -  "CountTrue",
      -  "OptionPositionValue",
      -  "OptionPositionCount",
      -  "OptionPositionPercentChange",
      -  "OptionPositionMaxDrawdown",
      -  "OptionDaysToExpiration",
      -  "OptionDaysHeld",
      -  "OptionCollateral",
      -  "OptionSpreadCount",
      -  "OptionSpreadEntryPrice",
      -  "OptionUnrealizedPnL",
      -  "OptionRealizedPnL",
      -  "OptionRealizedPremium",
      -  "OptionGrossExposurePercent"
      -]New value: +[
      +  "DaysSinceAgent",
      +  "MinutesSinceAgent",
      +  "DaysSinceAlert",
      +  "MinutesSinceAlert",
      +  "StockReport",
      +  "DaysUntilEarnings",
      +  "DaysSinceEarnings",
      +  "ImpliedVolatility",
      +  "IVRank",
      +  "IVPercentile",
      +  "IVHVRatio",
      +  "LastOrderPrice",
      +  "Fundamental",
      +  "Economic",
      +  "CustomIndicator",
      +  "Index",
      +  "BollingerBand",
      +  "RelativeStrengthIndex",
      +  "MovingAverageConvergenceDivergence",
      +  "AverageDirectionalIndex",
      +  "RelativeVolume",
      +  "PriceMeanAbsoluteDeviation",
      +  "ExponentialMovingAverage",
      +  "SimpleMovingAverage",
      +  "PriceStandardDeviation",
      +  "PriceRateOfChange",
      +  "MaxDrawdown",
      +  "MaxDrawup",
      +  "MinimumPrice",
      +  "MaximumPrice",
      +  "IndicatorMeanAbsoluteDeviation",
      +  "IndicatorExponentialMovingAverage",
      +  "IndicatorSimpleMovingAverage",
      +  "IndicatorStandardDeviation",
      +  "IndicatorRateOfChange",
      +  "DaysSinceOrder",
      +  "DaysSinceOptionOrder",
      +  "DaysSinceStrategyFired",
      +  "DaysSinceLastRebalanceOptionOrder",
      +  "MinutesSinceOptionOrder",
      +  "MinutesSinceOrder",
      +  "DaysSinceTransaction",
      +  "InitialValue",
      +  "BuyingPower",
      +  "PositionValue",
      +  "PositionPercentChange",
      +  "PortfolioValue",
      +  "RebalanceDecisionMetric",
      +  "Value",
      +  "Price",
      +  "Plus",
      +  "Minus",
      +  "Multiply",
      +  "Divide",
      +  "Negative",
      +  "AbsoluteValue",
      +  "SquareRoot",
      +  "Max",
      +  "Min",
      +  "Day",
      +  "Month",
      +  "Date",
      +  "Year",
      +  "CurrentTimeSeconds",
      +  "CurrentTimeMinutes",
      +  "CurrentTimeHours",
      +  "TrailingSum",
      +  "CompoundAnnualGrowthRate",
      +  "Log",
      +  "Exponentiation",
      +  "SumOrderQuantity",
      +  "SumOrderAmount",
      +  "MinutesAfterOpen",
      +  "OpeningPrice",
      +  "PreviousClosingPrice",
      +  "HighOfDay",
      +  "LowOfDay",
      +  "MinutesUntilClose",
      +  "PriceChangeSinceOpen",
      +  "GapSize",
      +  "GapPercentage",
      +  "TrueRange",
      +  "AverageTrueRange",
      +  "Volume",
      +  "VWAP",
      +  "BullishFairValueGap",
      +  "BearishFairValueGap",
      +  "IndicatorAtMinutesAfterOpen",
      +  "IndicatorWindowAgo",
      +  "IndicatorAtEntry",
      +  "IsIndexMember",
      +  "PoliticalTrades",
      +  "InsiderTrades",
      +  "IsIndustry",
      +  "IsAssetType",
      +  "IsAsset",
      +  "IsNotAsset",
      +  "CrossAbove",
      +  "CrossBelow",
      +  "PositionMaxDrawdown",
      +  "PositionMaxDrawup",
      +  "UnderlyingMaxDrawdown",
      +  "ConsecutiveTrue",
      +  "CountTrue",
      +  "OptionPositionValue",
      +  "OptionPositionCount",
      +  "OptionPositionPercentChange",
      +  "OptionPositionMaxDrawdown",
      +  "OptionDaysToExpiration",
      +  "OptionDaysHeld",
      +  "OptionCollateral",
      +  "OptionSpreadCount",
      +  "OptionSpreadEntryPrice",
      +  "OptionUnrealizedPnL",
      +  "OptionRealizedPnL",
      +  "OptionRealizedPremium",
      +  "OptionGrossExposurePercent"
      +]
  4. Changed7 schema fields changed
    • changedInput schema / $defs / indicator / description
      Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
    • addedInput schema / $defs / indicator / properties / amountBasis
      Added value: +{
      +  "description": "PoliticalTrades disclosed range endpoint. LowerBound is conservative.",
      +  "enum": [
      +    "LowerBound",
      +    "Midpoint",
      +    "UpperBound"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / $defs / indicator / properties / chamber
      Added value: +{
      +  "description": "PoliticalTrades optional cohort filter. All combines House and Senate.",
      +  "enum": [
      +    "All",
      +    "House",
      +    "Senate"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / $defs / indicator / properties / filer
      Added value: +{
      +  "description": "PoliticalTrades member full or last name; empty means all members.",
      +  "type": "string"
      +}
    • addedInput schema / $defs / indicator / properties / instrument
      Added value: +{
      +  "description": "PoliticalTrades instrument class. Equity excludes confirmed options.",
      +  "enum": [
      +    "Equity",
      +    "Option",
      +    "All"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / $defs / indicator / properties / metric / description
      Previous value: -"Fundamental/CompoundAnnualGrowthRate: financial metric (e.g. 'peRatio'). Economic: economic indicator (e.g. 'UNRATE'). Index: index symbol (e.g. 'VIX', 'SPX'). RebalanceDecisionMetric: allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit."New value: +"PoliticalTrades: NetAmount, BuyAmount, SellAmount, BuyCount, SellCount, DistinctBuyers. Fundamental/CompoundAnnualGrowthRate: financial metric (e.g. 'peRatio'). Economic: economic indicator (e.g. 'UNRATE'). Index: index symbol (e.g. 'VIX', 'SPX'). RebalanceDecisionMetric: allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit."
    • addedInput schema / $defs / indicator / properties / windowDays
      Added value: +{
      +  "description": "PoliticalTrades / InsiderTrades trailing calendar days.",
      +  "maximum": 3650,
      +  "minimum": 1,
      +  "type": "integer"
      +}
  5. Changed14 schema fields changed
    • changedInput schema / $defs / indicator / description
      Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
    • changedInput schema / $defs / indicator / properties / type / enum
      Previous value: -[
      -  "DaysSinceAgent",
      -  "MinutesSinceAgent",
      -  "DaysSinceAlert",
      -  "MinutesSinceAlert",
      -  "StockReport",
      -  "DaysUntilEarnings",
      -  "DaysSinceEarnings",
      -  "ImpliedVolatility",
      -  "IVRank",
      -  "IVPercentile",
      -  "IVHVRatio",
      -  "LastOrderPrice",
      -  "Fundamental",
      -  "Economic",
      -  "CustomIndicator",
      -  "Index",
      -  "BollingerBand",
      -  "RelativeStrengthIndex",
      -  "PriceMeanAbsoluteDeviation",
      -  "ExponentialMovingAverage",
      -  "SimpleMovingAverage",
      -  "PriceStandardDeviation",
      -  "PriceRateOfChange",
      -  "MaxDrawdown",
      -  "MaxDrawup",
      -  "MinimumPrice",
      -  "MaximumPrice",
      -  "IndicatorMeanAbsoluteDeviation",
      -  "IndicatorExponentialMovingAverage",
      -  "IndicatorSimpleMovingAverage",
      -  "IndicatorStandardDeviation",
      -  "IndicatorRateOfChange",
      -  "DaysSinceOrder",
      -  "DaysSinceOptionOrder",
      -  "DaysSinceStrategyFired",
      -  "DaysSinceLastRebalanceOptionOrder",
      -  "MinutesSinceOptionOrder",
      -  "MinutesSinceOrder",
      -  "DaysSinceTransaction",
      -  "InitialValue",
      -  "BuyingPower",
      -  "PositionValue",
      -  "PositionPercentChange",
      -  "PortfolioValue",
      -  "RebalanceDecisionMetric",
      -  "Value",
      -  "Price",
      -  "Plus",
      -  "Minus",
      -  "Multiply",
      -  "Divide",
      -  "Negative",
      -  "AbsoluteValue",
      -  "SquareRoot",
      -  "Max",
      -  "Min",
      -  "Day",
      -  "Month",
      -  "Date",
      -  "Year",
      -  "CurrentTimeSeconds",
      -  "CurrentTimeMinutes",
      -  "CurrentTimeHours",
      -  "TrailingSum",
      -  "CompoundAnnualGrowthRate",
      -  "Log",
      -  "Exponentiation",
      -  "SumOrderQuantity",
      -  "SumOrderAmount",
      -  "MinutesAfterOpen",
      -  "OpeningPrice",
      -  "PreviousClosingPrice",
      -  "HighOfDay",
      -  "LowOfDay",
      -  "MinutesUntilClose",
      -  "PriceChangeSinceOpen",
      -  "GapSize",
      -  "GapPercentage",
      -  "TrueRange",
      -  "AverageTrueRange",
      -  "Volume",
      -  "VWAP",
      -  "BullishFairValueGap",
      -  "BearishFairValueGap",
      -  "IndicatorAtMinutesAfterOpen",
      -  "IndicatorWindowAgo",
      -  "IndicatorAtEntry",
      -  "IsIndexMember",
      -  "IsIndustry",
      -  "IsAssetType",
      -  "IsAsset",
      -  "IsNotAsset",
      -  "CrossAbove",
      -  "CrossBelow",
      -  "PositionMaxDrawdown",
      -  "PositionMaxDrawup",
      -  "UnderlyingMaxDrawdown",
      -  "ConsecutiveTrue",
      -  "CountTrue",
      -  "OptionPositionValue",
      -  "OptionPositionCount",
      -  "OptionPositionPercentChange",
      -  "OptionPositionMaxDrawdown",
      -  "OptionDaysToExpiration",
      -  "OptionDaysHeld",
      -  "OptionCollateral",
      -  "OptionSpreadCount",
      -  "OptionUnrealizedPnL",
      -  "OptionRealizedPnL",
      -  "OptionRealizedPremium",
      -  "OptionGrossExposurePercent"
      -]New value: +[
      +  "DaysSinceAgent",
      +  "MinutesSinceAgent",
      +  "DaysSinceAlert",
      +  "MinutesSinceAlert",
      +  "StockReport",
      +  "DaysUntilEarnings",
      +  "DaysSinceEarnings",
      +  "ImpliedVolatility",
      +  "IVRank",
      +  "IVPercentile",
      +  "IVHVRatio",
      +  "LastOrderPrice",
      +  "Fundamental",
      +  "Economic",
      +  "CustomIndicator",
      +  "Index",
      +  "BollingerBand",
      +  "RelativeStrengthIndex",
      +  "PriceMeanAbsoluteDeviation",
      +  "ExponentialMovingAverage",
      +  "SimpleMovingAverage",
      +  "PriceStandardDeviation",
      +  "PriceRateOfChange",
      +  "MaxDrawdown",
      +  "MaxDrawup",
      +  "MinimumPrice",
      +  "MaximumPrice",
      +  "IndicatorMeanAbsoluteDeviation",
      +  "IndicatorExponentialMovingAverage",
      +  "IndicatorSimpleMovingAverage",
      +  "IndicatorStandardDeviation",
      +  "IndicatorRateOfChange",
      +  "DaysSinceOrder",
      +  "DaysSinceOptionOrder",
      +  "DaysSinceStrategyFired",
      +  "DaysSinceLastRebalanceOptionOrder",
      +  "MinutesSinceOptionOrder",
      +  "MinutesSinceOrder",
      +  "DaysSinceTransaction",
      +  "InitialValue",
      +  "BuyingPower",
      +  "PositionValue",
      +  "PositionPercentChange",
      +  "PortfolioValue",
      +  "RebalanceDecisionMetric",
      +  "Value",
      +  "Price",
      +  "Plus",
      +  "Minus",
      +  "Multiply",
      +  "Divide",
      +  "Negative",
      +  "AbsoluteValue",
      +  "SquareRoot",
      +  "Max",
      +  "Min",
      +  "Day",
      +  "Month",
      +  "Date",
      +  "Year",
      +  "CurrentTimeSeconds",
      +  "CurrentTimeMinutes",
      +  "CurrentTimeHours",
      +  "TrailingSum",
      +  "CompoundAnnualGrowthRate",
      +  "Log",
      +  "Exponentiation",
      +  "SumOrderQuantity",
      +  "SumOrderAmount",
      +  "MinutesAfterOpen",
      +  "OpeningPrice",
      +  "PreviousClosingPrice",
      +  "HighOfDay",
      +  "LowOfDay",
      +  "MinutesUntilClose",
      +  "PriceChangeSinceOpen",
      +  "GapSize",
      +  "GapPercentage",
      +  "TrueRange",
      +  "AverageTrueRange",
      +  "Volume",
      +  "VWAP",
      +  "BullishFairValueGap",
      +  "BearishFairValueGap",
      +  "IndicatorAtMinutesAfterOpen",
      +  "IndicatorWindowAgo",
      +  "IndicatorAtEntry",
      +  "IsIndexMember",
      +  "PoliticalTrades",
      +  "InsiderTrades",
      +  "IsIndustry",
      +  "IsAssetType",
      +  "IsAsset",
      +  "IsNotAsset",
      +  "CrossAbove",
      +  "CrossBelow",
      +  "PositionMaxDrawdown",
      +  "PositionMaxDrawup",
      +  "UnderlyingMaxDrawdown",
      +  "ConsecutiveTrue",
      +  "CountTrue",
      +  "OptionPositionValue",
      +  "OptionPositionCount",
      +  "OptionPositionPercentChange",
      +  "OptionPositionMaxDrawdown",
      +  "OptionDaysToExpiration",
      +  "OptionDaysHeld",
      +  "OptionCollateral",
      +  "OptionSpreadCount",
      +  "OptionSpreadEntryPrice",
      +  "OptionUnrealizedPnL",
      +  "OptionRealizedPnL",
      +  "OptionRealizedPremium",
      +  "OptionGrossExposurePercent"
      +]
    • changedInput schema / $defs / orderExecution / description
      Previous value: -"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
    • changedInput schema / $defs / orderExecution / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "type": {
      -        "const": "Market",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "price": {
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
      -            "properties": {
      -              "amount": {
      -                "minimum": 1e-8,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "UnitPrice",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "amount"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
      -            "properties": {
      -              "amount": {
      -                "minimum": 1e-8,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MinimumNetCredit",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "amount"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
      -            "properties": {
      -              "amount": {
      -                "minimum": 1e-8,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MaximumNetDebit",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "amount"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
      -            "properties": {
      -              "reference": {
      -                "const": "Current",
      -                "type": "string"
      -              },
      -              "type": {
      -                "const": "QuoteRelative",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "reference"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      },
      -      "type": {
      -        "const": "Limit",
      -        "type": "string"
      -      },
      -      "workingTime": {
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
      -            "properties": {
      -              "type": {
      -                "const": "Day",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "minutes": {
      -                "minimum": 1,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "Minutes",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "minutes"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "price"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "type": {
      +        "const": "Market",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "price": {
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
      +            "properties": {
      +              "amount": {
      +                "minimum": 1e-8,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "UnitPrice",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "amount"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
      +            "properties": {
      +              "amount": {
      +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
      +                "oneOf": [
      +                  {
      +                    "minimum": 1e-8,
      +                    "type": "number"
      +                  },
      +                  {
      +                    "$ref": "#/$defs/indicator"
      +                  }
      +                ]
      +              },
      +              "type": {
      +                "const": "MinimumNetCredit",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "amount"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
      +            "properties": {
      +              "amount": {
      +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
      +                "oneOf": [
      +                  {
      +                    "minimum": 1e-8,
      +                    "type": "number"
      +                  },
      +                  {
      +                    "$ref": "#/$defs/indicator"
      +                  }
      +                ]
      +              },
      +              "type": {
      +                "const": "MaximumNetDebit",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "amount"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
      +            "properties": {
      +              "reference": {
      +                "const": "Current",
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "QuoteRelative",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "reference"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      },
      +      "type": {
      +        "const": "Limit",
      +        "type": "string"
      +      },
      +      "workingTime": {
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
      +            "properties": {
      +              "type": {
      +                "const": "Day",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "minutes": {
      +                "minimum": 1,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "Minutes",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "minutes"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "price"
      +    ],
      +    "type": "object"
      +  }
      +]
    • changedInput schema / $defs / strategy / description
      Previous value: -"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
    • changedInput schema / $defs / strategy / properties / orderExecution / description
      Previous value: -"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
    • changedInput schema / $defs / strategy / properties / orderExecution / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "type": {
      -        "const": "Market",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "price": {
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
      -            "properties": {
      -              "amount": {
      -                "minimum": 1e-8,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "UnitPrice",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "amount"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
      -            "properties": {
      -              "amount": {
      -                "minimum": 1e-8,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MinimumNetCredit",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "amount"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
      -            "properties": {
      -              "amount": {
      -                "minimum": 1e-8,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MaximumNetDebit",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "amount"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
      -            "properties": {
      -              "reference": {
      -                "const": "Current",
      -                "type": "string"
      -              },
      -              "type": {
      -                "const": "QuoteRelative",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "reference"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      },
      -      "type": {
      -        "const": "Limit",
      -        "type": "string"
      -      },
      -      "workingTime": {
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
      -            "properties": {
      -              "type": {
      -                "const": "Day",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "minutes": {
      -                "minimum": 1,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "Minutes",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "minutes"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "price"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "type": {
      +        "const": "Market",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "price": {
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
      +            "properties": {
      +              "amount": {
      +                "minimum": 1e-8,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "UnitPrice",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "amount"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
      +            "properties": {
      +              "amount": {
      +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
      +                "oneOf": [
      +                  {
      +                    "minimum": 1e-8,
      +                    "type": "number"
      +                  },
      +                  {
      +                    "$ref": "#/$defs/indicator"
      +                  }
      +                ]
      +              },
      +              "type": {
      +                "const": "MinimumNetCredit",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "amount"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
      +            "properties": {
      +              "amount": {
      +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
      +                "oneOf": [
      +                  {
      +                    "minimum": 1e-8,
      +                    "type": "number"
      +                  },
      +                  {
      +                    "$ref": "#/$defs/indicator"
      +                  }
      +                ]
      +              },
      +              "type": {
      +                "const": "MaximumNetDebit",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "amount"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
      +            "properties": {
      +              "reference": {
      +                "const": "Current",
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "QuoteRelative",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "reference"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      },
      +      "type": {
      +        "const": "Limit",
      +        "type": "string"
      +      },
      +      "workingTime": {
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
      +            "properties": {
      +              "type": {
      +                "const": "Day",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "minutes": {
      +                "minimum": 1,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "Minutes",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "minutes"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "price"
      +    ],
      +    "type": "object"
      +  }
      +]
    • changedInput schema / properties / operations / description
      Previous value: -"Array of edit operations. Each operation needs \"portfolioId\" (live, paper, or chat — server resolves automatically). Supported types include \"rename\" (requires non-empty \"name\"), \"delete\" (permanently remove a chat/paper/live portfolio; archives deployed books; pass confirmLive:true only after explicit user confirmation when deleting an active live portfolio). DEPLOY SAFETY: deploying a chat portfolio ID creates a NEW PAPER-TRADING portfolio (simulated money, no broker order ever placed). It cannot place real-money trades. A LIVE/real-brokerage deployment only happens when the target is an EXISTING real-brokerage portfolio (re-activating it, or addStrategies/replaceStrategies on a portfolio already connected to a live broker). You cannot create a live brokerage account from a chat portfolio through this tool. Fetch the portfolio first and use strategy IDs from the returned \"strategies\" array for removals. To add/replace strategies, pass FINISHED strategy objects ({name, condition, action, orderExecution?} — same shape as create_portfolio.strategies) via \"strategyObjects\" (or \"strategyObject\" for replaceStrategy). These are ingested deterministically with zero LLM cost; prefer them. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. RebalanceOption `action.positionScope`: `\"portfolio\"` (default for single-book portfolios — rotation-close and open-skip span all option spreads in the portfolio) or `\"strategy\"` (only spreads this strategy opened; use when multiple RebalanceOption strategies share one portfolio). Set on `create_portfolio` strategies[].action or on `update_portfolio` replaceStrategy/replaceStrategies `strategyObject.action`. Examples: [{\"type\":\"deploy\",\"portfolioId\":\"id\"}, {\"type\":\"undeploy\",\"portfolioId\":\"id\"}, {\"type\":\"delete\",\"portfolioId\":\"id\"}, {\"type\":\"addStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...},\"orderExecution\":{\"type\":\"Limit\",\"price\":{\"type\":\"UnitPrice\",\"amount\":150},\"workingTime\":{\"type\":\"Day\"}}}]}, {\"type\":\"removeStrategies\",\"portfolioId\":\"id\",\"strategyIds\":[\"strategyId\"]}, {\"type\":\"replaceStrategy\",\"portfolioId\":\"id\",\"targetStrategyId\":\"strategyId\",\"strategyObject\":{\"name\":\"...\",\"condition\":{...},\"action\":{\"type\":\"RebalanceOption\",\"positionScope\":\"portfolio\",...}}}, {\"type\":\"replaceStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...}}]}, {\"type\":\"setDeploymentFrequency\",\"portfolioId\":\"id\",\"deploymentFrequency\":\"Constant\"}, {\"type\":\"rename\",\"portfolioId\":\"id\",\"name\":\"New Portfolio Name\"}]"New value: +"Array of edit operations. Each operation needs \"portfolioId\" (live, paper, or chat — server resolves automatically). Supported types include \"rename\" (requires non-empty \"name\"), \"delete\" (permanently remove a chat/paper/live portfolio; archives deployed books; pass confirmLive:true only after explicit user confirmation when deleting an active live portfolio). DEPLOY SAFETY: deploying a chat portfolio ID creates a NEW PAPER-TRADING portfolio (simulated money, no broker order ever placed). It cannot place real-money trades. A LIVE/real-brokerage deployment only happens when the target is an EXISTING real-brokerage portfolio (re-activating it, or addStrategies/replaceStrategies on a portfolio already connected to a live broker). You cannot create a live brokerage account from a chat portfolio through this tool. Fetch the portfolio first and use strategy IDs from the returned \"strategies\" array for removals. To add/replace strategies, pass FINISHED strategy objects ({name, condition, action, orderExecution?} — same shape as create_portfolio.strategies) via \"strategyObjects\" (or \"strategyObject\" for replaceStrategy). These are ingested deterministically with zero LLM cost; prefer them. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. RebalanceOption `action.positionScope`: `\"portfolio\"` (default for single-book portfolios — rotation-close and open-skip span all option spreads in the portfolio) or `\"strategy\"` (only spreads this strategy opened; use when multiple RebalanceOption strategies share one portfolio). Set on `create_portfolio` strategies[].action or on `update_portfolio` replaceStrategy/replaceStrategies `strategyObject.action`. Examples: [{\"type\":\"deploy\",\"portfolioId\":\"id\"}, {\"type\":\"undeploy\",\"portfolioId\":\"id\"}, {\"type\":\"delete\",\"portfolioId\":\"id\"}, {\"type\":\"addStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...},\"orderExecution\":{\"type\":\"Limit\",\"price\":{\"type\":\"UnitPrice\",\"amount\":150},\"workingTime\":{\"type\":\"Day\"}}}]}, {\"type\":\"removeStrategies\",\"portfolioId\":\"id\",\"strategyIds\":[\"strategyId\"]}, {\"type\":\"replaceStrategy\",\"portfolioId\":\"id\",\"targetStrategyId\":\"strategyId\",\"strategyObject\":{\"name\":\"...\",\"condition\":{...},\"action\":{\"type\":\"RebalanceOption\",\"positionScope\":\"portfolio\",...}}}, {\"type\":\"replaceStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...}}]}, {\"type\":\"setDeploymentFrequency\",\"portfolioId\":\"id\",\"deploymentFrequency\":\"Constant\"}, {\"type\":\"rename\",\"portfolioId\":\"id\",\"name\":\"New Portfolio Name\"}]"
    • changedInput schema / properties / operations / items / properties / strategyObject / description
      Previous value: -"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
    • changedInput schema / properties / operations / items / properties / strategyObject / properties / orderExecution / description
      Previous value: -"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
    • changedInput schema / properties / operations / items / properties / strategyObject / properties / orderExecution / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "type": {
      -        "const": "Market",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "price": {
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
      -            "properties": {
      -              "amount": {
      -                "minimum": 1e-8,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "UnitPrice",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "amount"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
      -            "properties": {
      -              "amount": {
      -                "minimum": 1e-8,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MinimumNetCredit",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "amount"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
      -            "properties": {
      -              "amount": {
      -                "minimum": 1e-8,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MaximumNetDebit",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "amount"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
      -            "properties": {
      -              "reference": {
      -                "const": "Current",
      -                "type": "string"
      -              },
      -              "type": {
      -                "const": "QuoteRelative",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "reference"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      },
      -      "type": {
      -        "const": "Limit",
      -        "type": "string"
      -      },
      -      "workingTime": {
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
      -            "properties": {
      -              "type": {
      -                "const": "Day",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "minutes": {
      -                "minimum": 1,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "Minutes",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "minutes"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "price"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "type": {
      +        "const": "Market",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "price": {
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
      +            "properties": {
      +              "amount": {
      +                "minimum": 1e-8,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "UnitPrice",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "amount"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
      +            "properties": {
      +              "amount": {
      +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
      +                "oneOf": [
      +                  {
      +                    "minimum": 1e-8,
      +                    "type": "number"
      +                  },
      +                  {
      +                    "$ref": "#/$defs/indicator"
      +                  }
      +                ]
      +              },
      +              "type": {
      +                "const": "MinimumNetCredit",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "amount"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
      +            "properties": {
      +              "amount": {
      +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
      +                "oneOf": [
      +                  {
      +                    "minimum": 1e-8,
      +                    "type": "number"
      +                  },
      +                  {
      +                    "$ref": "#/$defs/indicator"
      +                  }
      +                ]
      +              },
      +              "type": {
      +                "const": "MaximumNetDebit",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "amount"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
      +            "properties": {
      +              "reference": {
      +                "const": "Current",
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "QuoteRelative",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "reference"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      },
      +      "type": {
      +        "const": "Limit",
      +        "type": "string"
      +      },
      +      "workingTime": {
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
      +            "properties": {
      +              "type": {
      +                "const": "Day",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "minutes": {
      +                "minimum": 1,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "Minutes",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "minutes"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "price"
      +    ],
      +    "type": "object"
      +  }
      +]
    • changedInput schema / properties / operations / items / properties / strategyObjects / items / description
      Previous value: -"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
    • changedInput schema / properties / operations / items / properties / strategyObjects / items / properties / orderExecution / description
      Previous value: -"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
    • changedInput schema / properties / operations / items / properties / strategyObjects / items / properties / orderExecution / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "type": {
      -        "const": "Market",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "price": {
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
      -            "properties": {
      -              "amount": {
      -                "minimum": 1e-8,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "UnitPrice",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "amount"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
      -            "properties": {
      -              "amount": {
      -                "minimum": 1e-8,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MinimumNetCredit",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "amount"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
      -            "properties": {
      -              "amount": {
      -                "minimum": 1e-8,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MaximumNetDebit",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "amount"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
      -            "properties": {
      -              "reference": {
      -                "const": "Current",
      -                "type": "string"
      -              },
      -              "type": {
      -                "const": "QuoteRelative",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "reference"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      },
      -      "type": {
      -        "const": "Limit",
      -        "type": "string"
      -      },
      -      "workingTime": {
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
      -            "properties": {
      -              "type": {
      -                "const": "Day",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "minutes": {
      -                "minimum": 1,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "Minutes",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "minutes"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "price"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "type": {
      +        "const": "Market",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "price": {
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
      +            "properties": {
      +              "amount": {
      +                "minimum": 1e-8,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "UnitPrice",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "amount"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
      +            "properties": {
      +              "amount": {
      +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
      +                "oneOf": [
      +                  {
      +                    "minimum": 1e-8,
      +                    "type": "number"
      +                  },
      +                  {
      +                    "$ref": "#/$defs/indicator"
      +                  }
      +                ]
      +              },
      +              "type": {
      +                "const": "MinimumNetCredit",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "amount"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
      +            "properties": {
      +              "amount": {
      +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
      +                "oneOf": [
      +                  {
      +                    "minimum": 1e-8,
      +                    "type": "number"
      +                  },
      +                  {
      +                    "$ref": "#/$defs/indicator"
      +                  }
      +                ]
      +              },
      +              "type": {
      +                "const": "MaximumNetDebit",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "amount"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
      +            "properties": {
      +              "reference": {
      +                "const": "Current",
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "QuoteRelative",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "reference"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      },
      +      "type": {
      +        "const": "Limit",
      +        "type": "string"
      +      },
      +      "workingTime": {
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
      +            "properties": {
      +              "type": {
      +                "const": "Day",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "minutes": {
      +                "minimum": 1,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "Minutes",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "minutes"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "price"
      +    ],
      +    "type": "object"
      +  }
      +]
  6. Changed9 schema fields changed
    • changedInput schema / $defs / action / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": true,
      -    "description": "Buy or Sell a stock/crypto position.",
      -    "properties": {
      -      "amount": {
      -        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
      -        "properties": {
      -          "amount": {
      -            "type": "number"
      -          },
      -          "type": {
      -            "enum": [
      -              "percent of portfolio",
      -              "percent of buying power",
      -              "percent of current positions",
      -              "dollars",
      -              "number of assets"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "amount"
      -        ],
      -        "type": "object"
      -      },
      -      "targetAsset": {
      -        "additionalProperties": true,
      -        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      -        "properties": {
      -          "name": {
      -            "type": "string"
      -          },
      -          "symbol": {
      -            "type": "string"
      -          },
      -          "type": {
      -            "enum": [
      -              "Stock",
      -              "Cryptocurrency",
      -              "Option",
      -              "Other"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "symbol"
      -        ],
      -        "type": "object"
      -      },
      -      "type": {
      -        "enum": [
      -          "Buy",
      -          "Sell"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "targetAsset",
      -      "amount"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "Send an alert message (no order).",
      -    "properties": {
      -      "message": {
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "Alert",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "message"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
      -    "properties": {
      -      "allocationPolicy": {
      -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "expectedReturnShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "riskAversion": {
      -                "maximum": 1000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MeanVariance",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "riskAversion",
      -              "expectedReturnShrinkage",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "RiskParity",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MaximumDiversification",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      },
      -      "canSell": {
      -        "$ref": "#/$defs/condition",
      -        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
      -      },
      -      "deploymentPercent": {
      -        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "exposurePolicy": {
      -        "additionalProperties": false,
      -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      -        "properties": {
      -          "covarianceShrinkage": {
      -            "maximum": 1,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "estimatedTransactionCostBps": {
      -            "maximum": 10000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "lookbackPeriods": {
      -            "maximum": 5000,
      -            "minimum": 2,
      -            "type": "integer"
      -          },
      -          "minimumObservations": {
      -            "maximum": 5000,
      -            "minimum": 2,
      -            "type": "integer"
      -          },
      -          "targetAnnualizedVolatilityPercent": {
      -            "maximum": 1000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "type": {
      -            "const": "VolatilityTarget",
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "lookbackPeriods",
      -          "minimumObservations",
      -          "covarianceShrinkage",
      -          "targetAnnualizedVolatilityPercent",
      -          "estimatedTransactionCostBps"
      -        ],
      -        "type": "object"
      -      },
      -      "limit": {
      -        "minimum": 1,
      -        "type": "number"
      -      },
      -      "perNameAllocation": {
      -        "additionalProperties": true,
      -        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
      -        "properties": {
      -          "amount": {
      -            "exclusiveMinimum": 0,
      -            "type": "number"
      -          },
      -          "type": {
      -            "enum": [
      -              "percent of portfolio",
      -              "dollars"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "amount"
      -        ],
      -        "type": "object"
      -      },
      -      "pipeline": {
      -        "items": {
      -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      -          "oneOf": [
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "condition": {
      -                  "$ref": "#/$defs/condition"
      -                },
      -                "type": {
      -                  "const": "Filter",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "condition"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "direction": {
      -                  "enum": [
      -                    "Highest",
      -                    "Lowest"
      -                  ],
      -                  "type": "string"
      -                },
      -                "limit": {
      -                  "minimum": 1,
      -                  "type": "number"
      -                },
      -                "metric": {
      -                  "$ref": "#/$defs/indicator"
      -                },
      -                "type": {
      -                  "const": "SelectTop",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "metric",
      -                "limit",
      -                "direction"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "direction": {
      -                  "enum": [
      -                    "Highest",
      -                    "Lowest"
      -                  ],
      -                  "type": "string"
      -                },
      -                "metric": {
      -                  "$ref": "#/$defs/indicator"
      -                },
      -                "percentile": {
      -                  "maximum": 100,
      -                  "minimum": 0,
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "SelectPercentile",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "metric",
      -                "percentile",
      -                "direction"
      -              ],
      -              "type": "object"
      -            }
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "type": {
      -        "const": "DynamicRebalance",
      -        "type": "string"
      -      },
      -      "universe": {
      -        "additionalProperties": true,
      -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      -        "properties": {
      -          "assets": {
      -            "items": {
      -              "additionalProperties": true,
      -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      -              "properties": {
      -                "name": {
      -                  "type": "string"
      -                },
      -                "symbol": {
      -                  "type": "string"
      -                },
      -                "type": {
      -                  "enum": [
      -                    "Stock",
      -                    "Cryptocurrency",
      -                    "Option",
      -                    "Other"
      -                  ],
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "symbol"
      -              ],
      -              "type": "object"
      -            },
      -            "type": "array"
      -          },
      -          "source": {
      -            "enum": [
      -              "ALL_US_STOCKS",
      -              "SP500",
      -              "NASDAQ100",
      -              "DJIA",
      -              "CRYPTO",
      -              "SPECIFIC_ASSETS"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "source"
      -        ],
      -        "type": "object"
      -      },
      -      "weightIndicator": {
      -        "$ref": "#/$defs/indicator"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "universe",
      -      "pipeline",
      -      "weightIndicator"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
      -    "properties": {
      -      "continueExisting": {
      -        "type": "boolean"
      -      },
      -      "cooldownMinutes": {
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "executionModel": {
      -        "type": "string"
      -      },
      -      "includeMarketData": {
      -        "type": "boolean"
      -      },
      -      "initialMessage": {
      -        "type": "string"
      -      },
      -      "maxIterations": {
      -        "minimum": 1,
      -        "type": "number"
      -      },
      -      "planningModel": {
      -        "type": "string"
      -      },
      -      "skipPlanning": {
      -        "type": "boolean"
      -      },
      -      "type": {
      -        "const": "LaunchAgent",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "planningModel",
      -      "executionModel",
      -      "initialMessage",
      -      "maxIterations",
      -      "includeMarketData",
      -      "continueExisting",
      -      "skipPlanning"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
      -    "properties": {
      -      "against": {
      -        "additionalProperties": true,
      -        "description": "Optional parent-position selector (e.g. for covered calls).",
      -        "type": "object"
      -      },
      -      "allocation": {
      -        "additionalProperties": true,
      -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      -        "properties": {
      -          "amount": {
      -            "type": "number"
      -          },
      -          "type": {
      -            "enum": [
      -              "dollars",
      -              "percent of portfolio",
      -              "percent of buying power",
      -              "contracts"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "amount"
      -        ],
      -        "type": "object"
      -      },
      -      "builder": {
      -        "additionalProperties": true,
      -        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
      -        "properties": {
      -          "dynamicUnderlying": {
      -            "additionalProperties": true,
      -            "properties": {
      -              "limit": {
      -                "minimum": 1,
      -                "type": "number"
      -              },
      -              "pipeline": {
      -                "items": {
      -                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      -                  "oneOf": [
      -                    {
      -                      "additionalProperties": true,
      -                      "properties": {
      -                        "condition": {
      -                          "$ref": "#/$defs/condition"
      -                        },
      -                        "type": {
      -                          "const": "Filter",
      -                          "type": "string"
      -                        }
      -                      },
      -                      "required": [
      -                        "type",
      -                        "condition"
      -                      ],
      -                      "type": "object"
      -                    },
      -                    {
      -                      "additionalProperties": true,
      -                      "properties": {
      -                        "direction": {
      -                          "enum": [
      -                            "Highest",
      -                            "Lowest"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "limit": {
      -                          "minimum": 1,
      -                          "type": "number"
      -                        },
      -                        "metric": {
      -                          "$ref": "#/$defs/indicator"
      -                        },
      -                        "type": {
      -                          "const": "SelectTop",
      -                          "type": "string"
      -                        }
      -                      },
      -                      "required": [
      -                        "type",
      -                        "metric",
      -                        "limit",
      -                        "direction"
      -                      ],
      -                      "type": "object"
      -                    },
      -                    {
      -                      "additionalProperties": true,
      -                      "properties": {
      -                        "direction": {
      -                          "enum": [
      -                            "Highest",
      -                            "Lowest"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "metric": {
      -                          "$ref": "#/$defs/indicator"
      -                        },
      -                        "percentile": {
      -                          "maximum": 100,
      -                          "minimum": 0,
      -                          "type": "number"
      -                        },
      -                        "type": {
      -                          "const": "SelectPercentile",
      -                          "type": "string"
      -                        }
      -                      },
      -                      "required": [
      -                        "type",
      -                        "metric",
      -                        "percentile",
      -                        "direction"
      -                      ],
      -                      "type": "object"
      -                    }
      -                  ],
      -                  "type": "object"
      -                },
      -                "type": "array"
      -              },
      -              "universe": {
      -                "additionalProperties": true,
      -                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      -                "properties": {
      -                  "assets": {
      -                    "items": {
      -                      "additionalProperties": true,
      -                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      -                      "properties": {
      -                        "name": {
      -                          "type": "string"
      -                        },
      -                        "symbol": {
      -                          "type": "string"
      -                        },
      -                        "type": {
      -                          "enum": [
      -                            "Stock",
      -                            "Cryptocurrency",
      -                            "Option",
      -                            "Other"
      -                          ],
      -                          "type": "string"
      -                        }
      -                      },
      -                      "required": [
      -                        "type",
      -                        "symbol"
      -                      ],
      -                      "type": "object"
      -                    },
      -                    "type": "array"
      -                  },
      -                  "source": {
      -                    "enum": [
      -                      "ALL_US_STOCKS",
      -                      "SP500",
      -                      "NASDAQ100",
      -                      "DJIA",
      -                      "CRYPTO",
      -                      "SPECIFIC_ASSETS"
      -                    ],
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "source"
      -                ],
      -                "type": "object"
      -              }
      -            },
      -            "required": [
      -              "universe"
      -            ],
      -            "type": "object"
      -          },
      -          "legs": {
      -            "items": {
      -              "additionalProperties": true,
      -              "description": "Single leg of an option builder.",
      -              "properties": {
      -                "direction": {
      -                  "enum": [
      -                    "long",
      -                    "short"
      -                  ],
      -                  "type": "string"
      -                },
      -                "expirationRange": {
      -                  "additionalProperties": true,
      -                  "type": "object"
      -                },
      -                "expirationSelector": {
      -                  "properties": {
      -                    "maxDaysToExpiration": {
      -                      "minimum": 0,
      -                      "type": "number"
      -                    },
      -                    "minDaysToExpiration": {
      -                      "minimum": 0,
      -                      "type": "number"
      -                    },
      -                    "preference": {
      -                      "enum": [
      -                        "nearest",
      -                        "middle",
      -                        "furthest"
      -                      ],
      -                      "type": "string"
      -                    }
      -                  },
      -                  "required": [
      -                    "minDaysToExpiration",
      -                    "maxDaysToExpiration",
      -                    "preference"
      -                  ],
      -                  "type": "object"
      -                },
      -                "fallbackStrikeSelector": {
      -                  "additionalProperties": false,
      -                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      -                  "properties": {
      -                    "distance": {
      -                      "type": "number"
      -                    },
      -                    "distanceType": {
      -                      "enum": [
      -                        "percent",
      -                        "dollars"
      -                      ],
      -                      "type": "string"
      -                    }
      -                  },
      -                  "required": [
      -                    "distanceType",
      -                    "distance"
      -                  ],
      -                  "type": "object"
      -                },
      -                "greekFilter": {
      -                  "additionalProperties": true,
      -                  "description": "Optional min/max constraints on Greeks during resolution.",
      -                  "type": "object"
      -                },
      -                "liquidityFilter": {
      -                  "additionalProperties": false,
      -                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      -                  "properties": {
      -                    "maxSpreadAbsolute": {
      -                      "type": "number"
      -                    },
      -                    "maxSpreadPct": {
      -                      "type": "number"
      -                    },
      -                    "minBid": {
      -                      "type": "number"
      -                    }
      -                  },
      -                  "type": "object"
      -                },
      -                "optionType": {
      -                  "enum": [
      -                    "call",
      -                    "put"
      -                  ],
      -                  "type": "string"
      -                },
      -                "ratio": {
      -                  "type": "number"
      -                },
      -                "strikeRange": {
      -                  "additionalProperties": true,
      -                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      -                  "type": "object"
      -                },
      -                "strikeSelector": {
      -                  "properties": {
      -                    "distance": {
      -                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      -                      "type": "number"
      -                    },
      -                    "distanceType": {
      -                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      -                      "type": "string"
      -                    }
      -                  },
      -                  "required": [
      -                    "distanceType",
      -                    "distance"
      -                  ],
      -                  "type": "object"
      -                }
      -              },
      -              "required": [
      -                "optionType",
      -                "direction",
      -                "expirationSelector",
      -                "strikeSelector"
      -              ],
      -              "type": "object"
      -            },
      -            "minItems": 1,
      -            "type": "array"
      -          },
      -          "spreadType": {
      -            "enum": [
      -              "vertical",
      -              "calendar",
      -              "diagonal",
      -              "ironCondor",
      -              "straddle",
      -              "strangle",
      -              "custom"
      -            ],
      -            "type": "string"
      -          },
      -          "underlyingSymbol": {
      -            "type": "string"
      -          },
      -          "widthConstraint": {
      -            "additionalProperties": false,
      -            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      -            "properties": {
      -              "minWidthDollars": {
      -                "exclusiveMinimum": 0,
      -                "type": "number"
      -              },
      -              "minWidthPercent": {
      -                "exclusiveMinimum": 0,
      -                "type": "number"
      -              }
      -            },
      -            "type": "object"
      -          }
      -        },
      -        "required": [
      -          "legs"
      -        ],
      -        "type": "object"
      -      },
      -      "type": {
      -        "const": "OpenOption",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "builder"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
      -    "properties": {
      -      "allocationPolicy": {
      -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "expectedReturnShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "riskAversion": {
      -                "maximum": 1000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MeanVariance",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "riskAversion",
      -              "expectedReturnShrinkage",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "RiskParity",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MaximumDiversification",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      },
      -      "exposurePolicy": {
      -        "additionalProperties": false,
      -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      -        "properties": {
      -          "covarianceShrinkage": {
      -            "maximum": 1,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "estimatedTransactionCostBps": {
      -            "maximum": 10000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "lookbackPeriods": {
      -            "maximum": 5000,
      -            "minimum": 2,
      -            "type": "integer"
      -          },
      -          "minimumObservations": {
      -            "maximum": 5000,
      -            "minimum": 2,
      -            "type": "integer"
      -          },
      -          "targetAnnualizedVolatilityPercent": {
      -            "maximum": 1000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "type": {
      -            "const": "VolatilityTarget",
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "lookbackPeriods",
      -          "minimumObservations",
      -          "covarianceShrinkage",
      -          "targetAnnualizedVolatilityPercent",
      -          "estimatedTransactionCostBps"
      -        ],
      -        "type": "object"
      -      },
      -      "limit": {
      -        "minimum": 1,
      -        "type": "number"
      -      },
      -      "perNameAllocation": {
      -        "additionalProperties": true,
      -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      -        "properties": {
      -          "amount": {
      -            "type": "number"
      -          },
      -          "type": {
      -            "enum": [
      -              "dollars",
      -              "percent of portfolio",
      -              "percent of buying power",
      -              "contracts"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "amount"
      -        ],
      -        "type": "object"
      -      },
      -      "pipeline": {
      -        "items": {
      -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      -          "oneOf": [
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "condition": {
      -                  "$ref": "#/$defs/condition"
      -                },
      -                "type": {
      -                  "const": "Filter",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "condition"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "direction": {
      -                  "enum": [
      -                    "Highest",
      -                    "Lowest"
      -                  ],
      -                  "type": "string"
      -                },
      -                "limit": {
      -                  "minimum": 1,
      -                  "type": "number"
      -                },
      -                "metric": {
      -                  "$ref": "#/$defs/indicator"
      -                },
      -                "type": {
      -                  "const": "SelectTop",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "metric",
      -                "limit",
      -                "direction"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "direction": {
      -                  "enum": [
      -                    "Highest",
      -                    "Lowest"
      -                  ],
      -                  "type": "string"
      -                },
      -                "metric": {
      -                  "$ref": "#/$defs/indicator"
      -                },
      -                "percentile": {
      -                  "maximum": 100,
      -                  "minimum": 0,
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "SelectPercentile",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "metric",
      -                "percentile",
      -                "direction"
      -              ],
      -              "type": "object"
      -            }
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "positionScope": {
      -        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
      -        "enum": [
      -          "portfolio",
      -          "strategy"
      -        ],
      -        "type": "string"
      -      },
      -      "sleeves": {
      -        "items": {
      -          "additionalProperties": true,
      -          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
      -          "properties": {
      -            "limit": {
      -              "minimum": 1,
      -              "type": "number"
      -            },
      -            "name": {
      -              "type": "string"
      -            },
      -            "perNameAllocation": {
      -              "additionalProperties": true,
      -              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      -              "properties": {
      -                "amount": {
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "enum": [
      -                    "dollars",
      -                    "percent of portfolio",
      -                    "percent of buying power",
      -                    "contracts"
      -                  ],
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "amount"
      -              ],
      -              "type": "object"
      -            },
      -            "pipeline": {
      -              "items": {
      -                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      -                "oneOf": [
      -                  {
      -                    "additionalProperties": true,
      -                    "properties": {
      -                      "condition": {
      -                        "$ref": "#/$defs/condition"
      -                      },
      -                      "type": {
      -                        "const": "Filter",
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "type",
      -                      "condition"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  {
      -                    "additionalProperties": true,
      -                    "properties": {
      -                      "direction": {
      -                        "enum": [
      -                          "Highest",
      -                          "Lowest"
      -                        ],
      -                        "type": "string"
      -                      },
      -                      "limit": {
      -                        "minimum": 1,
      -                        "type": "number"
      -                      },
      -                      "metric": {
      -                        "$ref": "#/$defs/indicator"
      -                      },
      -                      "type": {
      -                        "const": "SelectTop",
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "type",
      -                      "metric",
      -                      "limit",
      -                      "direction"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  {
      -                    "additionalProperties": true,
      -                    "properties": {
      -                      "direction": {
      -                        "enum": [
      -                          "Highest",
      -                          "Lowest"
      -                        ],
      -                        "type": "string"
      -                      },
      -                      "metric": {
      -                        "$ref": "#/$defs/indicator"
      -                      },
      -                      "percentile": {
      -                        "maximum": 100,
      -                        "minimum": 0,
      -                        "type": "number"
      -                      },
      -                      "type": {
      -                        "const": "SelectPercentile",
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "type",
      -                      "metric",
      -                      "percentile",
      -                      "direction"
      -                    ],
      -                    "type": "object"
      -                  }
      -                ],
      -                "type": "object"
      -              },
      -              "type": "array"
      -            },
      -            "structureTemplates": {
      -              "items": {
      -                "additionalProperties": true,
      -                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      -                "properties": {
      -                  "eligibility": {
      -                    "$ref": "#/$defs/condition"
      -                  },
      -                  "legs": {
      -                    "items": {
      -                      "additionalProperties": true,
      -                      "description": "Single leg of an option builder.",
      -                      "properties": {
      -                        "direction": {
      -                          "enum": [
      -                            "long",
      -                            "short"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "expirationRange": {
      -                          "additionalProperties": true,
      -                          "type": "object"
      -                        },
      -                        "expirationSelector": {
      -                          "properties": {
      -                            "maxDaysToExpiration": {
      -                              "minimum": 0,
      -                              "type": "number"
      -                            },
      -                            "minDaysToExpiration": {
      -                              "minimum": 0,
      -                              "type": "number"
      -                            },
      -                            "preference": {
      -                              "enum": [
      -                                "nearest",
      -                                "middle",
      -                                "furthest"
      -                              ],
      -                              "type": "string"
      -                            }
      -                          },
      -                          "required": [
      -                            "minDaysToExpiration",
      -                            "maxDaysToExpiration",
      -                            "preference"
      -                          ],
      -                          "type": "object"
      -                        },
      -                        "fallbackStrikeSelector": {
      -                          "additionalProperties": false,
      -                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      -                          "properties": {
      -                            "distance": {
      -                              "type": "number"
      -                            },
      -                            "distanceType": {
      -                              "enum": [
      -                                "percent",
      -                                "dollars"
      -                              ],
      -                              "type": "string"
      -                            }
      -                          },
      -                          "required": [
      -                            "distanceType",
      -                            "distance"
      -                          ],
      -                          "type": "object"
      -                        },
      -                        "greekFilter": {
      -                          "additionalProperties": true,
      -                          "description": "Optional min/max constraints on Greeks during resolution.",
      -                          "type": "object"
      -                        },
      -                        "liquidityFilter": {
      -                          "additionalProperties": false,
      -                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      -                          "properties": {
      -                            "maxSpreadAbsolute": {
      -                              "type": "number"
      -                            },
      -                            "maxSpreadPct": {
      -                              "type": "number"
      -                            },
      -                            "minBid": {
      -                              "type": "number"
      -                            }
      -                          },
      -                          "type": "object"
      -                        },
      -                        "optionType": {
      -                          "enum": [
      -                            "call",
      -                            "put"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "ratio": {
      -                          "type": "number"
      -                        },
      -                        "strikeRange": {
      -                          "additionalProperties": true,
      -                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      -                          "type": "object"
      -                        },
      -                        "strikeSelector": {
      -                          "properties": {
      -                            "distance": {
      -                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      -                              "type": "number"
      -                            },
      -                            "distanceType": {
      -                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      -                              "type": "string"
      -                            }
      -                          },
      -                          "required": [
      -                            "distanceType",
      -                            "distance"
      -                          ],
      -                          "type": "object"
      -                        }
      -                      },
      -                      "required": [
      -                        "optionType",
      -                        "direction",
      -                        "expirationSelector",
      -                        "strikeSelector"
      -                      ],
      -                      "type": "object"
      -                    },
      -                    "minItems": 1,
      -                    "type": "array"
      -                  },
      -                  "name": {
      -                    "type": "string"
      -                  },
      -                  "spreadType": {
      -                    "enum": [
      -                      "vertical",
      -                      "calendar",
      -                      "diagonal",
      -                      "ironCondor",
      -                      "straddle",
      -                      "strangle",
      -                      "custom"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "widthConstraint": {
      -                    "additionalProperties": false,
      -                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      -                    "properties": {
      -                      "minWidthDollars": {
      -                        "exclusiveMinimum": 0,
      -                        "type": "number"
      -                      },
      -                      "minWidthPercent": {
      -                        "exclusiveMinimum": 0,
      -                        "type": "number"
      -                      }
      -                    },
      -                    "type": "object"
      -                  }
      -                },
      -                "required": [
      -                  "legs"
      -                ],
      -                "type": "object"
      -              },
      -              "minItems": 1,
      -              "type": "array"
      -            },
      -            "universe": {
      -              "additionalProperties": true,
      -              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      -              "properties": {
      -                "assets": {
      -                  "items": {
      -                    "additionalProperties": true,
      -                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      -                    "properties": {
      -                      "name": {
      -                        "type": "string"
      -                      },
      -                      "symbol": {
      -                        "type": "string"
      -                      },
      -                      "type": {
      -                        "enum": [
      -                          "Stock",
      -                          "Cryptocurrency",
      -                          "Option",
      -                          "Other"
      -                        ],
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "type",
      -                      "symbol"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "type": "array"
      -                },
      -                "source": {
      -                  "enum": [
      -                    "ALL_US_STOCKS",
      -                    "SP500",
      -                    "NASDAQ100",
      -                    "DJIA",
      -                    "CRYPTO",
      -                    "SPECIFIC_ASSETS"
      -                  ],
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "source"
      -              ],
      -              "type": "object"
      -            },
      -            "weightIndicator": {
      -              "$ref": "#/$defs/indicator"
      -            }
      -          },
      -          "required": [
      -            "name"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "structureTemplates": {
      -        "items": {
      -          "additionalProperties": true,
      -          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      -          "properties": {
      -            "eligibility": {
      -              "$ref": "#/$defs/condition"
      -            },
      -            "legs": {
      -              "items": {
      -                "additionalProperties": true,
      -                "description": "Single leg of an option builder.",
      -                "properties": {
      -                  "direction": {
      -                    "enum": [
      -                      "long",
      -                      "short"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "expirationRange": {
      -                    "additionalProperties": true,
      -                    "type": "object"
      -                  },
      -                  "expirationSelector": {
      -                    "properties": {
      -                      "maxDaysToExpiration": {
      -                        "minimum": 0,
      -                        "type": "number"
      -                      },
      -                      "minDaysToExpiration": {
      -                        "minimum": 0,
      -                        "type": "number"
      -                      },
      -                      "preference": {
      -                        "enum": [
      -                          "nearest",
      -                          "middle",
      -                          "furthest"
      -                        ],
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "minDaysToExpiration",
      -                      "maxDaysToExpiration",
      -                      "preference"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "fallbackStrikeSelector": {
      -                    "additionalProperties": false,
      -                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      -                    "properties": {
      -                      "distance": {
      -                        "type": "number"
      -                      },
      -                      "distanceType": {
      -                        "enum": [
      -                          "percent",
      -                          "dollars"
      -                        ],
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "distanceType",
      -                      "distance"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "greekFilter": {
      -                    "additionalProperties": true,
      -                    "description": "Optional min/max constraints on Greeks during resolution.",
      -                    "type": "object"
      -                  },
      -                  "liquidityFilter": {
      -                    "additionalProperties": false,
      -                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      -                    "properties": {
      -                      "maxSpreadAbsolute": {
      -                        "type": "number"
      -                      },
      -                      "maxSpreadPct": {
      -                        "type": "number"
      -                      },
      -                      "minBid": {
      -                        "type": "number"
      -                      }
      -                    },
      -                    "type": "object"
      -                  },
      -                  "optionType": {
      -                    "enum": [
      -                      "call",
      -                      "put"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "ratio": {
      -                    "type": "number"
      -                  },
      -                  "strikeRange": {
      -                    "additionalProperties": true,
      -                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      -                    "type": "object"
      -                  },
      -                  "strikeSelector": {
      -                    "properties": {
      -                      "distance": {
      -                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      -                        "type": "number"
      -                      },
      -                      "distanceType": {
      -                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "distanceType",
      -                      "distance"
      -                    ],
      -                    "type": "object"
      -                  }
      -                },
      -                "required": [
      -                  "optionType",
      -                  "direction",
      -                  "expirationSelector",
      -                  "strikeSelector"
      -                ],
      -                "type": "object"
      -              },
      -              "minItems": 1,
      -              "type": "array"
      -            },
      -            "name": {
      -              "type": "string"
      -            },
      -            "spreadType": {
      -              "enum": [
      -                "vertical",
      -                "calendar",
      -                "diagonal",
      -                "ironCondor",
      -                "straddle",
      -                "strangle",
      -                "custom"
      -              ],
      -              "type": "string"
      -            },
      -            "widthConstraint": {
      -              "additionalProperties": false,
      -              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      -              "properties": {
      -                "minWidthDollars": {
      -                  "exclusiveMinimum": 0,
      -                  "type": "number"
      -                },
      -                "minWidthPercent": {
      -                  "exclusiveMinimum": 0,
      -                  "type": "number"
      -                }
      -              },
      -              "type": "object"
      -            }
      -          },
      -          "required": [
      -            "legs"
      -          ],
      -          "type": "object"
      -        },
      -        "minItems": 1,
      -        "type": "array"
      -      },
      -      "totalBudget": {
      -        "additionalProperties": true,
      -        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
      -        "properties": {
      -          "amount": {
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "type": {
      -            "enum": [
      -              "dollars",
      -              "percent of portfolio"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "amount"
      -        ],
      -        "type": "object"
      -      },
      -      "type": {
      -        "const": "RebalanceOption",
      -        "type": "string"
      -      },
      -      "universe": {
      -        "additionalProperties": true,
      -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      -        "properties": {
      -          "assets": {
      -            "items": {
      -              "additionalProperties": true,
      -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      -              "properties": {
      -                "name": {
      -                  "type": "string"
      -                },
      -                "symbol": {
      -                  "type": "string"
      -                },
      -                "type": {
      -                  "enum": [
      -                    "Stock",
      -                    "Cryptocurrency",
      -                    "Option",
      -                    "Other"
      -                  ],
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "symbol"
      -              ],
      -              "type": "object"
      -            },
      -            "type": "array"
      -          },
      -          "source": {
      -            "enum": [
      -              "ALL_US_STOCKS",
      -              "SP500",
      -              "NASDAQ100",
      -              "DJIA",
      -              "CRYPTO",
      -              "SPECIFIC_ASSETS"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "source"
      -        ],
      -        "type": "object"
      -      },
      -      "weightIndicator": {
      -        "$ref": "#/$defs/indicator"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "universe",
      -      "pipeline",
      -      "weightIndicator",
      -      "structureTemplates"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
      -    "properties": {
      -      "closeScope": {
      -        "enum": [
      -          "spread",
      -          "leg"
      -        ],
      -        "type": "string"
      -      },
      -      "direction": {
      -        "enum": [
      -          "long",
      -          "short"
      -        ],
      -        "type": "string"
      -      },
      -      "optionType": {
      -        "enum": [
      -          "call",
      -          "put"
      -        ],
      -        "type": "string"
      -      },
      -      "quantity": {
      -        "additionalProperties": true,
      -        "description": "How many contracts to close. Defaults to all matching when omitted.",
      -        "type": "object"
      -      },
      -      "spreadType": {
      -        "enum": [
      -          "vertical",
      -          "calendar",
      -          "diagonal",
      -          "ironCondor",
      -          "straddle",
      -          "strangle",
      -          "custom"
      -        ],
      -        "type": "string"
      -      },
      -      "triggers": {
      -        "items": {
      -          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
      -          "oneOf": [
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "maxPnlPercent": {
      -                  "type": "number"
      -                },
      -                "minPnlPercent": {
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "pnl",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "maxDte": {
      -                  "type": "number"
      -                },
      -                "minDte": {
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "dte",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "maxDaysHeld": {
      -                  "type": "number"
      -                },
      -                "minDaysHeld": {
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "daysHeld",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "maxIv": {
      -                  "type": "number"
      -                },
      -                "maxSpreadDelta": {
      -                  "type": "number"
      -                },
      -                "maxSpreadTheta": {
      -                  "type": "number"
      -                },
      -                "minIv": {
      -                  "type": "number"
      -                },
      -                "minSpreadDelta": {
      -                  "type": "number"
      -                },
      -                "minSpreadTheta": {
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "greeks",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type"
      -              ],
      -              "type": "object"
      -            }
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "type": {
      -        "const": "CloseOption",
      -        "type": "string"
      -      },
      -      "underlyings": {
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": true,
      +    "description": "Buy or Sell a stock/crypto position.",
      +    "properties": {
      +      "amount": {
      +        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
      +        "properties": {
      +          "amount": {
      +            "type": "number"
      +          },
      +          "type": {
      +            "enum": [
      +              "percent of portfolio",
      +              "percent of buying power",
      +              "percent of current positions",
      +              "dollars",
      +              "number of assets"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      "targetAsset": {
      +        "additionalProperties": true,
      +        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +        "properties": {
      +          "name": {
      +            "type": "string"
      +          },
      +          "symbol": {
      +            "type": "string"
      +          },
      +          "type": {
      +            "enum": [
      +              "Stock",
      +              "Cryptocurrency",
      +              "Option",
      +              "Other"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "symbol"
      +        ],
      +        "type": "object"
      +      },
      +      "type": {
      +        "enum": [
      +          "Buy",
      +          "Sell"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "targetAsset",
      +      "amount"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "Send an alert message (no order).",
      +    "properties": {
      +      "message": {
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "Alert",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "message"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
      +    "properties": {
      +      "allocationPolicy": {
      +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "expectedReturnShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "riskAversion": {
      +                "maximum": 1000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "MeanVariance",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "riskAversion",
      +              "expectedReturnShrinkage",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "RiskParity",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "MaximumDiversification",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      },
      +      "canSell": {
      +        "$ref": "#/$defs/condition",
      +        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
      +      },
      +      "deploymentPercent": {
      +        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "exposurePolicy": {
      +        "additionalProperties": false,
      +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      +        "properties": {
      +          "covarianceShrinkage": {
      +            "maximum": 1,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "estimatedTransactionCostBps": {
      +            "maximum": 10000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "lookbackPeriods": {
      +            "maximum": 5000,
      +            "minimum": 2,
      +            "type": "integer"
      +          },
      +          "minimumObservations": {
      +            "maximum": 5000,
      +            "minimum": 2,
      +            "type": "integer"
      +          },
      +          "targetAnnualizedVolatilityPercent": {
      +            "maximum": 1000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "type": {
      +            "const": "VolatilityTarget",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "lookbackPeriods",
      +          "minimumObservations",
      +          "covarianceShrinkage",
      +          "targetAnnualizedVolatilityPercent",
      +          "estimatedTransactionCostBps"
      +        ],
      +        "type": "object"
      +      },
      +      "limit": {
      +        "minimum": 1,
      +        "type": "number"
      +      },
      +      "perNameAllocation": {
      +        "additionalProperties": true,
      +        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.",
      +        "properties": {
      +          "amount": {
      +            "exclusiveMinimum": 0,
      +            "type": "number"
      +          },
      +          "type": {
      +            "enum": [
      +              "percent of portfolio",
      +              "dollars"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      "pipeline": {
      +        "items": {
      +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +          "oneOf": [
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "condition": {
      +                  "$ref": "#/$defs/condition"
      +                },
      +                "type": {
      +                  "const": "Filter",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "condition"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "Highest",
      +                    "Lowest"
      +                  ],
      +                  "type": "string"
      +                },
      +                "limit": {
      +                  "minimum": 1,
      +                  "type": "number"
      +                },
      +                "metric": {
      +                  "$ref": "#/$defs/indicator"
      +                },
      +                "type": {
      +                  "const": "SelectTop",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "metric",
      +                "limit",
      +                "direction"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "Highest",
      +                    "Lowest"
      +                  ],
      +                  "type": "string"
      +                },
      +                "metric": {
      +                  "$ref": "#/$defs/indicator"
      +                },
      +                "percentile": {
      +                  "maximum": 100,
      +                  "minimum": 0,
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "SelectPercentile",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "metric",
      +                "percentile",
      +                "direction"
      +              ],
      +              "type": "object"
      +            }
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "type": {
      +        "const": "DynamicRebalance",
      +        "type": "string"
      +      },
      +      "universe": {
      +        "additionalProperties": true,
      +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +        "properties": {
      +          "assets": {
      +            "items": {
      +              "additionalProperties": true,
      +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +              "properties": {
      +                "name": {
      +                  "type": "string"
      +                },
      +                "symbol": {
      +                  "type": "string"
      +                },
      +                "type": {
      +                  "enum": [
      +                    "Stock",
      +                    "Cryptocurrency",
      +                    "Option",
      +                    "Other"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "symbol"
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "source": {
      +            "enum": [
      +              "ALL_US_STOCKS",
      +              "SP500",
      +              "NASDAQ100",
      +              "DJIA",
      +              "CRYPTO",
      +              "SPECIFIC_ASSETS"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "source"
      +        ],
      +        "type": "object"
      +      },
      +      "weightIndicator": {
      +        "$ref": "#/$defs/indicator"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "universe",
      +      "pipeline",
      +      "weightIndicator"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
      +    "properties": {
      +      "continueExisting": {
      +        "type": "boolean"
      +      },
      +      "cooldownMinutes": {
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "executionModel": {
      +        "type": "string"
      +      },
      +      "includeMarketData": {
      +        "type": "boolean"
      +      },
      +      "initialMessage": {
      +        "type": "string"
      +      },
      +      "maxIterations": {
      +        "minimum": 1,
      +        "type": "number"
      +      },
      +      "planningModel": {
      +        "type": "string"
      +      },
      +      "skipPlanning": {
      +        "type": "boolean"
      +      },
      +      "type": {
      +        "const": "LaunchAgent",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "planningModel",
      +      "executionModel",
      +      "initialMessage",
      +      "maxIterations",
      +      "includeMarketData",
      +      "continueExisting",
      +      "skipPlanning"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
      +    "properties": {
      +      "against": {
      +        "additionalProperties": true,
      +        "description": "Optional parent-position selector (e.g. for covered calls).",
      +        "type": "object"
      +      },
      +      "allocation": {
      +        "additionalProperties": true,
      +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +        "properties": {
      +          "amount": {
      +            "type": "number"
      +          },
      +          "type": {
      +            "enum": [
      +              "dollars",
      +              "percent of portfolio",
      +              "percent of buying power",
      +              "contracts",
      +              "percent of realized premium"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      "builder": {
      +        "additionalProperties": true,
      +        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
      +        "properties": {
      +          "dynamicUnderlying": {
      +            "additionalProperties": true,
      +            "properties": {
      +              "limit": {
      +                "minimum": 1,
      +                "type": "number"
      +              },
      +              "pipeline": {
      +                "items": {
      +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                  "oneOf": [
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "condition": {
      +                          "$ref": "#/$defs/condition"
      +                        },
      +                        "type": {
      +                          "const": "Filter",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "condition"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "Highest",
      +                            "Lowest"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "limit": {
      +                          "minimum": 1,
      +                          "type": "number"
      +                        },
      +                        "metric": {
      +                          "$ref": "#/$defs/indicator"
      +                        },
      +                        "type": {
      +                          "const": "SelectTop",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "metric",
      +                        "limit",
      +                        "direction"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "Highest",
      +                            "Lowest"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "metric": {
      +                          "$ref": "#/$defs/indicator"
      +                        },
      +                        "percentile": {
      +                          "maximum": 100,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "SelectPercentile",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "metric",
      +                        "percentile",
      +                        "direction"
      +                      ],
      +                      "type": "object"
      +                    }
      +                  ],
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "universe": {
      +                "additionalProperties": true,
      +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +                "properties": {
      +                  "assets": {
      +                    "items": {
      +                      "additionalProperties": true,
      +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                      "properties": {
      +                        "name": {
      +                          "type": "string"
      +                        },
      +                        "symbol": {
      +                          "type": "string"
      +                        },
      +                        "type": {
      +                          "enum": [
      +                            "Stock",
      +                            "Cryptocurrency",
      +                            "Option",
      +                            "Other"
      +                          ],
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "symbol"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "type": "array"
      +                  },
      +                  "source": {
      +                    "enum": [
      +                      "ALL_US_STOCKS",
      +                      "SP500",
      +                      "NASDAQ100",
      +                      "DJIA",
      +                      "CRYPTO",
      +                      "SPECIFIC_ASSETS"
      +                    ],
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "source"
      +                ],
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "universe"
      +            ],
      +            "type": "object"
      +          },
      +          "legs": {
      +            "items": {
      +              "additionalProperties": true,
      +              "description": "Single leg of an option builder.",
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "long",
      +                    "short"
      +                  ],
      +                  "type": "string"
      +                },
      +                "expirationRange": {
      +                  "additionalProperties": true,
      +                  "type": "object"
      +                },
      +                "expirationSelector": {
      +                  "properties": {
      +                    "maxDaysToExpiration": {
      +                      "minimum": 0,
      +                      "type": "number"
      +                    },
      +                    "minDaysToExpiration": {
      +                      "minimum": 0,
      +                      "type": "number"
      +                    },
      +                    "preference": {
      +                      "enum": [
      +                        "nearest",
      +                        "middle",
      +                        "furthest"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "minDaysToExpiration",
      +                    "maxDaysToExpiration",
      +                    "preference"
      +                  ],
      +                  "type": "object"
      +                },
      +                "fallbackStrikeSelector": {
      +                  "additionalProperties": false,
      +                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                  "properties": {
      +                    "distance": {
      +                      "type": "number"
      +                    },
      +                    "distanceType": {
      +                      "enum": [
      +                        "percent",
      +                        "dollars"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "distanceType",
      +                    "distance"
      +                  ],
      +                  "type": "object"
      +                },
      +                "greekFilter": {
      +                  "additionalProperties": true,
      +                  "description": "Optional min/max constraints on Greeks during resolution.",
      +                  "type": "object"
      +                },
      +                "liquidityFilter": {
      +                  "additionalProperties": false,
      +                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                  "properties": {
      +                    "maxSpreadAbsolute": {
      +                      "type": "number"
      +                    },
      +                    "maxSpreadPct": {
      +                      "type": "number"
      +                    },
      +                    "minBid": {
      +                      "type": "number"
      +                    }
      +                  },
      +                  "type": "object"
      +                },
      +                "optionType": {
      +                  "enum": [
      +                    "call",
      +                    "put"
      +                  ],
      +                  "type": "string"
      +                },
      +                "ratio": {
      +                  "type": "number"
      +                },
      +                "strikeRange": {
      +                  "additionalProperties": true,
      +                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                  "type": "object"
      +                },
      +                "strikeSelector": {
      +                  "properties": {
      +                    "distance": {
      +                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                      "type": "number"
      +                    },
      +                    "distanceType": {
      +                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "distanceType",
      +                    "distance"
      +                  ],
      +                  "type": "object"
      +                }
      +              },
      +              "required": [
      +                "optionType",
      +                "direction",
      +                "expirationSelector",
      +                "strikeSelector"
      +              ],
      +              "type": "object"
      +            },
      +            "minItems": 1,
      +            "type": "array"
      +          },
      +          "spreadType": {
      +            "enum": [
      +              "vertical",
      +              "calendar",
      +              "diagonal",
      +              "ironCondor",
      +              "straddle",
      +              "strangle",
      +              "custom"
      +            ],
      +            "type": "string"
      +          },
      +          "underlyingSymbol": {
      +            "type": "string"
      +          },
      +          "widthConstraint": {
      +            "additionalProperties": false,
      +            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +            "properties": {
      +              "minWidthDollars": {
      +                "exclusiveMinimum": 0,
      +                "type": "number"
      +              },
      +              "minWidthPercent": {
      +                "exclusiveMinimum": 0,
      +                "type": "number"
      +              }
      +            },
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "legs"
      +        ],
      +        "type": "object"
      +      },
      +      "type": {
      +        "const": "OpenOption",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "builder"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
      +    "properties": {
      +      "allocationPolicy": {
      +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "expectedReturnShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "riskAversion": {
      +                "maximum": 1000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "MeanVariance",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "riskAversion",
      +              "expectedReturnShrinkage",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "RiskParity",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "MaximumDiversification",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      },
      +      "exposurePolicy": {
      +        "additionalProperties": false,
      +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      +        "properties": {
      +          "covarianceShrinkage": {
      +            "maximum": 1,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "estimatedTransactionCostBps": {
      +            "maximum": 10000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "lookbackPeriods": {
      +            "maximum": 5000,
      +            "minimum": 2,
      +            "type": "integer"
      +          },
      +          "minimumObservations": {
      +            "maximum": 5000,
      +            "minimum": 2,
      +            "type": "integer"
      +          },
      +          "targetAnnualizedVolatilityPercent": {
      +            "maximum": 1000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "type": {
      +            "const": "VolatilityTarget",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "lookbackPeriods",
      +          "minimumObservations",
      +          "covarianceShrinkage",
      +          "targetAnnualizedVolatilityPercent",
      +          "estimatedTransactionCostBps"
      +        ],
      +        "type": "object"
      +      },
      +      "limit": {
      +        "minimum": 1,
      +        "type": "number"
      +      },
      +      "perNameAllocation": {
      +        "additionalProperties": true,
      +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +        "properties": {
      +          "amount": {
      +            "type": "number"
      +          },
      +          "type": {
      +            "enum": [
      +              "dollars",
      +              "percent of portfolio",
      +              "percent of buying power",
      +              "contracts",
      +              "percent of realized premium"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      "pipeline": {
      +        "items": {
      +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +          "oneOf": [
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "condition": {
      +                  "$ref": "#/$defs/condition"
      +                },
      +                "type": {
      +                  "const": "Filter",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "condition"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "Highest",
      +                    "Lowest"
      +                  ],
      +                  "type": "string"
      +                },
      +                "limit": {
      +                  "minimum": 1,
      +                  "type": "number"
      +                },
      +                "metric": {
      +                  "$ref": "#/$defs/indicator"
      +                },
      +                "type": {
      +                  "const": "SelectTop",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "metric",
      +                "limit",
      +                "direction"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "Highest",
      +                    "Lowest"
      +                  ],
      +                  "type": "string"
      +                },
      +                "metric": {
      +                  "$ref": "#/$defs/indicator"
      +                },
      +                "percentile": {
      +                  "maximum": 100,
      +                  "minimum": 0,
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "SelectPercentile",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "metric",
      +                "percentile",
      +                "direction"
      +              ],
      +              "type": "object"
      +            }
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "positionScope": {
      +        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
      +        "enum": [
      +          "portfolio",
      +          "strategy"
      +        ],
      +        "type": "string"
      +      },
      +      "sleeves": {
      +        "items": {
      +          "additionalProperties": true,
      +          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
      +          "properties": {
      +            "limit": {
      +              "minimum": 1,
      +              "type": "number"
      +            },
      +            "name": {
      +              "type": "string"
      +            },
      +            "perNameAllocation": {
      +              "additionalProperties": true,
      +              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +              "properties": {
      +                "amount": {
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "enum": [
      +                    "dollars",
      +                    "percent of portfolio",
      +                    "percent of buying power",
      +                    "contracts",
      +                    "percent of realized premium"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "amount"
      +              ],
      +              "type": "object"
      +            },
      +            "pipeline": {
      +              "items": {
      +                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                "oneOf": [
      +                  {
      +                    "additionalProperties": true,
      +                    "properties": {
      +                      "condition": {
      +                        "$ref": "#/$defs/condition"
      +                      },
      +                      "type": {
      +                        "const": "Filter",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "condition"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": true,
      +                    "properties": {
      +                      "direction": {
      +                        "enum": [
      +                          "Highest",
      +                          "Lowest"
      +                        ],
      +                        "type": "string"
      +                      },
      +                      "limit": {
      +                        "minimum": 1,
      +                        "type": "number"
      +                      },
      +                      "metric": {
      +                        "$ref": "#/$defs/indicator"
      +                      },
      +                      "type": {
      +                        "const": "SelectTop",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "metric",
      +                      "limit",
      +                      "direction"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": true,
      +                    "properties": {
      +                      "direction": {
      +                        "enum": [
      +                          "Highest",
      +                          "Lowest"
      +                        ],
      +                        "type": "string"
      +                      },
      +                      "metric": {
      +                        "$ref": "#/$defs/indicator"
      +                      },
      +                      "percentile": {
      +                        "maximum": 100,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "SelectPercentile",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "metric",
      +                      "percentile",
      +                      "direction"
      +                    ],
      +                    "type": "object"
      +                  }
      +                ],
      +                "type": "object"
      +              },
      +              "type": "array"
      +            },
      +            "structureTemplates": {
      +              "items": {
      +                "additionalProperties": true,
      +                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      +                "properties": {
      +                  "eligibility": {
      +                    "$ref": "#/$defs/condition"
      +                  },
      +                  "legs": {
      +                    "items": {
      +                      "additionalProperties": true,
      +                      "description": "Single leg of an option builder.",
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "long",
      +                            "short"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "expirationRange": {
      +                          "additionalProperties": true,
      +                          "type": "object"
      +                        },
      +                        "expirationSelector": {
      +                          "properties": {
      +                            "maxDaysToExpiration": {
      +                              "minimum": 0,
      +                              "type": "number"
      +                            },
      +                            "minDaysToExpiration": {
      +                              "minimum": 0,
      +                              "type": "number"
      +                            },
      +                            "preference": {
      +                              "enum": [
      +                                "nearest",
      +                                "middle",
      +                                "furthest"
      +                              ],
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "minDaysToExpiration",
      +                            "maxDaysToExpiration",
      +                            "preference"
      +                          ],
      +                          "type": "object"
      +                        },
      +                        "fallbackStrikeSelector": {
      +                          "additionalProperties": false,
      +                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                          "properties": {
      +                            "distance": {
      +                              "type": "number"
      +                            },
      +                            "distanceType": {
      +                              "enum": [
      +                                "percent",
      +                                "dollars"
      +                              ],
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "distanceType",
      +                            "distance"
      +                          ],
      +                          "type": "object"
      +                        },
      +                        "greekFilter": {
      +                          "additionalProperties": true,
      +                          "description": "Optional min/max constraints on Greeks during resolution.",
      +                          "type": "object"
      +                        },
      +                        "liquidityFilter": {
      +                          "additionalProperties": false,
      +                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                          "properties": {
      +                            "maxSpreadAbsolute": {
      +                              "type": "number"
      +                            },
      +                            "maxSpreadPct": {
      +                              "type": "number"
      +                            },
      +                            "minBid": {
      +                              "type": "number"
      +                            }
      +                          },
      +                          "type": "object"
      +                        },
      +                        "optionType": {
      +                          "enum": [
      +                            "call",
      +                            "put"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "ratio": {
      +                          "type": "number"
      +                        },
      +                        "strikeRange": {
      +                          "additionalProperties": true,
      +                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                          "type": "object"
      +                        },
      +                        "strikeSelector": {
      +                          "properties": {
      +                            "distance": {
      +                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                              "type": "number"
      +                            },
      +                            "distanceType": {
      +                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "distanceType",
      +                            "distance"
      +                          ],
      +                          "type": "object"
      +                        }
      +                      },
      +                      "required": [
      +                        "optionType",
      +                        "direction",
      +                        "expirationSelector",
      +                        "strikeSelector"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "minItems": 1,
      +                    "type": "array"
      +                  },
      +                  "name": {
      +                    "type": "string"
      +                  },
      +                  "spreadType": {
      +                    "enum": [
      +                      "vertical",
      +                      "calendar",
      +                      "diagonal",
      +                      "ironCondor",
      +                      "straddle",
      +                      "strangle",
      +                      "custom"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "widthConstraint": {
      +                    "additionalProperties": false,
      +                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +                    "properties": {
      +                      "minWidthDollars": {
      +                        "exclusiveMinimum": 0,
      +                        "type": "number"
      +                      },
      +                      "minWidthPercent": {
      +                        "exclusiveMinimum": 0,
      +                        "type": "number"
      +                      }
      +                    },
      +                    "type": "object"
      +                  }
      +                },
      +                "required": [
      +                  "legs"
      +                ],
      +                "type": "object"
      +              },
      +              "minItems": 1,
      +              "type": "array"
      +            },
      +            "universe": {
      +              "additionalProperties": true,
      +              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +              "properties": {
      +                "assets": {
      +                  "items": {
      +                    "additionalProperties": true,
      +                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                    "properties": {
      +                      "name": {
      +                        "type": "string"
      +                      },
      +                      "symbol": {
      +                        "type": "string"
      +                      },
      +                      "type": {
      +                        "enum": [
      +                          "Stock",
      +                          "Cryptocurrency",
      +                          "Option",
      +                          "Other"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "symbol"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "type": "array"
      +                },
      +                "source": {
      +                  "enum": [
      +                    "ALL_US_STOCKS",
      +                    "SP500",
      +                    "NASDAQ100",
      +                    "DJIA",
      +                    "CRYPTO",
      +                    "SPECIFIC_ASSETS"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "source"
      +              ],
      +              "type": "object"
      +            },
      +            "weightIndicator": {
      +              "$ref": "#/$defs/indicator"
      +            }
      +          },
      +          "required": [
      +            "name"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "structureTemplates": {
      +        "items": {
      +          "additionalProperties": true,
      +          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      +          "properties": {
      +            "eligibility": {
      +              "$ref": "#/$defs/condition"
      +            },
      +            "legs": {
      +              "items": {
      +                "additionalProperties": true,
      +                "description": "Single leg of an option builder.",
      +                "properties": {
      +                  "direction": {
      +                    "enum": [
      +                      "long",
      +                      "short"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "expirationRange": {
      +                    "additionalProperties": true,
      +                    "type": "object"
      +                  },
      +                  "expirationSelector": {
      +                    "properties": {
      +                      "maxDaysToExpiration": {
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "minDaysToExpiration": {
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "preference": {
      +                        "enum": [
      +                          "nearest",
      +                          "middle",
      +                          "furthest"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "minDaysToExpiration",
      +                      "maxDaysToExpiration",
      +                      "preference"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "fallbackStrikeSelector": {
      +                    "additionalProperties": false,
      +                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                    "properties": {
      +                      "distance": {
      +                        "type": "number"
      +                      },
      +                      "distanceType": {
      +                        "enum": [
      +                          "percent",
      +                          "dollars"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "distanceType",
      +                      "distance"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "greekFilter": {
      +                    "additionalProperties": true,
      +                    "description": "Optional min/max constraints on Greeks during resolution.",
      +                    "type": "object"
      +                  },
      +                  "liquidityFilter": {
      +                    "additionalProperties": false,
      +                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                    "properties": {
      +                      "maxSpreadAbsolute": {
      +                        "type": "number"
      +                      },
      +                      "maxSpreadPct": {
      +                        "type": "number"
      +                      },
      +                      "minBid": {
      +                        "type": "number"
      +                      }
      +                    },
      +                    "type": "object"
      +                  },
      +                  "optionType": {
      +                    "enum": [
      +                      "call",
      +                      "put"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "ratio": {
      +                    "type": "number"
      +                  },
      +                  "strikeRange": {
      +                    "additionalProperties": true,
      +                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                    "type": "object"
      +                  },
      +                  "strikeSelector": {
      +                    "properties": {
      +                      "distance": {
      +                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                        "type": "number"
      +                      },
      +                      "distanceType": {
      +                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "distanceType",
      +                      "distance"
      +                    ],
      +                    "type": "object"
      +                  }
      +                },
      +                "required": [
      +                  "optionType",
      +                  "direction",
      +                  "expirationSelector",
      +                  "strikeSelector"
      +                ],
      +                "type": "object"
      +              },
      +              "minItems": 1,
      +              "type": "array"
      +            },
      +            "name": {
      +              "type": "string"
      +            },
      +            "spreadType": {
      +              "enum": [
      +                "vertical",
      +                "calendar",
      +                "diagonal",
      +                "ironCondor",
      +                "straddle",
      +                "strangle",
      +                "custom"
      +              ],
      +              "type": "string"
      +            },
      +            "widthConstraint": {
      +              "additionalProperties": false,
      +              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +              "properties": {
      +                "minWidthDollars": {
      +                  "exclusiveMinimum": 0,
      +                  "type": "number"
      +                },
      +                "minWidthPercent": {
      +                  "exclusiveMinimum": 0,
      +                  "type": "number"
      +                }
      +              },
      +              "type": "object"
      +            }
      +          },
      +          "required": [
      +            "legs"
      +          ],
      +          "type": "object"
      +        },
      +        "minItems": 1,
      +        "type": "array"
      +      },
      +      "totalBudget": {
      +        "additionalProperties": true,
      +        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
      +        "properties": {
      +          "amount": {
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "type": {
      +            "enum": [
      +              "dollars",
      +              "percent of portfolio"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      "type": {
      +        "const": "RebalanceOption",
      +        "type": "string"
      +      },
      +      "universe": {
      +        "additionalProperties": true,
      +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +        "properties": {
      +          "assets": {
      +            "items": {
      +              "additionalProperties": true,
      +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +              "properties": {
      +                "name": {
      +                  "type": "string"
      +                },
      +                "symbol": {
      +                  "type": "string"
      +                },
      +                "type": {
      +                  "enum": [
      +                    "Stock",
      +                    "Cryptocurrency",
      +                    "Option",
      +                    "Other"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "symbol"
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "source": {
      +            "enum": [
      +              "ALL_US_STOCKS",
      +              "SP500",
      +              "NASDAQ100",
      +              "DJIA",
      +              "CRYPTO",
      +              "SPECIFIC_ASSETS"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "source"
      +        ],
      +        "type": "object"
      +      },
      +      "weightIndicator": {
      +        "$ref": "#/$defs/indicator"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "universe",
      +      "pipeline",
      +      "weightIndicator",
      +      "structureTemplates"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
      +    "properties": {
      +      "closeScope": {
      +        "enum": [
      +          "spread",
      +          "leg"
      +        ],
      +        "type": "string"
      +      },
      +      "direction": {
      +        "enum": [
      +          "long",
      +          "short"
      +        ],
      +        "type": "string"
      +      },
      +      "optionType": {
      +        "enum": [
      +          "call",
      +          "put"
      +        ],
      +        "type": "string"
      +      },
      +      "quantity": {
      +        "additionalProperties": true,
      +        "description": "How many contracts to close. Defaults to all matching when omitted.",
      +        "type": "object"
      +      },
      +      "spreadType": {
      +        "enum": [
      +          "vertical",
      +          "calendar",
      +          "diagonal",
      +          "ironCondor",
      +          "straddle",
      +          "strangle",
      +          "custom"
      +        ],
      +        "type": "string"
      +      },
      +      "triggers": {
      +        "items": {
      +          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
      +          "oneOf": [
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "maxPnlPercent": {
      +                  "type": "number"
      +                },
      +                "minPnlPercent": {
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "pnl",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "maxDte": {
      +                  "type": "number"
      +                },
      +                "minDte": {
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "dte",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "maxDaysHeld": {
      +                  "type": "number"
      +                },
      +                "minDaysHeld": {
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "daysHeld",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "maxIv": {
      +                  "type": "number"
      +                },
      +                "maxSpreadDelta": {
      +                  "type": "number"
      +                },
      +                "maxSpreadTheta": {
      +                  "type": "number"
      +                },
      +                "minIv": {
      +                  "type": "number"
      +                },
      +                "minSpreadDelta": {
      +                  "type": "number"
      +                },
      +                "minSpreadTheta": {
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "greeks",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type"
      +              ],
      +              "type": "object"
      +            }
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "type": {
      +        "const": "CloseOption",
      +        "type": "string"
      +      },
      +      "underlyings": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  }
      +]
    • changedInput schema / $defs / indicator / description
      Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), Option* indicators (need underlying + optionType + direction + spreadType), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
    • addedInput schema / $defs / indicator / properties / lookbackDays
      Added value: +{
      +  "description": "OptionRealizedPnL / OptionRealizedPremium: only count activity within this many days of the evaluation date. Omit for the whole life of the book.",
      +  "maximum": 36500,
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • changedInput schema / $defs / indicator / properties / type / enum
      Previous value: -[
      -  "DaysSinceAgent",
      -  "MinutesSinceAgent",
      -  "DaysSinceAlert",
      -  "MinutesSinceAlert",
      -  "StockReport",
      -  "DaysUntilEarnings",
      -  "DaysSinceEarnings",
      -  "ImpliedVolatility",
      -  "IVRank",
      -  "IVPercentile",
      -  "IVHVRatio",
      -  "LastOrderPrice",
      -  "Fundamental",
      -  "Economic",
      -  "CustomIndicator",
      -  "Index",
      -  "BollingerBand",
      -  "RelativeStrengthIndex",
      -  "PriceMeanAbsoluteDeviation",
      -  "ExponentialMovingAverage",
      -  "SimpleMovingAverage",
      -  "PriceStandardDeviation",
      -  "PriceRateOfChange",
      -  "MaxDrawdown",
      -  "MaxDrawup",
      -  "MinimumPrice",
      -  "MaximumPrice",
      -  "IndicatorMeanAbsoluteDeviation",
      -  "IndicatorExponentialMovingAverage",
      -  "IndicatorSimpleMovingAverage",
      -  "IndicatorStandardDeviation",
      -  "IndicatorRateOfChange",
      -  "DaysSinceOrder",
      -  "DaysSinceOptionOrder",
      -  "DaysSinceStrategyFired",
      -  "DaysSinceLastRebalanceOptionOrder",
      -  "MinutesSinceOptionOrder",
      -  "MinutesSinceOrder",
      -  "DaysSinceTransaction",
      -  "InitialValue",
      -  "BuyingPower",
      -  "PositionValue",
      -  "PositionPercentChange",
      -  "PortfolioValue",
      -  "RebalanceDecisionMetric",
      -  "Value",
      -  "Price",
      -  "Plus",
      -  "Minus",
      -  "Multiply",
      -  "Divide",
      -  "Negative",
      -  "AbsoluteValue",
      -  "SquareRoot",
      -  "Max",
      -  "Min",
      -  "Day",
      -  "Month",
      -  "Date",
      -  "Year",
      -  "CurrentTimeSeconds",
      -  "CurrentTimeMinutes",
      -  "CurrentTimeHours",
      -  "TrailingSum",
      -  "CompoundAnnualGrowthRate",
      -  "Log",
      -  "Exponentiation",
      -  "SumOrderQuantity",
      -  "SumOrderAmount",
      -  "MinutesAfterOpen",
      -  "OpeningPrice",
      -  "PreviousClosingPrice",
      -  "HighOfDay",
      -  "LowOfDay",
      -  "MinutesUntilClose",
      -  "PriceChangeSinceOpen",
      -  "GapSize",
      -  "GapPercentage",
      -  "TrueRange",
      -  "AverageTrueRange",
      -  "Volume",
      -  "VWAP",
      -  "BullishFairValueGap",
      -  "BearishFairValueGap",
      -  "IndicatorAtMinutesAfterOpen",
      -  "IndicatorWindowAgo",
      -  "IndicatorAtEntry",
      -  "IsIndexMember",
      -  "IsIndustry",
      -  "IsAssetType",
      -  "IsAsset",
      -  "IsNotAsset",
      -  "CrossAbove",
      -  "CrossBelow",
      -  "PositionMaxDrawdown",
      -  "PositionMaxDrawup",
      -  "UnderlyingMaxDrawdown",
      -  "ConsecutiveTrue",
      -  "CountTrue",
      -  "OptionPositionValue",
      -  "OptionPositionCount",
      -  "OptionPositionPercentChange",
      -  "OptionPositionMaxDrawdown",
      -  "OptionDaysToExpiration",
      -  "OptionDaysHeld",
      -  "OptionCollateral",
      -  "OptionSpreadCount",
      -  "OptionUnrealizedPnL",
      -  "OptionGrossExposurePercent"
      -]New value: +[
      +  "DaysSinceAgent",
      +  "MinutesSinceAgent",
      +  "DaysSinceAlert",
      +  "MinutesSinceAlert",
      +  "StockReport",
      +  "DaysUntilEarnings",
      +  "DaysSinceEarnings",
      +  "ImpliedVolatility",
      +  "IVRank",
      +  "IVPercentile",
      +  "IVHVRatio",
      +  "LastOrderPrice",
      +  "Fundamental",
      +  "Economic",
      +  "CustomIndicator",
      +  "Index",
      +  "BollingerBand",
      +  "RelativeStrengthIndex",
      +  "PriceMeanAbsoluteDeviation",
      +  "ExponentialMovingAverage",
      +  "SimpleMovingAverage",
      +  "PriceStandardDeviation",
      +  "PriceRateOfChange",
      +  "MaxDrawdown",
      +  "MaxDrawup",
      +  "MinimumPrice",
      +  "MaximumPrice",
      +  "IndicatorMeanAbsoluteDeviation",
      +  "IndicatorExponentialMovingAverage",
      +  "IndicatorSimpleMovingAverage",
      +  "IndicatorStandardDeviation",
      +  "IndicatorRateOfChange",
      +  "DaysSinceOrder",
      +  "DaysSinceOptionOrder",
      +  "DaysSinceStrategyFired",
      +  "DaysSinceLastRebalanceOptionOrder",
      +  "MinutesSinceOptionOrder",
      +  "MinutesSinceOrder",
      +  "DaysSinceTransaction",
      +  "InitialValue",
      +  "BuyingPower",
      +  "PositionValue",
      +  "PositionPercentChange",
      +  "PortfolioValue",
      +  "RebalanceDecisionMetric",
      +  "Value",
      +  "Price",
      +  "Plus",
      +  "Minus",
      +  "Multiply",
      +  "Divide",
      +  "Negative",
      +  "AbsoluteValue",
      +  "SquareRoot",
      +  "Max",
      +  "Min",
      +  "Day",
      +  "Month",
      +  "Date",
      +  "Year",
      +  "CurrentTimeSeconds",
      +  "CurrentTimeMinutes",
      +  "CurrentTimeHours",
      +  "TrailingSum",
      +  "CompoundAnnualGrowthRate",
      +  "Log",
      +  "Exponentiation",
      +  "SumOrderQuantity",
      +  "SumOrderAmount",
      +  "MinutesAfterOpen",
      +  "OpeningPrice",
      +  "PreviousClosingPrice",
      +  "HighOfDay",
      +  "LowOfDay",
      +  "MinutesUntilClose",
      +  "PriceChangeSinceOpen",
      +  "GapSize",
      +  "GapPercentage",
      +  "TrueRange",
      +  "AverageTrueRange",
      +  "Volume",
      +  "VWAP",
      +  "BullishFairValueGap",
      +  "BearishFairValueGap",
      +  "IndicatorAtMinutesAfterOpen",
      +  "IndicatorWindowAgo",
      +  "IndicatorAtEntry",
      +  "IsIndexMember",
      +  "IsIndustry",
      +  "IsAssetType",
      +  "IsAsset",
      +  "IsNotAsset",
      +  "CrossAbove",
      +  "CrossBelow",
      +  "PositionMaxDrawdown",
      +  "PositionMaxDrawup",
      +  "UnderlyingMaxDrawdown",
      +  "ConsecutiveTrue",
      +  "CountTrue",
      +  "OptionPositionValue",
      +  "OptionPositionCount",
      +  "OptionPositionPercentChange",
      +  "OptionPositionMaxDrawdown",
      +  "OptionDaysToExpiration",
      +  "OptionDaysHeld",
      +  "OptionCollateral",
      +  "OptionSpreadCount",
      +  "OptionUnrealizedPnL",
      +  "OptionRealizedPnL",
      +  "OptionRealizedPremium",
      +  "OptionGrossExposurePercent"
      +]
    • changedInput schema / $defs / rebalanceOptionSleeve / properties / perNameAllocation / description
      Previous value: -"Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'."New value: +"Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'."
    • changedInput schema / $defs / rebalanceOptionSleeve / properties / perNameAllocation / properties / type / enum
      Previous value: -[
      -  "dollars",
      -  "percent of portfolio",
      -  "percent of buying power",
      -  "contracts"
      -]New value: +[
      +  "dollars",
      +  "percent of portfolio",
      +  "percent of buying power",
      +  "contracts",
      +  "percent of realized premium"
      +]
    • changedInput schema / $defs / strategy / properties / action / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": true,
      -    "description": "Buy or Sell a stock/crypto position.",
      -    "properties": {
      -      "amount": {
      -        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
      -        "properties": {
      -          "amount": {
      -            "type": "number"
      -          },
      -          "type": {
      -            "enum": [
      -              "percent of portfolio",
      -              "percent of buying power",
      -              "percent of current positions",
      -              "dollars",
      -              "number of assets"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "amount"
      -        ],
      -        "type": "object"
      -      },
      -      "targetAsset": {
      -        "additionalProperties": true,
      -        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      -        "properties": {
      -          "name": {
      -            "type": "string"
      -          },
      -          "symbol": {
      -            "type": "string"
      -          },
      -          "type": {
      -            "enum": [
      -              "Stock",
      -              "Cryptocurrency",
      -              "Option",
      -              "Other"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "symbol"
      -        ],
      -        "type": "object"
      -      },
      -      "type": {
      -        "enum": [
      -          "Buy",
      -          "Sell"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "targetAsset",
      -      "amount"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "Send an alert message (no order).",
      -    "properties": {
      -      "message": {
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "Alert",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "message"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
      -    "properties": {
      -      "allocationPolicy": {
      -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "expectedReturnShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "riskAversion": {
      -                "maximum": 1000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MeanVariance",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "riskAversion",
      -              "expectedReturnShrinkage",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "RiskParity",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MaximumDiversification",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      },
      -      "canSell": {
      -        "$ref": "#/$defs/condition",
      -        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
      -      },
      -      "deploymentPercent": {
      -        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "exposurePolicy": {
      -        "additionalProperties": false,
      -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      -        "properties": {
      -          "covarianceShrinkage": {
      -            "maximum": 1,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "estimatedTransactionCostBps": {
      -            "maximum": 10000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "lookbackPeriods": {
      -            "maximum": 5000,
      -            "minimum": 2,
      -            "type": "integer"
      -          },
      -          "minimumObservations": {
      -            "maximum": 5000,
      -            "minimum": 2,
      -            "type": "integer"
      -          },
      -          "targetAnnualizedVolatilityPercent": {
      -            "maximum": 1000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "type": {
      -            "const": "VolatilityTarget",
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "lookbackPeriods",
      -          "minimumObservations",
      -          "covarianceShrinkage",
      -          "targetAnnualizedVolatilityPercent",
      -          "estimatedTransactionCostBps"
      -        ],
      -        "type": "object"
      -      },
      -      "limit": {
      -        "minimum": 1,
      -        "type": "number"
      -      },
      -      "perNameAllocation": {
      -        "additionalProperties": true,
      -        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
      -        "properties": {
      -          "amount": {
      -            "exclusiveMinimum": 0,
      -            "type": "number"
      -          },
      -          "type": {
      -            "enum": [
      -              "percent of portfolio",
      -              "dollars"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "amount"
      -        ],
      -        "type": "object"
      -      },
      -      "pipeline": {
      -        "items": {
      -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      -          "oneOf": [
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "condition": {
      -                  "$ref": "#/$defs/condition"
      -                },
      -                "type": {
      -                  "const": "Filter",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "condition"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "direction": {
      -                  "enum": [
      -                    "Highest",
      -                    "Lowest"
      -                  ],
      -                  "type": "string"
      -                },
      -                "limit": {
      -                  "minimum": 1,
      -                  "type": "number"
      -                },
      -                "metric": {
      -                  "$ref": "#/$defs/indicator"
      -                },
      -                "type": {
      -                  "const": "SelectTop",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "metric",
      -                "limit",
      -                "direction"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "direction": {
      -                  "enum": [
      -                    "Highest",
      -                    "Lowest"
      -                  ],
      -                  "type": "string"
      -                },
      -                "metric": {
      -                  "$ref": "#/$defs/indicator"
      -                },
      -                "percentile": {
      -                  "maximum": 100,
      -                  "minimum": 0,
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "SelectPercentile",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "metric",
      -                "percentile",
      -                "direction"
      -              ],
      -              "type": "object"
      -            }
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "type": {
      -        "const": "DynamicRebalance",
      -        "type": "string"
      -      },
      -      "universe": {
      -        "additionalProperties": true,
      -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      -        "properties": {
      -          "assets": {
      -            "items": {
      -              "additionalProperties": true,
      -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      -              "properties": {
      -                "name": {
      -                  "type": "string"
      -                },
      -                "symbol": {
      -                  "type": "string"
      -                },
      -                "type": {
      -                  "enum": [
      -                    "Stock",
      -                    "Cryptocurrency",
      -                    "Option",
      -                    "Other"
      -                  ],
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "symbol"
      -              ],
      -              "type": "object"
      -            },
      -            "type": "array"
      -          },
      -          "source": {
      -            "enum": [
      -              "ALL_US_STOCKS",
      -              "SP500",
      -              "NASDAQ100",
      -              "DJIA",
      -              "CRYPTO",
      -              "SPECIFIC_ASSETS"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "source"
      -        ],
      -        "type": "object"
      -      },
      -      "weightIndicator": {
      -        "$ref": "#/$defs/indicator"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "universe",
      -      "pipeline",
      -      "weightIndicator"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
      -    "properties": {
      -      "continueExisting": {
      -        "type": "boolean"
      -      },
      -      "cooldownMinutes": {
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "executionModel": {
      -        "type": "string"
      -      },
      -      "includeMarketData": {
      -        "type": "boolean"
      -      },
      -      "initialMessage": {
      -        "type": "string"
      -      },
      -      "maxIterations": {
      -        "minimum": 1,
      -        "type": "number"
      -      },
      -      "planningModel": {
      -        "type": "string"
      -      },
      -      "skipPlanning": {
      -        "type": "boolean"
      -      },
      -      "type": {
      -        "const": "LaunchAgent",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "planningModel",
      -      "executionModel",
      -      "initialMessage",
      -      "maxIterations",
      -      "includeMarketData",
      -      "continueExisting",
      -      "skipPlanning"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
      -    "properties": {
      -      "against": {
      -        "additionalProperties": true,
      -        "description": "Optional parent-position selector (e.g. for covered calls).",
      -        "type": "object"
      -      },
      -      "allocation": {
      -        "additionalProperties": true,
      -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      -        "properties": {
      -          "amount": {
      -            "type": "number"
      -          },
      -          "type": {
      -            "enum": [
      -              "dollars",
      -              "percent of portfolio",
      -              "percent of buying power",
      -              "contracts"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "amount"
      -        ],
      -        "type": "object"
      -      },
      -      "builder": {
      -        "additionalProperties": true,
      -        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
      -        "properties": {
      -          "dynamicUnderlying": {
      -            "additionalProperties": true,
      -            "properties": {
      -              "limit": {
      -                "minimum": 1,
      -                "type": "number"
      -              },
      -              "pipeline": {
      -                "items": {
      -                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      -                  "oneOf": [
      -                    {
      -                      "additionalProperties": true,
      -                      "properties": {
      -                        "condition": {
      -                          "$ref": "#/$defs/condition"
      -                        },
      -                        "type": {
      -                          "const": "Filter",
      -                          "type": "string"
      -                        }
      -                      },
      -                      "required": [
      -                        "type",
      -                        "condition"
      -                      ],
      -                      "type": "object"
      -                    },
      -                    {
      -                      "additionalProperties": true,
      -                      "properties": {
      -                        "direction": {
      -                          "enum": [
      -                            "Highest",
      -                            "Lowest"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "limit": {
      -                          "minimum": 1,
      -                          "type": "number"
      -                        },
      -                        "metric": {
      -                          "$ref": "#/$defs/indicator"
      -                        },
      -                        "type": {
      -                          "const": "SelectTop",
      -                          "type": "string"
      -                        }
      -                      },
      -                      "required": [
      -                        "type",
      -                        "metric",
      -                        "limit",
      -                        "direction"
      -                      ],
      -                      "type": "object"
      -                    },
      -                    {
      -                      "additionalProperties": true,
      -                      "properties": {
      -                        "direction": {
      -                          "enum": [
      -                            "Highest",
      -                            "Lowest"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "metric": {
      -                          "$ref": "#/$defs/indicator"
      -                        },
      -                        "percentile": {
      -                          "maximum": 100,
      -                          "minimum": 0,
      -                          "type": "number"
      -                        },
      -                        "type": {
      -                          "const": "SelectPercentile",
      -                          "type": "string"
      -                        }
      -                      },
      -                      "required": [
      -                        "type",
      -                        "metric",
      -                        "percentile",
      -                        "direction"
      -                      ],
      -                      "type": "object"
      -                    }
      -                  ],
      -                  "type": "object"
      -                },
      -                "type": "array"
      -              },
      -              "universe": {
      -                "additionalProperties": true,
      -                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      -                "properties": {
      -                  "assets": {
      -                    "items": {
      -                      "additionalProperties": true,
      -                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      -                      "properties": {
      -                        "name": {
      -                          "type": "string"
      -                        },
      -                        "symbol": {
      -                          "type": "string"
      -                        },
      -                        "type": {
      -                          "enum": [
      -                            "Stock",
      -                            "Cryptocurrency",
      -                            "Option",
      -                            "Other"
      -                          ],
      -                          "type": "string"
      -                        }
      -                      },
      -                      "required": [
      -                        "type",
      -                        "symbol"
      -                      ],
      -                      "type": "object"
      -                    },
      -                    "type": "array"
      -                  },
      -                  "source": {
      -                    "enum": [
      -                      "ALL_US_STOCKS",
      -                      "SP500",
      -                      "NASDAQ100",
      -                      "DJIA",
      -                      "CRYPTO",
      -                      "SPECIFIC_ASSETS"
      -                    ],
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "source"
      -                ],
      -                "type": "object"
      -              }
      -            },
      -            "required": [
      -              "universe"
      -            ],
      -            "type": "object"
      -          },
      -          "legs": {
      -            "items": {
      -              "additionalProperties": true,
      -              "description": "Single leg of an option builder.",
      -              "properties": {
      -                "direction": {
      -                  "enum": [
      -                    "long",
      -                    "short"
      -                  ],
      -                  "type": "string"
      -                },
      -                "expirationRange": {
      -                  "additionalProperties": true,
      -                  "type": "object"
      -                },
      -                "expirationSelector": {
      -                  "properties": {
      -                    "maxDaysToExpiration": {
      -                      "minimum": 0,
      -                      "type": "number"
      -                    },
      -                    "minDaysToExpiration": {
      -                      "minimum": 0,
      -                      "type": "number"
      -                    },
      -                    "preference": {
      -                      "enum": [
      -                        "nearest",
      -                        "middle",
      -                        "furthest"
      -                      ],
      -                      "type": "string"
      -                    }
      -                  },
      -                  "required": [
      -                    "minDaysToExpiration",
      -                    "maxDaysToExpiration",
      -                    "preference"
      -                  ],
      -                  "type": "object"
      -                },
      -                "fallbackStrikeSelector": {
      -                  "additionalProperties": false,
      -                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      -                  "properties": {
      -                    "distance": {
      -                      "type": "number"
      -                    },
      -                    "distanceType": {
      -                      "enum": [
      -                        "percent",
      -                        "dollars"
      -                      ],
      -                      "type": "string"
      -                    }
      -                  },
      -                  "required": [
      -                    "distanceType",
      -                    "distance"
      -                  ],
      -                  "type": "object"
      -                },
      -                "greekFilter": {
      -                  "additionalProperties": true,
      -                  "description": "Optional min/max constraints on Greeks during resolution.",
      -                  "type": "object"
      -                },
      -                "liquidityFilter": {
      -                  "additionalProperties": false,
      -                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      -                  "properties": {
      -                    "maxSpreadAbsolute": {
      -                      "type": "number"
      -                    },
      -                    "maxSpreadPct": {
      -                      "type": "number"
      -                    },
      -                    "minBid": {
      -                      "type": "number"
      -                    }
      -                  },
      -                  "type": "object"
      -                },
      -                "optionType": {
      -                  "enum": [
      -                    "call",
      -                    "put"
      -                  ],
      -                  "type": "string"
      -                },
      -                "ratio": {
      -                  "type": "number"
      -                },
      -                "strikeRange": {
      -                  "additionalProperties": true,
      -                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      -                  "type": "object"
      -                },
      -                "strikeSelector": {
      -                  "properties": {
      -                    "distance": {
      -                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      -                      "type": "number"
      -                    },
      -                    "distanceType": {
      -                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      -                      "type": "string"
      -                    }
      -                  },
      -                  "required": [
      -                    "distanceType",
      -                    "distance"
      -                  ],
      -                  "type": "object"
      -                }
      -              },
      -              "required": [
      -                "optionType",
      -                "direction",
      -                "expirationSelector",
      -                "strikeSelector"
      -              ],
      -              "type": "object"
      -            },
      -            "minItems": 1,
      -            "type": "array"
      -          },
      -          "spreadType": {
      -            "enum": [
      -              "vertical",
      -              "calendar",
      -              "diagonal",
      -              "ironCondor",
      -              "straddle",
      -              "strangle",
      -              "custom"
      -            ],
      -            "type": "string"
      -          },
      -          "underlyingSymbol": {
      -            "type": "string"
      -          },
      -          "widthConstraint": {
      -            "additionalProperties": false,
      -            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      -            "properties": {
      -              "minWidthDollars": {
      -                "exclusiveMinimum": 0,
      -                "type": "number"
      -              },
      -              "minWidthPercent": {
      -                "exclusiveMinimum": 0,
      -                "type": "number"
      -              }
      -            },
      -            "type": "object"
      -          }
      -        },
      -        "required": [
      -          "legs"
      -        ],
      -        "type": "object"
      -      },
      -      "type": {
      -        "const": "OpenOption",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "builder"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
      -    "properties": {
      -      "allocationPolicy": {
      -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "expectedReturnShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "riskAversion": {
      -                "maximum": 1000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MeanVariance",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "riskAversion",
      -              "expectedReturnShrinkage",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "RiskParity",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MaximumDiversification",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      },
      -      "exposurePolicy": {
      -        "additionalProperties": false,
      -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      -        "properties": {
      -          "covarianceShrinkage": {
      -            "maximum": 1,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "estimatedTransactionCostBps": {
      -            "maximum": 10000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "lookbackPeriods": {
      -            "maximum": 5000,
      -            "minimum": 2,
      -            "type": "integer"
      -          },
      -          "minimumObservations": {
      -            "maximum": 5000,
      -            "minimum": 2,
      -            "type": "integer"
      -          },
      -          "targetAnnualizedVolatilityPercent": {
      -            "maximum": 1000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "type": {
      -            "const": "VolatilityTarget",
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "lookbackPeriods",
      -          "minimumObservations",
      -          "covarianceShrinkage",
      -          "targetAnnualizedVolatilityPercent",
      -          "estimatedTransactionCostBps"
      -        ],
      -        "type": "object"
      -      },
      -      "limit": {
      -        "minimum": 1,
      -        "type": "number"
      -      },
      -      "perNameAllocation": {
      -        "additionalProperties": true,
      -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      -        "properties": {
      -          "amount": {
      -            "type": "number"
      -          },
      -          "type": {
      -            "enum": [
      -              "dollars",
      -              "percent of portfolio",
      -              "percent of buying power",
      -              "contracts"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "amount"
      -        ],
      -        "type": "object"
      -      },
      -      "pipeline": {
      -        "items": {
      -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      -          "oneOf": [
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "condition": {
      -                  "$ref": "#/$defs/condition"
      -                },
      -                "type": {
      -                  "const": "Filter",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "condition"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "direction": {
      -                  "enum": [
      -                    "Highest",
      -                    "Lowest"
      -                  ],
      -                  "type": "string"
      -                },
      -                "limit": {
      -                  "minimum": 1,
      -                  "type": "number"
      -                },
      -                "metric": {
      -                  "$ref": "#/$defs/indicator"
      -                },
      -                "type": {
      -                  "const": "SelectTop",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "metric",
      -                "limit",
      -                "direction"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "direction": {
      -                  "enum": [
      -                    "Highest",
      -                    "Lowest"
      -                  ],
      -                  "type": "string"
      -                },
      -                "metric": {
      -                  "$ref": "#/$defs/indicator"
      -                },
      -                "percentile": {
      -                  "maximum": 100,
      -                  "minimum": 0,
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "SelectPercentile",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "metric",
      -                "percentile",
      -                "direction"
      -              ],
      -              "type": "object"
      -            }
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "positionScope": {
      -        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
      -        "enum": [
      -          "portfolio",
      -          "strategy"
      -        ],
      -        "type": "string"
      -      },
      -      "sleeves": {
      -        "items": {
      -          "additionalProperties": true,
      -          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
      -          "properties": {
      -            "limit": {
      -              "minimum": 1,
      -              "type": "number"
      -            },
      -            "name": {
      -              "type": "string"
      -            },
      -            "perNameAllocation": {
      -              "additionalProperties": true,
      -              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      -              "properties": {
      -                "amount": {
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "enum": [
      -                    "dollars",
      -                    "percent of portfolio",
      -                    "percent of buying power",
      -                    "contracts"
      -                  ],
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "amount"
      -              ],
      -              "type": "object"
      -            },
      -            "pipeline": {
      -              "items": {
      -                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      -                "oneOf": [
      -                  {
      -                    "additionalProperties": true,
      -                    "properties": {
      -                      "condition": {
      -                        "$ref": "#/$defs/condition"
      -                      },
      -                      "type": {
      -                        "const": "Filter",
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "type",
      -                      "condition"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  {
      -                    "additionalProperties": true,
      -                    "properties": {
      -                      "direction": {
      -                        "enum": [
      -                          "Highest",
      -                          "Lowest"
      -                        ],
      -                        "type": "string"
      -                      },
      -                      "limit": {
      -                        "minimum": 1,
      -                        "type": "number"
      -                      },
      -                      "metric": {
      -                        "$ref": "#/$defs/indicator"
      -                      },
      -                      "type": {
      -                        "const": "SelectTop",
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "type",
      -                      "metric",
      -                      "limit",
      -                      "direction"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  {
      -                    "additionalProperties": true,
      -                    "properties": {
      -                      "direction": {
      -                        "enum": [
      -                          "Highest",
      -                          "Lowest"
      -                        ],
      -                        "type": "string"
      -                      },
      -                      "metric": {
      -                        "$ref": "#/$defs/indicator"
      -                      },
      -                      "percentile": {
      -                        "maximum": 100,
      -                        "minimum": 0,
      -                        "type": "number"
      -                      },
      -                      "type": {
      -                        "const": "SelectPercentile",
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "type",
      -                      "metric",
      -                      "percentile",
      -                      "direction"
      -                    ],
      -                    "type": "object"
      -                  }
      -                ],
      -                "type": "object"
      -              },
      -              "type": "array"
      -            },
      -            "structureTemplates": {
      -              "items": {
      -                "additionalProperties": true,
      -                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      -                "properties": {
      -                  "eligibility": {
      -                    "$ref": "#/$defs/condition"
      -                  },
      -                  "legs": {
      -                    "items": {
      -                      "additionalProperties": true,
      -                      "description": "Single leg of an option builder.",
      -                      "properties": {
      -                        "direction": {
      -                          "enum": [
      -                            "long",
      -                            "short"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "expirationRange": {
      -                          "additionalProperties": true,
      -                          "type": "object"
      -                        },
      -                        "expirationSelector": {
      -                          "properties": {
      -                            "maxDaysToExpiration": {
      -                              "minimum": 0,
      -                              "type": "number"
      -                            },
      -                            "minDaysToExpiration": {
      -                              "minimum": 0,
      -                              "type": "number"
      -                            },
      -                            "preference": {
      -                              "enum": [
      -                                "nearest",
      -                                "middle",
      -                                "furthest"
      -                              ],
      -                              "type": "string"
      -                            }
      -                          },
      -                          "required": [
      -                            "minDaysToExpiration",
      -                            "maxDaysToExpiration",
      -                            "preference"
      -                          ],
      -                          "type": "object"
      -                        },
      -                        "fallbackStrikeSelector": {
      -                          "additionalProperties": false,
      -                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      -                          "properties": {
      -                            "distance": {
      -                              "type": "number"
      -                            },
      -                            "distanceType": {
      -                              "enum": [
      -                                "percent",
      -                                "dollars"
      -                              ],
      -                              "type": "string"
      -                            }
      -                          },
      -                          "required": [
      -                            "distanceType",
      -                            "distance"
      -                          ],
      -                          "type": "object"
      -                        },
      -                        "greekFilter": {
      -                          "additionalProperties": true,
      -                          "description": "Optional min/max constraints on Greeks during resolution.",
      -                          "type": "object"
      -                        },
      -                        "liquidityFilter": {
      -                          "additionalProperties": false,
      -                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      -                          "properties": {
      -                            "maxSpreadAbsolute": {
      -                              "type": "number"
      -                            },
      -                            "maxSpreadPct": {
      -                              "type": "number"
      -                            },
      -                            "minBid": {
      -                              "type": "number"
      -                            }
      -                          },
      -                          "type": "object"
      -                        },
      -                        "optionType": {
      -                          "enum": [
      -                            "call",
      -                            "put"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "ratio": {
      -                          "type": "number"
      -                        },
      -                        "strikeRange": {
      -                          "additionalProperties": true,
      -                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      -                          "type": "object"
      -                        },
      -                        "strikeSelector": {
      -                          "properties": {
      -                            "distance": {
      -                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      -                              "type": "number"
      -                            },
      -                            "distanceType": {
      -                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      -                              "type": "string"
      -                            }
      -                          },
      -                          "required": [
      -                            "distanceType",
      -                            "distance"
      -                          ],
      -                          "type": "object"
      -                        }
      -                      },
      -                      "required": [
      -                        "optionType",
      -                        "direction",
      -                        "expirationSelector",
      -                        "strikeSelector"
      -                      ],
      -                      "type": "object"
      -                    },
      -                    "minItems": 1,
      -                    "type": "array"
      -                  },
      -                  "name": {
      -                    "type": "string"
      -                  },
      -                  "spreadType": {
      -                    "enum": [
      -                      "vertical",
      -                      "calendar",
      -                      "diagonal",
      -                      "ironCondor",
      -                      "straddle",
      -                      "strangle",
      -                      "custom"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "widthConstraint": {
      -                    "additionalProperties": false,
      -                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      -                    "properties": {
      -                      "minWidthDollars": {
      -                        "exclusiveMinimum": 0,
      -                        "type": "number"
      -                      },
      -                      "minWidthPercent": {
      -                        "exclusiveMinimum": 0,
      -                        "type": "number"
      -                      }
      -                    },
      -                    "type": "object"
      -                  }
      -                },
      -                "required": [
      -                  "legs"
      -                ],
      -                "type": "object"
      -              },
      -              "minItems": 1,
      -              "type": "array"
      -            },
      -            "universe": {
      -              "additionalProperties": true,
      -              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      -              "properties": {
      -                "assets": {
      -                  "items": {
      -                    "additionalProperties": true,
      -                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      -                    "properties": {
      -                      "name": {
      -                        "type": "string"
      -                      },
      -                      "symbol": {
      -                        "type": "string"
      -                      },
      -                      "type": {
      -                        "enum": [
      -                          "Stock",
      -                          "Cryptocurrency",
      -                          "Option",
      -                          "Other"
      -                        ],
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "type",
      -                      "symbol"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "type": "array"
      -                },
      -                "source": {
      -                  "enum": [
      -                    "ALL_US_STOCKS",
      -                    "SP500",
      -                    "NASDAQ100",
      -                    "DJIA",
      -                    "CRYPTO",
      -                    "SPECIFIC_ASSETS"
      -                  ],
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "source"
      -              ],
      -              "type": "object"
      -            },
      -            "weightIndicator": {
      -              "$ref": "#/$defs/indicator"
      -            }
      -          },
      -          "required": [
      -            "name"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "structureTemplates": {
      -        "items": {
      -          "additionalProperties": true,
      -          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      -          "properties": {
      -            "eligibility": {
      -              "$ref": "#/$defs/condition"
      -            },
      -            "legs": {
      -              "items": {
      -                "additionalProperties": true,
      -                "description": "Single leg of an option builder.",
      -                "properties": {
      -                  "direction": {
      -                    "enum": [
      -                      "long",
      -                      "short"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "expirationRange": {
      -                    "additionalProperties": true,
      -                    "type": "object"
      -                  },
      -                  "expirationSelector": {
      -                    "properties": {
      -                      "maxDaysToExpiration": {
      -                        "minimum": 0,
      -                        "type": "number"
      -                      },
      -                      "minDaysToExpiration": {
      -                        "minimum": 0,
      -                        "type": "number"
      -                      },
      -                      "preference": {
      -                        "enum": [
      -                          "nearest",
      -                          "middle",
      -                          "furthest"
      -                        ],
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "minDaysToExpiration",
      -                      "maxDaysToExpiration",
      -                      "preference"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "fallbackStrikeSelector": {
      -                    "additionalProperties": false,
      -                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      -                    "properties": {
      -                      "distance": {
      -                        "type": "number"
      -                      },
      -                      "distanceType": {
      -                        "enum": [
      -                          "percent",
      -                          "dollars"
      -                        ],
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "distanceType",
      -                      "distance"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "greekFilter": {
      -                    "additionalProperties": true,
      -                    "description": "Optional min/max constraints on Greeks during resolution.",
      -                    "type": "object"
      -                  },
      -                  "liquidityFilter": {
      -                    "additionalProperties": false,
      -                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      -                    "properties": {
      -                      "maxSpreadAbsolute": {
      -                        "type": "number"
      -                      },
      -                      "maxSpreadPct": {
      -                        "type": "number"
      -                      },
      -                      "minBid": {
      -                        "type": "number"
      -                      }
      -                    },
      -                    "type": "object"
      -                  },
      -                  "optionType": {
      -                    "enum": [
      -                      "call",
      -                      "put"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "ratio": {
      -                    "type": "number"
      -                  },
      -                  "strikeRange": {
      -                    "additionalProperties": true,
      -                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      -                    "type": "object"
      -                  },
      -                  "strikeSelector": {
      -                    "properties": {
      -                      "distance": {
      -                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      -                        "type": "number"
      -                      },
      -                      "distanceType": {
      -                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "distanceType",
      -                      "distance"
      -                    ],
      -                    "type": "object"
      -                  }
      -                },
      -                "required": [
      -                  "optionType",
      -                  "direction",
      -                  "expirationSelector",
      -                  "strikeSelector"
      -                ],
      -                "type": "object"
      -              },
      -              "minItems": 1,
      -              "type": "array"
      -            },
      -            "name": {
      -              "type": "string"
      -            },
      -            "spreadType": {
      -              "enum": [
      -                "vertical",
      -                "calendar",
      -                "diagonal",
      -                "ironCondor",
      -                "straddle",
      -                "strangle",
      -                "custom"
      -              ],
      -              "type": "string"
      -            },
      -            "widthConstraint": {
      -              "additionalProperties": false,
      -              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      -              "properties": {
      -                "minWidthDollars": {
      -                  "exclusiveMinimum": 0,
      -                  "type": "number"
      -                },
      -                "minWidthPercent": {
      -                  "exclusiveMinimum": 0,
      -                  "type": "number"
      -                }
      -              },
      -              "type": "object"
      -            }
      -          },
      -          "required": [
      -            "legs"
      -          ],
      -          "type": "object"
      -        },
      -        "minItems": 1,
      -        "type": "array"
      -      },
      -      "totalBudget": {
      -        "additionalProperties": true,
      -        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
      -        "properties": {
      -          "amount": {
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "type": {
      -            "enum": [
      -              "dollars",
      -              "percent of portfolio"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "amount"
      -        ],
      -        "type": "object"
      -      },
      -      "type": {
      -        "const": "RebalanceOption",
      -        "type": "string"
      -      },
      -      "universe": {
      -        "additionalProperties": true,
      -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      -        "properties": {
      -          "assets": {
      -            "items": {
      -              "additionalProperties": true,
      -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      -              "properties": {
      -                "name": {
      -                  "type": "string"
      -                },
      -                "symbol": {
      -                  "type": "string"
      -                },
      -                "type": {
      -                  "enum": [
      -                    "Stock",
      -                    "Cryptocurrency",
      -                    "Option",
      -                    "Other"
      -                  ],
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "symbol"
      -              ],
      -              "type": "object"
      -            },
      -            "type": "array"
      -          },
      -          "source": {
      -            "enum": [
      -              "ALL_US_STOCKS",
      -              "SP500",
      -              "NASDAQ100",
      -              "DJIA",
      -              "CRYPTO",
      -              "SPECIFIC_ASSETS"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "source"
      -        ],
      -        "type": "object"
      -      },
      -      "weightIndicator": {
      -        "$ref": "#/$defs/indicator"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "universe",
      -      "pipeline",
      -      "weightIndicator",
      -      "structureTemplates"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
      -    "properties": {
      -      "closeScope": {
      -        "enum": [
      -          "spread",
      -          "leg"
      -        ],
      -        "type": "string"
      -      },
      -      "direction": {
      -        "enum": [
      -          "long",
      -          "short"
      -        ],
      -        "type": "string"
      -      },
      -      "optionType": {
      -        "enum": [
      -          "call",
      -          "put"
      -        ],
      -        "type": "string"
      -      },
      -      "quantity": {
      -        "additionalProperties": true,
      -        "description": "How many contracts to close. Defaults to all matching when omitted.",
      -        "type": "object"
      -      },
      -      "spreadType": {
      -        "enum": [
      -          "vertical",
      -          "calendar",
      -          "diagonal",
      -          "ironCondor",
      -          "straddle",
      -          "strangle",
      -          "custom"
      -        ],
      -        "type": "string"
      -      },
      -      "triggers": {
      -        "items": {
      -          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
      -          "oneOf": [
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "maxPnlPercent": {
      -                  "type": "number"
      -                },
      -                "minPnlPercent": {
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "pnl",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "maxDte": {
      -                  "type": "number"
      -                },
      -                "minDte": {
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "dte",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "maxDaysHeld": {
      -                  "type": "number"
      -                },
      -                "minDaysHeld": {
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "daysHeld",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "maxIv": {
      -                  "type": "number"
      -                },
      -                "maxSpreadDelta": {
      -                  "type": "number"
      -                },
      -                "maxSpreadTheta": {
      -                  "type": "number"
      -                },
      -                "minIv": {
      -                  "type": "number"
      -                },
      -                "minSpreadDelta": {
      -                  "type": "number"
      -                },
      -                "minSpreadTheta": {
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "greeks",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type"
      -              ],
      -              "type": "object"
      -            }
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "type": {
      -        "const": "CloseOption",
      -        "type": "string"
      -      },
      -      "underlyings": {
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": true,
      +    "description": "Buy or Sell a stock/crypto position.",
      +    "properties": {
      +      "amount": {
      +        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
      +        "properties": {
      +          "amount": {
      +            "type": "number"
      +          },
      +          "type": {
      +            "enum": [
      +              "percent of portfolio",
      +              "percent of buying power",
      +              "percent of current positions",
      +              "dollars",
      +              "number of assets"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      "targetAsset": {
      +        "additionalProperties": true,
      +        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +        "properties": {
      +          "name": {
      +            "type": "string"
      +          },
      +          "symbol": {
      +            "type": "string"
      +          },
      +          "type": {
      +            "enum": [
      +              "Stock",
      +              "Cryptocurrency",
      +              "Option",
      +              "Other"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "symbol"
      +        ],
      +        "type": "object"
      +      },
      +      "type": {
      +        "enum": [
      +          "Buy",
      +          "Sell"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "targetAsset",
      +      "amount"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "Send an alert message (no order).",
      +    "properties": {
      +      "message": {
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "Alert",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "message"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
      +    "properties": {
      +      "allocationPolicy": {
      +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "expectedReturnShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "riskAversion": {
      +                "maximum": 1000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "MeanVariance",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "riskAversion",
      +              "expectedReturnShrinkage",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "RiskParity",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "MaximumDiversification",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      },
      +      "canSell": {
      +        "$ref": "#/$defs/condition",
      +        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
      +      },
      +      "deploymentPercent": {
      +        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "exposurePolicy": {
      +        "additionalProperties": false,
      +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      +        "properties": {
      +          "covarianceShrinkage": {
      +            "maximum": 1,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "estimatedTransactionCostBps": {
      +            "maximum": 10000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "lookbackPeriods": {
      +            "maximum": 5000,
      +            "minimum": 2,
      +            "type": "integer"
      +          },
      +          "minimumObservations": {
      +            "maximum": 5000,
      +            "minimum": 2,
      +            "type": "integer"
      +          },
      +          "targetAnnualizedVolatilityPercent": {
      +            "maximum": 1000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "type": {
      +            "const": "VolatilityTarget",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "lookbackPeriods",
      +          "minimumObservations",
      +          "covarianceShrinkage",
      +          "targetAnnualizedVolatilityPercent",
      +          "estimatedTransactionCostBps"
      +        ],
      +        "type": "object"
      +      },
      +      "limit": {
      +        "minimum": 1,
      +        "type": "number"
      +      },
      +      "perNameAllocation": {
      +        "additionalProperties": true,
      +        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.",
      +        "properties": {
      +          "amount": {
      +            "exclusiveMinimum": 0,
      +            "type": "number"
      +          },
      +          "type": {
      +            "enum": [
      +              "percent of portfolio",
      +              "dollars"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      "pipeline": {
      +        "items": {
      +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +          "oneOf": [
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "condition": {
      +                  "$ref": "#/$defs/condition"
      +                },
      +                "type": {
      +                  "const": "Filter",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "condition"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "Highest",
      +                    "Lowest"
      +                  ],
      +                  "type": "string"
      +                },
      +                "limit": {
      +                  "minimum": 1,
      +                  "type": "number"
      +                },
      +                "metric": {
      +                  "$ref": "#/$defs/indicator"
      +                },
      +                "type": {
      +                  "const": "SelectTop",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "metric",
      +                "limit",
      +                "direction"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "Highest",
      +                    "Lowest"
      +                  ],
      +                  "type": "string"
      +                },
      +                "metric": {
      +                  "$ref": "#/$defs/indicator"
      +                },
      +                "percentile": {
      +                  "maximum": 100,
      +                  "minimum": 0,
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "SelectPercentile",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "metric",
      +                "percentile",
      +                "direction"
      +              ],
      +              "type": "object"
      +            }
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "type": {
      +        "const": "DynamicRebalance",
      +        "type": "string"
      +      },
      +      "universe": {
      +        "additionalProperties": true,
      +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +        "properties": {
      +          "assets": {
      +            "items": {
      +              "additionalProperties": true,
      +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +              "properties": {
      +                "name": {
      +                  "type": "string"
      +                },
      +                "symbol": {
      +                  "type": "string"
      +                },
      +                "type": {
      +                  "enum": [
      +                    "Stock",
      +                    "Cryptocurrency",
      +                    "Option",
      +                    "Other"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "symbol"
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "source": {
      +            "enum": [
      +              "ALL_US_STOCKS",
      +              "SP500",
      +              "NASDAQ100",
      +              "DJIA",
      +              "CRYPTO",
      +              "SPECIFIC_ASSETS"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "source"
      +        ],
      +        "type": "object"
      +      },
      +      "weightIndicator": {
      +        "$ref": "#/$defs/indicator"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "universe",
      +      "pipeline",
      +      "weightIndicator"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
      +    "properties": {
      +      "continueExisting": {
      +        "type": "boolean"
      +      },
      +      "cooldownMinutes": {
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "executionModel": {
      +        "type": "string"
      +      },
      +      "includeMarketData": {
      +        "type": "boolean"
      +      },
      +      "initialMessage": {
      +        "type": "string"
      +      },
      +      "maxIterations": {
      +        "minimum": 1,
      +        "type": "number"
      +      },
      +      "planningModel": {
      +        "type": "string"
      +      },
      +      "skipPlanning": {
      +        "type": "boolean"
      +      },
      +      "type": {
      +        "const": "LaunchAgent",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "planningModel",
      +      "executionModel",
      +      "initialMessage",
      +      "maxIterations",
      +      "includeMarketData",
      +      "continueExisting",
      +      "skipPlanning"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
      +    "properties": {
      +      "against": {
      +        "additionalProperties": true,
      +        "description": "Optional parent-position selector (e.g. for covered calls).",
      +        "type": "object"
      +      },
      +      "allocation": {
      +        "additionalProperties": true,
      +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +        "properties": {
      +          "amount": {
      +            "type": "number"
      +          },
      +          "type": {
      +            "enum": [
      +              "dollars",
      +              "percent of portfolio",
      +              "percent of buying power",
      +              "contracts",
      +              "percent of realized premium"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      "builder": {
      +        "additionalProperties": true,
      +        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
      +        "properties": {
      +          "dynamicUnderlying": {
      +            "additionalProperties": true,
      +            "properties": {
      +              "limit": {
      +                "minimum": 1,
      +                "type": "number"
      +              },
      +              "pipeline": {
      +                "items": {
      +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                  "oneOf": [
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "condition": {
      +                          "$ref": "#/$defs/condition"
      +                        },
      +                        "type": {
      +                          "const": "Filter",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "condition"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "Highest",
      +                            "Lowest"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "limit": {
      +                          "minimum": 1,
      +                          "type": "number"
      +                        },
      +                        "metric": {
      +                          "$ref": "#/$defs/indicator"
      +                        },
      +                        "type": {
      +                          "const": "SelectTop",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "metric",
      +                        "limit",
      +                        "direction"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "Highest",
      +                            "Lowest"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "metric": {
      +                          "$ref": "#/$defs/indicator"
      +                        },
      +                        "percentile": {
      +                          "maximum": 100,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "SelectPercentile",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "metric",
      +                        "percentile",
      +                        "direction"
      +                      ],
      +                      "type": "object"
      +                    }
      +                  ],
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "universe": {
      +                "additionalProperties": true,
      +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +                "properties": {
      +                  "assets": {
      +                    "items": {
      +                      "additionalProperties": true,
      +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                      "properties": {
      +                        "name": {
      +                          "type": "string"
      +                        },
      +                        "symbol": {
      +                          "type": "string"
      +                        },
      +                        "type": {
      +                          "enum": [
      +                            "Stock",
      +                            "Cryptocurrency",
      +                            "Option",
      +                            "Other"
      +                          ],
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "symbol"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "type": "array"
      +                  },
      +                  "source": {
      +                    "enum": [
      +                      "ALL_US_STOCKS",
      +                      "SP500",
      +                      "NASDAQ100",
      +                      "DJIA",
      +                      "CRYPTO",
      +                      "SPECIFIC_ASSETS"
      +                    ],
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "source"
      +                ],
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "universe"
      +            ],
      +            "type": "object"
      +          },
      +          "legs": {
      +            "items": {
      +              "additionalProperties": true,
      +              "description": "Single leg of an option builder.",
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "long",
      +                    "short"
      +                  ],
      +                  "type": "string"
      +                },
      +                "expirationRange": {
      +                  "additionalProperties": true,
      +                  "type": "object"
      +                },
      +                "expirationSelector": {
      +                  "properties": {
      +                    "maxDaysToExpiration": {
      +                      "minimum": 0,
      +                      "type": "number"
      +                    },
      +                    "minDaysToExpiration": {
      +                      "minimum": 0,
      +                      "type": "number"
      +                    },
      +                    "preference": {
      +                      "enum": [
      +                        "nearest",
      +                        "middle",
      +                        "furthest"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "minDaysToExpiration",
      +                    "maxDaysToExpiration",
      +                    "preference"
      +                  ],
      +                  "type": "object"
      +                },
      +                "fallbackStrikeSelector": {
      +                  "additionalProperties": false,
      +                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                  "properties": {
      +                    "distance": {
      +                      "type": "number"
      +                    },
      +                    "distanceType": {
      +                      "enum": [
      +                        "percent",
      +                        "dollars"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "distanceType",
      +                    "distance"
      +                  ],
      +                  "type": "object"
      +                },
      +                "greekFilter": {
      +                  "additionalProperties": true,
      +                  "description": "Optional min/max constraints on Greeks during resolution.",
      +                  "type": "object"
      +                },
      +                "liquidityFilter": {
      +                  "additionalProperties": false,
      +                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                  "properties": {
      +                    "maxSpreadAbsolute": {
      +                      "type": "number"
      +                    },
      +                    "maxSpreadPct": {
      +                      "type": "number"
      +                    },
      +                    "minBid": {
      +                      "type": "number"
      +                    }
      +                  },
      +                  "type": "object"
      +                },
      +                "optionType": {
      +                  "enum": [
      +                    "call",
      +                    "put"
      +                  ],
      +                  "type": "string"
      +                },
      +                "ratio": {
      +                  "type": "number"
      +                },
      +                "strikeRange": {
      +                  "additionalProperties": true,
      +                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                  "type": "object"
      +                },
      +                "strikeSelector": {
      +                  "properties": {
      +                    "distance": {
      +                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                      "type": "number"
      +                    },
      +                    "distanceType": {
      +                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "distanceType",
      +                    "distance"
      +                  ],
      +                  "type": "object"
      +                }
      +              },
      +              "required": [
      +                "optionType",
      +                "direction",
      +                "expirationSelector",
      +                "strikeSelector"
      +              ],
      +              "type": "object"
      +            },
      +            "minItems": 1,
      +            "type": "array"
      +          },
      +          "spreadType": {
      +            "enum": [
      +              "vertical",
      +              "calendar",
      +              "diagonal",
      +              "ironCondor",
      +              "straddle",
      +              "strangle",
      +              "custom"
      +            ],
      +            "type": "string"
      +          },
      +          "underlyingSymbol": {
      +            "type": "string"
      +          },
      +          "widthConstraint": {
      +            "additionalProperties": false,
      +            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +            "properties": {
      +              "minWidthDollars": {
      +                "exclusiveMinimum": 0,
      +                "type": "number"
      +              },
      +              "minWidthPercent": {
      +                "exclusiveMinimum": 0,
      +                "type": "number"
      +              }
      +            },
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "legs"
      +        ],
      +        "type": "object"
      +      },
      +      "type": {
      +        "const": "OpenOption",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "builder"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
      +    "properties": {
      +      "allocationPolicy": {
      +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "expectedReturnShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "riskAversion": {
      +                "maximum": 1000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "MeanVariance",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "riskAversion",
      +              "expectedReturnShrinkage",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "RiskParity",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "MaximumDiversification",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      },
      +      "exposurePolicy": {
      +        "additionalProperties": false,
      +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      +        "properties": {
      +          "covarianceShrinkage": {
      +            "maximum": 1,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "estimatedTransactionCostBps": {
      +            "maximum": 10000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "lookbackPeriods": {
      +            "maximum": 5000,
      +            "minimum": 2,
      +            "type": "integer"
      +          },
      +          "minimumObservations": {
      +            "maximum": 5000,
      +            "minimum": 2,
      +            "type": "integer"
      +          },
      +          "targetAnnualizedVolatilityPercent": {
      +            "maximum": 1000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "type": {
      +            "const": "VolatilityTarget",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "lookbackPeriods",
      +          "minimumObservations",
      +          "covarianceShrinkage",
      +          "targetAnnualizedVolatilityPercent",
      +          "estimatedTransactionCostBps"
      +        ],
      +        "type": "object"
      +      },
      +      "limit": {
      +        "minimum": 1,
      +        "type": "number"
      +      },
      +      "perNameAllocation": {
      +        "additionalProperties": true,
      +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +        "properties": {
      +          "amount": {
      +            "type": "number"
      +          },
      +          "type": {
      +            "enum": [
      +              "dollars",
      +              "percent of portfolio",
      +              "percent of buying power",
      +              "contracts",
      +              "percent of realized premium"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      "pipeline": {
      +        "items": {
      +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +          "oneOf": [
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "condition": {
      +                  "$ref": "#/$defs/condition"
      +                },
      +                "type": {
      +                  "const": "Filter",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "condition"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "Highest",
      +                    "Lowest"
      +                  ],
      +                  "type": "string"
      +                },
      +                "limit": {
      +                  "minimum": 1,
      +                  "type": "number"
      +                },
      +                "metric": {
      +                  "$ref": "#/$defs/indicator"
      +                },
      +                "type": {
      +                  "const": "SelectTop",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "metric",
      +                "limit",
      +                "direction"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "Highest",
      +                    "Lowest"
      +                  ],
      +                  "type": "string"
      +                },
      +                "metric": {
      +                  "$ref": "#/$defs/indicator"
      +                },
      +                "percentile": {
      +                  "maximum": 100,
      +                  "minimum": 0,
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "SelectPercentile",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "metric",
      +                "percentile",
      +                "direction"
      +              ],
      +              "type": "object"
      +            }
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "positionScope": {
      +        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
      +        "enum": [
      +          "portfolio",
      +          "strategy"
      +        ],
      +        "type": "string"
      +      },
      +      "sleeves": {
      +        "items": {
      +          "additionalProperties": true,
      +          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
      +          "properties": {
      +            "limit": {
      +              "minimum": 1,
      +              "type": "number"
      +            },
      +            "name": {
      +              "type": "string"
      +            },
      +            "perNameAllocation": {
      +              "additionalProperties": true,
      +              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +              "properties": {
      +                "amount": {
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "enum": [
      +                    "dollars",
      +                    "percent of portfolio",
      +                    "percent of buying power",
      +                    "contracts",
      +                    "percent of realized premium"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "amount"
      +              ],
      +              "type": "object"
      +            },
      +            "pipeline": {
      +              "items": {
      +                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                "oneOf": [
      +                  {
      +                    "additionalProperties": true,
      +                    "properties": {
      +                      "condition": {
      +                        "$ref": "#/$defs/condition"
      +                      },
      +                      "type": {
      +                        "const": "Filter",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "condition"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": true,
      +                    "properties": {
      +                      "direction": {
      +                        "enum": [
      +                          "Highest",
      +                          "Lowest"
      +                        ],
      +                        "type": "string"
      +                      },
      +                      "limit": {
      +                        "minimum": 1,
      +                        "type": "number"
      +                      },
      +                      "metric": {
      +                        "$ref": "#/$defs/indicator"
      +                      },
      +                      "type": {
      +                        "const": "SelectTop",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "metric",
      +                      "limit",
      +                      "direction"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": true,
      +                    "properties": {
      +                      "direction": {
      +                        "enum": [
      +                          "Highest",
      +                          "Lowest"
      +                        ],
      +                        "type": "string"
      +                      },
      +                      "metric": {
      +                        "$ref": "#/$defs/indicator"
      +                      },
      +                      "percentile": {
      +                        "maximum": 100,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "SelectPercentile",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "metric",
      +                      "percentile",
      +                      "direction"
      +                    ],
      +                    "type": "object"
      +                  }
      +                ],
      +                "type": "object"
      +              },
      +              "type": "array"
      +            },
      +            "structureTemplates": {
      +              "items": {
      +                "additionalProperties": true,
      +                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      +                "properties": {
      +                  "eligibility": {
      +                    "$ref": "#/$defs/condition"
      +                  },
      +                  "legs": {
      +                    "items": {
      +                      "additionalProperties": true,
      +                      "description": "Single leg of an option builder.",
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "long",
      +                            "short"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "expirationRange": {
      +                          "additionalProperties": true,
      +                          "type": "object"
      +                        },
      +                        "expirationSelector": {
      +                          "properties": {
      +                            "maxDaysToExpiration": {
      +                              "minimum": 0,
      +                              "type": "number"
      +                            },
      +                            "minDaysToExpiration": {
      +                              "minimum": 0,
      +                              "type": "number"
      +                            },
      +                            "preference": {
      +                              "enum": [
      +                                "nearest",
      +                                "middle",
      +                                "furthest"
      +                              ],
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "minDaysToExpiration",
      +                            "maxDaysToExpiration",
      +                            "preference"
      +                          ],
      +                          "type": "object"
      +                        },
      +                        "fallbackStrikeSelector": {
      +                          "additionalProperties": false,
      +                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                          "properties": {
      +                            "distance": {
      +                              "type": "number"
      +                            },
      +                            "distanceType": {
      +                              "enum": [
      +                                "percent",
      +                                "dollars"
      +                              ],
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "distanceType",
      +                            "distance"
      +                          ],
      +                          "type": "object"
      +                        },
      +                        "greekFilter": {
      +                          "additionalProperties": true,
      +                          "description": "Optional min/max constraints on Greeks during resolution.",
      +                          "type": "object"
      +                        },
      +                        "liquidityFilter": {
      +                          "additionalProperties": false,
      +                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                          "properties": {
      +                            "maxSpreadAbsolute": {
      +                              "type": "number"
      +                            },
      +                            "maxSpreadPct": {
      +                              "type": "number"
      +                            },
      +                            "minBid": {
      +                              "type": "number"
      +                            }
      +                          },
      +                          "type": "object"
      +                        },
      +                        "optionType": {
      +                          "enum": [
      +                            "call",
      +                            "put"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "ratio": {
      +                          "type": "number"
      +                        },
      +                        "strikeRange": {
      +                          "additionalProperties": true,
      +                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                          "type": "object"
      +                        },
      +                        "strikeSelector": {
      +                          "properties": {
      +                            "distance": {
      +                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                              "type": "number"
      +                            },
      +                            "distanceType": {
      +                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "distanceType",
      +                            "distance"
      +                          ],
      +                          "type": "object"
      +                        }
      +                      },
      +                      "required": [
      +                        "optionType",
      +                        "direction",
      +                        "expirationSelector",
      +                        "strikeSelector"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "minItems": 1,
      +                    "type": "array"
      +                  },
      +                  "name": {
      +                    "type": "string"
      +                  },
      +                  "spreadType": {
      +                    "enum": [
      +                      "vertical",
      +                      "calendar",
      +                      "diagonal",
      +                      "ironCondor",
      +                      "straddle",
      +                      "strangle",
      +                      "custom"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "widthConstraint": {
      +                    "additionalProperties": false,
      +                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +                    "properties": {
      +                      "minWidthDollars": {
      +                        "exclusiveMinimum": 0,
      +                        "type": "number"
      +                      },
      +                      "minWidthPercent": {
      +                        "exclusiveMinimum": 0,
      +                        "type": "number"
      +                      }
      +                    },
      +                    "type": "object"
      +                  }
      +                },
      +                "required": [
      +                  "legs"
      +                ],
      +                "type": "object"
      +              },
      +              "minItems": 1,
      +              "type": "array"
      +            },
      +            "universe": {
      +              "additionalProperties": true,
      +              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +              "properties": {
      +                "assets": {
      +                  "items": {
      +                    "additionalProperties": true,
      +                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                    "properties": {
      +                      "name": {
      +                        "type": "string"
      +                      },
      +                      "symbol": {
      +                        "type": "string"
      +                      },
      +                      "type": {
      +                        "enum": [
      +                          "Stock",
      +                          "Cryptocurrency",
      +                          "Option",
      +                          "Other"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "symbol"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "type": "array"
      +                },
      +                "source": {
      +                  "enum": [
      +                    "ALL_US_STOCKS",
      +                    "SP500",
      +                    "NASDAQ100",
      +                    "DJIA",
      +                    "CRYPTO",
      +                    "SPECIFIC_ASSETS"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "source"
      +              ],
      +              "type": "object"
      +            },
      +            "weightIndicator": {
      +              "$ref": "#/$defs/indicator"
      +            }
      +          },
      +          "required": [
      +            "name"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "structureTemplates": {
      +        "items": {
      +          "additionalProperties": true,
      +          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      +          "properties": {
      +            "eligibility": {
      +              "$ref": "#/$defs/condition"
      +            },
      +            "legs": {
      +              "items": {
      +                "additionalProperties": true,
      +                "description": "Single leg of an option builder.",
      +                "properties": {
      +                  "direction": {
      +                    "enum": [
      +                      "long",
      +                      "short"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "expirationRange": {
      +                    "additionalProperties": true,
      +                    "type": "object"
      +                  },
      +                  "expirationSelector": {
      +                    "properties": {
      +                      "maxDaysToExpiration": {
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "minDaysToExpiration": {
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "preference": {
      +                        "enum": [
      +                          "nearest",
      +                          "middle",
      +                          "furthest"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "minDaysToExpiration",
      +                      "maxDaysToExpiration",
      +                      "preference"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "fallbackStrikeSelector": {
      +                    "additionalProperties": false,
      +                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                    "properties": {
      +                      "distance": {
      +                        "type": "number"
      +                      },
      +                      "distanceType": {
      +                        "enum": [
      +                          "percent",
      +                          "dollars"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "distanceType",
      +                      "distance"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "greekFilter": {
      +                    "additionalProperties": true,
      +                    "description": "Optional min/max constraints on Greeks during resolution.",
      +                    "type": "object"
      +                  },
      +                  "liquidityFilter": {
      +                    "additionalProperties": false,
      +                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                    "properties": {
      +                      "maxSpreadAbsolute": {
      +                        "type": "number"
      +                      },
      +                      "maxSpreadPct": {
      +                        "type": "number"
      +                      },
      +                      "minBid": {
      +                        "type": "number"
      +                      }
      +                    },
      +                    "type": "object"
      +                  },
      +                  "optionType": {
      +                    "enum": [
      +                      "call",
      +                      "put"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "ratio": {
      +                    "type": "number"
      +                  },
      +                  "strikeRange": {
      +                    "additionalProperties": true,
      +                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                    "type": "object"
      +                  },
      +                  "strikeSelector": {
      +                    "properties": {
      +                      "distance": {
      +                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                        "type": "number"
      +                      },
      +                      "distanceType": {
      +                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "distanceType",
      +                      "distance"
      +                    ],
      +                    "type": "object"
      +                  }
      +                },
      +                "required": [
      +                  "optionType",
      +                  "direction",
      +                  "expirationSelector",
      +                  "strikeSelector"
      +                ],
      +                "type": "object"
      +              },
      +              "minItems": 1,
      +              "type": "array"
      +            },
      +            "name": {
      +              "type": "string"
      +            },
      +            "spreadType": {
      +              "enum": [
      +                "vertical",
      +                "calendar",
      +                "diagonal",
      +                "ironCondor",
      +                "straddle",
      +                "strangle",
      +                "custom"
      +              ],
      +              "type": "string"
      +            },
      +            "widthConstraint": {
      +              "additionalProperties": false,
      +              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +              "properties": {
      +                "minWidthDollars": {
      +                  "exclusiveMinimum": 0,
      +                  "type": "number"
      +                },
      +                "minWidthPercent": {
      +                  "exclusiveMinimum": 0,
      +                  "type": "number"
      +                }
      +              },
      +              "type": "object"
      +            }
      +          },
      +          "required": [
      +            "legs"
      +          ],
      +          "type": "object"
      +        },
      +        "minItems": 1,
      +        "type": "array"
      +      },
      +      "totalBudget": {
      +        "additionalProperties": true,
      +        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
      +        "properties": {
      +          "amount": {
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "type": {
      +            "enum": [
      +              "dollars",
      +              "percent of portfolio"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      "type": {
      +        "const": "RebalanceOption",
      +        "type": "string"
      +      },
      +      "universe": {
      +        "additionalProperties": true,
      +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +        "properties": {
      +          "assets": {
      +            "items": {
      +              "additionalProperties": true,
      +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +              "properties": {
      +                "name": {
      +                  "type": "string"
      +                },
      +                "symbol": {
      +                  "type": "string"
      +                },
      +                "type": {
      +                  "enum": [
      +                    "Stock",
      +                    "Cryptocurrency",
      +                    "Option",
      +                    "Other"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "symbol"
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "source": {
      +            "enum": [
      +              "ALL_US_STOCKS",
      +              "SP500",
      +              "NASDAQ100",
      +              "DJIA",
      +              "CRYPTO",
      +              "SPECIFIC_ASSETS"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "source"
      +        ],
      +        "type": "object"
      +      },
      +      "weightIndicator": {
      +        "$ref": "#/$defs/indicator"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "universe",
      +      "pipeline",
      +      "weightIndicator",
      +      "structureTemplates"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
      +    "properties": {
      +      "closeScope": {
      +        "enum": [
      +          "spread",
      +          "leg"
      +        ],
      +        "type": "string"
      +      },
      +      "direction": {
      +        "enum": [
      +          "long",
      +          "short"
      +        ],
      +        "type": "string"
      +      },
      +      "optionType": {
      +        "enum": [
      +          "call",
      +          "put"
      +        ],
      +        "type": "string"
      +      },
      +      "quantity": {
      +        "additionalProperties": true,
      +        "description": "How many contracts to close. Defaults to all matching when omitted.",
      +        "type": "object"
      +      },
      +      "spreadType": {
      +        "enum": [
      +          "vertical",
      +          "calendar",
      +          "diagonal",
      +          "ironCondor",
      +          "straddle",
      +          "strangle",
      +          "custom"
      +        ],
      +        "type": "string"
      +      },
      +      "triggers": {
      +        "items": {
      +          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
      +          "oneOf": [
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "maxPnlPercent": {
      +                  "type": "number"
      +                },
      +                "minPnlPercent": {
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "pnl",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "maxDte": {
      +                  "type": "number"
      +                },
      +                "minDte": {
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "dte",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "maxDaysHeld": {
      +                  "type": "number"
      +                },
      +                "minDaysHeld": {
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "daysHeld",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "maxIv": {
      +                  "type": "number"
      +                },
      +                "maxSpreadDelta": {
      +                  "type": "number"
      +                },
      +                "maxSpreadTheta": {
      +                  "type": "number"
      +                },
      +                "minIv": {
      +                  "type": "number"
      +                },
      +                "minSpreadDelta": {
      +                  "type": "number"
      +                },
      +                "minSpreadTheta": {
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "greeks",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type"
      +              ],
      +              "type": "object"
      +            }
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "type": {
      +        "const": "CloseOption",
      +        "type": "string"
      +      },
      +      "underlyings": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  }
      +]
    • changedInput schema / properties / operations / items / properties / strategyObject / properties / action / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": true,
      -    "description": "Buy or Sell a stock/crypto position.",
      -    "properties": {
      -      "amount": {
      -        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
      -        "properties": {
      -          "amount": {
      -            "type": "number"
      -          },
      -          "type": {
      -            "enum": [
      -              "percent of portfolio",
      -              "percent of buying power",
      -              "percent of current positions",
      -              "dollars",
      -              "number of assets"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "amount"
      -        ],
      -        "type": "object"
      -      },
      -      "targetAsset": {
      -        "additionalProperties": true,
      -        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      -        "properties": {
      -          "name": {
      -            "type": "string"
      -          },
      -          "symbol": {
      -            "type": "string"
      -          },
      -          "type": {
      -            "enum": [
      -              "Stock",
      -              "Cryptocurrency",
      -              "Option",
      -              "Other"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "symbol"
      -        ],
      -        "type": "object"
      -      },
      -      "type": {
      -        "enum": [
      -          "Buy",
      -          "Sell"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "targetAsset",
      -      "amount"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "Send an alert message (no order).",
      -    "properties": {
      -      "message": {
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "Alert",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "message"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
      -    "properties": {
      -      "allocationPolicy": {
      -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "expectedReturnShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "riskAversion": {
      -                "maximum": 1000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MeanVariance",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "riskAversion",
      -              "expectedReturnShrinkage",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "RiskParity",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MaximumDiversification",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      },
      -      "canSell": {
      -        "$ref": "#/$defs/condition",
      -        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
      -      },
      -      "deploymentPercent": {
      -        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "exposurePolicy": {
      -        "additionalProperties": false,
      -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      -        "properties": {
      -          "covarianceShrinkage": {
      -            "maximum": 1,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "estimatedTransactionCostBps": {
      -            "maximum": 10000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "lookbackPeriods": {
      -            "maximum": 5000,
      -            "minimum": 2,
      -            "type": "integer"
      -          },
      -          "minimumObservations": {
      -            "maximum": 5000,
      -            "minimum": 2,
      -            "type": "integer"
      -          },
      -          "targetAnnualizedVolatilityPercent": {
      -            "maximum": 1000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "type": {
      -            "const": "VolatilityTarget",
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "lookbackPeriods",
      -          "minimumObservations",
      -          "covarianceShrinkage",
      -          "targetAnnualizedVolatilityPercent",
      -          "estimatedTransactionCostBps"
      -        ],
      -        "type": "object"
      -      },
      -      "limit": {
      -        "minimum": 1,
      -        "type": "number"
      -      },
      -      "perNameAllocation": {
      -        "additionalProperties": true,
      -        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
      -        "properties": {
      -          "amount": {
      -            "exclusiveMinimum": 0,
      -            "type": "number"
      -          },
      -          "type": {
      -            "enum": [
      -              "percent of portfolio",
      -              "dollars"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "amount"
      -        ],
      -        "type": "object"
      -      },
      -      "pipeline": {
      -        "items": {
      -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      -          "oneOf": [
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "condition": {
      -                  "$ref": "#/$defs/condition"
      -                },
      -                "type": {
      -                  "const": "Filter",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "condition"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "direction": {
      -                  "enum": [
      -                    "Highest",
      -                    "Lowest"
      -                  ],
      -                  "type": "string"
      -                },
      -                "limit": {
      -                  "minimum": 1,
      -                  "type": "number"
      -                },
      -                "metric": {
      -                  "$ref": "#/$defs/indicator"
      -                },
      -                "type": {
      -                  "const": "SelectTop",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "metric",
      -                "limit",
      -                "direction"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "direction": {
      -                  "enum": [
      -                    "Highest",
      -                    "Lowest"
      -                  ],
      -                  "type": "string"
      -                },
      -                "metric": {
      -                  "$ref": "#/$defs/indicator"
      -                },
      -                "percentile": {
      -                  "maximum": 100,
      -                  "minimum": 0,
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "SelectPercentile",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "metric",
      -                "percentile",
      -                "direction"
      -              ],
      -              "type": "object"
      -            }
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "type": {
      -        "const": "DynamicRebalance",
      -        "type": "string"
      -      },
      -      "universe": {
      -        "additionalProperties": true,
      -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      -        "properties": {
      -          "assets": {
      -            "items": {
      -              "additionalProperties": true,
      -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      -              "properties": {
      -                "name": {
      -                  "type": "string"
      -                },
      -                "symbol": {
      -                  "type": "string"
      -                },
      -                "type": {
      -                  "enum": [
      -                    "Stock",
      -                    "Cryptocurrency",
      -                    "Option",
      -                    "Other"
      -                  ],
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "symbol"
      -              ],
      -              "type": "object"
      -            },
      -            "type": "array"
      -          },
      -          "source": {
      -            "enum": [
      -              "ALL_US_STOCKS",
      -              "SP500",
      -              "NASDAQ100",
      -              "DJIA",
      -              "CRYPTO",
      -              "SPECIFIC_ASSETS"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "source"
      -        ],
      -        "type": "object"
      -      },
      -      "weightIndicator": {
      -        "$ref": "#/$defs/indicator"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "universe",
      -      "pipeline",
      -      "weightIndicator"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
      -    "properties": {
      -      "continueExisting": {
      -        "type": "boolean"
      -      },
      -      "cooldownMinutes": {
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "executionModel": {
      -        "type": "string"
      -      },
      -      "includeMarketData": {
      -        "type": "boolean"
      -      },
      -      "initialMessage": {
      -        "type": "string"
      -      },
      -      "maxIterations": {
      -        "minimum": 1,
      -        "type": "number"
      -      },
      -      "planningModel": {
      -        "type": "string"
      -      },
      -      "skipPlanning": {
      -        "type": "boolean"
      -      },
      -      "type": {
      -        "const": "LaunchAgent",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "planningModel",
      -      "executionModel",
      -      "initialMessage",
      -      "maxIterations",
      -      "includeMarketData",
      -      "continueExisting",
      -      "skipPlanning"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
      -    "properties": {
      -      "against": {
      -        "additionalProperties": true,
      -        "description": "Optional parent-position selector (e.g. for covered calls).",
      -        "type": "object"
      -      },
      -      "allocation": {
      -        "additionalProperties": true,
      -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      -        "properties": {
      -          "amount": {
      -            "type": "number"
      -          },
      -          "type": {
      -            "enum": [
      -              "dollars",
      -              "percent of portfolio",
      -              "percent of buying power",
      -              "contracts"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "amount"
      -        ],
      -        "type": "object"
      -      },
      -      "builder": {
      -        "additionalProperties": true,
      -        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
      -        "properties": {
      -          "dynamicUnderlying": {
      -            "additionalProperties": true,
      -            "properties": {
      -              "limit": {
      -                "minimum": 1,
      -                "type": "number"
      -              },
      -              "pipeline": {
      -                "items": {
      -                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      -                  "oneOf": [
      -                    {
      -                      "additionalProperties": true,
      -                      "properties": {
      -                        "condition": {
      -                          "$ref": "#/$defs/condition"
      -                        },
      -                        "type": {
      -                          "const": "Filter",
      -                          "type": "string"
      -                        }
      -                      },
      -                      "required": [
      -                        "type",
      -                        "condition"
      -                      ],
      -                      "type": "object"
      -                    },
      -                    {
      -                      "additionalProperties": true,
      -                      "properties": {
      -                        "direction": {
      -                          "enum": [
      -                            "Highest",
      -                            "Lowest"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "limit": {
      -                          "minimum": 1,
      -                          "type": "number"
      -                        },
      -                        "metric": {
      -                          "$ref": "#/$defs/indicator"
      -                        },
      -                        "type": {
      -                          "const": "SelectTop",
      -                          "type": "string"
      -                        }
      -                      },
      -                      "required": [
      -                        "type",
      -                        "metric",
      -                        "limit",
      -                        "direction"
      -                      ],
      -                      "type": "object"
      -                    },
      -                    {
      -                      "additionalProperties": true,
      -                      "properties": {
      -                        "direction": {
      -                          "enum": [
      -                            "Highest",
      -                            "Lowest"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "metric": {
      -                          "$ref": "#/$defs/indicator"
      -                        },
      -                        "percentile": {
      -                          "maximum": 100,
      -                          "minimum": 0,
      -                          "type": "number"
      -                        },
      -                        "type": {
      -                          "const": "SelectPercentile",
      -                          "type": "string"
      -                        }
      -                      },
      -                      "required": [
      -                        "type",
      -                        "metric",
      -                        "percentile",
      -                        "direction"
      -                      ],
      -                      "type": "object"
      -                    }
      -                  ],
      -                  "type": "object"
      -                },
      -                "type": "array"
      -              },
      -              "universe": {
      -                "additionalProperties": true,
      -                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      -                "properties": {
      -                  "assets": {
      -                    "items": {
      -                      "additionalProperties": true,
      -                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      -                      "properties": {
      -                        "name": {
      -                          "type": "string"
      -                        },
      -                        "symbol": {
      -                          "type": "string"
      -                        },
      -                        "type": {
      -                          "enum": [
      -                            "Stock",
      -                            "Cryptocurrency",
      -                            "Option",
      -                            "Other"
      -                          ],
      -                          "type": "string"
      -                        }
      -                      },
      -                      "required": [
      -                        "type",
      -                        "symbol"
      -                      ],
      -                      "type": "object"
      -                    },
      -                    "type": "array"
      -                  },
      -                  "source": {
      -                    "enum": [
      -                      "ALL_US_STOCKS",
      -                      "SP500",
      -                      "NASDAQ100",
      -                      "DJIA",
      -                      "CRYPTO",
      -                      "SPECIFIC_ASSETS"
      -                    ],
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "source"
      -                ],
      -                "type": "object"
      -              }
      -            },
      -            "required": [
      -              "universe"
      -            ],
      -            "type": "object"
      -          },
      -          "legs": {
      -            "items": {
      -              "additionalProperties": true,
      -              "description": "Single leg of an option builder.",
      -              "properties": {
      -                "direction": {
      -                  "enum": [
      -                    "long",
      -                    "short"
      -                  ],
      -                  "type": "string"
      -                },
      -                "expirationRange": {
      -                  "additionalProperties": true,
      -                  "type": "object"
      -                },
      -                "expirationSelector": {
      -                  "properties": {
      -                    "maxDaysToExpiration": {
      -                      "minimum": 0,
      -                      "type": "number"
      -                    },
      -                    "minDaysToExpiration": {
      -                      "minimum": 0,
      -                      "type": "number"
      -                    },
      -                    "preference": {
      -                      "enum": [
      -                        "nearest",
      -                        "middle",
      -                        "furthest"
      -                      ],
      -                      "type": "string"
      -                    }
      -                  },
      -                  "required": [
      -                    "minDaysToExpiration",
      -                    "maxDaysToExpiration",
      -                    "preference"
      -                  ],
      -                  "type": "object"
      -                },
      -                "fallbackStrikeSelector": {
      -                  "additionalProperties": false,
      -                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      -                  "properties": {
      -                    "distance": {
      -                      "type": "number"
      -                    },
      -                    "distanceType": {
      -                      "enum": [
      -                        "percent",
      -                        "dollars"
      -                      ],
      -                      "type": "string"
      -                    }
      -                  },
      -                  "required": [
      -                    "distanceType",
      -                    "distance"
      -                  ],
      -                  "type": "object"
      -                },
      -                "greekFilter": {
      -                  "additionalProperties": true,
      -                  "description": "Optional min/max constraints on Greeks during resolution.",
      -                  "type": "object"
      -                },
      -                "liquidityFilter": {
      -                  "additionalProperties": false,
      -                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      -                  "properties": {
      -                    "maxSpreadAbsolute": {
      -                      "type": "number"
      -                    },
      -                    "maxSpreadPct": {
      -                      "type": "number"
      -                    },
      -                    "minBid": {
      -                      "type": "number"
      -                    }
      -                  },
      -                  "type": "object"
      -                },
      -                "optionType": {
      -                  "enum": [
      -                    "call",
      -                    "put"
      -                  ],
      -                  "type": "string"
      -                },
      -                "ratio": {
      -                  "type": "number"
      -                },
      -                "strikeRange": {
      -                  "additionalProperties": true,
      -                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      -                  "type": "object"
      -                },
      -                "strikeSelector": {
      -                  "properties": {
      -                    "distance": {
      -                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      -                      "type": "number"
      -                    },
      -                    "distanceType": {
      -                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      -                      "type": "string"
      -                    }
      -                  },
      -                  "required": [
      -                    "distanceType",
      -                    "distance"
      -                  ],
      -                  "type": "object"
      -                }
      -              },
      -              "required": [
      -                "optionType",
      -                "direction",
      -                "expirationSelector",
      -                "strikeSelector"
      -              ],
      -              "type": "object"
      -            },
      -            "minItems": 1,
      -            "type": "array"
      -          },
      -          "spreadType": {
      -            "enum": [
      -              "vertical",
      -              "calendar",
      -              "diagonal",
      -              "ironCondor",
      -              "straddle",
      -              "strangle",
      -              "custom"
      -            ],
      -            "type": "string"
      -          },
      -          "underlyingSymbol": {
      -            "type": "string"
      -          },
      -          "widthConstraint": {
      -            "additionalProperties": false,
      -            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      -            "properties": {
      -              "minWidthDollars": {
      -                "exclusiveMinimum": 0,
      -                "type": "number"
      -              },
      -              "minWidthPercent": {
      -                "exclusiveMinimum": 0,
      -                "type": "number"
      -              }
      -            },
      -            "type": "object"
      -          }
      -        },
      -        "required": [
      -          "legs"
      -        ],
      -        "type": "object"
      -      },
      -      "type": {
      -        "const": "OpenOption",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "builder"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
      -    "properties": {
      -      "allocationPolicy": {
      -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "expectedReturnShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "riskAversion": {
      -                "maximum": 1000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MeanVariance",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "riskAversion",
      -              "expectedReturnShrinkage",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "RiskParity",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MaximumDiversification",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      },
      -      "exposurePolicy": {
      -        "additionalProperties": false,
      -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      -        "properties": {
      -          "covarianceShrinkage": {
      -            "maximum": 1,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "estimatedTransactionCostBps": {
      -            "maximum": 10000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "lookbackPeriods": {
      -            "maximum": 5000,
      -            "minimum": 2,
      -            "type": "integer"
      -          },
      -          "minimumObservations": {
      -            "maximum": 5000,
      -            "minimum": 2,
      -            "type": "integer"
      -          },
      -          "targetAnnualizedVolatilityPercent": {
      -            "maximum": 1000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "type": {
      -            "const": "VolatilityTarget",
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "lookbackPeriods",
      -          "minimumObservations",
      -          "covarianceShrinkage",
      -          "targetAnnualizedVolatilityPercent",
      -          "estimatedTransactionCostBps"
      -        ],
      -        "type": "object"
      -      },
      -      "limit": {
      -        "minimum": 1,
      -        "type": "number"
      -      },
      -      "perNameAllocation": {
      -        "additionalProperties": true,
      -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      -        "properties": {
      -          "amount": {
      -            "type": "number"
      -          },
      -          "type": {
      -            "enum": [
      -              "dollars",
      -              "percent of portfolio",
      -              "percent of buying power",
      -              "contracts"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "amount"
      -        ],
      -        "type": "object"
      -      },
      -      "pipeline": {
      -        "items": {
      -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      -          "oneOf": [
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "condition": {
      -                  "$ref": "#/$defs/condition"
      -                },
      -                "type": {
      -                  "const": "Filter",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "condition"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "direction": {
      -                  "enum": [
      -                    "Highest",
      -                    "Lowest"
      -                  ],
      -                  "type": "string"
      -                },
      -                "limit": {
      -                  "minimum": 1,
      -                  "type": "number"
      -                },
      -                "metric": {
      -                  "$ref": "#/$defs/indicator"
      -                },
      -                "type": {
      -                  "const": "SelectTop",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "metric",
      -                "limit",
      -                "direction"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "direction": {
      -                  "enum": [
      -                    "Highest",
      -                    "Lowest"
      -                  ],
      -                  "type": "string"
      -                },
      -                "metric": {
      -                  "$ref": "#/$defs/indicator"
      -                },
      -                "percentile": {
      -                  "maximum": 100,
      -                  "minimum": 0,
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "SelectPercentile",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "metric",
      -                "percentile",
      -                "direction"
      -              ],
      -              "type": "object"
      -            }
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "positionScope": {
      -        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
      -        "enum": [
      -          "portfolio",
      -          "strategy"
      -        ],
      -        "type": "string"
      -      },
      -      "sleeves": {
      -        "items": {
      -          "additionalProperties": true,
      -          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
      -          "properties": {
      -            "limit": {
      -              "minimum": 1,
      -              "type": "number"
      -            },
      -            "name": {
      -              "type": "string"
      -            },
      -            "perNameAllocation": {
      -              "additionalProperties": true,
      -              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      -              "properties": {
      -                "amount": {
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "enum": [
      -                    "dollars",
      -                    "percent of portfolio",
      -                    "percent of buying power",
      -                    "contracts"
      -                  ],
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "amount"
      -              ],
      -              "type": "object"
      -            },
      -            "pipeline": {
      -              "items": {
      -                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      -                "oneOf": [
      -                  {
      -                    "additionalProperties": true,
      -                    "properties": {
      -                      "condition": {
      -                        "$ref": "#/$defs/condition"
      -                      },
      -                      "type": {
      -                        "const": "Filter",
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "type",
      -                      "condition"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  {
      -                    "additionalProperties": true,
      -                    "properties": {
      -                      "direction": {
      -                        "enum": [
      -                          "Highest",
      -                          "Lowest"
      -                        ],
      -                        "type": "string"
      -                      },
      -                      "limit": {
      -                        "minimum": 1,
      -                        "type": "number"
      -                      },
      -                      "metric": {
      -                        "$ref": "#/$defs/indicator"
      -                      },
      -                      "type": {
      -                        "const": "SelectTop",
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "type",
      -                      "metric",
      -                      "limit",
      -                      "direction"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  {
      -                    "additionalProperties": true,
      -                    "properties": {
      -                      "direction": {
      -                        "enum": [
      -                          "Highest",
      -                          "Lowest"
      -                        ],
      -                        "type": "string"
      -                      },
      -                      "metric": {
      -                        "$ref": "#/$defs/indicator"
      -                      },
      -                      "percentile": {
      -                        "maximum": 100,
      -                        "minimum": 0,
      -                        "type": "number"
      -                      },
      -                      "type": {
      -                        "const": "SelectPercentile",
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "type",
      -                      "metric",
      -                      "percentile",
      -                      "direction"
      -                    ],
      -                    "type": "object"
      -                  }
      -                ],
      -                "type": "object"
      -              },
      -              "type": "array"
      -            },
      -            "structureTemplates": {
      -              "items": {
      -                "additionalProperties": true,
      -                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      -                "properties": {
      -                  "eligibility": {
      -                    "$ref": "#/$defs/condition"
      -                  },
      -                  "legs": {
      -                    "items": {
      -                      "additionalProperties": true,
      -                      "description": "Single leg of an option builder.",
      -                      "properties": {
      -                        "direction": {
      -                          "enum": [
      -                            "long",
      -                            "short"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "expirationRange": {
      -                          "additionalProperties": true,
      -                          "type": "object"
      -                        },
      -                        "expirationSelector": {
      -                          "properties": {
      -                            "maxDaysToExpiration": {
      -                              "minimum": 0,
      -                              "type": "number"
      -                            },
      -                            "minDaysToExpiration": {
      -                              "minimum": 0,
      -                              "type": "number"
      -                            },
      -                            "preference": {
      -                              "enum": [
      -                                "nearest",
      -                                "middle",
      -                                "furthest"
      -                              ],
      -                              "type": "string"
      -                            }
      -                          },
      -                          "required": [
      -                            "minDaysToExpiration",
      -                            "maxDaysToExpiration",
      -                            "preference"
      -                          ],
      -                          "type": "object"
      -                        },
      -                        "fallbackStrikeSelector": {
      -                          "additionalProperties": false,
      -                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      -                          "properties": {
      -                            "distance": {
      -                              "type": "number"
      -                            },
      -                            "distanceType": {
      -                              "enum": [
      -                                "percent",
      -                                "dollars"
      -                              ],
      -                              "type": "string"
      -                            }
      -                          },
      -                          "required": [
      -                            "distanceType",
      -                            "distance"
      -                          ],
      -                          "type": "object"
      -                        },
      -                        "greekFilter": {
      -                          "additionalProperties": true,
      -                          "description": "Optional min/max constraints on Greeks during resolution.",
      -                          "type": "object"
      -                        },
      -                        "liquidityFilter": {
      -                          "additionalProperties": false,
      -                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      -                          "properties": {
      -                            "maxSpreadAbsolute": {
      -                              "type": "number"
      -                            },
      -                            "maxSpreadPct": {
      -                              "type": "number"
      -                            },
      -                            "minBid": {
      -                              "type": "number"
      -                            }
      -                          },
      -                          "type": "object"
      -                        },
      -                        "optionType": {
      -                          "enum": [
      -                            "call",
      -                            "put"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "ratio": {
      -                          "type": "number"
      -                        },
      -                        "strikeRange": {
      -                          "additionalProperties": true,
      -                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      -                          "type": "object"
      -                        },
      -                        "strikeSelector": {
      -                          "properties": {
      -                            "distance": {
      -                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      -                              "type": "number"
      -                            },
      -                            "distanceType": {
      -                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      -                              "type": "string"
      -                            }
      -                          },
      -                          "required": [
      -                            "distanceType",
      -                            "distance"
      -                          ],
      -                          "type": "object"
      -                        }
      -                      },
      -                      "required": [
      -                        "optionType",
      -                        "direction",
      -                        "expirationSelector",
      -                        "strikeSelector"
      -                      ],
      -                      "type": "object"
      -                    },
      -                    "minItems": 1,
      -                    "type": "array"
      -                  },
      -                  "name": {
      -                    "type": "string"
      -                  },
      -                  "spreadType": {
      -                    "enum": [
      -                      "vertical",
      -                      "calendar",
      -                      "diagonal",
      -                      "ironCondor",
      -                      "straddle",
      -                      "strangle",
      -                      "custom"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "widthConstraint": {
      -                    "additionalProperties": false,
      -                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      -                    "properties": {
      -                      "minWidthDollars": {
      -                        "exclusiveMinimum": 0,
      -                        "type": "number"
      -                      },
      -                      "minWidthPercent": {
      -                        "exclusiveMinimum": 0,
      -                        "type": "number"
      -                      }
      -                    },
      -                    "type": "object"
      -                  }
      -                },
      -                "required": [
      -                  "legs"
      -                ],
      -                "type": "object"
      -              },
      -              "minItems": 1,
      -              "type": "array"
      -            },
      -            "universe": {
      -              "additionalProperties": true,
      -              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      -              "properties": {
      -                "assets": {
      -                  "items": {
      -                    "additionalProperties": true,
      -                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      -                    "properties": {
      -                      "name": {
      -                        "type": "string"
      -                      },
      -                      "symbol": {
      -                        "type": "string"
      -                      },
      -                      "type": {
      -                        "enum": [
      -                          "Stock",
      -                          "Cryptocurrency",
      -                          "Option",
      -                          "Other"
      -                        ],
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "type",
      -                      "symbol"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "type": "array"
      -                },
      -                "source": {
      -                  "enum": [
      -                    "ALL_US_STOCKS",
      -                    "SP500",
      -                    "NASDAQ100",
      -                    "DJIA",
      -                    "CRYPTO",
      -                    "SPECIFIC_ASSETS"
      -                  ],
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "source"
      -              ],
      -              "type": "object"
      -            },
      -            "weightIndicator": {
      -              "$ref": "#/$defs/indicator"
      -            }
      -          },
      -          "required": [
      -            "name"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "structureTemplates": {
      -        "items": {
      -          "additionalProperties": true,
      -          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      -          "properties": {
      -            "eligibility": {
      -              "$ref": "#/$defs/condition"
      -            },
      -            "legs": {
      -              "items": {
      -                "additionalProperties": true,
      -                "description": "Single leg of an option builder.",
      -                "properties": {
      -                  "direction": {
      -                    "enum": [
      -                      "long",
      -                      "short"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "expirationRange": {
      -                    "additionalProperties": true,
      -                    "type": "object"
      -                  },
      -                  "expirationSelector": {
      -                    "properties": {
      -                      "maxDaysToExpiration": {
      -                        "minimum": 0,
      -                        "type": "number"
      -                      },
      -                      "minDaysToExpiration": {
      -                        "minimum": 0,
      -                        "type": "number"
      -                      },
      -                      "preference": {
      -                        "enum": [
      -                          "nearest",
      -                          "middle",
      -                          "furthest"
      -                        ],
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "minDaysToExpiration",
      -                      "maxDaysToExpiration",
      -                      "preference"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "fallbackStrikeSelector": {
      -                    "additionalProperties": false,
      -                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      -                    "properties": {
      -                      "distance": {
      -                        "type": "number"
      -                      },
      -                      "distanceType": {
      -                        "enum": [
      -                          "percent",
      -                          "dollars"
      -                        ],
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "distanceType",
      -                      "distance"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "greekFilter": {
      -                    "additionalProperties": true,
      -                    "description": "Optional min/max constraints on Greeks during resolution.",
      -                    "type": "object"
      -                  },
      -                  "liquidityFilter": {
      -                    "additionalProperties": false,
      -                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      -                    "properties": {
      -                      "maxSpreadAbsolute": {
      -                        "type": "number"
      -                      },
      -                      "maxSpreadPct": {
      -                        "type": "number"
      -                      },
      -                      "minBid": {
      -                        "type": "number"
      -                      }
      -                    },
      -                    "type": "object"
      -                  },
      -                  "optionType": {
      -                    "enum": [
      -                      "call",
      -                      "put"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "ratio": {
      -                    "type": "number"
      -                  },
      -                  "strikeRange": {
      -                    "additionalProperties": true,
      -                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      -                    "type": "object"
      -                  },
      -                  "strikeSelector": {
      -                    "properties": {
      -                      "distance": {
      -                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      -                        "type": "number"
      -                      },
      -                      "distanceType": {
      -                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "distanceType",
      -                      "distance"
      -                    ],
      -                    "type": "object"
      -                  }
      -                },
      -                "required": [
      -                  "optionType",
      -                  "direction",
      -                  "expirationSelector",
      -                  "strikeSelector"
      -                ],
      -                "type": "object"
      -              },
      -              "minItems": 1,
      -              "type": "array"
      -            },
      -            "name": {
      -              "type": "string"
      -            },
      -            "spreadType": {
      -              "enum": [
      -                "vertical",
      -                "calendar",
      -                "diagonal",
      -                "ironCondor",
      -                "straddle",
      -                "strangle",
      -                "custom"
      -              ],
      -              "type": "string"
      -            },
      -            "widthConstraint": {
      -              "additionalProperties": false,
      -              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      -              "properties": {
      -                "minWidthDollars": {
      -                  "exclusiveMinimum": 0,
      -                  "type": "number"
      -                },
      -                "minWidthPercent": {
      -                  "exclusiveMinimum": 0,
      -                  "type": "number"
      -                }
      -              },
      -              "type": "object"
      -            }
      -          },
      -          "required": [
      -            "legs"
      -          ],
      -          "type": "object"
      -        },
      -        "minItems": 1,
      -        "type": "array"
      -      },
      -      "totalBudget": {
      -        "additionalProperties": true,
      -        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
      -        "properties": {
      -          "amount": {
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "type": {
      -            "enum": [
      -              "dollars",
      -              "percent of portfolio"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "amount"
      -        ],
      -        "type": "object"
      -      },
      -      "type": {
      -        "const": "RebalanceOption",
      -        "type": "string"
      -      },
      -      "universe": {
      -        "additionalProperties": true,
      -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      -        "properties": {
      -          "assets": {
      -            "items": {
      -              "additionalProperties": true,
      -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      -              "properties": {
      -                "name": {
      -                  "type": "string"
      -                },
      -                "symbol": {
      -                  "type": "string"
      -                },
      -                "type": {
      -                  "enum": [
      -                    "Stock",
      -                    "Cryptocurrency",
      -                    "Option",
      -                    "Other"
      -                  ],
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "symbol"
      -              ],
      -              "type": "object"
      -            },
      -            "type": "array"
      -          },
      -          "source": {
      -            "enum": [
      -              "ALL_US_STOCKS",
      -              "SP500",
      -              "NASDAQ100",
      -              "DJIA",
      -              "CRYPTO",
      -              "SPECIFIC_ASSETS"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "source"
      -        ],
      -        "type": "object"
      -      },
      -      "weightIndicator": {
      -        "$ref": "#/$defs/indicator"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "universe",
      -      "pipeline",
      -      "weightIndicator",
      -      "structureTemplates"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
      -    "properties": {
      -      "closeScope": {
      -        "enum": [
      -          "spread",
      -          "leg"
      -        ],
      -        "type": "string"
      -      },
      -      "direction": {
      -        "enum": [
      -          "long",
      -          "short"
      -        ],
      -        "type": "string"
      -      },
      -      "optionType": {
      -        "enum": [
      -          "call",
      -          "put"
      -        ],
      -        "type": "string"
      -      },
      -      "quantity": {
      -        "additionalProperties": true,
      -        "description": "How many contracts to close. Defaults to all matching when omitted.",
      -        "type": "object"
      -      },
      -      "spreadType": {
      -        "enum": [
      -          "vertical",
      -          "calendar",
      -          "diagonal",
      -          "ironCondor",
      -          "straddle",
      -          "strangle",
      -          "custom"
      -        ],
      -        "type": "string"
      -      },
      -      "triggers": {
      -        "items": {
      -          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
      -          "oneOf": [
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "maxPnlPercent": {
      -                  "type": "number"
      -                },
      -                "minPnlPercent": {
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "pnl",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "maxDte": {
      -                  "type": "number"
      -                },
      -                "minDte": {
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "dte",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "maxDaysHeld": {
      -                  "type": "number"
      -                },
      -                "minDaysHeld": {
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "daysHeld",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "maxIv": {
      -                  "type": "number"
      -                },
      -                "maxSpreadDelta": {
      -                  "type": "number"
      -                },
      -                "maxSpreadTheta": {
      -                  "type": "number"
      -                },
      -                "minIv": {
      -                  "type": "number"
      -                },
      -                "minSpreadDelta": {
      -                  "type": "number"
      -                },
      -                "minSpreadTheta": {
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "greeks",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type"
      -              ],
      -              "type": "object"
      -            }
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "type": {
      -        "const": "CloseOption",
      -        "type": "string"
      -      },
      -      "underlyings": {
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": true,
      +    "description": "Buy or Sell a stock/crypto position.",
      +    "properties": {
      +      "amount": {
      +        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
      +        "properties": {
      +          "amount": {
      +            "type": "number"
      +          },
      +          "type": {
      +            "enum": [
      +              "percent of portfolio",
      +              "percent of buying power",
      +              "percent of current positions",
      +              "dollars",
      +              "number of assets"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      "targetAsset": {
      +        "additionalProperties": true,
      +        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +        "properties": {
      +          "name": {
      +            "type": "string"
      +          },
      +          "symbol": {
      +            "type": "string"
      +          },
      +          "type": {
      +            "enum": [
      +              "Stock",
      +              "Cryptocurrency",
      +              "Option",
      +              "Other"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "symbol"
      +        ],
      +        "type": "object"
      +      },
      +      "type": {
      +        "enum": [
      +          "Buy",
      +          "Sell"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "targetAsset",
      +      "amount"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "Send an alert message (no order).",
      +    "properties": {
      +      "message": {
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "Alert",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "message"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
      +    "properties": {
      +      "allocationPolicy": {
      +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "expectedReturnShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "riskAversion": {
      +                "maximum": 1000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "MeanVariance",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "riskAversion",
      +              "expectedReturnShrinkage",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "RiskParity",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "MaximumDiversification",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      },
      +      "canSell": {
      +        "$ref": "#/$defs/condition",
      +        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
      +      },
      +      "deploymentPercent": {
      +        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "exposurePolicy": {
      +        "additionalProperties": false,
      +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      +        "properties": {
      +          "covarianceShrinkage": {
      +            "maximum": 1,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "estimatedTransactionCostBps": {
      +            "maximum": 10000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "lookbackPeriods": {
      +            "maximum": 5000,
      +            "minimum": 2,
      +            "type": "integer"
      +          },
      +          "minimumObservations": {
      +            "maximum": 5000,
      +            "minimum": 2,
      +            "type": "integer"
      +          },
      +          "targetAnnualizedVolatilityPercent": {
      +            "maximum": 1000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "type": {
      +            "const": "VolatilityTarget",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "lookbackPeriods",
      +          "minimumObservations",
      +          "covarianceShrinkage",
      +          "targetAnnualizedVolatilityPercent",
      +          "estimatedTransactionCostBps"
      +        ],
      +        "type": "object"
      +      },
      +      "limit": {
      +        "minimum": 1,
      +        "type": "number"
      +      },
      +      "perNameAllocation": {
      +        "additionalProperties": true,
      +        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.",
      +        "properties": {
      +          "amount": {
      +            "exclusiveMinimum": 0,
      +            "type": "number"
      +          },
      +          "type": {
      +            "enum": [
      +              "percent of portfolio",
      +              "dollars"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      "pipeline": {
      +        "items": {
      +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +          "oneOf": [
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "condition": {
      +                  "$ref": "#/$defs/condition"
      +                },
      +                "type": {
      +                  "const": "Filter",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "condition"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "Highest",
      +                    "Lowest"
      +                  ],
      +                  "type": "string"
      +                },
      +                "limit": {
      +                  "minimum": 1,
      +                  "type": "number"
      +                },
      +                "metric": {
      +                  "$ref": "#/$defs/indicator"
      +                },
      +                "type": {
      +                  "const": "SelectTop",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "metric",
      +                "limit",
      +                "direction"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "Highest",
      +                    "Lowest"
      +                  ],
      +                  "type": "string"
      +                },
      +                "metric": {
      +                  "$ref": "#/$defs/indicator"
      +                },
      +                "percentile": {
      +                  "maximum": 100,
      +                  "minimum": 0,
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "SelectPercentile",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "metric",
      +                "percentile",
      +                "direction"
      +              ],
      +              "type": "object"
      +            }
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "type": {
      +        "const": "DynamicRebalance",
      +        "type": "string"
      +      },
      +      "universe": {
      +        "additionalProperties": true,
      +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +        "properties": {
      +          "assets": {
      +            "items": {
      +              "additionalProperties": true,
      +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +              "properties": {
      +                "name": {
      +                  "type": "string"
      +                },
      +                "symbol": {
      +                  "type": "string"
      +                },
      +                "type": {
      +                  "enum": [
      +                    "Stock",
      +                    "Cryptocurrency",
      +                    "Option",
      +                    "Other"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "symbol"
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "source": {
      +            "enum": [
      +              "ALL_US_STOCKS",
      +              "SP500",
      +              "NASDAQ100",
      +              "DJIA",
      +              "CRYPTO",
      +              "SPECIFIC_ASSETS"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "source"
      +        ],
      +        "type": "object"
      +      },
      +      "weightIndicator": {
      +        "$ref": "#/$defs/indicator"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "universe",
      +      "pipeline",
      +      "weightIndicator"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
      +    "properties": {
      +      "continueExisting": {
      +        "type": "boolean"
      +      },
      +      "cooldownMinutes": {
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "executionModel": {
      +        "type": "string"
      +      },
      +      "includeMarketData": {
      +        "type": "boolean"
      +      },
      +      "initialMessage": {
      +        "type": "string"
      +      },
      +      "maxIterations": {
      +        "minimum": 1,
      +        "type": "number"
      +      },
      +      "planningModel": {
      +        "type": "string"
      +      },
      +      "skipPlanning": {
      +        "type": "boolean"
      +      },
      +      "type": {
      +        "const": "LaunchAgent",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "planningModel",
      +      "executionModel",
      +      "initialMessage",
      +      "maxIterations",
      +      "includeMarketData",
      +      "continueExisting",
      +      "skipPlanning"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
      +    "properties": {
      +      "against": {
      +        "additionalProperties": true,
      +        "description": "Optional parent-position selector (e.g. for covered calls).",
      +        "type": "object"
      +      },
      +      "allocation": {
      +        "additionalProperties": true,
      +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +        "properties": {
      +          "amount": {
      +            "type": "number"
      +          },
      +          "type": {
      +            "enum": [
      +              "dollars",
      +              "percent of portfolio",
      +              "percent of buying power",
      +              "contracts",
      +              "percent of realized premium"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      "builder": {
      +        "additionalProperties": true,
      +        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
      +        "properties": {
      +          "dynamicUnderlying": {
      +            "additionalProperties": true,
      +            "properties": {
      +              "limit": {
      +                "minimum": 1,
      +                "type": "number"
      +              },
      +              "pipeline": {
      +                "items": {
      +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                  "oneOf": [
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "condition": {
      +                          "$ref": "#/$defs/condition"
      +                        },
      +                        "type": {
      +                          "const": "Filter",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "condition"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "Highest",
      +                            "Lowest"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "limit": {
      +                          "minimum": 1,
      +                          "type": "number"
      +                        },
      +                        "metric": {
      +                          "$ref": "#/$defs/indicator"
      +                        },
      +                        "type": {
      +                          "const": "SelectTop",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "metric",
      +                        "limit",
      +                        "direction"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "Highest",
      +                            "Lowest"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "metric": {
      +                          "$ref": "#/$defs/indicator"
      +                        },
      +                        "percentile": {
      +                          "maximum": 100,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "SelectPercentile",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "metric",
      +                        "percentile",
      +                        "direction"
      +                      ],
      +                      "type": "object"
      +                    }
      +                  ],
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "universe": {
      +                "additionalProperties": true,
      +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +                "properties": {
      +                  "assets": {
      +                    "items": {
      +                      "additionalProperties": true,
      +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                      "properties": {
      +                        "name": {
      +                          "type": "string"
      +                        },
      +                        "symbol": {
      +                          "type": "string"
      +                        },
      +                        "type": {
      +                          "enum": [
      +                            "Stock",
      +                            "Cryptocurrency",
      +                            "Option",
      +                            "Other"
      +                          ],
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "symbol"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "type": "array"
      +                  },
      +                  "source": {
      +                    "enum": [
      +                      "ALL_US_STOCKS",
      +                      "SP500",
      +                      "NASDAQ100",
      +                      "DJIA",
      +                      "CRYPTO",
      +                      "SPECIFIC_ASSETS"
      +                    ],
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "source"
      +                ],
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "universe"
      +            ],
      +            "type": "object"
      +          },
      +          "legs": {
      +            "items": {
      +              "additionalProperties": true,
      +              "description": "Single leg of an option builder.",
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "long",
      +                    "short"
      +                  ],
      +                  "type": "string"
      +                },
      +                "expirationRange": {
      +                  "additionalProperties": true,
      +                  "type": "object"
      +                },
      +                "expirationSelector": {
      +                  "properties": {
      +                    "maxDaysToExpiration": {
      +                      "minimum": 0,
      +                      "type": "number"
      +                    },
      +                    "minDaysToExpiration": {
      +                      "minimum": 0,
      +                      "type": "number"
      +                    },
      +                    "preference": {
      +                      "enum": [
      +                        "nearest",
      +                        "middle",
      +                        "furthest"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "minDaysToExpiration",
      +                    "maxDaysToExpiration",
      +                    "preference"
      +                  ],
      +                  "type": "object"
      +                },
      +                "fallbackStrikeSelector": {
      +                  "additionalProperties": false,
      +                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                  "properties": {
      +                    "distance": {
      +                      "type": "number"
      +                    },
      +                    "distanceType": {
      +                      "enum": [
      +                        "percent",
      +                        "dollars"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "distanceType",
      +                    "distance"
      +                  ],
      +                  "type": "object"
      +                },
      +                "greekFilter": {
      +                  "additionalProperties": true,
      +                  "description": "Optional min/max constraints on Greeks during resolution.",
      +                  "type": "object"
      +                },
      +                "liquidityFilter": {
      +                  "additionalProperties": false,
      +                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                  "properties": {
      +                    "maxSpreadAbsolute": {
      +                      "type": "number"
      +                    },
      +                    "maxSpreadPct": {
      +                      "type": "number"
      +                    },
      +                    "minBid": {
      +                      "type": "number"
      +                    }
      +                  },
      +                  "type": "object"
      +                },
      +                "optionType": {
      +                  "enum": [
      +                    "call",
      +                    "put"
      +                  ],
      +                  "type": "string"
      +                },
      +                "ratio": {
      +                  "type": "number"
      +                },
      +                "strikeRange": {
      +                  "additionalProperties": true,
      +                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                  "type": "object"
      +                },
      +                "strikeSelector": {
      +                  "properties": {
      +                    "distance": {
      +                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                      "type": "number"
      +                    },
      +                    "distanceType": {
      +                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "distanceType",
      +                    "distance"
      +                  ],
      +                  "type": "object"
      +                }
      +              },
      +              "required": [
      +                "optionType",
      +                "direction",
      +                "expirationSelector",
      +                "strikeSelector"
      +              ],
      +              "type": "object"
      +            },
      +            "minItems": 1,
      +            "type": "array"
      +          },
      +          "spreadType": {
      +            "enum": [
      +              "vertical",
      +              "calendar",
      +              "diagonal",
      +              "ironCondor",
      +              "straddle",
      +              "strangle",
      +              "custom"
      +            ],
      +            "type": "string"
      +          },
      +          "underlyingSymbol": {
      +            "type": "string"
      +          },
      +          "widthConstraint": {
      +            "additionalProperties": false,
      +            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +            "properties": {
      +              "minWidthDollars": {
      +                "exclusiveMinimum": 0,
      +                "type": "number"
      +              },
      +              "minWidthPercent": {
      +                "exclusiveMinimum": 0,
      +                "type": "number"
      +              }
      +            },
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "legs"
      +        ],
      +        "type": "object"
      +      },
      +      "type": {
      +        "const": "OpenOption",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "builder"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
      +    "properties": {
      +      "allocationPolicy": {
      +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "expectedReturnShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "riskAversion": {
      +                "maximum": 1000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "MeanVariance",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "riskAversion",
      +              "expectedReturnShrinkage",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "RiskParity",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "MaximumDiversification",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      },
      +      "exposurePolicy": {
      +        "additionalProperties": false,
      +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      +        "properties": {
      +          "covarianceShrinkage": {
      +            "maximum": 1,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "estimatedTransactionCostBps": {
      +            "maximum": 10000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "lookbackPeriods": {
      +            "maximum": 5000,
      +            "minimum": 2,
      +            "type": "integer"
      +          },
      +          "minimumObservations": {
      +            "maximum": 5000,
      +            "minimum": 2,
      +            "type": "integer"
      +          },
      +          "targetAnnualizedVolatilityPercent": {
      +            "maximum": 1000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "type": {
      +            "const": "VolatilityTarget",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "lookbackPeriods",
      +          "minimumObservations",
      +          "covarianceShrinkage",
      +          "targetAnnualizedVolatilityPercent",
      +          "estimatedTransactionCostBps"
      +        ],
      +        "type": "object"
      +      },
      +      "limit": {
      +        "minimum": 1,
      +        "type": "number"
      +      },
      +      "perNameAllocation": {
      +        "additionalProperties": true,
      +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +        "properties": {
      +          "amount": {
      +            "type": "number"
      +          },
      +          "type": {
      +            "enum": [
      +              "dollars",
      +              "percent of portfolio",
      +              "percent of buying power",
      +              "contracts",
      +              "percent of realized premium"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      "pipeline": {
      +        "items": {
      +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +          "oneOf": [
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "condition": {
      +                  "$ref": "#/$defs/condition"
      +                },
      +                "type": {
      +                  "const": "Filter",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "condition"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "Highest",
      +                    "Lowest"
      +                  ],
      +                  "type": "string"
      +                },
      +                "limit": {
      +                  "minimum": 1,
      +                  "type": "number"
      +                },
      +                "metric": {
      +                  "$ref": "#/$defs/indicator"
      +                },
      +                "type": {
      +                  "const": "SelectTop",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "metric",
      +                "limit",
      +                "direction"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "Highest",
      +                    "Lowest"
      +                  ],
      +                  "type": "string"
      +                },
      +                "metric": {
      +                  "$ref": "#/$defs/indicator"
      +                },
      +                "percentile": {
      +                  "maximum": 100,
      +                  "minimum": 0,
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "SelectPercentile",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "metric",
      +                "percentile",
      +                "direction"
      +              ],
      +              "type": "object"
      +            }
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "positionScope": {
      +        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
      +        "enum": [
      +          "portfolio",
      +          "strategy"
      +        ],
      +        "type": "string"
      +      },
      +      "sleeves": {
      +        "items": {
      +          "additionalProperties": true,
      +          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
      +          "properties": {
      +            "limit": {
      +              "minimum": 1,
      +              "type": "number"
      +            },
      +            "name": {
      +              "type": "string"
      +            },
      +            "perNameAllocation": {
      +              "additionalProperties": true,
      +              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +              "properties": {
      +                "amount": {
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "enum": [
      +                    "dollars",
      +                    "percent of portfolio",
      +                    "percent of buying power",
      +                    "contracts",
      +                    "percent of realized premium"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "amount"
      +              ],
      +              "type": "object"
      +            },
      +            "pipeline": {
      +              "items": {
      +                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                "oneOf": [
      +                  {
      +                    "additionalProperties": true,
      +                    "properties": {
      +                      "condition": {
      +                        "$ref": "#/$defs/condition"
      +                      },
      +                      "type": {
      +                        "const": "Filter",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "condition"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": true,
      +                    "properties": {
      +                      "direction": {
      +                        "enum": [
      +                          "Highest",
      +                          "Lowest"
      +                        ],
      +                        "type": "string"
      +                      },
      +                      "limit": {
      +                        "minimum": 1,
      +                        "type": "number"
      +                      },
      +                      "metric": {
      +                        "$ref": "#/$defs/indicator"
      +                      },
      +                      "type": {
      +                        "const": "SelectTop",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "metric",
      +                      "limit",
      +                      "direction"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": true,
      +                    "properties": {
      +                      "direction": {
      +                        "enum": [
      +                          "Highest",
      +                          "Lowest"
      +                        ],
      +                        "type": "string"
      +                      },
      +                      "metric": {
      +                        "$ref": "#/$defs/indicator"
      +                      },
      +                      "percentile": {
      +                        "maximum": 100,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "SelectPercentile",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "metric",
      +                      "percentile",
      +                      "direction"
      +                    ],
      +                    "type": "object"
      +                  }
      +                ],
      +                "type": "object"
      +              },
      +              "type": "array"
      +            },
      +            "structureTemplates": {
      +              "items": {
      +                "additionalProperties": true,
      +                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      +                "properties": {
      +                  "eligibility": {
      +                    "$ref": "#/$defs/condition"
      +                  },
      +                  "legs": {
      +                    "items": {
      +                      "additionalProperties": true,
      +                      "description": "Single leg of an option builder.",
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "long",
      +                            "short"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "expirationRange": {
      +                          "additionalProperties": true,
      +                          "type": "object"
      +                        },
      +                        "expirationSelector": {
      +                          "properties": {
      +                            "maxDaysToExpiration": {
      +                              "minimum": 0,
      +                              "type": "number"
      +                            },
      +                            "minDaysToExpiration": {
      +                              "minimum": 0,
      +                              "type": "number"
      +                            },
      +                            "preference": {
      +                              "enum": [
      +                                "nearest",
      +                                "middle",
      +                                "furthest"
      +                              ],
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "minDaysToExpiration",
      +                            "maxDaysToExpiration",
      +                            "preference"
      +                          ],
      +                          "type": "object"
      +                        },
      +                        "fallbackStrikeSelector": {
      +                          "additionalProperties": false,
      +                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                          "properties": {
      +                            "distance": {
      +                              "type": "number"
      +                            },
      +                            "distanceType": {
      +                              "enum": [
      +                                "percent",
      +                                "dollars"
      +                              ],
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "distanceType",
      +                            "distance"
      +                          ],
      +                          "type": "object"
      +                        },
      +                        "greekFilter": {
      +                          "additionalProperties": true,
      +                          "description": "Optional min/max constraints on Greeks during resolution.",
      +                          "type": "object"
      +                        },
      +                        "liquidityFilter": {
      +                          "additionalProperties": false,
      +                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                          "properties": {
      +                            "maxSpreadAbsolute": {
      +                              "type": "number"
      +                            },
      +                            "maxSpreadPct": {
      +                              "type": "number"
      +                            },
      +                            "minBid": {
      +                              "type": "number"
      +                            }
      +                          },
      +                          "type": "object"
      +                        },
      +                        "optionType": {
      +                          "enum": [
      +                            "call",
      +                            "put"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "ratio": {
      +                          "type": "number"
      +                        },
      +                        "strikeRange": {
      +                          "additionalProperties": true,
      +                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                          "type": "object"
      +                        },
      +                        "strikeSelector": {
      +                          "properties": {
      +                            "distance": {
      +                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                              "type": "number"
      +                            },
      +                            "distanceType": {
      +                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "distanceType",
      +                            "distance"
      +                          ],
      +                          "type": "object"
      +                        }
      +                      },
      +                      "required": [
      +                        "optionType",
      +                        "direction",
      +                        "expirationSelector",
      +                        "strikeSelector"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "minItems": 1,
      +                    "type": "array"
      +                  },
      +                  "name": {
      +                    "type": "string"
      +                  },
      +                  "spreadType": {
      +                    "enum": [
      +                      "vertical",
      +                      "calendar",
      +                      "diagonal",
      +                      "ironCondor",
      +                      "straddle",
      +                      "strangle",
      +                      "custom"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "widthConstraint": {
      +                    "additionalProperties": false,
      +                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +                    "properties": {
      +                      "minWidthDollars": {
      +                        "exclusiveMinimum": 0,
      +                        "type": "number"
      +                      },
      +                      "minWidthPercent": {
      +                        "exclusiveMinimum": 0,
      +                        "type": "number"
      +                      }
      +                    },
      +                    "type": "object"
      +                  }
      +                },
      +                "required": [
      +                  "legs"
      +                ],
      +                "type": "object"
      +              },
      +              "minItems": 1,
      +              "type": "array"
      +            },
      +            "universe": {
      +              "additionalProperties": true,
      +              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +              "properties": {
      +                "assets": {
      +                  "items": {
      +                    "additionalProperties": true,
      +                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                    "properties": {
      +                      "name": {
      +                        "type": "string"
      +                      },
      +                      "symbol": {
      +                        "type": "string"
      +                      },
      +                      "type": {
      +                        "enum": [
      +                          "Stock",
      +                          "Cryptocurrency",
      +                          "Option",
      +                          "Other"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "symbol"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "type": "array"
      +                },
      +                "source": {
      +                  "enum": [
      +                    "ALL_US_STOCKS",
      +                    "SP500",
      +                    "NASDAQ100",
      +                    "DJIA",
      +                    "CRYPTO",
      +                    "SPECIFIC_ASSETS"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "source"
      +              ],
      +              "type": "object"
      +            },
      +            "weightIndicator": {
      +              "$ref": "#/$defs/indicator"
      +            }
      +          },
      +          "required": [
      +            "name"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "structureTemplates": {
      +        "items": {
      +          "additionalProperties": true,
      +          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      +          "properties": {
      +            "eligibility": {
      +              "$ref": "#/$defs/condition"
      +            },
      +            "legs": {
      +              "items": {
      +                "additionalProperties": true,
      +                "description": "Single leg of an option builder.",
      +                "properties": {
      +                  "direction": {
      +                    "enum": [
      +                      "long",
      +                      "short"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "expirationRange": {
      +                    "additionalProperties": true,
      +                    "type": "object"
      +                  },
      +                  "expirationSelector": {
      +                    "properties": {
      +                      "maxDaysToExpiration": {
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "minDaysToExpiration": {
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "preference": {
      +                        "enum": [
      +                          "nearest",
      +                          "middle",
      +                          "furthest"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "minDaysToExpiration",
      +                      "maxDaysToExpiration",
      +                      "preference"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "fallbackStrikeSelector": {
      +                    "additionalProperties": false,
      +                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                    "properties": {
      +                      "distance": {
      +                        "type": "number"
      +                      },
      +                      "distanceType": {
      +                        "enum": [
      +                          "percent",
      +                          "dollars"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "distanceType",
      +                      "distance"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "greekFilter": {
      +                    "additionalProperties": true,
      +                    "description": "Optional min/max constraints on Greeks during resolution.",
      +                    "type": "object"
      +                  },
      +                  "liquidityFilter": {
      +                    "additionalProperties": false,
      +                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                    "properties": {
      +                      "maxSpreadAbsolute": {
      +                        "type": "number"
      +                      },
      +                      "maxSpreadPct": {
      +                        "type": "number"
      +                      },
      +                      "minBid": {
      +                        "type": "number"
      +                      }
      +                    },
      +                    "type": "object"
      +                  },
      +                  "optionType": {
      +                    "enum": [
      +                      "call",
      +                      "put"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "ratio": {
      +                    "type": "number"
      +                  },
      +                  "strikeRange": {
      +                    "additionalProperties": true,
      +                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                    "type": "object"
      +                  },
      +                  "strikeSelector": {
      +                    "properties": {
      +                      "distance": {
      +                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                        "type": "number"
      +                      },
      +                      "distanceType": {
      +                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "distanceType",
      +                      "distance"
      +                    ],
      +                    "type": "object"
      +                  }
      +                },
      +                "required": [
      +                  "optionType",
      +                  "direction",
      +                  "expirationSelector",
      +                  "strikeSelector"
      +                ],
      +                "type": "object"
      +              },
      +              "minItems": 1,
      +              "type": "array"
      +            },
      +            "name": {
      +              "type": "string"
      +            },
      +            "spreadType": {
      +              "enum": [
      +                "vertical",
      +                "calendar",
      +                "diagonal",
      +                "ironCondor",
      +                "straddle",
      +                "strangle",
      +                "custom"
      +              ],
      +              "type": "string"
      +            },
      +            "widthConstraint": {
      +              "additionalProperties": false,
      +              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +              "properties": {
      +                "minWidthDollars": {
      +                  "exclusiveMinimum": 0,
      +                  "type": "number"
      +                },
      +                "minWidthPercent": {
      +                  "exclusiveMinimum": 0,
      +                  "type": "number"
      +                }
      +              },
      +              "type": "object"
      +            }
      +          },
      +          "required": [
      +            "legs"
      +          ],
      +          "type": "object"
      +        },
      +        "minItems": 1,
      +        "type": "array"
      +      },
      +      "totalBudget": {
      +        "additionalProperties": true,
      +        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
      +        "properties": {
      +          "amount": {
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "type": {
      +            "enum": [
      +              "dollars",
      +              "percent of portfolio"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      "type": {
      +        "const": "RebalanceOption",
      +        "type": "string"
      +      },
      +      "universe": {
      +        "additionalProperties": true,
      +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +        "properties": {
      +          "assets": {
      +            "items": {
      +              "additionalProperties": true,
      +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +              "properties": {
      +                "name": {
      +                  "type": "string"
      +                },
      +                "symbol": {
      +                  "type": "string"
      +                },
      +                "type": {
      +                  "enum": [
      +                    "Stock",
      +                    "Cryptocurrency",
      +                    "Option",
      +                    "Other"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "symbol"
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "source": {
      +            "enum": [
      +              "ALL_US_STOCKS",
      +              "SP500",
      +              "NASDAQ100",
      +              "DJIA",
      +              "CRYPTO",
      +              "SPECIFIC_ASSETS"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "source"
      +        ],
      +        "type": "object"
      +      },
      +      "weightIndicator": {
      +        "$ref": "#/$defs/indicator"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "universe",
      +      "pipeline",
      +      "weightIndicator",
      +      "structureTemplates"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
      +    "properties": {
      +      "closeScope": {
      +        "enum": [
      +          "spread",
      +          "leg"
      +        ],
      +        "type": "string"
      +      },
      +      "direction": {
      +        "enum": [
      +          "long",
      +          "short"
      +        ],
      +        "type": "string"
      +      },
      +      "optionType": {
      +        "enum": [
      +          "call",
      +          "put"
      +        ],
      +        "type": "string"
      +      },
      +      "quantity": {
      +        "additionalProperties": true,
      +        "description": "How many contracts to close. Defaults to all matching when omitted.",
      +        "type": "object"
      +      },
      +      "spreadType": {
      +        "enum": [
      +          "vertical",
      +          "calendar",
      +          "diagonal",
      +          "ironCondor",
      +          "straddle",
      +          "strangle",
      +          "custom"
      +        ],
      +        "type": "string"
      +      },
      +      "triggers": {
      +        "items": {
      +          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
      +          "oneOf": [
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "maxPnlPercent": {
      +                  "type": "number"
      +                },
      +                "minPnlPercent": {
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "pnl",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "maxDte": {
      +                  "type": "number"
      +                },
      +                "minDte": {
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "dte",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "maxDaysHeld": {
      +                  "type": "number"
      +                },
      +                "minDaysHeld": {
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "daysHeld",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "maxIv": {
      +                  "type": "number"
      +                },
      +                "maxSpreadDelta": {
      +                  "type": "number"
      +                },
      +                "maxSpreadTheta": {
      +                  "type": "number"
      +                },
      +                "minIv": {
      +                  "type": "number"
      +                },
      +                "minSpreadDelta": {
      +                  "type": "number"
      +                },
      +                "minSpreadTheta": {
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "greeks",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type"
      +              ],
      +              "type": "object"
      +            }
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "type": {
      +        "const": "CloseOption",
      +        "type": "string"
      +      },
      +      "underlyings": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  }
      +]
    • changedInput schema / properties / operations / items / properties / strategyObjects / items / properties / action / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": true,
      -    "description": "Buy or Sell a stock/crypto position.",
      -    "properties": {
      -      "amount": {
      -        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
      -        "properties": {
      -          "amount": {
      -            "type": "number"
      -          },
      -          "type": {
      -            "enum": [
      -              "percent of portfolio",
      -              "percent of buying power",
      -              "percent of current positions",
      -              "dollars",
      -              "number of assets"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "amount"
      -        ],
      -        "type": "object"
      -      },
      -      "targetAsset": {
      -        "additionalProperties": true,
      -        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      -        "properties": {
      -          "name": {
      -            "type": "string"
      -          },
      -          "symbol": {
      -            "type": "string"
      -          },
      -          "type": {
      -            "enum": [
      -              "Stock",
      -              "Cryptocurrency",
      -              "Option",
      -              "Other"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "symbol"
      -        ],
      -        "type": "object"
      -      },
      -      "type": {
      -        "enum": [
      -          "Buy",
      -          "Sell"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "targetAsset",
      -      "amount"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "Send an alert message (no order).",
      -    "properties": {
      -      "message": {
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "Alert",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "message"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
      -    "properties": {
      -      "allocationPolicy": {
      -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "expectedReturnShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "riskAversion": {
      -                "maximum": 1000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MeanVariance",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "riskAversion",
      -              "expectedReturnShrinkage",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "RiskParity",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MaximumDiversification",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      },
      -      "canSell": {
      -        "$ref": "#/$defs/condition",
      -        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
      -      },
      -      "deploymentPercent": {
      -        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "exposurePolicy": {
      -        "additionalProperties": false,
      -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      -        "properties": {
      -          "covarianceShrinkage": {
      -            "maximum": 1,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "estimatedTransactionCostBps": {
      -            "maximum": 10000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "lookbackPeriods": {
      -            "maximum": 5000,
      -            "minimum": 2,
      -            "type": "integer"
      -          },
      -          "minimumObservations": {
      -            "maximum": 5000,
      -            "minimum": 2,
      -            "type": "integer"
      -          },
      -          "targetAnnualizedVolatilityPercent": {
      -            "maximum": 1000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "type": {
      -            "const": "VolatilityTarget",
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "lookbackPeriods",
      -          "minimumObservations",
      -          "covarianceShrinkage",
      -          "targetAnnualizedVolatilityPercent",
      -          "estimatedTransactionCostBps"
      -        ],
      -        "type": "object"
      -      },
      -      "limit": {
      -        "minimum": 1,
      -        "type": "number"
      -      },
      -      "perNameAllocation": {
      -        "additionalProperties": true,
      -        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
      -        "properties": {
      -          "amount": {
      -            "exclusiveMinimum": 0,
      -            "type": "number"
      -          },
      -          "type": {
      -            "enum": [
      -              "percent of portfolio",
      -              "dollars"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "amount"
      -        ],
      -        "type": "object"
      -      },
      -      "pipeline": {
      -        "items": {
      -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      -          "oneOf": [
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "condition": {
      -                  "$ref": "#/$defs/condition"
      -                },
      -                "type": {
      -                  "const": "Filter",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "condition"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "direction": {
      -                  "enum": [
      -                    "Highest",
      -                    "Lowest"
      -                  ],
      -                  "type": "string"
      -                },
      -                "limit": {
      -                  "minimum": 1,
      -                  "type": "number"
      -                },
      -                "metric": {
      -                  "$ref": "#/$defs/indicator"
      -                },
      -                "type": {
      -                  "const": "SelectTop",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "metric",
      -                "limit",
      -                "direction"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "direction": {
      -                  "enum": [
      -                    "Highest",
      -                    "Lowest"
      -                  ],
      -                  "type": "string"
      -                },
      -                "metric": {
      -                  "$ref": "#/$defs/indicator"
      -                },
      -                "percentile": {
      -                  "maximum": 100,
      -                  "minimum": 0,
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "SelectPercentile",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "metric",
      -                "percentile",
      -                "direction"
      -              ],
      -              "type": "object"
      -            }
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "type": {
      -        "const": "DynamicRebalance",
      -        "type": "string"
      -      },
      -      "universe": {
      -        "additionalProperties": true,
      -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      -        "properties": {
      -          "assets": {
      -            "items": {
      -              "additionalProperties": true,
      -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      -              "properties": {
      -                "name": {
      -                  "type": "string"
      -                },
      -                "symbol": {
      -                  "type": "string"
      -                },
      -                "type": {
      -                  "enum": [
      -                    "Stock",
      -                    "Cryptocurrency",
      -                    "Option",
      -                    "Other"
      -                  ],
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "symbol"
      -              ],
      -              "type": "object"
      -            },
      -            "type": "array"
      -          },
      -          "source": {
      -            "enum": [
      -              "ALL_US_STOCKS",
      -              "SP500",
      -              "NASDAQ100",
      -              "DJIA",
      -              "CRYPTO",
      -              "SPECIFIC_ASSETS"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "source"
      -        ],
      -        "type": "object"
      -      },
      -      "weightIndicator": {
      -        "$ref": "#/$defs/indicator"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "universe",
      -      "pipeline",
      -      "weightIndicator"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
      -    "properties": {
      -      "continueExisting": {
      -        "type": "boolean"
      -      },
      -      "cooldownMinutes": {
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "executionModel": {
      -        "type": "string"
      -      },
      -      "includeMarketData": {
      -        "type": "boolean"
      -      },
      -      "initialMessage": {
      -        "type": "string"
      -      },
      -      "maxIterations": {
      -        "minimum": 1,
      -        "type": "number"
      -      },
      -      "planningModel": {
      -        "type": "string"
      -      },
      -      "skipPlanning": {
      -        "type": "boolean"
      -      },
      -      "type": {
      -        "const": "LaunchAgent",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "planningModel",
      -      "executionModel",
      -      "initialMessage",
      -      "maxIterations",
      -      "includeMarketData",
      -      "continueExisting",
      -      "skipPlanning"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
      -    "properties": {
      -      "against": {
      -        "additionalProperties": true,
      -        "description": "Optional parent-position selector (e.g. for covered calls).",
      -        "type": "object"
      -      },
      -      "allocation": {
      -        "additionalProperties": true,
      -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      -        "properties": {
      -          "amount": {
      -            "type": "number"
      -          },
      -          "type": {
      -            "enum": [
      -              "dollars",
      -              "percent of portfolio",
      -              "percent of buying power",
      -              "contracts"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "amount"
      -        ],
      -        "type": "object"
      -      },
      -      "builder": {
      -        "additionalProperties": true,
      -        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
      -        "properties": {
      -          "dynamicUnderlying": {
      -            "additionalProperties": true,
      -            "properties": {
      -              "limit": {
      -                "minimum": 1,
      -                "type": "number"
      -              },
      -              "pipeline": {
      -                "items": {
      -                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      -                  "oneOf": [
      -                    {
      -                      "additionalProperties": true,
      -                      "properties": {
      -                        "condition": {
      -                          "$ref": "#/$defs/condition"
      -                        },
      -                        "type": {
      -                          "const": "Filter",
      -                          "type": "string"
      -                        }
      -                      },
      -                      "required": [
      -                        "type",
      -                        "condition"
      -                      ],
      -                      "type": "object"
      -                    },
      -                    {
      -                      "additionalProperties": true,
      -                      "properties": {
      -                        "direction": {
      -                          "enum": [
      -                            "Highest",
      -                            "Lowest"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "limit": {
      -                          "minimum": 1,
      -                          "type": "number"
      -                        },
      -                        "metric": {
      -                          "$ref": "#/$defs/indicator"
      -                        },
      -                        "type": {
      -                          "const": "SelectTop",
      -                          "type": "string"
      -                        }
      -                      },
      -                      "required": [
      -                        "type",
      -                        "metric",
      -                        "limit",
      -                        "direction"
      -                      ],
      -                      "type": "object"
      -                    },
      -                    {
      -                      "additionalProperties": true,
      -                      "properties": {
      -                        "direction": {
      -                          "enum": [
      -                            "Highest",
      -                            "Lowest"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "metric": {
      -                          "$ref": "#/$defs/indicator"
      -                        },
      -                        "percentile": {
      -                          "maximum": 100,
      -                          "minimum": 0,
      -                          "type": "number"
      -                        },
      -                        "type": {
      -                          "const": "SelectPercentile",
      -                          "type": "string"
      -                        }
      -                      },
      -                      "required": [
      -                        "type",
      -                        "metric",
      -                        "percentile",
      -                        "direction"
      -                      ],
      -                      "type": "object"
      -                    }
      -                  ],
      -                  "type": "object"
      -                },
      -                "type": "array"
      -              },
      -              "universe": {
      -                "additionalProperties": true,
      -                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      -                "properties": {
      -                  "assets": {
      -                    "items": {
      -                      "additionalProperties": true,
      -                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      -                      "properties": {
      -                        "name": {
      -                          "type": "string"
      -                        },
      -                        "symbol": {
      -                          "type": "string"
      -                        },
      -                        "type": {
      -                          "enum": [
      -                            "Stock",
      -                            "Cryptocurrency",
      -                            "Option",
      -                            "Other"
      -                          ],
      -                          "type": "string"
      -                        }
      -                      },
      -                      "required": [
      -                        "type",
      -                        "symbol"
      -                      ],
      -                      "type": "object"
      -                    },
      -                    "type": "array"
      -                  },
      -                  "source": {
      -                    "enum": [
      -                      "ALL_US_STOCKS",
      -                      "SP500",
      -                      "NASDAQ100",
      -                      "DJIA",
      -                      "CRYPTO",
      -                      "SPECIFIC_ASSETS"
      -                    ],
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "source"
      -                ],
      -                "type": "object"
      -              }
      -            },
      -            "required": [
      -              "universe"
      -            ],
      -            "type": "object"
      -          },
      -          "legs": {
      -            "items": {
      -              "additionalProperties": true,
      -              "description": "Single leg of an option builder.",
      -              "properties": {
      -                "direction": {
      -                  "enum": [
      -                    "long",
      -                    "short"
      -                  ],
      -                  "type": "string"
      -                },
      -                "expirationRange": {
      -                  "additionalProperties": true,
      -                  "type": "object"
      -                },
      -                "expirationSelector": {
      -                  "properties": {
      -                    "maxDaysToExpiration": {
      -                      "minimum": 0,
      -                      "type": "number"
      -                    },
      -                    "minDaysToExpiration": {
      -                      "minimum": 0,
      -                      "type": "number"
      -                    },
      -                    "preference": {
      -                      "enum": [
      -                        "nearest",
      -                        "middle",
      -                        "furthest"
      -                      ],
      -                      "type": "string"
      -                    }
      -                  },
      -                  "required": [
      -                    "minDaysToExpiration",
      -                    "maxDaysToExpiration",
      -                    "preference"
      -                  ],
      -                  "type": "object"
      -                },
      -                "fallbackStrikeSelector": {
      -                  "additionalProperties": false,
      -                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      -                  "properties": {
      -                    "distance": {
      -                      "type": "number"
      -                    },
      -                    "distanceType": {
      -                      "enum": [
      -                        "percent",
      -                        "dollars"
      -                      ],
      -                      "type": "string"
      -                    }
      -                  },
      -                  "required": [
      -                    "distanceType",
      -                    "distance"
      -                  ],
      -                  "type": "object"
      -                },
      -                "greekFilter": {
      -                  "additionalProperties": true,
      -                  "description": "Optional min/max constraints on Greeks during resolution.",
      -                  "type": "object"
      -                },
      -                "liquidityFilter": {
      -                  "additionalProperties": false,
      -                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      -                  "properties": {
      -                    "maxSpreadAbsolute": {
      -                      "type": "number"
      -                    },
      -                    "maxSpreadPct": {
      -                      "type": "number"
      -                    },
      -                    "minBid": {
      -                      "type": "number"
      -                    }
      -                  },
      -                  "type": "object"
      -                },
      -                "optionType": {
      -                  "enum": [
      -                    "call",
      -                    "put"
      -                  ],
      -                  "type": "string"
      -                },
      -                "ratio": {
      -                  "type": "number"
      -                },
      -                "strikeRange": {
      -                  "additionalProperties": true,
      -                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      -                  "type": "object"
      -                },
      -                "strikeSelector": {
      -                  "properties": {
      -                    "distance": {
      -                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      -                      "type": "number"
      -                    },
      -                    "distanceType": {
      -                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      -                      "type": "string"
      -                    }
      -                  },
      -                  "required": [
      -                    "distanceType",
      -                    "distance"
      -                  ],
      -                  "type": "object"
      -                }
      -              },
      -              "required": [
      -                "optionType",
      -                "direction",
      -                "expirationSelector",
      -                "strikeSelector"
      -              ],
      -              "type": "object"
      -            },
      -            "minItems": 1,
      -            "type": "array"
      -          },
      -          "spreadType": {
      -            "enum": [
      -              "vertical",
      -              "calendar",
      -              "diagonal",
      -              "ironCondor",
      -              "straddle",
      -              "strangle",
      -              "custom"
      -            ],
      -            "type": "string"
      -          },
      -          "underlyingSymbol": {
      -            "type": "string"
      -          },
      -          "widthConstraint": {
      -            "additionalProperties": false,
      -            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      -            "properties": {
      -              "minWidthDollars": {
      -                "exclusiveMinimum": 0,
      -                "type": "number"
      -              },
      -              "minWidthPercent": {
      -                "exclusiveMinimum": 0,
      -                "type": "number"
      -              }
      -            },
      -            "type": "object"
      -          }
      -        },
      -        "required": [
      -          "legs"
      -        ],
      -        "type": "object"
      -      },
      -      "type": {
      -        "const": "OpenOption",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "builder"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
      -    "properties": {
      -      "allocationPolicy": {
      -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "expectedReturnShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "riskAversion": {
      -                "maximum": 1000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MeanVariance",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "riskAversion",
      -              "expectedReturnShrinkage",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "RiskParity",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "covarianceShrinkage": {
      -                "maximum": 1,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "estimatedTransactionCostBps": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "lookbackPeriods": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "minimumObservations": {
      -                "maximum": 5000,
      -                "minimum": 2,
      -                "type": "integer"
      -              },
      -              "turnoverPenalty": {
      -                "maximum": 10000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "type": {
      -                "const": "MaximumDiversification",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "lookbackPeriods",
      -              "minimumObservations",
      -              "covarianceShrinkage",
      -              "turnoverPenalty",
      -              "estimatedTransactionCostBps"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      },
      -      "exposurePolicy": {
      -        "additionalProperties": false,
      -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      -        "properties": {
      -          "covarianceShrinkage": {
      -            "maximum": 1,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "estimatedTransactionCostBps": {
      -            "maximum": 10000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "lookbackPeriods": {
      -            "maximum": 5000,
      -            "minimum": 2,
      -            "type": "integer"
      -          },
      -          "minimumObservations": {
      -            "maximum": 5000,
      -            "minimum": 2,
      -            "type": "integer"
      -          },
      -          "targetAnnualizedVolatilityPercent": {
      -            "maximum": 1000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "type": {
      -            "const": "VolatilityTarget",
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "lookbackPeriods",
      -          "minimumObservations",
      -          "covarianceShrinkage",
      -          "targetAnnualizedVolatilityPercent",
      -          "estimatedTransactionCostBps"
      -        ],
      -        "type": "object"
      -      },
      -      "limit": {
      -        "minimum": 1,
      -        "type": "number"
      -      },
      -      "perNameAllocation": {
      -        "additionalProperties": true,
      -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      -        "properties": {
      -          "amount": {
      -            "type": "number"
      -          },
      -          "type": {
      -            "enum": [
      -              "dollars",
      -              "percent of portfolio",
      -              "percent of buying power",
      -              "contracts"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "amount"
      -        ],
      -        "type": "object"
      -      },
      -      "pipeline": {
      -        "items": {
      -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      -          "oneOf": [
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "condition": {
      -                  "$ref": "#/$defs/condition"
      -                },
      -                "type": {
      -                  "const": "Filter",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "condition"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "direction": {
      -                  "enum": [
      -                    "Highest",
      -                    "Lowest"
      -                  ],
      -                  "type": "string"
      -                },
      -                "limit": {
      -                  "minimum": 1,
      -                  "type": "number"
      -                },
      -                "metric": {
      -                  "$ref": "#/$defs/indicator"
      -                },
      -                "type": {
      -                  "const": "SelectTop",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "metric",
      -                "limit",
      -                "direction"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "direction": {
      -                  "enum": [
      -                    "Highest",
      -                    "Lowest"
      -                  ],
      -                  "type": "string"
      -                },
      -                "metric": {
      -                  "$ref": "#/$defs/indicator"
      -                },
      -                "percentile": {
      -                  "maximum": 100,
      -                  "minimum": 0,
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "SelectPercentile",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "metric",
      -                "percentile",
      -                "direction"
      -              ],
      -              "type": "object"
      -            }
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "positionScope": {
      -        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
      -        "enum": [
      -          "portfolio",
      -          "strategy"
      -        ],
      -        "type": "string"
      -      },
      -      "sleeves": {
      -        "items": {
      -          "additionalProperties": true,
      -          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
      -          "properties": {
      -            "limit": {
      -              "minimum": 1,
      -              "type": "number"
      -            },
      -            "name": {
      -              "type": "string"
      -            },
      -            "perNameAllocation": {
      -              "additionalProperties": true,
      -              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      -              "properties": {
      -                "amount": {
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "enum": [
      -                    "dollars",
      -                    "percent of portfolio",
      -                    "percent of buying power",
      -                    "contracts"
      -                  ],
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "amount"
      -              ],
      -              "type": "object"
      -            },
      -            "pipeline": {
      -              "items": {
      -                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      -                "oneOf": [
      -                  {
      -                    "additionalProperties": true,
      -                    "properties": {
      -                      "condition": {
      -                        "$ref": "#/$defs/condition"
      -                      },
      -                      "type": {
      -                        "const": "Filter",
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "type",
      -                      "condition"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  {
      -                    "additionalProperties": true,
      -                    "properties": {
      -                      "direction": {
      -                        "enum": [
      -                          "Highest",
      -                          "Lowest"
      -                        ],
      -                        "type": "string"
      -                      },
      -                      "limit": {
      -                        "minimum": 1,
      -                        "type": "number"
      -                      },
      -                      "metric": {
      -                        "$ref": "#/$defs/indicator"
      -                      },
      -                      "type": {
      -                        "const": "SelectTop",
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "type",
      -                      "metric",
      -                      "limit",
      -                      "direction"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  {
      -                    "additionalProperties": true,
      -                    "properties": {
      -                      "direction": {
      -                        "enum": [
      -                          "Highest",
      -                          "Lowest"
      -                        ],
      -                        "type": "string"
      -                      },
      -                      "metric": {
      -                        "$ref": "#/$defs/indicator"
      -                      },
      -                      "percentile": {
      -                        "maximum": 100,
      -                        "minimum": 0,
      -                        "type": "number"
      -                      },
      -                      "type": {
      -                        "const": "SelectPercentile",
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "type",
      -                      "metric",
      -                      "percentile",
      -                      "direction"
      -                    ],
      -                    "type": "object"
      -                  }
      -                ],
      -                "type": "object"
      -              },
      -              "type": "array"
      -            },
      -            "structureTemplates": {
      -              "items": {
      -                "additionalProperties": true,
      -                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      -                "properties": {
      -                  "eligibility": {
      -                    "$ref": "#/$defs/condition"
      -                  },
      -                  "legs": {
      -                    "items": {
      -                      "additionalProperties": true,
      -                      "description": "Single leg of an option builder.",
      -                      "properties": {
      -                        "direction": {
      -                          "enum": [
      -                            "long",
      -                            "short"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "expirationRange": {
      -                          "additionalProperties": true,
      -                          "type": "object"
      -                        },
      -                        "expirationSelector": {
      -                          "properties": {
      -                            "maxDaysToExpiration": {
      -                              "minimum": 0,
      -                              "type": "number"
      -                            },
      -                            "minDaysToExpiration": {
      -                              "minimum": 0,
      -                              "type": "number"
      -                            },
      -                            "preference": {
      -                              "enum": [
      -                                "nearest",
      -                                "middle",
      -                                "furthest"
      -                              ],
      -                              "type": "string"
      -                            }
      -                          },
      -                          "required": [
      -                            "minDaysToExpiration",
      -                            "maxDaysToExpiration",
      -                            "preference"
      -                          ],
      -                          "type": "object"
      -                        },
      -                        "fallbackStrikeSelector": {
      -                          "additionalProperties": false,
      -                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      -                          "properties": {
      -                            "distance": {
      -                              "type": "number"
      -                            },
      -                            "distanceType": {
      -                              "enum": [
      -                                "percent",
      -                                "dollars"
      -                              ],
      -                              "type": "string"
      -                            }
      -                          },
      -                          "required": [
      -                            "distanceType",
      -                            "distance"
      -                          ],
      -                          "type": "object"
      -                        },
      -                        "greekFilter": {
      -                          "additionalProperties": true,
      -                          "description": "Optional min/max constraints on Greeks during resolution.",
      -                          "type": "object"
      -                        },
      -                        "liquidityFilter": {
      -                          "additionalProperties": false,
      -                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      -                          "properties": {
      -                            "maxSpreadAbsolute": {
      -                              "type": "number"
      -                            },
      -                            "maxSpreadPct": {
      -                              "type": "number"
      -                            },
      -                            "minBid": {
      -                              "type": "number"
      -                            }
      -                          },
      -                          "type": "object"
      -                        },
      -                        "optionType": {
      -                          "enum": [
      -                            "call",
      -                            "put"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "ratio": {
      -                          "type": "number"
      -                        },
      -                        "strikeRange": {
      -                          "additionalProperties": true,
      -                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      -                          "type": "object"
      -                        },
      -                        "strikeSelector": {
      -                          "properties": {
      -                            "distance": {
      -                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      -                              "type": "number"
      -                            },
      -                            "distanceType": {
      -                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      -                              "type": "string"
      -                            }
      -                          },
      -                          "required": [
      -                            "distanceType",
      -                            "distance"
      -                          ],
      -                          "type": "object"
      -                        }
      -                      },
      -                      "required": [
      -                        "optionType",
      -                        "direction",
      -                        "expirationSelector",
      -                        "strikeSelector"
      -                      ],
      -                      "type": "object"
      -                    },
      -                    "minItems": 1,
      -                    "type": "array"
      -                  },
      -                  "name": {
      -                    "type": "string"
      -                  },
      -                  "spreadType": {
      -                    "enum": [
      -                      "vertical",
      -                      "calendar",
      -                      "diagonal",
      -                      "ironCondor",
      -                      "straddle",
      -                      "strangle",
      -                      "custom"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "widthConstraint": {
      -                    "additionalProperties": false,
      -                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      -                    "properties": {
      -                      "minWidthDollars": {
      -                        "exclusiveMinimum": 0,
      -                        "type": "number"
      -                      },
      -                      "minWidthPercent": {
      -                        "exclusiveMinimum": 0,
      -                        "type": "number"
      -                      }
      -                    },
      -                    "type": "object"
      -                  }
      -                },
      -                "required": [
      -                  "legs"
      -                ],
      -                "type": "object"
      -              },
      -              "minItems": 1,
      -              "type": "array"
      -            },
      -            "universe": {
      -              "additionalProperties": true,
      -              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      -              "properties": {
      -                "assets": {
      -                  "items": {
      -                    "additionalProperties": true,
      -                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      -                    "properties": {
      -                      "name": {
      -                        "type": "string"
      -                      },
      -                      "symbol": {
      -                        "type": "string"
      -                      },
      -                      "type": {
      -                        "enum": [
      -                          "Stock",
      -                          "Cryptocurrency",
      -                          "Option",
      -                          "Other"
      -                        ],
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "type",
      -                      "symbol"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "type": "array"
      -                },
      -                "source": {
      -                  "enum": [
      -                    "ALL_US_STOCKS",
      -                    "SP500",
      -                    "NASDAQ100",
      -                    "DJIA",
      -                    "CRYPTO",
      -                    "SPECIFIC_ASSETS"
      -                  ],
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "source"
      -              ],
      -              "type": "object"
      -            },
      -            "weightIndicator": {
      -              "$ref": "#/$defs/indicator"
      -            }
      -          },
      -          "required": [
      -            "name"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "structureTemplates": {
      -        "items": {
      -          "additionalProperties": true,
      -          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      -          "properties": {
      -            "eligibility": {
      -              "$ref": "#/$defs/condition"
      -            },
      -            "legs": {
      -              "items": {
      -                "additionalProperties": true,
      -                "description": "Single leg of an option builder.",
      -                "properties": {
      -                  "direction": {
      -                    "enum": [
      -                      "long",
      -                      "short"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "expirationRange": {
      -                    "additionalProperties": true,
      -                    "type": "object"
      -                  },
      -                  "expirationSelector": {
      -                    "properties": {
      -                      "maxDaysToExpiration": {
      -                        "minimum": 0,
      -                        "type": "number"
      -                      },
      -                      "minDaysToExpiration": {
      -                        "minimum": 0,
      -                        "type": "number"
      -                      },
      -                      "preference": {
      -                        "enum": [
      -                          "nearest",
      -                          "middle",
      -                          "furthest"
      -                        ],
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "minDaysToExpiration",
      -                      "maxDaysToExpiration",
      -                      "preference"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "fallbackStrikeSelector": {
      -                    "additionalProperties": false,
      -                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      -                    "properties": {
      -                      "distance": {
      -                        "type": "number"
      -                      },
      -                      "distanceType": {
      -                        "enum": [
      -                          "percent",
      -                          "dollars"
      -                        ],
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "distanceType",
      -                      "distance"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "greekFilter": {
      -                    "additionalProperties": true,
      -                    "description": "Optional min/max constraints on Greeks during resolution.",
      -                    "type": "object"
      -                  },
      -                  "liquidityFilter": {
      -                    "additionalProperties": false,
      -                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      -                    "properties": {
      -                      "maxSpreadAbsolute": {
      -                        "type": "number"
      -                      },
      -                      "maxSpreadPct": {
      -                        "type": "number"
      -                      },
      -                      "minBid": {
      -                        "type": "number"
      -                      }
      -                    },
      -                    "type": "object"
      -                  },
      -                  "optionType": {
      -                    "enum": [
      -                      "call",
      -                      "put"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "ratio": {
      -                    "type": "number"
      -                  },
      -                  "strikeRange": {
      -                    "additionalProperties": true,
      -                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      -                    "type": "object"
      -                  },
      -                  "strikeSelector": {
      -                    "properties": {
      -                      "distance": {
      -                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      -                        "type": "number"
      -                      },
      -                      "distanceType": {
      -                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "distanceType",
      -                      "distance"
      -                    ],
      -                    "type": "object"
      -                  }
      -                },
      -                "required": [
      -                  "optionType",
      -                  "direction",
      -                  "expirationSelector",
      -                  "strikeSelector"
      -                ],
      -                "type": "object"
      -              },
      -              "minItems": 1,
      -              "type": "array"
      -            },
      -            "name": {
      -              "type": "string"
      -            },
      -            "spreadType": {
      -              "enum": [
      -                "vertical",
      -                "calendar",
      -                "diagonal",
      -                "ironCondor",
      -                "straddle",
      -                "strangle",
      -                "custom"
      -              ],
      -              "type": "string"
      -            },
      -            "widthConstraint": {
      -              "additionalProperties": false,
      -              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      -              "properties": {
      -                "minWidthDollars": {
      -                  "exclusiveMinimum": 0,
      -                  "type": "number"
      -                },
      -                "minWidthPercent": {
      -                  "exclusiveMinimum": 0,
      -                  "type": "number"
      -                }
      -              },
      -              "type": "object"
      -            }
      -          },
      -          "required": [
      -            "legs"
      -          ],
      -          "type": "object"
      -        },
      -        "minItems": 1,
      -        "type": "array"
      -      },
      -      "totalBudget": {
      -        "additionalProperties": true,
      -        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
      -        "properties": {
      -          "amount": {
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "type": {
      -            "enum": [
      -              "dollars",
      -              "percent of portfolio"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "type",
      -          "amount"
      -        ],
      -        "type": "object"
      -      },
      -      "type": {
      -        "const": "RebalanceOption",
      -        "type": "string"
      -      },
      -      "universe": {
      -        "additionalProperties": true,
      -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      -        "properties": {
      -          "assets": {
      -            "items": {
      -              "additionalProperties": true,
      -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      -              "properties": {
      -                "name": {
      -                  "type": "string"
      -                },
      -                "symbol": {
      -                  "type": "string"
      -                },
      -                "type": {
      -                  "enum": [
      -                    "Stock",
      -                    "Cryptocurrency",
      -                    "Option",
      -                    "Other"
      -                  ],
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type",
      -                "symbol"
      -              ],
      -              "type": "object"
      -            },
      -            "type": "array"
      -          },
      -          "source": {
      -            "enum": [
      -              "ALL_US_STOCKS",
      -              "SP500",
      -              "NASDAQ100",
      -              "DJIA",
      -              "CRYPTO",
      -              "SPECIFIC_ASSETS"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "source"
      -        ],
      -        "type": "object"
      -      },
      -      "weightIndicator": {
      -        "$ref": "#/$defs/indicator"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "universe",
      -      "pipeline",
      -      "weightIndicator",
      -      "structureTemplates"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": true,
      -    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
      -    "properties": {
      -      "closeScope": {
      -        "enum": [
      -          "spread",
      -          "leg"
      -        ],
      -        "type": "string"
      -      },
      -      "direction": {
      -        "enum": [
      -          "long",
      -          "short"
      -        ],
      -        "type": "string"
      -      },
      -      "optionType": {
      -        "enum": [
      -          "call",
      -          "put"
      -        ],
      -        "type": "string"
      -      },
      -      "quantity": {
      -        "additionalProperties": true,
      -        "description": "How many contracts to close. Defaults to all matching when omitted.",
      -        "type": "object"
      -      },
      -      "spreadType": {
      -        "enum": [
      -          "vertical",
      -          "calendar",
      -          "diagonal",
      -          "ironCondor",
      -          "straddle",
      -          "strangle",
      -          "custom"
      -        ],
      -        "type": "string"
      -      },
      -      "triggers": {
      -        "items": {
      -          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
      -          "oneOf": [
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "maxPnlPercent": {
      -                  "type": "number"
      -                },
      -                "minPnlPercent": {
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "pnl",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "maxDte": {
      -                  "type": "number"
      -                },
      -                "minDte": {
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "dte",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "maxDaysHeld": {
      -                  "type": "number"
      -                },
      -                "minDaysHeld": {
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "daysHeld",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type"
      -              ],
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "properties": {
      -                "maxIv": {
      -                  "type": "number"
      -                },
      -                "maxSpreadDelta": {
      -                  "type": "number"
      -                },
      -                "maxSpreadTheta": {
      -                  "type": "number"
      -                },
      -                "minIv": {
      -                  "type": "number"
      -                },
      -                "minSpreadDelta": {
      -                  "type": "number"
      -                },
      -                "minSpreadTheta": {
      -                  "type": "number"
      -                },
      -                "type": {
      -                  "const": "greeks",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "type"
      -              ],
      -              "type": "object"
      -            }
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "type": {
      -        "const": "CloseOption",
      -        "type": "string"
      -      },
      -      "underlyings": {
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": true,
      +    "description": "Buy or Sell a stock/crypto position.",
      +    "properties": {
      +      "amount": {
      +        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
      +        "properties": {
      +          "amount": {
      +            "type": "number"
      +          },
      +          "type": {
      +            "enum": [
      +              "percent of portfolio",
      +              "percent of buying power",
      +              "percent of current positions",
      +              "dollars",
      +              "number of assets"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      "targetAsset": {
      +        "additionalProperties": true,
      +        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +        "properties": {
      +          "name": {
      +            "type": "string"
      +          },
      +          "symbol": {
      +            "type": "string"
      +          },
      +          "type": {
      +            "enum": [
      +              "Stock",
      +              "Cryptocurrency",
      +              "Option",
      +              "Other"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "symbol"
      +        ],
      +        "type": "object"
      +      },
      +      "type": {
      +        "enum": [
      +          "Buy",
      +          "Sell"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "targetAsset",
      +      "amount"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "Send an alert message (no order).",
      +    "properties": {
      +      "message": {
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "Alert",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "message"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
      +    "properties": {
      +      "allocationPolicy": {
      +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "expectedReturnShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "riskAversion": {
      +                "maximum": 1000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "MeanVariance",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "riskAversion",
      +              "expectedReturnShrinkage",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "RiskParity",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "MaximumDiversification",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      },
      +      "canSell": {
      +        "$ref": "#/$defs/condition",
      +        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
      +      },
      +      "deploymentPercent": {
      +        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "exposurePolicy": {
      +        "additionalProperties": false,
      +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      +        "properties": {
      +          "covarianceShrinkage": {
      +            "maximum": 1,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "estimatedTransactionCostBps": {
      +            "maximum": 10000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "lookbackPeriods": {
      +            "maximum": 5000,
      +            "minimum": 2,
      +            "type": "integer"
      +          },
      +          "minimumObservations": {
      +            "maximum": 5000,
      +            "minimum": 2,
      +            "type": "integer"
      +          },
      +          "targetAnnualizedVolatilityPercent": {
      +            "maximum": 1000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "type": {
      +            "const": "VolatilityTarget",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "lookbackPeriods",
      +          "minimumObservations",
      +          "covarianceShrinkage",
      +          "targetAnnualizedVolatilityPercent",
      +          "estimatedTransactionCostBps"
      +        ],
      +        "type": "object"
      +      },
      +      "limit": {
      +        "minimum": 1,
      +        "type": "number"
      +      },
      +      "perNameAllocation": {
      +        "additionalProperties": true,
      +        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.",
      +        "properties": {
      +          "amount": {
      +            "exclusiveMinimum": 0,
      +            "type": "number"
      +          },
      +          "type": {
      +            "enum": [
      +              "percent of portfolio",
      +              "dollars"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      "pipeline": {
      +        "items": {
      +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +          "oneOf": [
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "condition": {
      +                  "$ref": "#/$defs/condition"
      +                },
      +                "type": {
      +                  "const": "Filter",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "condition"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "Highest",
      +                    "Lowest"
      +                  ],
      +                  "type": "string"
      +                },
      +                "limit": {
      +                  "minimum": 1,
      +                  "type": "number"
      +                },
      +                "metric": {
      +                  "$ref": "#/$defs/indicator"
      +                },
      +                "type": {
      +                  "const": "SelectTop",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "metric",
      +                "limit",
      +                "direction"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "Highest",
      +                    "Lowest"
      +                  ],
      +                  "type": "string"
      +                },
      +                "metric": {
      +                  "$ref": "#/$defs/indicator"
      +                },
      +                "percentile": {
      +                  "maximum": 100,
      +                  "minimum": 0,
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "SelectPercentile",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "metric",
      +                "percentile",
      +                "direction"
      +              ],
      +              "type": "object"
      +            }
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "type": {
      +        "const": "DynamicRebalance",
      +        "type": "string"
      +      },
      +      "universe": {
      +        "additionalProperties": true,
      +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +        "properties": {
      +          "assets": {
      +            "items": {
      +              "additionalProperties": true,
      +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +              "properties": {
      +                "name": {
      +                  "type": "string"
      +                },
      +                "symbol": {
      +                  "type": "string"
      +                },
      +                "type": {
      +                  "enum": [
      +                    "Stock",
      +                    "Cryptocurrency",
      +                    "Option",
      +                    "Other"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "symbol"
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "source": {
      +            "enum": [
      +              "ALL_US_STOCKS",
      +              "SP500",
      +              "NASDAQ100",
      +              "DJIA",
      +              "CRYPTO",
      +              "SPECIFIC_ASSETS"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "source"
      +        ],
      +        "type": "object"
      +      },
      +      "weightIndicator": {
      +        "$ref": "#/$defs/indicator"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "universe",
      +      "pipeline",
      +      "weightIndicator"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
      +    "properties": {
      +      "continueExisting": {
      +        "type": "boolean"
      +      },
      +      "cooldownMinutes": {
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "executionModel": {
      +        "type": "string"
      +      },
      +      "includeMarketData": {
      +        "type": "boolean"
      +      },
      +      "initialMessage": {
      +        "type": "string"
      +      },
      +      "maxIterations": {
      +        "minimum": 1,
      +        "type": "number"
      +      },
      +      "planningModel": {
      +        "type": "string"
      +      },
      +      "skipPlanning": {
      +        "type": "boolean"
      +      },
      +      "type": {
      +        "const": "LaunchAgent",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "planningModel",
      +      "executionModel",
      +      "initialMessage",
      +      "maxIterations",
      +      "includeMarketData",
      +      "continueExisting",
      +      "skipPlanning"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
      +    "properties": {
      +      "against": {
      +        "additionalProperties": true,
      +        "description": "Optional parent-position selector (e.g. for covered calls).",
      +        "type": "object"
      +      },
      +      "allocation": {
      +        "additionalProperties": true,
      +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +        "properties": {
      +          "amount": {
      +            "type": "number"
      +          },
      +          "type": {
      +            "enum": [
      +              "dollars",
      +              "percent of portfolio",
      +              "percent of buying power",
      +              "contracts",
      +              "percent of realized premium"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      "builder": {
      +        "additionalProperties": true,
      +        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
      +        "properties": {
      +          "dynamicUnderlying": {
      +            "additionalProperties": true,
      +            "properties": {
      +              "limit": {
      +                "minimum": 1,
      +                "type": "number"
      +              },
      +              "pipeline": {
      +                "items": {
      +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                  "oneOf": [
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "condition": {
      +                          "$ref": "#/$defs/condition"
      +                        },
      +                        "type": {
      +                          "const": "Filter",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "condition"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "Highest",
      +                            "Lowest"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "limit": {
      +                          "minimum": 1,
      +                          "type": "number"
      +                        },
      +                        "metric": {
      +                          "$ref": "#/$defs/indicator"
      +                        },
      +                        "type": {
      +                          "const": "SelectTop",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "metric",
      +                        "limit",
      +                        "direction"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "Highest",
      +                            "Lowest"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "metric": {
      +                          "$ref": "#/$defs/indicator"
      +                        },
      +                        "percentile": {
      +                          "maximum": 100,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "SelectPercentile",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "metric",
      +                        "percentile",
      +                        "direction"
      +                      ],
      +                      "type": "object"
      +                    }
      +                  ],
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "universe": {
      +                "additionalProperties": true,
      +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +                "properties": {
      +                  "assets": {
      +                    "items": {
      +                      "additionalProperties": true,
      +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                      "properties": {
      +                        "name": {
      +                          "type": "string"
      +                        },
      +                        "symbol": {
      +                          "type": "string"
      +                        },
      +                        "type": {
      +                          "enum": [
      +                            "Stock",
      +                            "Cryptocurrency",
      +                            "Option",
      +                            "Other"
      +                          ],
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "symbol"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "type": "array"
      +                  },
      +                  "source": {
      +                    "enum": [
      +                      "ALL_US_STOCKS",
      +                      "SP500",
      +                      "NASDAQ100",
      +                      "DJIA",
      +                      "CRYPTO",
      +                      "SPECIFIC_ASSETS"
      +                    ],
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "source"
      +                ],
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "universe"
      +            ],
      +            "type": "object"
      +          },
      +          "legs": {
      +            "items": {
      +              "additionalProperties": true,
      +              "description": "Single leg of an option builder.",
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "long",
      +                    "short"
      +                  ],
      +                  "type": "string"
      +                },
      +                "expirationRange": {
      +                  "additionalProperties": true,
      +                  "type": "object"
      +                },
      +                "expirationSelector": {
      +                  "properties": {
      +                    "maxDaysToExpiration": {
      +                      "minimum": 0,
      +                      "type": "number"
      +                    },
      +                    "minDaysToExpiration": {
      +                      "minimum": 0,
      +                      "type": "number"
      +                    },
      +                    "preference": {
      +                      "enum": [
      +                        "nearest",
      +                        "middle",
      +                        "furthest"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "minDaysToExpiration",
      +                    "maxDaysToExpiration",
      +                    "preference"
      +                  ],
      +                  "type": "object"
      +                },
      +                "fallbackStrikeSelector": {
      +                  "additionalProperties": false,
      +                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                  "properties": {
      +                    "distance": {
      +                      "type": "number"
      +                    },
      +                    "distanceType": {
      +                      "enum": [
      +                        "percent",
      +                        "dollars"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "distanceType",
      +                    "distance"
      +                  ],
      +                  "type": "object"
      +                },
      +                "greekFilter": {
      +                  "additionalProperties": true,
      +                  "description": "Optional min/max constraints on Greeks during resolution.",
      +                  "type": "object"
      +                },
      +                "liquidityFilter": {
      +                  "additionalProperties": false,
      +                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                  "properties": {
      +                    "maxSpreadAbsolute": {
      +                      "type": "number"
      +                    },
      +                    "maxSpreadPct": {
      +                      "type": "number"
      +                    },
      +                    "minBid": {
      +                      "type": "number"
      +                    }
      +                  },
      +                  "type": "object"
      +                },
      +                "optionType": {
      +                  "enum": [
      +                    "call",
      +                    "put"
      +                  ],
      +                  "type": "string"
      +                },
      +                "ratio": {
      +                  "type": "number"
      +                },
      +                "strikeRange": {
      +                  "additionalProperties": true,
      +                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                  "type": "object"
      +                },
      +                "strikeSelector": {
      +                  "properties": {
      +                    "distance": {
      +                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                      "type": "number"
      +                    },
      +                    "distanceType": {
      +                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "distanceType",
      +                    "distance"
      +                  ],
      +                  "type": "object"
      +                }
      +              },
      +              "required": [
      +                "optionType",
      +                "direction",
      +                "expirationSelector",
      +                "strikeSelector"
      +              ],
      +              "type": "object"
      +            },
      +            "minItems": 1,
      +            "type": "array"
      +          },
      +          "spreadType": {
      +            "enum": [
      +              "vertical",
      +              "calendar",
      +              "diagonal",
      +              "ironCondor",
      +              "straddle",
      +              "strangle",
      +              "custom"
      +            ],
      +            "type": "string"
      +          },
      +          "underlyingSymbol": {
      +            "type": "string"
      +          },
      +          "widthConstraint": {
      +            "additionalProperties": false,
      +            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +            "properties": {
      +              "minWidthDollars": {
      +                "exclusiveMinimum": 0,
      +                "type": "number"
      +              },
      +              "minWidthPercent": {
      +                "exclusiveMinimum": 0,
      +                "type": "number"
      +              }
      +            },
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "legs"
      +        ],
      +        "type": "object"
      +      },
      +      "type": {
      +        "const": "OpenOption",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "builder"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
      +    "properties": {
      +      "allocationPolicy": {
      +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "expectedReturnShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "riskAversion": {
      +                "maximum": 1000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "MeanVariance",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "riskAversion",
      +              "expectedReturnShrinkage",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "RiskParity",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "turnoverPenalty": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "MaximumDiversification",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "covarianceShrinkage",
      +              "turnoverPenalty",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      },
      +      "exposurePolicy": {
      +        "additionalProperties": false,
      +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      +        "properties": {
      +          "covarianceShrinkage": {
      +            "maximum": 1,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "estimatedTransactionCostBps": {
      +            "maximum": 10000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "lookbackPeriods": {
      +            "maximum": 5000,
      +            "minimum": 2,
      +            "type": "integer"
      +          },
      +          "minimumObservations": {
      +            "maximum": 5000,
      +            "minimum": 2,
      +            "type": "integer"
      +          },
      +          "targetAnnualizedVolatilityPercent": {
      +            "maximum": 1000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "type": {
      +            "const": "VolatilityTarget",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "lookbackPeriods",
      +          "minimumObservations",
      +          "covarianceShrinkage",
      +          "targetAnnualizedVolatilityPercent",
      +          "estimatedTransactionCostBps"
      +        ],
      +        "type": "object"
      +      },
      +      "limit": {
      +        "minimum": 1,
      +        "type": "number"
      +      },
      +      "perNameAllocation": {
      +        "additionalProperties": true,
      +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +        "properties": {
      +          "amount": {
      +            "type": "number"
      +          },
      +          "type": {
      +            "enum": [
      +              "dollars",
      +              "percent of portfolio",
      +              "percent of buying power",
      +              "contracts",
      +              "percent of realized premium"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      "pipeline": {
      +        "items": {
      +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +          "oneOf": [
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "condition": {
      +                  "$ref": "#/$defs/condition"
      +                },
      +                "type": {
      +                  "const": "Filter",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "condition"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "Highest",
      +                    "Lowest"
      +                  ],
      +                  "type": "string"
      +                },
      +                "limit": {
      +                  "minimum": 1,
      +                  "type": "number"
      +                },
      +                "metric": {
      +                  "$ref": "#/$defs/indicator"
      +                },
      +                "type": {
      +                  "const": "SelectTop",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "metric",
      +                "limit",
      +                "direction"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "Highest",
      +                    "Lowest"
      +                  ],
      +                  "type": "string"
      +                },
      +                "metric": {
      +                  "$ref": "#/$defs/indicator"
      +                },
      +                "percentile": {
      +                  "maximum": 100,
      +                  "minimum": 0,
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "SelectPercentile",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "metric",
      +                "percentile",
      +                "direction"
      +              ],
      +              "type": "object"
      +            }
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "positionScope": {
      +        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
      +        "enum": [
      +          "portfolio",
      +          "strategy"
      +        ],
      +        "type": "string"
      +      },
      +      "sleeves": {
      +        "items": {
      +          "additionalProperties": true,
      +          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
      +          "properties": {
      +            "limit": {
      +              "minimum": 1,
      +              "type": "number"
      +            },
      +            "name": {
      +              "type": "string"
      +            },
      +            "perNameAllocation": {
      +              "additionalProperties": true,
      +              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +              "properties": {
      +                "amount": {
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "enum": [
      +                    "dollars",
      +                    "percent of portfolio",
      +                    "percent of buying power",
      +                    "contracts",
      +                    "percent of realized premium"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "amount"
      +              ],
      +              "type": "object"
      +            },
      +            "pipeline": {
      +              "items": {
      +                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                "oneOf": [
      +                  {
      +                    "additionalProperties": true,
      +                    "properties": {
      +                      "condition": {
      +                        "$ref": "#/$defs/condition"
      +                      },
      +                      "type": {
      +                        "const": "Filter",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "condition"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": true,
      +                    "properties": {
      +                      "direction": {
      +                        "enum": [
      +                          "Highest",
      +                          "Lowest"
      +                        ],
      +                        "type": "string"
      +                      },
      +                      "limit": {
      +                        "minimum": 1,
      +                        "type": "number"
      +                      },
      +                      "metric": {
      +                        "$ref": "#/$defs/indicator"
      +                      },
      +                      "type": {
      +                        "const": "SelectTop",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "metric",
      +                      "limit",
      +                      "direction"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": true,
      +                    "properties": {
      +                      "direction": {
      +                        "enum": [
      +                          "Highest",
      +                          "Lowest"
      +                        ],
      +                        "type": "string"
      +                      },
      +                      "metric": {
      +                        "$ref": "#/$defs/indicator"
      +                      },
      +                      "percentile": {
      +                        "maximum": 100,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "SelectPercentile",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "metric",
      +                      "percentile",
      +                      "direction"
      +                    ],
      +                    "type": "object"
      +                  }
      +                ],
      +                "type": "object"
      +              },
      +              "type": "array"
      +            },
      +            "structureTemplates": {
      +              "items": {
      +                "additionalProperties": true,
      +                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      +                "properties": {
      +                  "eligibility": {
      +                    "$ref": "#/$defs/condition"
      +                  },
      +                  "legs": {
      +                    "items": {
      +                      "additionalProperties": true,
      +                      "description": "Single leg of an option builder.",
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "long",
      +                            "short"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "expirationRange": {
      +                          "additionalProperties": true,
      +                          "type": "object"
      +                        },
      +                        "expirationSelector": {
      +                          "properties": {
      +                            "maxDaysToExpiration": {
      +                              "minimum": 0,
      +                              "type": "number"
      +                            },
      +                            "minDaysToExpiration": {
      +                              "minimum": 0,
      +                              "type": "number"
      +                            },
      +                            "preference": {
      +                              "enum": [
      +                                "nearest",
      +                                "middle",
      +                                "furthest"
      +                              ],
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "minDaysToExpiration",
      +                            "maxDaysToExpiration",
      +                            "preference"
      +                          ],
      +                          "type": "object"
      +                        },
      +                        "fallbackStrikeSelector": {
      +                          "additionalProperties": false,
      +                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                          "properties": {
      +                            "distance": {
      +                              "type": "number"
      +                            },
      +                            "distanceType": {
      +                              "enum": [
      +                                "percent",
      +                                "dollars"
      +                              ],
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "distanceType",
      +                            "distance"
      +                          ],
      +                          "type": "object"
      +                        },
      +                        "greekFilter": {
      +                          "additionalProperties": true,
      +                          "description": "Optional min/max constraints on Greeks during resolution.",
      +                          "type": "object"
      +                        },
      +                        "liquidityFilter": {
      +                          "additionalProperties": false,
      +                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                          "properties": {
      +                            "maxSpreadAbsolute": {
      +                              "type": "number"
      +                            },
      +                            "maxSpreadPct": {
      +                              "type": "number"
      +                            },
      +                            "minBid": {
      +                              "type": "number"
      +                            }
      +                          },
      +                          "type": "object"
      +                        },
      +                        "optionType": {
      +                          "enum": [
      +                            "call",
      +                            "put"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "ratio": {
      +                          "type": "number"
      +                        },
      +                        "strikeRange": {
      +                          "additionalProperties": true,
      +                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                          "type": "object"
      +                        },
      +                        "strikeSelector": {
      +                          "properties": {
      +                            "distance": {
      +                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                              "type": "number"
      +                            },
      +                            "distanceType": {
      +                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "distanceType",
      +                            "distance"
      +                          ],
      +                          "type": "object"
      +                        }
      +                      },
      +                      "required": [
      +                        "optionType",
      +                        "direction",
      +                        "expirationSelector",
      +                        "strikeSelector"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "minItems": 1,
      +                    "type": "array"
      +                  },
      +                  "name": {
      +                    "type": "string"
      +                  },
      +                  "spreadType": {
      +                    "enum": [
      +                      "vertical",
      +                      "calendar",
      +                      "diagonal",
      +                      "ironCondor",
      +                      "straddle",
      +                      "strangle",
      +                      "custom"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "widthConstraint": {
      +                    "additionalProperties": false,
      +                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +                    "properties": {
      +                      "minWidthDollars": {
      +                        "exclusiveMinimum": 0,
      +                        "type": "number"
      +                      },
      +                      "minWidthPercent": {
      +                        "exclusiveMinimum": 0,
      +                        "type": "number"
      +                      }
      +                    },
      +                    "type": "object"
      +                  }
      +                },
      +                "required": [
      +                  "legs"
      +                ],
      +                "type": "object"
      +              },
      +              "minItems": 1,
      +              "type": "array"
      +            },
      +            "universe": {
      +              "additionalProperties": true,
      +              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +              "properties": {
      +                "assets": {
      +                  "items": {
      +                    "additionalProperties": true,
      +                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                    "properties": {
      +                      "name": {
      +                        "type": "string"
      +                      },
      +                      "symbol": {
      +                        "type": "string"
      +                      },
      +                      "type": {
      +                        "enum": [
      +                          "Stock",
      +                          "Cryptocurrency",
      +                          "Option",
      +                          "Other"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "symbol"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "type": "array"
      +                },
      +                "source": {
      +                  "enum": [
      +                    "ALL_US_STOCKS",
      +                    "SP500",
      +                    "NASDAQ100",
      +                    "DJIA",
      +                    "CRYPTO",
      +                    "SPECIFIC_ASSETS"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "source"
      +              ],
      +              "type": "object"
      +            },
      +            "weightIndicator": {
      +              "$ref": "#/$defs/indicator"
      +            }
      +          },
      +          "required": [
      +            "name"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "structureTemplates": {
      +        "items": {
      +          "additionalProperties": true,
      +          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      +          "properties": {
      +            "eligibility": {
      +              "$ref": "#/$defs/condition"
      +            },
      +            "legs": {
      +              "items": {
      +                "additionalProperties": true,
      +                "description": "Single leg of an option builder.",
      +                "properties": {
      +                  "direction": {
      +                    "enum": [
      +                      "long",
      +                      "short"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "expirationRange": {
      +                    "additionalProperties": true,
      +                    "type": "object"
      +                  },
      +                  "expirationSelector": {
      +                    "properties": {
      +                      "maxDaysToExpiration": {
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "minDaysToExpiration": {
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "preference": {
      +                        "enum": [
      +                          "nearest",
      +                          "middle",
      +                          "furthest"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "minDaysToExpiration",
      +                      "maxDaysToExpiration",
      +                      "preference"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "fallbackStrikeSelector": {
      +                    "additionalProperties": false,
      +                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                    "properties": {
      +                      "distance": {
      +                        "type": "number"
      +                      },
      +                      "distanceType": {
      +                        "enum": [
      +                          "percent",
      +                          "dollars"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "distanceType",
      +                      "distance"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "greekFilter": {
      +                    "additionalProperties": true,
      +                    "description": "Optional min/max constraints on Greeks during resolution.",
      +                    "type": "object"
      +                  },
      +                  "liquidityFilter": {
      +                    "additionalProperties": false,
      +                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                    "properties": {
      +                      "maxSpreadAbsolute": {
      +                        "type": "number"
      +                      },
      +                      "maxSpreadPct": {
      +                        "type": "number"
      +                      },
      +                      "minBid": {
      +                        "type": "number"
      +                      }
      +                    },
      +                    "type": "object"
      +                  },
      +                  "optionType": {
      +                    "enum": [
      +                      "call",
      +                      "put"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "ratio": {
      +                    "type": "number"
      +                  },
      +                  "strikeRange": {
      +                    "additionalProperties": true,
      +                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                    "type": "object"
      +                  },
      +                  "strikeSelector": {
      +                    "properties": {
      +                      "distance": {
      +                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                        "type": "number"
      +                      },
      +                      "distanceType": {
      +                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "distanceType",
      +                      "distance"
      +                    ],
      +                    "type": "object"
      +                  }
      +                },
      +                "required": [
      +                  "optionType",
      +                  "direction",
      +                  "expirationSelector",
      +                  "strikeSelector"
      +                ],
      +                "type": "object"
      +              },
      +              "minItems": 1,
      +              "type": "array"
      +            },
      +            "name": {
      +              "type": "string"
      +            },
      +            "spreadType": {
      +              "enum": [
      +                "vertical",
      +                "calendar",
      +                "diagonal",
      +                "ironCondor",
      +                "straddle",
      +                "strangle",
      +                "custom"
      +              ],
      +              "type": "string"
      +            },
      +            "widthConstraint": {
      +              "additionalProperties": false,
      +              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +              "properties": {
      +                "minWidthDollars": {
      +                  "exclusiveMinimum": 0,
      +                  "type": "number"
      +                },
      +                "minWidthPercent": {
      +                  "exclusiveMinimum": 0,
      +                  "type": "number"
      +                }
      +              },
      +              "type": "object"
      +            }
      +          },
      +          "required": [
      +            "legs"
      +          ],
      +          "type": "object"
      +        },
      +        "minItems": 1,
      +        "type": "array"
      +      },
      +      "totalBudget": {
      +        "additionalProperties": true,
      +        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
      +        "properties": {
      +          "amount": {
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "type": {
      +            "enum": [
      +              "dollars",
      +              "percent of portfolio"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      "type": {
      +        "const": "RebalanceOption",
      +        "type": "string"
      +      },
      +      "universe": {
      +        "additionalProperties": true,
      +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +        "properties": {
      +          "assets": {
      +            "items": {
      +              "additionalProperties": true,
      +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +              "properties": {
      +                "name": {
      +                  "type": "string"
      +                },
      +                "symbol": {
      +                  "type": "string"
      +                },
      +                "type": {
      +                  "enum": [
      +                    "Stock",
      +                    "Cryptocurrency",
      +                    "Option",
      +                    "Other"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "symbol"
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "source": {
      +            "enum": [
      +              "ALL_US_STOCKS",
      +              "SP500",
      +              "NASDAQ100",
      +              "DJIA",
      +              "CRYPTO",
      +              "SPECIFIC_ASSETS"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "source"
      +        ],
      +        "type": "object"
      +      },
      +      "weightIndicator": {
      +        "$ref": "#/$defs/indicator"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "universe",
      +      "pipeline",
      +      "weightIndicator",
      +      "structureTemplates"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": true,
      +    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
      +    "properties": {
      +      "closeScope": {
      +        "enum": [
      +          "spread",
      +          "leg"
      +        ],
      +        "type": "string"
      +      },
      +      "direction": {
      +        "enum": [
      +          "long",
      +          "short"
      +        ],
      +        "type": "string"
      +      },
      +      "optionType": {
      +        "enum": [
      +          "call",
      +          "put"
      +        ],
      +        "type": "string"
      +      },
      +      "quantity": {
      +        "additionalProperties": true,
      +        "description": "How many contracts to close. Defaults to all matching when omitted.",
      +        "type": "object"
      +      },
      +      "spreadType": {
      +        "enum": [
      +          "vertical",
      +          "calendar",
      +          "diagonal",
      +          "ironCondor",
      +          "straddle",
      +          "strangle",
      +          "custom"
      +        ],
      +        "type": "string"
      +      },
      +      "triggers": {
      +        "items": {
      +          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
      +          "oneOf": [
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "maxPnlPercent": {
      +                  "type": "number"
      +                },
      +                "minPnlPercent": {
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "pnl",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "maxDte": {
      +                  "type": "number"
      +                },
      +                "minDte": {
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "dte",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "maxDaysHeld": {
      +                  "type": "number"
      +                },
      +                "minDaysHeld": {
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "daysHeld",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "maxIv": {
      +                  "type": "number"
      +                },
      +                "maxSpreadDelta": {
      +                  "type": "number"
      +                },
      +                "maxSpreadTheta": {
      +                  "type": "number"
      +                },
      +                "minIv": {
      +                  "type": "number"
      +                },
      +                "minSpreadDelta": {
      +                  "type": "number"
      +                },
      +                "minSpreadTheta": {
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "greeks",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type"
      +              ],
      +              "type": "object"
      +            }
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "type": {
      +        "const": "CloseOption",
      +        "type": "string"
      +      },
      +      "underlyings": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  }
      +]
  7. Changed5 schema fields changed
    • addedInput schema / $defs
      Added value: +{
      +  "action": {
      +    "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).",
      +    "oneOf": [
      +      {
      +        "additionalProperties": true,
      +        "description": "Buy or Sell a stock/crypto position.",
      +        "properties": {
      +          "amount": {
      +            "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
      +            "properties": {
      +              "amount": {
      +                "type": "number"
      +              },
      +              "type": {
      +                "enum": [
      +                  "percent of portfolio",
      +                  "percent of buying power",
      +                  "percent of current positions",
      +                  "dollars",
      +                  "number of assets"
      +                ],
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "amount"
      +            ],
      +            "type": "object"
      +          },
      +          "targetAsset": {
      +            "additionalProperties": true,
      +            "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +            "properties": {
      +              "name": {
      +                "type": "string"
      +              },
      +              "symbol": {
      +                "type": "string"
      +              },
      +              "type": {
      +                "enum": [
      +                  "Stock",
      +                  "Cryptocurrency",
      +                  "Option",
      +                  "Other"
      +                ],
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "symbol"
      +            ],
      +            "type": "object"
      +          },
      +          "type": {
      +            "enum": [
      +              "Buy",
      +              "Sell"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "targetAsset",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      {
      +        "additionalProperties": true,
      +        "description": "Send an alert message (no order).",
      +        "properties": {
      +          "message": {
      +            "type": "string"
      +          },
      +          "type": {
      +            "const": "Alert",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "message"
      +        ],
      +        "type": "object"
      +      },
      +      {
      +        "additionalProperties": true,
      +        "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
      +        "properties": {
      +          "allocationPolicy": {
      +            "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      +            "oneOf": [
      +              {
      +                "additionalProperties": false,
      +                "properties": {
      +                  "covarianceShrinkage": {
      +                    "maximum": 1,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "estimatedTransactionCostBps": {
      +                    "maximum": 10000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "expectedReturnShrinkage": {
      +                    "maximum": 1,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "lookbackPeriods": {
      +                    "maximum": 5000,
      +                    "minimum": 2,
      +                    "type": "integer"
      +                  },
      +                  "minimumObservations": {
      +                    "maximum": 5000,
      +                    "minimum": 2,
      +                    "type": "integer"
      +                  },
      +                  "riskAversion": {
      +                    "maximum": 1000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "turnoverPenalty": {
      +                    "maximum": 10000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "const": "MeanVariance",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "lookbackPeriods",
      +                  "minimumObservations",
      +                  "riskAversion",
      +                  "expectedReturnShrinkage",
      +                  "covarianceShrinkage",
      +                  "turnoverPenalty",
      +                  "estimatedTransactionCostBps"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "additionalProperties": false,
      +                "properties": {
      +                  "covarianceShrinkage": {
      +                    "maximum": 1,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "estimatedTransactionCostBps": {
      +                    "maximum": 10000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "lookbackPeriods": {
      +                    "maximum": 5000,
      +                    "minimum": 2,
      +                    "type": "integer"
      +                  },
      +                  "minimumObservations": {
      +                    "maximum": 5000,
      +                    "minimum": 2,
      +                    "type": "integer"
      +                  },
      +                  "turnoverPenalty": {
      +                    "maximum": 10000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "const": "RiskParity",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "lookbackPeriods",
      +                  "minimumObservations",
      +                  "covarianceShrinkage",
      +                  "turnoverPenalty",
      +                  "estimatedTransactionCostBps"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "additionalProperties": false,
      +                "properties": {
      +                  "covarianceShrinkage": {
      +                    "maximum": 1,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "estimatedTransactionCostBps": {
      +                    "maximum": 10000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "lookbackPeriods": {
      +                    "maximum": 5000,
      +                    "minimum": 2,
      +                    "type": "integer"
      +                  },
      +                  "minimumObservations": {
      +                    "maximum": 5000,
      +                    "minimum": 2,
      +                    "type": "integer"
      +                  },
      +                  "turnoverPenalty": {
      +                    "maximum": 10000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "const": "MaximumDiversification",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "lookbackPeriods",
      +                  "minimumObservations",
      +                  "covarianceShrinkage",
      +                  "turnoverPenalty",
      +                  "estimatedTransactionCostBps"
      +                ],
      +                "type": "object"
      +              }
      +            ]
      +          },
      +          "canSell": {
      +            "$ref": "#/$defs/condition",
      +            "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
      +          },
      +          "deploymentPercent": {
      +            "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
      +            "maximum": 100,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "exposurePolicy": {
      +            "additionalProperties": false,
      +            "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "targetAnnualizedVolatilityPercent": {
      +                "maximum": 1000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "VolatilityTarget",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "covarianceShrinkage",
      +              "targetAnnualizedVolatilityPercent",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          },
      +          "limit": {
      +            "minimum": 1,
      +            "type": "number"
      +          },
      +          "perNameAllocation": {
      +            "additionalProperties": true,
      +            "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
      +            "properties": {
      +              "amount": {
      +                "exclusiveMinimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "enum": [
      +                  "percent of portfolio",
      +                  "dollars"
      +                ],
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "amount"
      +            ],
      +            "type": "object"
      +          },
      +          "pipeline": {
      +            "items": {
      +              "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +              "oneOf": [
      +                {
      +                  "additionalProperties": true,
      +                  "properties": {
      +                    "condition": {
      +                      "$ref": "#/$defs/condition"
      +                    },
      +                    "type": {
      +                      "const": "Filter",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type",
      +                    "condition"
      +                  ],
      +                  "type": "object"
      +                },
      +                {
      +                  "additionalProperties": true,
      +                  "properties": {
      +                    "direction": {
      +                      "enum": [
      +                        "Highest",
      +                        "Lowest"
      +                      ],
      +                      "type": "string"
      +                    },
      +                    "limit": {
      +                      "minimum": 1,
      +                      "type": "number"
      +                    },
      +                    "metric": {
      +                      "$ref": "#/$defs/indicator"
      +                    },
      +                    "type": {
      +                      "const": "SelectTop",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type",
      +                    "metric",
      +                    "limit",
      +                    "direction"
      +                  ],
      +                  "type": "object"
      +                },
      +                {
      +                  "additionalProperties": true,
      +                  "properties": {
      +                    "direction": {
      +                      "enum": [
      +                        "Highest",
      +                        "Lowest"
      +                      ],
      +                      "type": "string"
      +                    },
      +                    "metric": {
      +                      "$ref": "#/$defs/indicator"
      +                    },
      +                    "percentile": {
      +                      "maximum": 100,
      +                      "minimum": 0,
      +                      "type": "number"
      +                    },
      +                    "type": {
      +                      "const": "SelectPercentile",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type",
      +                    "metric",
      +                    "percentile",
      +                    "direction"
      +                  ],
      +                  "type": "object"
      +                }
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "type": {
      +            "const": "DynamicRebalance",
      +            "type": "string"
      +          },
      +          "universe": {
      +            "additionalProperties": true,
      +            "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +            "properties": {
      +              "assets": {
      +                "items": {
      +                  "additionalProperties": true,
      +                  "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                  "properties": {
      +                    "name": {
      +                      "type": "string"
      +                    },
      +                    "symbol": {
      +                      "type": "string"
      +                    },
      +                    "type": {
      +                      "enum": [
      +                        "Stock",
      +                        "Cryptocurrency",
      +                        "Option",
      +                        "Other"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type",
      +                    "symbol"
      +                  ],
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "source": {
      +                "enum": [
      +                  "ALL_US_STOCKS",
      +                  "SP500",
      +                  "NASDAQ100",
      +                  "DJIA",
      +                  "CRYPTO",
      +                  "SPECIFIC_ASSETS"
      +                ],
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "source"
      +            ],
      +            "type": "object"
      +          },
      +          "weightIndicator": {
      +            "$ref": "#/$defs/indicator"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "universe",
      +          "pipeline",
      +          "weightIndicator"
      +        ],
      +        "type": "object"
      +      },
      +      {
      +        "additionalProperties": true,
      +        "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
      +        "properties": {
      +          "continueExisting": {
      +            "type": "boolean"
      +          },
      +          "cooldownMinutes": {
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "executionModel": {
      +            "type": "string"
      +          },
      +          "includeMarketData": {
      +            "type": "boolean"
      +          },
      +          "initialMessage": {
      +            "type": "string"
      +          },
      +          "maxIterations": {
      +            "minimum": 1,
      +            "type": "number"
      +          },
      +          "planningModel": {
      +            "type": "string"
      +          },
      +          "skipPlanning": {
      +            "type": "boolean"
      +          },
      +          "type": {
      +            "const": "LaunchAgent",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "planningModel",
      +          "executionModel",
      +          "initialMessage",
      +          "maxIterations",
      +          "includeMarketData",
      +          "continueExisting",
      +          "skipPlanning"
      +        ],
      +        "type": "object"
      +      },
      +      {
      +        "additionalProperties": true,
      +        "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
      +        "properties": {
      +          "against": {
      +            "additionalProperties": true,
      +            "description": "Optional parent-position selector (e.g. for covered calls).",
      +            "type": "object"
      +          },
      +          "allocation": {
      +            "additionalProperties": true,
      +            "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +            "properties": {
      +              "amount": {
      +                "type": "number"
      +              },
      +              "type": {
      +                "enum": [
      +                  "dollars",
      +                  "percent of portfolio",
      +                  "percent of buying power",
      +                  "contracts"
      +                ],
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "amount"
      +            ],
      +            "type": "object"
      +          },
      +          "builder": {
      +            "additionalProperties": true,
      +            "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
      +            "properties": {
      +              "dynamicUnderlying": {
      +                "additionalProperties": true,
      +                "properties": {
      +                  "limit": {
      +                    "minimum": 1,
      +                    "type": "number"
      +                  },
      +                  "pipeline": {
      +                    "items": {
      +                      "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                      "oneOf": [
      +                        {
      +                          "additionalProperties": true,
      +                          "properties": {
      +                            "condition": {
      +                              "$ref": "#/$defs/condition"
      +                            },
      +                            "type": {
      +                              "const": "Filter",
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "type",
      +                            "condition"
      +                          ],
      +                          "type": "object"
      +                        },
      +                        {
      +                          "additionalProperties": true,
      +                          "properties": {
      +                            "direction": {
      +                              "enum": [
      +                                "Highest",
      +                                "Lowest"
      +                              ],
      +                              "type": "string"
      +                            },
      +                            "limit": {
      +                              "minimum": 1,
      +                              "type": "number"
      +                            },
      +                            "metric": {
      +                              "$ref": "#/$defs/indicator"
      +                            },
      +                            "type": {
      +                              "const": "SelectTop",
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "type",
      +                            "metric",
      +                            "limit",
      +                            "direction"
      +                          ],
      +                          "type": "object"
      +                        },
      +                        {
      +                          "additionalProperties": true,
      +                          "properties": {
      +                            "direction": {
      +                              "enum": [
      +                                "Highest",
      +                                "Lowest"
      +                              ],
      +                              "type": "string"
      +                            },
      +                            "metric": {
      +                              "$ref": "#/$defs/indicator"
      +                            },
      +                            "percentile": {
      +                              "maximum": 100,
      +                              "minimum": 0,
      +                              "type": "number"
      +                            },
      +                            "type": {
      +                              "const": "SelectPercentile",
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "type",
      +                            "metric",
      +                            "percentile",
      +                            "direction"
      +                          ],
      +                          "type": "object"
      +                        }
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "type": "array"
      +                  },
      +                  "universe": {
      +                    "additionalProperties": true,
      +                    "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +                    "properties": {
      +                      "assets": {
      +                        "items": {
      +                          "additionalProperties": true,
      +                          "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                          "properties": {
      +                            "name": {
      +                              "type": "string"
      +                            },
      +                            "symbol": {
      +                              "type": "string"
      +                            },
      +                            "type": {
      +                              "enum": [
      +                                "Stock",
      +                                "Cryptocurrency",
      +                                "Option",
      +                                "Other"
      +                              ],
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "type",
      +                            "symbol"
      +                          ],
      +                          "type": "object"
      +                        },
      +                        "type": "array"
      +                      },
      +                      "source": {
      +                        "enum": [
      +                          "ALL_US_STOCKS",
      +                          "SP500",
      +                          "NASDAQ100",
      +                          "DJIA",
      +                          "CRYPTO",
      +                          "SPECIFIC_ASSETS"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "source"
      +                    ],
      +                    "type": "object"
      +                  }
      +                },
      +                "required": [
      +                  "universe"
      +                ],
      +                "type": "object"
      +              },
      +              "legs": {
      +                "items": {
      +                  "additionalProperties": true,
      +                  "description": "Single leg of an option builder.",
      +                  "properties": {
      +                    "direction": {
      +                      "enum": [
      +                        "long",
      +                        "short"
      +                      ],
      +                      "type": "string"
      +                    },
      +                    "expirationRange": {
      +                      "additionalProperties": true,
      +                      "type": "object"
      +                    },
      +                    "expirationSelector": {
      +                      "properties": {
      +                        "maxDaysToExpiration": {
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "minDaysToExpiration": {
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "preference": {
      +                          "enum": [
      +                            "nearest",
      +                            "middle",
      +                            "furthest"
      +                          ],
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "minDaysToExpiration",
      +                        "maxDaysToExpiration",
      +                        "preference"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "fallbackStrikeSelector": {
      +                      "additionalProperties": false,
      +                      "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                      "properties": {
      +                        "distance": {
      +                          "type": "number"
      +                        },
      +                        "distanceType": {
      +                          "enum": [
      +                            "percent",
      +                            "dollars"
      +                          ],
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "distanceType",
      +                        "distance"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "greekFilter": {
      +                      "additionalProperties": true,
      +                      "description": "Optional min/max constraints on Greeks during resolution.",
      +                      "type": "object"
      +                    },
      +                    "liquidityFilter": {
      +                      "additionalProperties": false,
      +                      "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                      "properties": {
      +                        "maxSpreadAbsolute": {
      +                          "type": "number"
      +                        },
      +                        "maxSpreadPct": {
      +                          "type": "number"
      +                        },
      +                        "minBid": {
      +                          "type": "number"
      +                        }
      +                      },
      +                      "type": "object"
      +                    },
      +                    "optionType": {
      +                      "enum": [
      +                        "call",
      +                        "put"
      +                      ],
      +                      "type": "string"
      +                    },
      +                    "ratio": {
      +                      "type": "number"
      +                    },
      +                    "strikeRange": {
      +                      "additionalProperties": true,
      +                      "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                      "type": "object"
      +                    },
      +                    "strikeSelector": {
      +                      "properties": {
      +                        "distance": {
      +                          "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                          "type": "number"
      +                        },
      +                        "distanceType": {
      +                          "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "distanceType",
      +                        "distance"
      +                      ],
      +                      "type": "object"
      +                    }
      +                  },
      +                  "required": [
      +                    "optionType",
      +                    "direction",
      +                    "expirationSelector",
      +                    "strikeSelector"
      +                  ],
      +                  "type": "object"
      +                },
      +                "minItems": 1,
      +                "type": "array"
      +              },
      +              "spreadType": {
      +                "enum": [
      +                  "vertical",
      +                  "calendar",
      +                  "diagonal",
      +                  "ironCondor",
      +                  "straddle",
      +                  "strangle",
      +                  "custom"
      +                ],
      +                "type": "string"
      +              },
      +              "underlyingSymbol": {
      +                "type": "string"
      +              },
      +              "widthConstraint": {
      +                "additionalProperties": false,
      +                "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +                "properties": {
      +                  "minWidthDollars": {
      +                    "exclusiveMinimum": 0,
      +                    "type": "number"
      +                  },
      +                  "minWidthPercent": {
      +                    "exclusiveMinimum": 0,
      +                    "type": "number"
      +                  }
      +                },
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "legs"
      +            ],
      +            "type": "object"
      +          },
      +          "type": {
      +            "const": "OpenOption",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "builder"
      +        ],
      +        "type": "object"
      +      },
      +      {
      +        "additionalProperties": true,
      +        "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
      +        "properties": {
      +          "allocationPolicy": {
      +            "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      +            "oneOf": [
      +              {
      +                "additionalProperties": false,
      +                "properties": {
      +                  "covarianceShrinkage": {
      +                    "maximum": 1,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "estimatedTransactionCostBps": {
      +                    "maximum": 10000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "expectedReturnShrinkage": {
      +                    "maximum": 1,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "lookbackPeriods": {
      +                    "maximum": 5000,
      +                    "minimum": 2,
      +                    "type": "integer"
      +                  },
      +                  "minimumObservations": {
      +                    "maximum": 5000,
      +                    "minimum": 2,
      +                    "type": "integer"
      +                  },
      +                  "riskAversion": {
      +                    "maximum": 1000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "turnoverPenalty": {
      +                    "maximum": 10000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "const": "MeanVariance",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "lookbackPeriods",
      +                  "minimumObservations",
      +                  "riskAversion",
      +                  "expectedReturnShrinkage",
      +                  "covarianceShrinkage",
      +                  "turnoverPenalty",
      +                  "estimatedTransactionCostBps"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "additionalProperties": false,
      +                "properties": {
      +                  "covarianceShrinkage": {
      +                    "maximum": 1,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "estimatedTransactionCostBps": {
      +                    "maximum": 10000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "lookbackPeriods": {
      +                    "maximum": 5000,
      +                    "minimum": 2,
      +                    "type": "integer"
      +                  },
      +                  "minimumObservations": {
      +                    "maximum": 5000,
      +                    "minimum": 2,
      +                    "type": "integer"
      +                  },
      +                  "turnoverPenalty": {
      +                    "maximum": 10000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "const": "RiskParity",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "lookbackPeriods",
      +                  "minimumObservations",
      +                  "covarianceShrinkage",
      +                  "turnoverPenalty",
      +                  "estimatedTransactionCostBps"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "additionalProperties": false,
      +                "properties": {
      +                  "covarianceShrinkage": {
      +                    "maximum": 1,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "estimatedTransactionCostBps": {
      +                    "maximum": 10000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "lookbackPeriods": {
      +                    "maximum": 5000,
      +                    "minimum": 2,
      +                    "type": "integer"
      +                  },
      +                  "minimumObservations": {
      +                    "maximum": 5000,
      +                    "minimum": 2,
      +                    "type": "integer"
      +                  },
      +                  "turnoverPenalty": {
      +                    "maximum": 10000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "const": "MaximumDiversification",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "lookbackPeriods",
      +                  "minimumObservations",
      +                  "covarianceShrinkage",
      +                  "turnoverPenalty",
      +                  "estimatedTransactionCostBps"
      +                ],
      +                "type": "object"
      +              }
      +            ]
      +          },
      +          "exposurePolicy": {
      +            "additionalProperties": false,
      +            "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      +            "properties": {
      +              "covarianceShrinkage": {
      +                "maximum": 1,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "estimatedTransactionCostBps": {
      +                "maximum": 10000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "lookbackPeriods": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "minimumObservations": {
      +                "maximum": 5000,
      +                "minimum": 2,
      +                "type": "integer"
      +              },
      +              "targetAnnualizedVolatilityPercent": {
      +                "maximum": 1000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "const": "VolatilityTarget",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "lookbackPeriods",
      +              "minimumObservations",
      +              "covarianceShrinkage",
      +              "targetAnnualizedVolatilityPercent",
      +              "estimatedTransactionCostBps"
      +            ],
      +            "type": "object"
      +          },
      +          "limit": {
      +            "minimum": 1,
      +            "type": "number"
      +          },
      +          "perNameAllocation": {
      +            "additionalProperties": true,
      +            "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +            "properties": {
      +              "amount": {
      +                "type": "number"
      +              },
      +              "type": {
      +                "enum": [
      +                  "dollars",
      +                  "percent of portfolio",
      +                  "percent of buying power",
      +                  "contracts"
      +                ],
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "amount"
      +            ],
      +            "type": "object"
      +          },
      +          "pipeline": {
      +            "items": {
      +              "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +              "oneOf": [
      +                {
      +                  "additionalProperties": true,
      +                  "properties": {
      +                    "condition": {
      +                      "$ref": "#/$defs/condition"
      +                    },
      +                    "type": {
      +                      "const": "Filter",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type",
      +                    "condition"
      +                  ],
      +                  "type": "object"
      +                },
      +                {
      +                  "additionalProperties": true,
      +                  "properties": {
      +                    "direction": {
      +                      "enum": [
      +                        "Highest",
      +                        "Lowest"
      +                      ],
      +                      "type": "string"
      +                    },
      +                    "limit": {
      +                      "minimum": 1,
      +                      "type": "number"
      +                    },
      +                    "metric": {
      +                      "$ref": "#/$defs/indicator"
      +                    },
      +                    "type": {
      +                      "const": "SelectTop",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type",
      +                    "metric",
      +                    "limit",
      +                    "direction"
      +                  ],
      +                  "type": "object"
      +                },
      +                {
      +                  "additionalProperties": true,
      +                  "properties": {
      +                    "direction": {
      +                      "enum": [
      +                        "Highest",
      +                        "Lowest"
      +                      ],
      +                      "type": "string"
      +                    },
      +                    "metric": {
      +                      "$ref": "#/$defs/indicator"
      +                    },
      +                    "percentile": {
      +                      "maximum": 100,
      +                      "minimum": 0,
      +                      "type": "number"
      +                    },
      +                    "type": {
      +                      "const": "SelectPercentile",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type",
      +                    "metric",
      +                    "percentile",
      +                    "direction"
      +                  ],
      +                  "type": "object"
      +                }
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "positionScope": {
      +            "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
      +            "enum": [
      +              "portfolio",
      +              "strategy"
      +            ],
      +            "type": "string"
      +          },
      +          "sleeves": {
      +            "items": {
      +              "additionalProperties": true,
      +              "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
      +              "properties": {
      +                "limit": {
      +                  "minimum": 1,
      +                  "type": "number"
      +                },
      +                "name": {
      +                  "type": "string"
      +                },
      +                "perNameAllocation": {
      +                  "additionalProperties": true,
      +                  "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +                  "properties": {
      +                    "amount": {
      +                      "type": "number"
      +                    },
      +                    "type": {
      +                      "enum": [
      +                        "dollars",
      +                        "percent of portfolio",
      +                        "percent of buying power",
      +                        "contracts"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type",
      +                    "amount"
      +                  ],
      +                  "type": "object"
      +                },
      +                "pipeline": {
      +                  "items": {
      +                    "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                    "oneOf": [
      +                      {
      +                        "additionalProperties": true,
      +                        "properties": {
      +                          "condition": {
      +                            "$ref": "#/$defs/condition"
      +                          },
      +                          "type": {
      +                            "const": "Filter",
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "type",
      +                          "condition"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      {
      +                        "additionalProperties": true,
      +                        "properties": {
      +                          "direction": {
      +                            "enum": [
      +                              "Highest",
      +                              "Lowest"
      +                            ],
      +                            "type": "string"
      +                          },
      +                          "limit": {
      +                            "minimum": 1,
      +                            "type": "number"
      +                          },
      +                          "metric": {
      +                            "$ref": "#/$defs/indicator"
      +                          },
      +                          "type": {
      +                            "const": "SelectTop",
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "type",
      +                          "metric",
      +                          "limit",
      +                          "direction"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      {
      +                        "additionalProperties": true,
      +                        "properties": {
      +                          "direction": {
      +                            "enum": [
      +                              "Highest",
      +                              "Lowest"
      +                            ],
      +                            "type": "string"
      +                          },
      +                          "metric": {
      +                            "$ref": "#/$defs/indicator"
      +                          },
      +                          "percentile": {
      +                            "maximum": 100,
      +                            "minimum": 0,
      +                            "type": "number"
      +                          },
      +                          "type": {
      +                            "const": "SelectPercentile",
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "type",
      +                          "metric",
      +                          "percentile",
      +                          "direction"
      +                        ],
      +                        "type": "object"
      +                      }
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "type": "array"
      +                },
      +                "structureTemplates": {
      +                  "items": {
      +                    "additionalProperties": true,
      +                    "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      +                    "properties": {
      +                      "eligibility": {
      +                        "$ref": "#/$defs/condition"
      +                      },
      +                      "legs": {
      +                        "items": {
      +                          "additionalProperties": true,
      +                          "description": "Single leg of an option builder.",
      +                          "properties": {
      +                            "direction": {
      +                              "enum": [
      +                                "long",
      +                                "short"
      +                              ],
      +                              "type": "string"
      +                            },
      +                            "expirationRange": {
      +                              "additionalProperties": true,
      +                              "type": "object"
      +                            },
      +                            "expirationSelector": {
      +                              "properties": {
      +                                "maxDaysToExpiration": {
      +                                  "minimum": 0,
      +                                  "type": "number"
      +                                },
      +                                "minDaysToExpiration": {
      +                                  "minimum": 0,
      +                                  "type": "number"
      +                                },
      +                                "preference": {
      +                                  "enum": [
      +                                    "nearest",
      +                                    "middle",
      +                                    "furthest"
      +                                  ],
      +                                  "type": "string"
      +                                }
      +                              },
      +                              "required": [
      +                                "minDaysToExpiration",
      +                                "maxDaysToExpiration",
      +                                "preference"
      +                              ],
      +                              "type": "object"
      +                            },
      +                            "fallbackStrikeSelector": {
      +                              "additionalProperties": false,
      +                              "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                              "properties": {
      +                                "distance": {
      +                                  "type": "number"
      +                                },
      +                                "distanceType": {
      +                                  "enum": [
      +                                    "percent",
      +                                    "dollars"
      +                                  ],
      +                                  "type": "string"
      +                                }
      +                              },
      +                              "required": [
      +                                "distanceType",
      +                                "distance"
      +                              ],
      +                              "type": "object"
      +                            },
      +                            "greekFilter": {
      +                              "additionalProperties": true,
      +                              "description": "Optional min/max constraints on Greeks during resolution.",
      +                              "type": "object"
      +                            },
      +                            "liquidityFilter": {
      +                              "additionalProperties": false,
      +                              "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                              "properties": {
      +                                "maxSpreadAbsolute": {
      +                                  "type": "number"
      +                                },
      +                                "maxSpreadPct": {
      +                                  "type": "number"
      +                                },
      +                                "minBid": {
      +                                  "type": "number"
      +                                }
      +                              },
      +                              "type": "object"
      +                            },
      +                            "optionType": {
      +                              "enum": [
      +                                "call",
      +                                "put"
      +                              ],
      +                              "type": "string"
      +                            },
      +                            "ratio": {
      +                              "type": "number"
      +                            },
      +                            "strikeRange": {
      +                              "additionalProperties": true,
      +                              "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                              "type": "object"
      +                            },
      +                            "strikeSelector": {
      +                              "properties": {
      +                                "distance": {
      +                                  "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                                  "type": "number"
      +                                },
      +                                "distanceType": {
      +                                  "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                                  "type": "string"
      +                                }
      +                              },
      +                              "required": [
      +                                "distanceType",
      +                                "distance"
      +                              ],
      +                              "type": "object"
      +                            }
      +                          },
      +                          "required": [
      +                            "optionType",
      +                            "direction",
      +                            "expirationSelector",
      +                            "strikeSelector"
      +                          ],
      +                          "type": "object"
      +                        },
      +                        "minItems": 1,
      +                        "type": "array"
      +                      },
      +                      "name": {
      +                        "type": "string"
      +                      },
      +                      "spreadType": {
      +                        "enum": [
      +                          "vertical",
      +                          "calendar",
      +                          "diagonal",
      +                          "ironCondor",
      +                          "straddle",
      +                          "strangle",
      +                          "custom"
      +                        ],
      +                        "type": "string"
      +                      },
      +                      "widthConstraint": {
      +                        "additionalProperties": false,
      +                        "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +                        "properties": {
      +                          "minWidthDollars": {
      +                            "exclusiveMinimum": 0,
      +                            "type": "number"
      +                          },
      +                          "minWidthPercent": {
      +                            "exclusiveMinimum": 0,
      +                            "type": "number"
      +                          }
      +                        },
      +                        "type": "object"
      +                      }
      +                    },
      +                    "required": [
      +                      "legs"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "minItems": 1,
      +                  "type": "array"
      +                },
      +                "universe": {
      +                  "additionalProperties": true,
      +                  "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +                  "properties": {
      +                    "assets": {
      +                      "items": {
      +                        "additionalProperties": true,
      +                        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                        "properties": {
      +                          "name": {
      +                            "type": "string"
      +                          },
      +                          "symbol": {
      +                            "type": "string"
      +                          },
      +                          "type": {
      +                            "enum": [
      +                              "Stock",
      +                              "Cryptocurrency",
      +                              "Option",
      +                              "Other"
      +                            ],
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "type",
      +                          "symbol"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      "type": "array"
      +                    },
      +                    "source": {
      +                      "enum": [
      +                        "ALL_US_STOCKS",
      +                        "SP500",
      +                        "NASDAQ100",
      +                        "DJIA",
      +                        "CRYPTO",
      +                        "SPECIFIC_ASSETS"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "source"
      +                  ],
      +                  "type": "object"
      +                },
      +                "weightIndicator": {
      +                  "$ref": "#/$defs/indicator"
      +                }
      +              },
      +              "required": [
      +                "name"
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "structureTemplates": {
      +            "items": {
      +              "additionalProperties": true,
      +              "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      +              "properties": {
      +                "eligibility": {
      +                  "$ref": "#/$defs/condition"
      +                },
      +                "legs": {
      +                  "items": {
      +                    "additionalProperties": true,
      +                    "description": "Single leg of an option builder.",
      +                    "properties": {
      +                      "direction": {
      +                        "enum": [
      +                          "long",
      +                          "short"
      +                        ],
      +                        "type": "string"
      +                      },
      +                      "expirationRange": {
      +                        "additionalProperties": true,
      +                        "type": "object"
      +                      },
      +                      "expirationSelector": {
      +                        "properties": {
      +                          "maxDaysToExpiration": {
      +                            "minimum": 0,
      +                            "type": "number"
      +                          },
      +                          "minDaysToExpiration": {
      +                            "minimum": 0,
      +                            "type": "number"
      +                          },
      +                          "preference": {
      +                            "enum": [
      +                              "nearest",
      +                              "middle",
      +                              "furthest"
      +                            ],
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "minDaysToExpiration",
      +                          "maxDaysToExpiration",
      +                          "preference"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      "fallbackStrikeSelector": {
      +                        "additionalProperties": false,
      +                        "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                        "properties": {
      +                          "distance": {
      +                            "type": "number"
      +                          },
      +                          "distanceType": {
      +                            "enum": [
      +                              "percent",
      +                              "dollars"
      +                            ],
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "distanceType",
      +                          "distance"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      "greekFilter": {
      +                        "additionalProperties": true,
      +                        "description": "Optional min/max constraints on Greeks during resolution.",
      +                        "type": "object"
      +                      },
      +                      "liquidityFilter": {
      +                        "additionalProperties": false,
      +                        "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                        "properties": {
      +                          "maxSpreadAbsolute": {
      +                            "type": "number"
      +                          },
      +                          "maxSpreadPct": {
      +                            "type": "number"
      +                          },
      +                          "minBid": {
      +                            "type": "number"
      +                          }
      +                        },
      +                        "type": "object"
      +                      },
      +                      "optionType": {
      +                        "enum": [
      +                          "call",
      +                          "put"
      +                        ],
      +                        "type": "string"
      +                      },
      +                      "ratio": {
      +                        "type": "number"
      +                      },
      +                      "strikeRange": {
      +                        "additionalProperties": true,
      +                        "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                        "type": "object"
      +                      },
      +                      "strikeSelector": {
      +                        "properties": {
      +                          "distance": {
      +                            "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                            "type": "number"
      +                          },
      +                          "distanceType": {
      +                            "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "distanceType",
      +                          "distance"
      +                        ],
      +                        "type": "object"
      +                      }
      +                    },
      +                    "required": [
      +                      "optionType",
      +                      "direction",
      +                      "expirationSelector",
      +                      "strikeSelector"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "minItems": 1,
      +                  "type": "array"
      +                },
      +                "name": {
      +                  "type": "string"
      +                },
      +                "spreadType": {
      +                  "enum": [
      +                    "vertical",
      +                    "calendar",
      +                    "diagonal",
      +                    "ironCondor",
      +                    "straddle",
      +                    "strangle",
      +                    "custom"
      +                  ],
      +                  "type": "string"
      +                },
      +                "widthConstraint": {
      +                  "additionalProperties": false,
      +                  "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +                  "properties": {
      +                    "minWidthDollars": {
      +                      "exclusiveMinimum": 0,
      +                      "type": "number"
      +                    },
      +                    "minWidthPercent": {
      +                      "exclusiveMinimum": 0,
      +                      "type": "number"
      +                    }
      +                  },
      +                  "type": "object"
      +                }
      +              },
      +              "required": [
      +                "legs"
      +              ],
      +              "type": "object"
      +            },
      +            "minItems": 1,
      +            "type": "array"
      +          },
      +          "totalBudget": {
      +            "additionalProperties": true,
      +            "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
      +            "properties": {
      +              "amount": {
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "type": {
      +                "enum": [
      +                  "dollars",
      +                  "percent of portfolio"
      +                ],
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "amount"
      +            ],
      +            "type": "object"
      +          },
      +          "type": {
      +            "const": "RebalanceOption",
      +            "type": "string"
      +          },
      +          "universe": {
      +            "additionalProperties": true,
      +            "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +            "properties": {
      +              "assets": {
      +                "items": {
      +                  "additionalProperties": true,
      +                  "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                  "properties": {
      +                    "name": {
      +                      "type": "string"
      +                    },
      +                    "symbol": {
      +                      "type": "string"
      +                    },
      +                    "type": {
      +                      "enum": [
      +                        "Stock",
      +                        "Cryptocurrency",
      +                        "Option",
      +                        "Other"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type",
      +                    "symbol"
      +                  ],
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "source": {
      +                "enum": [
      +                  "ALL_US_STOCKS",
      +                  "SP500",
      +                  "NASDAQ100",
      +                  "DJIA",
      +                  "CRYPTO",
      +                  "SPECIFIC_ASSETS"
      +                ],
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "source"
      +            ],
      +            "type": "object"
      +          },
      +          "weightIndicator": {
      +            "$ref": "#/$defs/indicator"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "universe",
      +          "pipeline",
      +          "weightIndicator",
      +          "structureTemplates"
      +        ],
      +        "type": "object"
      +      },
      +      {
      +        "additionalProperties": true,
      +        "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
      +        "properties": {
      +          "closeScope": {
      +            "enum": [
      +              "spread",
      +              "leg"
      +            ],
      +            "type": "string"
      +          },
      +          "direction": {
      +            "enum": [
      +              "long",
      +              "short"
      +            ],
      +            "type": "string"
      +          },
      +          "optionType": {
      +            "enum": [
      +              "call",
      +              "put"
      +            ],
      +            "type": "string"
      +          },
      +          "quantity": {
      +            "additionalProperties": true,
      +            "description": "How many contracts to close. Defaults to all matching when omitted.",
      +            "type": "object"
      +          },
      +          "spreadType": {
      +            "enum": [
      +              "vertical",
      +              "calendar",
      +              "diagonal",
      +              "ironCondor",
      +              "straddle",
      +              "strangle",
      +              "custom"
      +            ],
      +            "type": "string"
      +          },
      +          "triggers": {
      +            "items": {
      +              "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
      +              "oneOf": [
      +                {
      +                  "additionalProperties": true,
      +                  "properties": {
      +                    "maxPnlPercent": {
      +                      "type": "number"
      +                    },
      +                    "minPnlPercent": {
      +                      "type": "number"
      +                    },
      +                    "type": {
      +                      "const": "pnl",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type"
      +                  ],
      +                  "type": "object"
      +                },
      +                {
      +                  "additionalProperties": true,
      +                  "properties": {
      +                    "maxDte": {
      +                      "type": "number"
      +                    },
      +                    "minDte": {
      +                      "type": "number"
      +                    },
      +                    "type": {
      +                      "const": "dte",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type"
      +                  ],
      +                  "type": "object"
      +                },
      +                {
      +                  "additionalProperties": true,
      +                  "properties": {
      +                    "maxDaysHeld": {
      +                      "type": "number"
      +                    },
      +                    "minDaysHeld": {
      +                      "type": "number"
      +                    },
      +                    "type": {
      +                      "const": "daysHeld",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type"
      +                  ],
      +                  "type": "object"
      +                },
      +                {
      +                  "additionalProperties": true,
      +                  "properties": {
      +                    "maxIv": {
      +                      "type": "number"
      +                    },
      +                    "maxSpreadDelta": {
      +                      "type": "number"
      +                    },
      +                    "maxSpreadTheta": {
      +                      "type": "number"
      +                    },
      +                    "minIv": {
      +                      "type": "number"
      +                    },
      +                    "minSpreadDelta": {
      +                      "type": "number"
      +                    },
      +                    "minSpreadTheta": {
      +                      "type": "number"
      +                    },
      +                    "type": {
      +                      "const": "greeks",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type"
      +                  ],
      +                  "type": "object"
      +                }
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "type": {
      +            "const": "CloseOption",
      +            "type": "string"
      +          },
      +          "underlyings": {
      +            "items": {
      +              "type": "string"
      +            },
      +            "type": "array"
      +          }
      +        },
      +        "required": [
      +          "type"
      +        ],
      +        "type": "object"
      +      }
      +    ],
      +    "type": "object"
      +  },
      +  "asset": {
      +    "additionalProperties": true,
      +    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +    "properties": {
      +      "name": {
      +        "type": "string"
      +      },
      +      "symbol": {
      +        "type": "string"
      +      },
      +      "type": {
      +        "enum": [
      +          "Stock",
      +          "Cryptocurrency",
      +          "Option",
      +          "Other"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "symbol"
      +    ],
      +    "type": "object"
      +  },
      +  "condition": {
      +    "additionalProperties": true,
      +    "description": "A condition tree (Bridge pattern). type='Base' compares lhs vs rhs with a comparator; type='And'/'Or' combine an array of nested conditions; type='Multi' fires when N nested conditions are true (count vs threshold); type='Then' is sequential — it fires when the last nested condition is true now and each earlier one was true at a strictly earlier tick within 'window' of the next, so it needs at least 2 conditions and a window with length > 0.",
      +    "properties": {
      +      "comparison": {
      +        "description": "Base / Multi only: how to compare.",
      +        "enum": [
      +          "lessThan",
      +          "greaterThan",
      +          "lessThanOrEqual",
      +          "greaterThanOrEqual",
      +          "equal",
      +          "notEqual"
      +        ],
      +        "type": "string"
      +      },
      +      "conditions": {
      +        "description": "And / Or / Multi / Then only: nested conditions. Then reads them in order (at least 2).",
      +        "items": {
      +          "$ref": "#/$defs/condition"
      +        },
      +        "type": "array"
      +      },
      +      "lhs": {
      +        "$ref": "#/$defs/indicator",
      +        "description": "Base only: left-hand indicator."
      +      },
      +      "name": {
      +        "description": "Optional name; auto-derived if omitted.",
      +        "type": "string"
      +      },
      +      "rhs": {
      +        "$ref": "#/$defs/indicator",
      +        "description": "Base only: right-hand indicator."
      +      },
      +      "type": {
      +        "enum": [
      +          "And",
      +          "Or",
      +          "Base",
      +          "Multi",
      +          "Then"
      +        ],
      +        "type": "string"
      +      },
      +      "value": {
      +        "description": "Multi only: threshold count (>=1).",
      +        "type": "number"
      +      },
      +      "window": {
      +        "description": "Then only: how long each step has to be followed by the next one, e.g. {length: 30, interval: 'Minute'}. length must be > 0.",
      +        "properties": {
      +          "interval": {
      +            "enum": [
      +              "Day",
      +              "Hour",
      +              "Minute"
      +            ],
      +            "type": "string"
      +          },
      +          "length": {
      +            "type": "number"
      +          }
      +        },
      +        "required": [
      +          "length",
      +          "interval"
      +        ],
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  "deploymentBudget": {
      +    "additionalProperties": true,
      +    "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
      +    "properties": {
      +      "amount": {
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "type": {
      +        "enum": [
      +          "dollars",
      +          "percent of portfolio"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "amount"
      +    ],
      +    "type": "object"
      +  },
      +  "indicator": {
      +    "additionalProperties": true,
      +    "description": "An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), Option* indicators (need underlying + optionType + direction + spreadType), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown.",
      +    "properties": {
      +      "assetType": {
      +        "description": "IsAssetType: e.g. 'Stock', 'Cryptocurrency'.",
      +        "type": "string"
      +      },
      +      "base": {
      +        "description": "Log: logarithm base (>0, ≠1).",
      +        "type": "number"
      +      },
      +      "compound": {
      +        "type": "boolean"
      +      },
      +      "condition": {
      +        "$ref": "#/$defs/condition",
      +        "description": "ConsecutiveTrue / CountTrue: the condition to evaluate over the window."
      +      },
      +      "customIndicatorId": {
      +        "description": "REQUIRED when type is CustomIndicator. Mongo ObjectId hex string for the owned custom data source (see list_custom_indicators or MCP session instructions). Never omit — display name alone is rejected.",
      +        "type": "string"
      +      },
      +      "customIndicatorName": {
      +        "description": "Optional display label for CustomIndicator. Ignored for lookup; customIndicatorId is authoritative.",
      +        "type": "string"
      +      },
      +      "direction": {
      +        "description": "Option* indicators: long or short.",
      +        "enum": [
      +          "long",
      +          "short"
      +        ],
      +        "type": "string"
      +      },
      +      "exponent": {
      +        "description": "Exponentiation: power exponent.",
      +        "type": "number"
      +      },
      +      "form": {
      +        "additionalProperties": true,
      +        "description": "Optional auto-generated form metadata. Usually omit; the server fills this.",
      +        "type": "object"
      +      },
      +      "index": {
      +        "description": "IsIndexMember: point-in-time index id ('SP500', 'NASDAQ100', or 'DJIA').",
      +        "enum": [
      +          "SP500",
      +          "NASDAQ100",
      +          "DJIA"
      +        ],
      +        "type": "string"
      +      },
      +      "indicators": {
      +        "description": "Sub-indicators for compound types (Plus, CrossAbove, etc.).",
      +        "items": {
      +          "$ref": "#/$defs/indicator"
      +        },
      +        "type": "array"
      +      },
      +      "industry": {
      +        "description": "IsIndustry: industry tag.",
      +        "type": "string"
      +      },
      +      "length": {
      +        "description": "TrailingSum and similar — window length in days.",
      +        "type": "number"
      +      },
      +      "matchAsset": {
      +        "additionalProperties": true,
      +        "description": "IsAsset / IsNotAsset: the asset to match against.",
      +        "properties": {
      +          "name": {
      +            "type": "string"
      +          },
      +          "symbol": {
      +            "type": "string"
      +          },
      +          "type": {
      +            "enum": [
      +              "Stock",
      +              "Cryptocurrency",
      +              "Option",
      +              "Other"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "symbol"
      +        ],
      +        "type": "object"
      +      },
      +      "maxDte": {
      +        "description": "Option* indicators: max days to expiration.",
      +        "type": "number"
      +      },
      +      "message": {
      +        "description": "DaysSinceAlert / MinutesSinceAlert: alert message to match.",
      +        "type": "string"
      +      },
      +      "metric": {
      +        "description": "Fundamental/CompoundAnnualGrowthRate: financial metric (e.g. 'peRatio'). Economic: economic indicator (e.g. 'UNRATE'). Index: index symbol (e.g. 'VIX', 'SPX'). RebalanceDecisionMetric: allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit.",
      +        "type": "string"
      +      },
      +      "minDte": {
      +        "description": "Option* indicators: min days to expiration.",
      +        "type": "number"
      +      },
      +      "minOrMax": {
      +        "description": "OptionDaysToExpiration / OptionDaysHeld: aggregate selector.",
      +        "enum": [
      +          "min",
      +          "max"
      +        ],
      +        "type": "string"
      +      },
      +      "minutesAfterOpen": {
      +        "description": "IndicatorAtMinutesAfterOpen: 0–390.",
      +        "maximum": 390,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "name": {
      +        "description": "Optional human-readable name. Auto-derived if omitted.",
      +        "type": "string"
      +      },
      +      "numStandardDeviations": {
      +        "description": "BollingerBand: e.g. 2.",
      +        "type": "number"
      +      },
      +      "optionType": {
      +        "description": "Option* indicators: call or put.",
      +        "enum": [
      +          "call",
      +          "put"
      +        ],
      +        "type": "string"
      +      },
      +      "orderStatus": {
      +        "description": "Order-side indicators: filter by status.",
      +        "enum": [
      +          "Pending",
      +          "Accepted",
      +          "Pending User Approval",
      +          "Canceled",
      +          "Filled",
      +          "Partially Filled"
      +        ],
      +        "type": "string"
      +      },
      +      "positionEffect": {
      +        "description": "Option* indicators: open or close.",
      +        "type": "string"
      +      },
      +      "side": {
      +        "description": "Order-side indicators: Buy or Sell.",
      +        "enum": [
      +          "Buy",
      +          "Sell"
      +        ],
      +        "type": "string"
      +      },
      +      "spreadType": {
      +        "description": "Option* indicators: vertical, ironCondor, etc.",
      +        "enum": [
      +          "vertical",
      +          "calendar",
      +          "diagonal",
      +          "ironCondor",
      +          "straddle",
      +          "strangle",
      +          "custom"
      +        ],
      +        "type": "string"
      +      },
      +      "targetAsset": {
      +        "additionalProperties": true,
      +        "description": "The asset this indicator measures (most price/option indicators).",
      +        "properties": {
      +          "name": {
      +            "type": "string"
      +          },
      +          "symbol": {
      +            "type": "string"
      +          },
      +          "type": {
      +            "enum": [
      +              "Stock",
      +              "Cryptocurrency",
      +              "Option",
      +              "Other"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "symbol"
      +        ],
      +        "type": "object"
      +      },
      +      "targetAssets": {
      +        "description": "Multi-asset variant (position / order indicators).",
      +        "items": {
      +          "additionalProperties": true,
      +          "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +          "properties": {
      +            "name": {
      +              "type": "string"
      +            },
      +            "symbol": {
      +              "type": "string"
      +            },
      +            "type": {
      +              "enum": [
      +                "Stock",
      +                "Cryptocurrency",
      +                "Option",
      +                "Other"
      +              ],
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "type",
      +            "symbol"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "transactionStatus": {
      +        "description": "DaysSinceTransaction: transaction status.",
      +        "enum": [
      +          "Pending",
      +          "Canceled",
      +          "Completed"
      +        ],
      +        "type": "string"
      +      },
      +      "transactionType": {
      +        "description": "DaysSinceTransaction: Deposit or Withdraw.",
      +        "enum": [
      +          "Deposit",
      +          "Withdraw"
      +        ],
      +        "type": "string"
      +      },
      +      "type": {
      +        "enum": [
      +          "DaysSinceAgent",
      +          "MinutesSinceAgent",
      +          "DaysSinceAlert",
      +          "MinutesSinceAlert",
      +          "StockReport",
      +          "DaysUntilEarnings",
      +          "DaysSinceEarnings",
      +          "ImpliedVolatility",
      +          "IVRank",
      +          "IVPercentile",
      +          "IVHVRatio",
      +          "LastOrderPrice",
      +          "Fundamental",
      +          "Economic",
      +          "CustomIndicator",
      +          "Index",
      +          "BollingerBand",
      +          "RelativeStrengthIndex",
      +          "PriceMeanAbsoluteDeviation",
      +          "ExponentialMovingAverage",
      +          "SimpleMovingAverage",
      +          "PriceStandardDeviation",
      +          "PriceRateOfChange",
      +          "MaxDrawdown",
      +          "MaxDrawup",
      +          "MinimumPrice",
      +          "MaximumPrice",
      +          "IndicatorMeanAbsoluteDeviation",
      +          "IndicatorExponentialMovingAverage",
      +          "IndicatorSimpleMovingAverage",
      +          "IndicatorStandardDeviation",
      +          "IndicatorRateOfChange",
      +          "DaysSinceOrder",
      +          "DaysSinceOptionOrder",
      +          "DaysSinceStrategyFired",
      +          "DaysSinceLastRebalanceOptionOrder",
      +          "MinutesSinceOptionOrder",
      +          "MinutesSinceOrder",
      +          "DaysSinceTransaction",
      +          "InitialValue",
      +          "BuyingPower",
      +          "PositionValue",
      +          "PositionPercentChange",
      +          "PortfolioValue",
      +          "RebalanceDecisionMetric",
      +          "Value",
      +          "Price",
      +          "Plus",
      +          "Minus",
      +          "Multiply",
      +          "Divide",
      +          "Negative",
      +          "AbsoluteValue",
      +          "SquareRoot",
      +          "Max",
      +          "Min",
      +          "Day",
      +          "Month",
      +          "Date",
      +          "Year",
      +          "CurrentTimeSeconds",
      +          "CurrentTimeMinutes",
      +          "CurrentTimeHours",
      +          "TrailingSum",
      +          "CompoundAnnualGrowthRate",
      +          "Log",
      +          "Exponentiation",
      +          "SumOrderQuantity",
      +          "SumOrderAmount",
      +          "MinutesAfterOpen",
      +          "OpeningPrice",
      +          "PreviousClosingPrice",
      +          "HighOfDay",
      +          "LowOfDay",
      +          "MinutesUntilClose",
      +          "PriceChangeSinceOpen",
      +          "GapSize",
      +          "GapPercentage",
      +          "TrueRange",
      +          "AverageTrueRange",
      +          "Volume",
      +          "VWAP",
      +          "BullishFairValueGap",
      +          "BearishFairValueGap",
      +          "IndicatorAtMinutesAfterOpen",
      +          "IndicatorWindowAgo",
      +          "IndicatorAtEntry",
      +          "IsIndexMember",
      +          "IsIndustry",
      +          "IsAssetType",
      +          "IsAsset",
      +          "IsNotAsset",
      +          "CrossAbove",
      +          "CrossBelow",
      +          "PositionMaxDrawdown",
      +          "PositionMaxDrawup",
      +          "UnderlyingMaxDrawdown",
      +          "ConsecutiveTrue",
      +          "CountTrue",
      +          "OptionPositionValue",
      +          "OptionPositionCount",
      +          "OptionPositionPercentChange",
      +          "OptionPositionMaxDrawdown",
      +          "OptionDaysToExpiration",
      +          "OptionDaysHeld",
      +          "OptionCollateral",
      +          "OptionSpreadCount",
      +          "OptionUnrealizedPnL",
      +          "OptionGrossExposurePercent"
      +        ],
      +        "type": "string"
      +      },
      +      "underlying": {
      +        "description": "Option* indicators: underlying ticker (e.g. 'SPY').",
      +        "type": "string"
      +      },
      +      "value": {
      +        "description": "Required for Value indicators (numeric constant).",
      +        "type": "number"
      +      },
      +      "window": {
      +        "description": "Rolling time window. e.g. {length:14, interval:'Day'} = trailing 14 trading days.",
      +        "properties": {
      +          "interval": {
      +            "enum": [
      +              "Day",
      +              "Hour",
      +              "Minute"
      +            ],
      +            "type": "string"
      +          },
      +          "length": {
      +            "minimum": 1,
      +            "type": "number"
      +          }
      +        },
      +        "required": [
      +          "length",
      +          "interval"
      +        ],
      +        "type": "object"
      +      },
      +      "years": {
      +        "description": "CompoundAnnualGrowthRate: years over which to compute CAGR.",
      +        "type": "number"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  "optionStructureTemplate": {
      +    "additionalProperties": true,
      +    "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      +    "properties": {
      +      "eligibility": {
      +        "$ref": "#/$defs/condition"
      +      },
      +      "legs": {
      +        "items": {
      +          "additionalProperties": true,
      +          "description": "Single leg of an option builder.",
      +          "properties": {
      +            "direction": {
      +              "enum": [
      +                "long",
      +                "short"
      +              ],
      +              "type": "string"
      +            },
      +            "expirationRange": {
      +              "additionalProperties": true,
      +              "type": "object"
      +            },
      +            "expirationSelector": {
      +              "properties": {
      +                "maxDaysToExpiration": {
      +                  "minimum": 0,
      +                  "type": "number"
      +                },
      +                "minDaysToExpiration": {
      +                  "minimum": 0,
      +                  "type": "number"
      +                },
      +                "preference": {
      +                  "enum": [
      +                    "nearest",
      +                    "middle",
      +                    "furthest"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "minDaysToExpiration",
      +                "maxDaysToExpiration",
      +                "preference"
      +              ],
      +              "type": "object"
      +            },
      +            "fallbackStrikeSelector": {
      +              "additionalProperties": false,
      +              "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +              "properties": {
      +                "distance": {
      +                  "type": "number"
      +                },
      +                "distanceType": {
      +                  "enum": [
      +                    "percent",
      +                    "dollars"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "distanceType",
      +                "distance"
      +              ],
      +              "type": "object"
      +            },
      +            "greekFilter": {
      +              "additionalProperties": true,
      +              "description": "Optional min/max constraints on Greeks during resolution.",
      +              "type": "object"
      +            },
      +            "liquidityFilter": {
      +              "additionalProperties": false,
      +              "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +              "properties": {
      +                "maxSpreadAbsolute": {
      +                  "type": "number"
      +                },
      +                "maxSpreadPct": {
      +                  "type": "number"
      +                },
      +                "minBid": {
      +                  "type": "number"
      +                }
      +              },
      +              "type": "object"
      +            },
      +            "optionType": {
      +              "enum": [
      +                "call",
      +                "put"
      +              ],
      +              "type": "string"
      +            },
      +            "ratio": {
      +              "type": "number"
      +            },
      +            "strikeRange": {
      +              "additionalProperties": true,
      +              "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +              "type": "object"
      +            },
      +            "strikeSelector": {
      +              "properties": {
      +                "distance": {
      +                  "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                  "type": "number"
      +                },
      +                "distanceType": {
      +                  "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "distanceType",
      +                "distance"
      +              ],
      +              "type": "object"
      +            }
      +          },
      +          "required": [
      +            "optionType",
      +            "direction",
      +            "expirationSelector",
      +            "strikeSelector"
      +          ],
      +          "type": "object"
      +        },
      +        "minItems": 1,
      +        "type": "array"
      +      },
      +      "name": {
      +        "type": "string"
      +      },
      +      "spreadType": {
      +        "enum": [
      +          "vertical",
      +          "calendar",
      +          "diagonal",
      +          "ironCondor",
      +          "straddle",
      +          "strangle",
      +          "custom"
      +        ],
      +        "type": "string"
      +      },
      +      "widthConstraint": {
      +        "additionalProperties": false,
      +        "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +        "properties": {
      +          "minWidthDollars": {
      +            "exclusiveMinimum": 0,
      +            "type": "number"
      +          },
      +          "minWidthPercent": {
      +            "exclusiveMinimum": 0,
      +            "type": "number"
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "legs"
      +    ],
      +    "type": "object"
      +  },
      +  "orderExecution": {
      +    "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.",
      +    "oneOf": [
      +      {
      +        "additionalProperties": false,
      +        "properties": {
      +          "type": {
      +            "const": "Market",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type"
      +        ],
      +        "type": "object"
      +      },
      +      {
      +        "additionalProperties": false,
      +        "properties": {
      +          "price": {
      +            "oneOf": [
      +              {
      +                "additionalProperties": false,
      +                "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
      +                "properties": {
      +                  "amount": {
      +                    "minimum": 1e-8,
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "const": "UnitPrice",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "amount"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "additionalProperties": false,
      +                "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
      +                "properties": {
      +                  "amount": {
      +                    "minimum": 1e-8,
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "const": "MinimumNetCredit",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "amount"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "additionalProperties": false,
      +                "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
      +                "properties": {
      +                  "amount": {
      +                    "minimum": 1e-8,
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "const": "MaximumNetDebit",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "amount"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "additionalProperties": false,
      +                "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
      +                "properties": {
      +                  "reference": {
      +                    "const": "Current",
      +                    "type": "string"
      +                  },
      +                  "type": {
      +                    "const": "QuoteRelative",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "reference"
      +                ],
      +                "type": "object"
      +              }
      +            ]
      +          },
      +          "type": {
      +            "const": "Limit",
      +            "type": "string"
      +          },
      +          "workingTime": {
      +            "oneOf": [
      +              {
      +                "additionalProperties": false,
      +                "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
      +                "properties": {
      +                  "type": {
      +                    "const": "Day",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "additionalProperties": false,
      +                "properties": {
      +                  "minutes": {
      +                    "minimum": 1,
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "const": "Minutes",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "minutes"
      +                ],
      +                "type": "object"
      +              }
      +            ]
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "price"
      +        ],
      +        "type": "object"
      +      }
      +    ],
      +    "type": "object"
      +  },
      +  "rebalanceOptionSleeve": {
      +    "additionalProperties": true,
      +    "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
      +    "properties": {
      +      "limit": {
      +        "minimum": 1,
      +        "type": "number"
      +      },
      +      "name": {
      +        "type": "string"
      +      },
      +      "perNameAllocation": {
      +        "additionalProperties": true,
      +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +        "properties": {
      +          "amount": {
      +            "type": "number"
      +          },
      +          "type": {
      +            "enum": [
      +              "dollars",
      +              "percent of portfolio",
      +              "percent of buying power",
      +              "contracts"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "type",
      +          "amount"
      +        ],
      +        "type": "object"
      +      },
      +      "pipeline": {
      +        "items": {
      +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +          "oneOf": [
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "condition": {
      +                  "$ref": "#/$defs/condition"
      +                },
      +                "type": {
      +                  "const": "Filter",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "condition"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "Highest",
      +                    "Lowest"
      +                  ],
      +                  "type": "string"
      +                },
      +                "limit": {
      +                  "minimum": 1,
      +                  "type": "number"
      +                },
      +                "metric": {
      +                  "$ref": "#/$defs/indicator"
      +                },
      +                "type": {
      +                  "const": "SelectTop",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "metric",
      +                "limit",
      +                "direction"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "properties": {
      +                "direction": {
      +                  "enum": [
      +                    "Highest",
      +                    "Lowest"
      +                  ],
      +                  "type": "string"
      +                },
      +                "metric": {
      +                  "$ref": "#/$defs/indicator"
      +                },
      +                "percentile": {
      +                  "maximum": 100,
      +                  "minimum": 0,
      +                  "type": "number"
      +                },
      +                "type": {
      +                  "const": "SelectPercentile",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "metric",
      +                "percentile",
      +                "direction"
      +              ],
      +              "type": "object"
      +            }
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "structureTemplates": {
      +        "items": {
      +          "additionalProperties": true,
      +          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      +          "properties": {
      +            "eligibility": {
      +              "$ref": "#/$defs/condition"
      +            },
      +            "legs": {
      +              "items": {
      +                "additionalProperties": true,
      +                "description": "Single leg of an option builder.",
      +                "properties": {
      +                  "direction": {
      +                    "enum": [
      +                      "long",
      +                      "short"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "expirationRange": {
      +                    "additionalProperties": true,
      +                    "type": "object"
      +                  },
      +                  "expirationSelector": {
      +                    "properties": {
      +                      "maxDaysToExpiration": {
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "minDaysToExpiration": {
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "preference": {
      +                        "enum": [
      +                          "nearest",
      +                          "middle",
      +                          "furthest"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "minDaysToExpiration",
      +                      "maxDaysToExpiration",
      +                      "preference"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "fallbackStrikeSelector": {
      +                    "additionalProperties": false,
      +                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                    "properties": {
      +                      "distance": {
      +                        "type": "number"
      +                      },
      +                      "distanceType": {
      +                        "enum": [
      +                          "percent",
      +                          "dollars"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "distanceType",
      +                      "distance"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "greekFilter": {
      +                    "additionalProperties": true,
      +                    "description": "Optional min/max constraints on Greeks during resolution.",
      +                    "type": "object"
      +                  },
      +                  "liquidityFilter": {
      +                    "additionalProperties": false,
      +                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                    "properties": {
      +                      "maxSpreadAbsolute": {
      +                        "type": "number"
      +                      },
      +                      "maxSpreadPct": {
      +                        "type": "number"
      +                      },
      +                      "minBid": {
      +                        "type": "number"
      +                      }
      +                    },
      +                    "type": "object"
      +                  },
      +                  "optionType": {
      +                    "enum": [
      +                      "call",
      +                      "put"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "ratio": {
      +                    "type": "number"
      +                  },
      +                  "strikeRange": {
      +                    "additionalProperties": true,
      +                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                    "type": "object"
      +                  },
      +                  "strikeSelector": {
      +                    "properties": {
      +                      "distance": {
      +                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                        "type": "number"
      +                      },
      +                      "distanceType": {
      +                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "distanceType",
      +                      "distance"
      +                    ],
      +                    "type": "object"
      +                  }
      +                },
      +                "required": [
      +                  "optionType",
      +                  "direction",
      +                  "expirationSelector",
      +                  "strikeSelector"
      +                ],
      +                "type": "object"
      +              },
      +              "minItems": 1,
      +              "type": "array"
      +            },
      +            "name": {
      +              "type": "string"
      +            },
      +            "spreadType": {
      +              "enum": [
      +                "vertical",
      +                "calendar",
      +                "diagonal",
      +                "ironCondor",
      +                "straddle",
      +                "strangle",
      +                "custom"
      +              ],
      +              "type": "string"
      +            },
      +            "widthConstraint": {
      +              "additionalProperties": false,
      +              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +              "properties": {
      +                "minWidthDollars": {
      +                  "exclusiveMinimum": 0,
      +                  "type": "number"
      +                },
      +                "minWidthPercent": {
      +                  "exclusiveMinimum": 0,
      +                  "type": "number"
      +                }
      +              },
      +              "type": "object"
      +            }
      +          },
      +          "required": [
      +            "legs"
      +          ],
      +          "type": "object"
      +        },
      +        "minItems": 1,
      +        "type": "array"
      +      },
      +      "universe": {
      +        "additionalProperties": true,
      +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +        "properties": {
      +          "assets": {
      +            "items": {
      +              "additionalProperties": true,
      +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +              "properties": {
      +                "name": {
      +                  "type": "string"
      +                },
      +                "symbol": {
      +                  "type": "string"
      +                },
      +                "type": {
      +                  "enum": [
      +                    "Stock",
      +                    "Cryptocurrency",
      +                    "Option",
      +                    "Other"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "symbol"
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "source": {
      +            "enum": [
      +              "ALL_US_STOCKS",
      +              "SP500",
      +              "NASDAQ100",
      +              "DJIA",
      +              "CRYPTO",
      +              "SPECIFIC_ASSETS"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "source"
      +        ],
      +        "type": "object"
      +      },
      +      "weightIndicator": {
      +        "$ref": "#/$defs/indicator"
      +      }
      +    },
      +    "required": [
      +      "name"
      +    ],
      +    "type": "object"
      +  },
      +  "strategy": {
      +    "additionalProperties": true,
      +    "description": "A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.",
      +    "properties": {
      +      "action": {
      +        "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).",
      +        "oneOf": [
      +          {
      +            "additionalProperties": true,
      +            "description": "Buy or Sell a stock/crypto position.",
      +            "properties": {
      +              "amount": {
      +                "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
      +                "properties": {
      +                  "amount": {
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "enum": [
      +                      "percent of portfolio",
      +                      "percent of buying power",
      +                      "percent of current positions",
      +                      "dollars",
      +                      "number of assets"
      +                    ],
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "amount"
      +                ],
      +                "type": "object"
      +              },
      +              "targetAsset": {
      +                "additionalProperties": true,
      +                "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                "properties": {
      +                  "name": {
      +                    "type": "string"
      +                  },
      +                  "symbol": {
      +                    "type": "string"
      +                  },
      +                  "type": {
      +                    "enum": [
      +                      "Stock",
      +                      "Cryptocurrency",
      +                      "Option",
      +                      "Other"
      +                    ],
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "symbol"
      +                ],
      +                "type": "object"
      +              },
      +              "type": {
      +                "enum": [
      +                  "Buy",
      +                  "Sell"
      +                ],
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "targetAsset",
      +              "amount"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": true,
      +            "description": "Send an alert message (no order).",
      +            "properties": {
      +              "message": {
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "Alert",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "message"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": true,
      +            "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
      +            "properties": {
      +              "allocationPolicy": {
      +                "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      +                "oneOf": [
      +                  {
      +                    "additionalProperties": false,
      +                    "properties": {
      +                      "covarianceShrinkage": {
      +                        "maximum": 1,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "estimatedTransactionCostBps": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "expectedReturnShrinkage": {
      +                        "maximum": 1,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "lookbackPeriods": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "minimumObservations": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "riskAversion": {
      +                        "maximum": 1000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "turnoverPenalty": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "MeanVariance",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "lookbackPeriods",
      +                      "minimumObservations",
      +                      "riskAversion",
      +                      "expectedReturnShrinkage",
      +                      "covarianceShrinkage",
      +                      "turnoverPenalty",
      +                      "estimatedTransactionCostBps"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": false,
      +                    "properties": {
      +                      "covarianceShrinkage": {
      +                        "maximum": 1,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "estimatedTransactionCostBps": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "lookbackPeriods": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "minimumObservations": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "turnoverPenalty": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "RiskParity",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "lookbackPeriods",
      +                      "minimumObservations",
      +                      "covarianceShrinkage",
      +                      "turnoverPenalty",
      +                      "estimatedTransactionCostBps"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": false,
      +                    "properties": {
      +                      "covarianceShrinkage": {
      +                        "maximum": 1,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "estimatedTransactionCostBps": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "lookbackPeriods": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "minimumObservations": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "turnoverPenalty": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "MaximumDiversification",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "lookbackPeriods",
      +                      "minimumObservations",
      +                      "covarianceShrinkage",
      +                      "turnoverPenalty",
      +                      "estimatedTransactionCostBps"
      +                    ],
      +                    "type": "object"
      +                  }
      +                ]
      +              },
      +              "canSell": {
      +                "$ref": "#/$defs/condition",
      +                "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
      +              },
      +              "deploymentPercent": {
      +                "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
      +                "maximum": 100,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "exposurePolicy": {
      +                "additionalProperties": false,
      +                "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      +                "properties": {
      +                  "covarianceShrinkage": {
      +                    "maximum": 1,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "estimatedTransactionCostBps": {
      +                    "maximum": 10000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "lookbackPeriods": {
      +                    "maximum": 5000,
      +                    "minimum": 2,
      +                    "type": "integer"
      +                  },
      +                  "minimumObservations": {
      +                    "maximum": 5000,
      +                    "minimum": 2,
      +                    "type": "integer"
      +                  },
      +                  "targetAnnualizedVolatilityPercent": {
      +                    "maximum": 1000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "const": "VolatilityTarget",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "lookbackPeriods",
      +                  "minimumObservations",
      +                  "covarianceShrinkage",
      +                  "targetAnnualizedVolatilityPercent",
      +                  "estimatedTransactionCostBps"
      +                ],
      +                "type": "object"
      +              },
      +              "limit": {
      +                "minimum": 1,
      +                "type": "number"
      +              },
      +              "perNameAllocation": {
      +                "additionalProperties": true,
      +                "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
      +                "properties": {
      +                  "amount": {
      +                    "exclusiveMinimum": 0,
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "enum": [
      +                      "percent of portfolio",
      +                      "dollars"
      +                    ],
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "amount"
      +                ],
      +                "type": "object"
      +              },
      +              "pipeline": {
      +                "items": {
      +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                  "oneOf": [
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "condition": {
      +                          "$ref": "#/$defs/condition"
      +                        },
      +                        "type": {
      +                          "const": "Filter",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "condition"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "Highest",
      +                            "Lowest"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "limit": {
      +                          "minimum": 1,
      +                          "type": "number"
      +                        },
      +                        "metric": {
      +                          "$ref": "#/$defs/indicator"
      +                        },
      +                        "type": {
      +                          "const": "SelectTop",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "metric",
      +                        "limit",
      +                        "direction"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "Highest",
      +                            "Lowest"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "metric": {
      +                          "$ref": "#/$defs/indicator"
      +                        },
      +                        "percentile": {
      +                          "maximum": 100,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "SelectPercentile",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "metric",
      +                        "percentile",
      +                        "direction"
      +                      ],
      +                      "type": "object"
      +                    }
      +                  ],
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "type": {
      +                "const": "DynamicRebalance",
      +                "type": "string"
      +              },
      +              "universe": {
      +                "additionalProperties": true,
      +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +                "properties": {
      +                  "assets": {
      +                    "items": {
      +                      "additionalProperties": true,
      +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                      "properties": {
      +                        "name": {
      +                          "type": "string"
      +                        },
      +                        "symbol": {
      +                          "type": "string"
      +                        },
      +                        "type": {
      +                          "enum": [
      +                            "Stock",
      +                            "Cryptocurrency",
      +                            "Option",
      +                            "Other"
      +                          ],
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "symbol"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "type": "array"
      +                  },
      +                  "source": {
      +                    "enum": [
      +                      "ALL_US_STOCKS",
      +                      "SP500",
      +                      "NASDAQ100",
      +                      "DJIA",
      +                      "CRYPTO",
      +                      "SPECIFIC_ASSETS"
      +                    ],
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "source"
      +                ],
      +                "type": "object"
      +              },
      +              "weightIndicator": {
      +                "$ref": "#/$defs/indicator"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "universe",
      +              "pipeline",
      +              "weightIndicator"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": true,
      +            "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
      +            "properties": {
      +              "continueExisting": {
      +                "type": "boolean"
      +              },
      +              "cooldownMinutes": {
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "executionModel": {
      +                "type": "string"
      +              },
      +              "includeMarketData": {
      +                "type": "boolean"
      +              },
      +              "initialMessage": {
      +                "type": "string"
      +              },
      +              "maxIterations": {
      +                "minimum": 1,
      +                "type": "number"
      +              },
      +              "planningModel": {
      +                "type": "string"
      +              },
      +              "skipPlanning": {
      +                "type": "boolean"
      +              },
      +              "type": {
      +                "const": "LaunchAgent",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "planningModel",
      +              "executionModel",
      +              "initialMessage",
      +              "maxIterations",
      +              "includeMarketData",
      +              "continueExisting",
      +              "skipPlanning"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": true,
      +            "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
      +            "properties": {
      +              "against": {
      +                "additionalProperties": true,
      +                "description": "Optional parent-position selector (e.g. for covered calls).",
      +                "type": "object"
      +              },
      +              "allocation": {
      +                "additionalProperties": true,
      +                "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +                "properties": {
      +                  "amount": {
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "enum": [
      +                      "dollars",
      +                      "percent of portfolio",
      +                      "percent of buying power",
      +                      "contracts"
      +                    ],
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "amount"
      +                ],
      +                "type": "object"
      +              },
      +              "builder": {
      +                "additionalProperties": true,
      +                "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
      +                "properties": {
      +                  "dynamicUnderlying": {
      +                    "additionalProperties": true,
      +                    "properties": {
      +                      "limit": {
      +                        "minimum": 1,
      +                        "type": "number"
      +                      },
      +                      "pipeline": {
      +                        "items": {
      +                          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                          "oneOf": [
      +                            {
      +                              "additionalProperties": true,
      +                              "properties": {
      +                                "condition": {
      +                                  "$ref": "#/$defs/condition"
      +                                },
      +                                "type": {
      +                                  "const": "Filter",
      +                                  "type": "string"
      +                                }
      +                              },
      +                              "required": [
      +                                "type",
      +                                "condition"
      +                              ],
      +                              "type": "object"
      +                            },
      +                            {
      +                              "additionalProperties": true,
      +                              "properties": {
      +                                "direction": {
      +                                  "enum": [
      +                                    "Highest",
      +                                    "Lowest"
      +                                  ],
      +                                  "type": "string"
      +                                },
      +                                "limit": {
      +                                  "minimum": 1,
      +                                  "type": "number"
      +                                },
      +                                "metric": {
      +                                  "$ref": "#/$defs/indicator"
      +                                },
      +                                "type": {
      +                                  "const": "SelectTop",
      +                                  "type": "string"
      +                                }
      +                              },
      +                              "required": [
      +                                "type",
      +                                "metric",
      +                                "limit",
      +                                "direction"
      +                              ],
      +                              "type": "object"
      +                            },
      +                            {
      +                              "additionalProperties": true,
      +                              "properties": {
      +                                "direction": {
      +                                  "enum": [
      +                                    "Highest",
      +                                    "Lowest"
      +                                  ],
      +                                  "type": "string"
      +                                },
      +                                "metric": {
      +                                  "$ref": "#/$defs/indicator"
      +                                },
      +                                "percentile": {
      +                                  "maximum": 100,
      +                                  "minimum": 0,
      +                                  "type": "number"
      +                                },
      +                                "type": {
      +                                  "const": "SelectPercentile",
      +                                  "type": "string"
      +                                }
      +                              },
      +                              "required": [
      +                                "type",
      +                                "metric",
      +                                "percentile",
      +                                "direction"
      +                              ],
      +                              "type": "object"
      +                            }
      +                          ],
      +                          "type": "object"
      +                        },
      +                        "type": "array"
      +                      },
      +                      "universe": {
      +                        "additionalProperties": true,
      +                        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +                        "properties": {
      +                          "assets": {
      +                            "items": {
      +                              "additionalProperties": true,
      +                              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                              "properties": {
      +                                "name": {
      +                                  "type": "string"
      +                                },
      +                                "symbol": {
      +                                  "type": "string"
      +                                },
      +                                "type": {
      +                                  "enum": [
      +                                    "Stock",
      +                                    "Cryptocurrency",
      +                                    "Option",
      +                                    "Other"
      +                                  ],
      +                                  "type": "string"
      +                                }
      +                              },
      +                              "required": [
      +                                "type",
      +                                "symbol"
      +                              ],
      +                              "type": "object"
      +                            },
      +                            "type": "array"
      +                          },
      +                          "source": {
      +                            "enum": [
      +                              "ALL_US_STOCKS",
      +                              "SP500",
      +                              "NASDAQ100",
      +                              "DJIA",
      +                              "CRYPTO",
      +                              "SPECIFIC_ASSETS"
      +                            ],
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "source"
      +                        ],
      +                        "type": "object"
      +                      }
      +                    },
      +                    "required": [
      +                      "universe"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "legs": {
      +                    "items": {
      +                      "additionalProperties": true,
      +                      "description": "Single leg of an option builder.",
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "long",
      +                            "short"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "expirationRange": {
      +                          "additionalProperties": true,
      +                          "type": "object"
      +                        },
      +                        "expirationSelector": {
      +                          "properties": {
      +                            "maxDaysToExpiration": {
      +                              "minimum": 0,
      +                              "type": "number"
      +                            },
      +                            "minDaysToExpiration": {
      +                              "minimum": 0,
      +                              "type": "number"
      +                            },
      +                            "preference": {
      +                              "enum": [
      +                                "nearest",
      +                                "middle",
      +                                "furthest"
      +                              ],
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "minDaysToExpiration",
      +                            "maxDaysToExpiration",
      +                            "preference"
      +                          ],
      +                          "type": "object"
      +                        },
      +                        "fallbackStrikeSelector": {
      +                          "additionalProperties": false,
      +                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                          "properties": {
      +                            "distance": {
      +                              "type": "number"
      +                            },
      +                            "distanceType": {
      +                              "enum": [
      +                                "percent",
      +                                "dollars"
      +                              ],
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "distanceType",
      +                            "distance"
      +                          ],
      +                          "type": "object"
      +                        },
      +                        "greekFilter": {
      +                          "additionalProperties": true,
      +                          "description": "Optional min/max constraints on Greeks during resolution.",
      +                          "type": "object"
      +                        },
      +                        "liquidityFilter": {
      +                          "additionalProperties": false,
      +                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                          "properties": {
      +                            "maxSpreadAbsolute": {
      +                              "type": "number"
      +                            },
      +                            "maxSpreadPct": {
      +                              "type": "number"
      +                            },
      +                            "minBid": {
      +                              "type": "number"
      +                            }
      +                          },
      +                          "type": "object"
      +                        },
      +                        "optionType": {
      +                          "enum": [
      +                            "call",
      +                            "put"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "ratio": {
      +                          "type": "number"
      +                        },
      +                        "strikeRange": {
      +                          "additionalProperties": true,
      +                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                          "type": "object"
      +                        },
      +                        "strikeSelector": {
      +                          "properties": {
      +                            "distance": {
      +                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                              "type": "number"
      +                            },
      +                            "distanceType": {
      +                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "distanceType",
      +                            "distance"
      +                          ],
      +                          "type": "object"
      +                        }
      +                      },
      +                      "required": [
      +                        "optionType",
      +                        "direction",
      +                        "expirationSelector",
      +                        "strikeSelector"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "minItems": 1,
      +                    "type": "array"
      +                  },
      +                  "spreadType": {
      +                    "enum": [
      +                      "vertical",
      +                      "calendar",
      +                      "diagonal",
      +                      "ironCondor",
      +                      "straddle",
      +                      "strangle",
      +                      "custom"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "underlyingSymbol": {
      +                    "type": "string"
      +                  },
      +                  "widthConstraint": {
      +                    "additionalProperties": false,
      +                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +                    "properties": {
      +                      "minWidthDollars": {
      +                        "exclusiveMinimum": 0,
      +                        "type": "number"
      +                      },
      +                      "minWidthPercent": {
      +                        "exclusiveMinimum": 0,
      +                        "type": "number"
      +                      }
      +                    },
      +                    "type": "object"
      +                  }
      +                },
      +                "required": [
      +                  "legs"
      +                ],
      +                "type": "object"
      +              },
      +              "type": {
      +                "const": "OpenOption",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "builder"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": true,
      +            "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
      +            "properties": {
      +              "allocationPolicy": {
      +                "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      +                "oneOf": [
      +                  {
      +                    "additionalProperties": false,
      +                    "properties": {
      +                      "covarianceShrinkage": {
      +                        "maximum": 1,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "estimatedTransactionCostBps": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "expectedReturnShrinkage": {
      +                        "maximum": 1,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "lookbackPeriods": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "minimumObservations": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "riskAversion": {
      +                        "maximum": 1000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "turnoverPenalty": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "MeanVariance",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "lookbackPeriods",
      +                      "minimumObservations",
      +                      "riskAversion",
      +                      "expectedReturnShrinkage",
      +                      "covarianceShrinkage",
      +                      "turnoverPenalty",
      +                      "estimatedTransactionCostBps"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": false,
      +                    "properties": {
      +                      "covarianceShrinkage": {
      +                        "maximum": 1,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "estimatedTransactionCostBps": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "lookbackPeriods": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "minimumObservations": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "turnoverPenalty": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "RiskParity",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "lookbackPeriods",
      +                      "minimumObservations",
      +                      "covarianceShrinkage",
      +                      "turnoverPenalty",
      +                      "estimatedTransactionCostBps"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": false,
      +                    "properties": {
      +                      "covarianceShrinkage": {
      +                        "maximum": 1,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "estimatedTransactionCostBps": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "lookbackPeriods": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "minimumObservations": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "turnoverPenalty": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "MaximumDiversification",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "lookbackPeriods",
      +                      "minimumObservations",
      +                      "covarianceShrinkage",
      +                      "turnoverPenalty",
      +                      "estimatedTransactionCostBps"
      +                    ],
      +                    "type": "object"
      +                  }
      +                ]
      +              },
      +              "exposurePolicy": {
      +                "additionalProperties": false,
      +                "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      +                "properties": {
      +                  "covarianceShrinkage": {
      +                    "maximum": 1,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "estimatedTransactionCostBps": {
      +                    "maximum": 10000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "lookbackPeriods": {
      +                    "maximum": 5000,
      +                    "minimum": 2,
      +                    "type": "integer"
      +                  },
      +                  "minimumObservations": {
      +                    "maximum": 5000,
      +                    "minimum": 2,
      +                    "type": "integer"
      +                  },
      +                  "targetAnnualizedVolatilityPercent": {
      +                    "maximum": 1000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "const": "VolatilityTarget",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "lookbackPeriods",
      +                  "minimumObservations",
      +                  "covarianceShrinkage",
      +                  "targetAnnualizedVolatilityPercent",
      +                  "estimatedTransactionCostBps"
      +                ],
      +                "type": "object"
      +              },
      +              "limit": {
      +                "minimum": 1,
      +                "type": "number"
      +              },
      +              "perNameAllocation": {
      +                "additionalProperties": true,
      +                "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +                "properties": {
      +                  "amount": {
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "enum": [
      +                      "dollars",
      +                      "percent of portfolio",
      +                      "percent of buying power",
      +                      "contracts"
      +                    ],
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "amount"
      +                ],
      +                "type": "object"
      +              },
      +              "pipeline": {
      +                "items": {
      +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                  "oneOf": [
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "condition": {
      +                          "$ref": "#/$defs/condition"
      +                        },
      +                        "type": {
      +                          "const": "Filter",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "condition"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "Highest",
      +                            "Lowest"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "limit": {
      +                          "minimum": 1,
      +                          "type": "number"
      +                        },
      +                        "metric": {
      +                          "$ref": "#/$defs/indicator"
      +                        },
      +                        "type": {
      +                          "const": "SelectTop",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "metric",
      +                        "limit",
      +                        "direction"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "Highest",
      +                            "Lowest"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "metric": {
      +                          "$ref": "#/$defs/indicator"
      +                        },
      +                        "percentile": {
      +                          "maximum": 100,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "SelectPercentile",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "metric",
      +                        "percentile",
      +                        "direction"
      +                      ],
      +                      "type": "object"
      +                    }
      +                  ],
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "positionScope": {
      +                "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
      +                "enum": [
      +                  "portfolio",
      +                  "strategy"
      +                ],
      +                "type": "string"
      +              },
      +              "sleeves": {
      +                "items": {
      +                  "additionalProperties": true,
      +                  "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
      +                  "properties": {
      +                    "limit": {
      +                      "minimum": 1,
      +                      "type": "number"
      +                    },
      +                    "name": {
      +                      "type": "string"
      +                    },
      +                    "perNameAllocation": {
      +                      "additionalProperties": true,
      +                      "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +                      "properties": {
      +                        "amount": {
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "enum": [
      +                            "dollars",
      +                            "percent of portfolio",
      +                            "percent of buying power",
      +                            "contracts"
      +                          ],
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "amount"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "pipeline": {
      +                      "items": {
      +                        "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                        "oneOf": [
      +                          {
      +                            "additionalProperties": true,
      +                            "properties": {
      +                              "condition": {
      +                                "$ref": "#/$defs/condition"
      +                              },
      +                              "type": {
      +                                "const": "Filter",
      +                                "type": "string"
      +                              }
      +                            },
      +                            "required": [
      +                              "type",
      +                              "condition"
      +                            ],
      +                            "type": "object"
      +                          },
      +                          {
      +                            "additionalProperties": true,
      +                            "properties": {
      +                              "direction": {
      +                                "enum": [
      +                                  "Highest",
      +                                  "Lowest"
      +                                ],
      +                                "type": "string"
      +                              },
      +                              "limit": {
      +                                "minimum": 1,
      +                                "type": "number"
      +                              },
      +                              "metric": {
      +                                "$ref": "#/$defs/indicator"
      +                              },
      +                              "type": {
      +                                "const": "SelectTop",
      +                                "type": "string"
      +                              }
      +                            },
      +                            "required": [
      +                              "type",
      +                              "metric",
      +                              "limit",
      +                              "direction"
      +                            ],
      +                            "type": "object"
      +                          },
      +                          {
      +                            "additionalProperties": true,
      +                            "properties": {
      +                              "direction": {
      +                                "enum": [
      +                                  "Highest",
      +                                  "Lowest"
      +                                ],
      +                                "type": "string"
      +                              },
      +                              "metric": {
      +                                "$ref": "#/$defs/indicator"
      +                              },
      +                              "percentile": {
      +                                "maximum": 100,
      +                                "minimum": 0,
      +                                "type": "number"
      +                              },
      +                              "type": {
      +                                "const": "SelectPercentile",
      +                                "type": "string"
      +                              }
      +                            },
      +                            "required": [
      +                              "type",
      +                              "metric",
      +                              "percentile",
      +                              "direction"
      +                            ],
      +                            "type": "object"
      +                          }
      +                        ],
      +                        "type": "object"
      +                      },
      +                      "type": "array"
      +                    },
      +                    "structureTemplates": {
      +                      "items": {
      +                        "additionalProperties": true,
      +                        "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      +                        "properties": {
      +                          "eligibility": {
      +                            "$ref": "#/$defs/condition"
      +                          },
      +                          "legs": {
      +                            "items": {
      +                              "additionalProperties": true,
      +                              "description": "Single leg of an option builder.",
      +                              "properties": {
      +                                "direction": {
      +                                  "enum": [
      +                                    "long",
      +                                    "short"
      +                                  ],
      +                                  "type": "string"
      +                                },
      +                                "expirationRange": {
      +                                  "additionalProperties": true,
      +                                  "type": "object"
      +                                },
      +                                "expirationSelector": {
      +                                  "properties": {
      +                                    "maxDaysToExpiration": {
      +                                      "minimum": 0,
      +                                      "type": "number"
      +                                    },
      +                                    "minDaysToExpiration": {
      +                                      "minimum": 0,
      +                                      "type": "number"
      +                                    },
      +                                    "preference": {
      +                                      "enum": [
      +                                        "nearest",
      +                                        "middle",
      +                                        "furthest"
      +                                      ],
      +                                      "type": "string"
      +                                    }
      +                                  },
      +                                  "required": [
      +                                    "minDaysToExpiration",
      +                                    "maxDaysToExpiration",
      +                                    "preference"
      +                                  ],
      +                                  "type": "object"
      +                                },
      +                                "fallbackStrikeSelector": {
      +                                  "additionalProperties": false,
      +                                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                                  "properties": {
      +                                    "distance": {
      +                                      "type": "number"
      +                                    },
      +                                    "distanceType": {
      +                                      "enum": [
      +                                        "percent",
      +                                        "dollars"
      +                                      ],
      +                                      "type": "string"
      +                                    }
      +                                  },
      +                                  "required": [
      +                                    "distanceType",
      +                                    "distance"
      +                                  ],
      +                                  "type": "object"
      +                                },
      +                                "greekFilter": {
      +                                  "additionalProperties": true,
      +                                  "description": "Optional min/max constraints on Greeks during resolution.",
      +                                  "type": "object"
      +                                },
      +                                "liquidityFilter": {
      +                                  "additionalProperties": false,
      +                                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                                  "properties": {
      +                                    "maxSpreadAbsolute": {
      +                                      "type": "number"
      +                                    },
      +                                    "maxSpreadPct": {
      +                                      "type": "number"
      +                                    },
      +                                    "minBid": {
      +                                      "type": "number"
      +                                    }
      +                                  },
      +                                  "type": "object"
      +                                },
      +                                "optionType": {
      +                                  "enum": [
      +                                    "call",
      +                                    "put"
      +                                  ],
      +                                  "type": "string"
      +                                },
      +                                "ratio": {
      +                                  "type": "number"
      +                                },
      +                                "strikeRange": {
      +                                  "additionalProperties": true,
      +                                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                                  "type": "object"
      +                                },
      +                                "strikeSelector": {
      +                                  "properties": {
      +                                    "distance": {
      +                                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                                      "type": "number"
      +                                    },
      +                                    "distanceType": {
      +                                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                                      "type": "string"
      +                                    }
      +                                  },
      +                                  "required": [
      +                                    "distanceType",
      +                                    "distance"
      +                                  ],
      +                                  "type": "object"
      +                                }
      +                              },
      +                              "required": [
      +                                "optionType",
      +                                "direction",
      +                                "expirationSelector",
      +                                "strikeSelector"
      +                              ],
      +                              "type": "object"
      +                            },
      +                            "minItems": 1,
      +                            "type": "array"
      +                          },
      +                          "name": {
      +                            "type": "string"
      +                          },
      +                          "spreadType": {
      +                            "enum": [
      +                              "vertical",
      +                              "calendar",
      +                              "diagonal",
      +                              "ironCondor",
      +                              "straddle",
      +                              "strangle",
      +                              "custom"
      +                            ],
      +                            "type": "string"
      +                          },
      +                          "widthConstraint": {
      +                            "additionalProperties": false,
      +                            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +                            "properties": {
      +                              "minWidthDollars": {
      +                                "exclusiveMinimum": 0,
      +                                "type": "number"
      +                              },
      +                              "minWidthPercent": {
      +                                "exclusiveMinimum": 0,
      +                                "type": "number"
      +                              }
      +                            },
      +                            "type": "object"
      +                          }
      +                        },
      +                        "required": [
      +                          "legs"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      "minItems": 1,
      +                      "type": "array"
      +                    },
      +                    "universe": {
      +                      "additionalProperties": true,
      +                      "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +                      "properties": {
      +                        "assets": {
      +                          "items": {
      +                            "additionalProperties": true,
      +                            "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                            "properties": {
      +                              "name": {
      +                                "type": "string"
      +                              },
      +                              "symbol": {
      +                                "type": "string"
      +                              },
      +                              "type": {
      +                                "enum": [
      +                                  "Stock",
      +                                  "Cryptocurrency",
      +                                  "Option",
      +                                  "Other"
      +                                ],
      +                                "type": "string"
      +                              }
      +                            },
      +                            "required": [
      +                              "type",
      +                              "symbol"
      +                            ],
      +                            "type": "object"
      +                          },
      +                          "type": "array"
      +                        },
      +                        "source": {
      +                          "enum": [
      +                            "ALL_US_STOCKS",
      +                            "SP500",
      +                            "NASDAQ100",
      +                            "DJIA",
      +                            "CRYPTO",
      +                            "SPECIFIC_ASSETS"
      +                          ],
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "source"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "weightIndicator": {
      +                      "$ref": "#/$defs/indicator"
      +                    }
      +                  },
      +                  "required": [
      +                    "name"
      +                  ],
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "structureTemplates": {
      +                "items": {
      +                  "additionalProperties": true,
      +                  "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      +                  "properties": {
      +                    "eligibility": {
      +                      "$ref": "#/$defs/condition"
      +                    },
      +                    "legs": {
      +                      "items": {
      +                        "additionalProperties": true,
      +                        "description": "Single leg of an option builder.",
      +                        "properties": {
      +                          "direction": {
      +                            "enum": [
      +                              "long",
      +                              "short"
      +                            ],
      +                            "type": "string"
      +                          },
      +                          "expirationRange": {
      +                            "additionalProperties": true,
      +                            "type": "object"
      +                          },
      +                          "expirationSelector": {
      +                            "properties": {
      +                              "maxDaysToExpiration": {
      +                                "minimum": 0,
      +                                "type": "number"
      +                              },
      +                              "minDaysToExpiration": {
      +                                "minimum": 0,
      +                                "type": "number"
      +                              },
      +                              "preference": {
      +                                "enum": [
      +                                  "nearest",
      +                                  "middle",
      +                                  "furthest"
      +                                ],
      +                                "type": "string"
      +                              }
      +                            },
      +                            "required": [
      +                              "minDaysToExpiration",
      +                              "maxDaysToExpiration",
      +                              "preference"
      +                            ],
      +                            "type": "object"
      +                          },
      +                          "fallbackStrikeSelector": {
      +                            "additionalProperties": false,
      +                            "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                            "properties": {
      +                              "distance": {
      +                                "type": "number"
      +                              },
      +                              "distanceType": {
      +                                "enum": [
      +                                  "percent",
      +                                  "dollars"
      +                                ],
      +                                "type": "string"
      +                              }
      +                            },
      +                            "required": [
      +                              "distanceType",
      +                              "distance"
      +                            ],
      +                            "type": "object"
      +                          },
      +                          "greekFilter": {
      +                            "additionalProperties": true,
      +                            "description": "Optional min/max constraints on Greeks during resolution.",
      +                            "type": "object"
      +                          },
      +                          "liquidityFilter": {
      +                            "additionalProperties": false,
      +                            "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                            "properties": {
      +                              "maxSpreadAbsolute": {
      +                                "type": "number"
      +                              },
      +                              "maxSpreadPct": {
      +                                "type": "number"
      +                              },
      +                              "minBid": {
      +                                "type": "number"
      +                              }
      +                            },
      +                            "type": "object"
      +                          },
      +                          "optionType": {
      +                            "enum": [
      +                              "call",
      +                              "put"
      +                            ],
      +                            "type": "string"
      +                          },
      +                          "ratio": {
      +                            "type": "number"
      +                          },
      +                          "strikeRange": {
      +                            "additionalProperties": true,
      +                            "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                            "type": "object"
      +                          },
      +                          "strikeSelector": {
      +                            "properties": {
      +                              "distance": {
      +                                "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                                "type": "number"
      +                              },
      +                              "distanceType": {
      +                                "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                                "type": "string"
      +                              }
      +                            },
      +                            "required": [
      +                              "distanceType",
      +                              "distance"
      +                            ],
      +                            "type": "object"
      +                          }
      +                        },
      +                        "required": [
      +                          "optionType",
      +                          "direction",
      +                          "expirationSelector",
      +                          "strikeSelector"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      "minItems": 1,
      +                      "type": "array"
      +                    },
      +                    "name": {
      +                      "type": "string"
      +                    },
      +                    "spreadType": {
      +                      "enum": [
      +                        "vertical",
      +                        "calendar",
      +                        "diagonal",
      +                        "ironCondor",
      +                        "straddle",
      +                        "strangle",
      +                        "custom"
      +                      ],
      +                      "type": "string"
      +                    },
      +                    "widthConstraint": {
      +                      "additionalProperties": false,
      +                      "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +                      "properties": {
      +                        "minWidthDollars": {
      +                          "exclusiveMinimum": 0,
      +                          "type": "number"
      +                        },
      +                        "minWidthPercent": {
      +                          "exclusiveMinimum": 0,
      +                          "type": "number"
      +                        }
      +                      },
      +                      "type": "object"
      +                    }
      +                  },
      +                  "required": [
      +                    "legs"
      +                  ],
      +                  "type": "object"
      +                },
      +                "minItems": 1,
      +                "type": "array"
      +              },
      +              "totalBudget": {
      +                "additionalProperties": true,
      +                "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
      +                "properties": {
      +                  "amount": {
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "enum": [
      +                      "dollars",
      +                      "percent of portfolio"
      +                    ],
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "amount"
      +                ],
      +                "type": "object"
      +              },
      +              "type": {
      +                "const": "RebalanceOption",
      +                "type": "string"
      +              },
      +              "universe": {
      +                "additionalProperties": true,
      +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +                "properties": {
      +                  "assets": {
      +                    "items": {
      +                      "additionalProperties": true,
      +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                      "properties": {
      +                        "name": {
      +                          "type": "string"
      +                        },
      +                        "symbol": {
      +                          "type": "string"
      +                        },
      +                        "type": {
      +                          "enum": [
      +                            "Stock",
      +                            "Cryptocurrency",
      +                            "Option",
      +                            "Other"
      +                          ],
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "symbol"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "type": "array"
      +                  },
      +                  "source": {
      +                    "enum": [
      +                      "ALL_US_STOCKS",
      +                      "SP500",
      +                      "NASDAQ100",
      +                      "DJIA",
      +                      "CRYPTO",
      +                      "SPECIFIC_ASSETS"
      +                    ],
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "source"
      +                ],
      +                "type": "object"
      +              },
      +              "weightIndicator": {
      +                "$ref": "#/$defs/indicator"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "universe",
      +              "pipeline",
      +              "weightIndicator",
      +              "structureTemplates"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": true,
      +            "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
      +            "properties": {
      +              "closeScope": {
      +                "enum": [
      +                  "spread",
      +                  "leg"
      +                ],
      +                "type": "string"
      +              },
      +              "direction": {
      +                "enum": [
      +                  "long",
      +                  "short"
      +                ],
      +                "type": "string"
      +              },
      +              "optionType": {
      +                "enum": [
      +                  "call",
      +                  "put"
      +                ],
      +                "type": "string"
      +              },
      +              "quantity": {
      +                "additionalProperties": true,
      +                "description": "How many contracts to close. Defaults to all matching when omitted.",
      +                "type": "object"
      +              },
      +              "spreadType": {
      +                "enum": [
      +                  "vertical",
      +                  "calendar",
      +                  "diagonal",
      +                  "ironCondor",
      +                  "straddle",
      +                  "strangle",
      +                  "custom"
      +                ],
      +                "type": "string"
      +              },
      +              "triggers": {
      +                "items": {
      +                  "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
      +                  "oneOf": [
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "maxPnlPercent": {
      +                          "type": "number"
      +                        },
      +                        "minPnlPercent": {
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "pnl",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "maxDte": {
      +                          "type": "number"
      +                        },
      +                        "minDte": {
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "dte",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "maxDaysHeld": {
      +                          "type": "number"
      +                        },
      +                        "minDaysHeld": {
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "daysHeld",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "maxIv": {
      +                          "type": "number"
      +                        },
      +                        "maxSpreadDelta": {
      +                          "type": "number"
      +                        },
      +                        "maxSpreadTheta": {
      +                          "type": "number"
      +                        },
      +                        "minIv": {
      +                          "type": "number"
      +                        },
      +                        "minSpreadDelta": {
      +                          "type": "number"
      +                        },
      +                        "minSpreadTheta": {
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "greeks",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type"
      +                      ],
      +                      "type": "object"
      +                    }
      +                  ],
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "type": {
      +                "const": "CloseOption",
      +                "type": "string"
      +              },
      +              "underlyings": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              }
      +            },
      +            "required": [
      +              "type"
      +            ],
      +            "type": "object"
      +          }
      +        ],
      +        "type": "object"
      +      },
      +      "active": {
      +        "description": "Whether the strategy is active (default true).",
      +        "type": "boolean"
      +      },
      +      "condition": {
      +        "$ref": "#/$defs/condition"
      +      },
      +      "name": {
      +        "description": "Human-readable strategy name.",
      +        "type": "string"
      +      },
      +      "orderExecution": {
      +        "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.",
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "type": {
      +                "const": "Market",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "price": {
      +                "oneOf": [
      +                  {
      +                    "additionalProperties": false,
      +                    "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
      +                    "properties": {
      +                      "amount": {
      +                        "minimum": 1e-8,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "UnitPrice",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "amount"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": false,
      +                    "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
      +                    "properties": {
      +                      "amount": {
      +                        "minimum": 1e-8,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "MinimumNetCredit",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "amount"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": false,
      +                    "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
      +                    "properties": {
      +                      "amount": {
      +                        "minimum": 1e-8,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "MaximumNetDebit",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "amount"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": false,
      +                    "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
      +                    "properties": {
      +                      "reference": {
      +                        "const": "Current",
      +                        "type": "string"
      +                      },
      +                      "type": {
      +                        "const": "QuoteRelative",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "reference"
      +                    ],
      +                    "type": "object"
      +                  }
      +                ]
      +              },
      +              "type": {
      +                "const": "Limit",
      +                "type": "string"
      +              },
      +              "workingTime": {
      +                "oneOf": [
      +                  {
      +                    "additionalProperties": false,
      +                    "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
      +                    "properties": {
      +                      "type": {
      +                        "const": "Day",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": false,
      +                    "properties": {
      +                      "minutes": {
      +                        "minimum": 1,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "Minutes",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "minutes"
      +                    ],
      +                    "type": "object"
      +                  }
      +                ]
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "price"
      +            ],
      +            "type": "object"
      +          }
      +        ],
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "name",
      +      "condition",
      +      "action"
      +    ],
      +    "type": "object"
      +  },
      +  "window": {
      +    "description": "Rolling time window. e.g. {length:14, interval:'Day'} = trailing 14 trading days.",
      +    "properties": {
      +      "interval": {
      +        "enum": [
      +          "Day",
      +          "Hour",
      +          "Minute"
      +        ],
      +        "type": "string"
      +      },
      +      "length": {
      +        "minimum": 1,
      +        "type": "number"
      +      }
      +    },
      +    "required": [
      +      "length",
      +      "interval"
      +    ],
      +    "type": "object"
      +  }
      +}
    • changedInput schema / properties / operations / description
      Previous value: -"Array of edit operations. Each operation needs \"portfolioId\" (live, paper, or chat — server resolves automatically). Supported types include \"rename\" (requires non-empty \"name\"), \"delete\" (permanently remove a chat/paper/live portfolio; archives deployed books; pass confirmLive:true only after explicit user confirmation when deleting an active live portfolio). DEPLOY SAFETY: deploying a chat portfolio ID creates a NEW PAPER-TRADING portfolio (simulated money, no broker order ever placed). It cannot place real-money trades. A LIVE/real-brokerage deployment only happens when the target is an EXISTING real-brokerage portfolio (re-activating it, or addStrategies/replaceStrategies on a portfolio already connected to a live broker). You cannot create a live brokerage account from a chat portfolio through this tool. Fetch the portfolio first and use strategy IDs from the returned \"strategies\" array for removals. To add/replace strategies, pass FINISHED strategy objects ({name, condition, action} — same shape as create_portfolio.strategies) via \"strategyObjects\" (or \"strategyObject\" for replaceStrategy). These are ingested deterministically with zero LLM cost; prefer them. RebalanceOption `action.positionScope`: `\"portfolio\"` (default for single-book portfolios — rotation-close and open-skip span all option spreads in the portfolio) or `\"strategy\"` (only spreads this strategy opened; use when multiple RebalanceOption strategies share one portfolio). Set on `create_portfolio` strategies[].action or on `update_portfolio` replaceStrategy/replaceStrategies `strategyObject.action`. Examples: [{\"type\":\"deploy\",\"portfolioId\":\"id\"}, {\"type\":\"undeploy\",\"portfolioId\":\"id\"}, {\"type\":\"delete\",\"portfolioId\":\"id\"}, {\"type\":\"addStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...}}]}, {\"type\":\"removeStrategies\",\"portfolioId\":\"id\",\"strategyIds\":[\"strategyId\"]}, {\"type\":\"replaceStrategy\",\"portfolioId\":\"id\",\"targetStrategyId\":\"strategyId\",\"strategyObject\":{\"name\":\"...\",\"condition\":{...},\"action\":{\"type\":\"RebalanceOption\",\"positionScope\":\"portfolio\",...}}}, {\"type\":\"replaceStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...}}]}, {\"type\":\"setDeploymentFrequency\",\"portfolioId\":\"id\",\"deploymentFrequency\":\"Constant\"}, {\"type\":\"rename\",\"portfolioId\":\"id\",\"name\":\"New Portfolio Name\"}]"New value: +"Array of edit operations. Each operation needs \"portfolioId\" (live, paper, or chat — server resolves automatically). Supported types include \"rename\" (requires non-empty \"name\"), \"delete\" (permanently remove a chat/paper/live portfolio; archives deployed books; pass confirmLive:true only after explicit user confirmation when deleting an active live portfolio). DEPLOY SAFETY: deploying a chat portfolio ID creates a NEW PAPER-TRADING portfolio (simulated money, no broker order ever placed). It cannot place real-money trades. A LIVE/real-brokerage deployment only happens when the target is an EXISTING real-brokerage portfolio (re-activating it, or addStrategies/replaceStrategies on a portfolio already connected to a live broker). You cannot create a live brokerage account from a chat portfolio through this tool. Fetch the portfolio first and use strategy IDs from the returned \"strategies\" array for removals. To add/replace strategies, pass FINISHED strategy objects ({name, condition, action, orderExecution?} — same shape as create_portfolio.strategies) via \"strategyObjects\" (or \"strategyObject\" for replaceStrategy). These are ingested deterministically with zero LLM cost; prefer them. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. RebalanceOption `action.positionScope`: `\"portfolio\"` (default for single-book portfolios — rotation-close and open-skip span all option spreads in the portfolio) or `\"strategy\"` (only spreads this strategy opened; use when multiple RebalanceOption strategies share one portfolio). Set on `create_portfolio` strategies[].action or on `update_portfolio` replaceStrategy/replaceStrategies `strategyObject.action`. Examples: [{\"type\":\"deploy\",\"portfolioId\":\"id\"}, {\"type\":\"undeploy\",\"portfolioId\":\"id\"}, {\"type\":\"delete\",\"portfolioId\":\"id\"}, {\"type\":\"addStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...},\"orderExecution\":{\"type\":\"Limit\",\"price\":{\"type\":\"UnitPrice\",\"amount\":150},\"workingTime\":{\"type\":\"Day\"}}}]}, {\"type\":\"removeStrategies\",\"portfolioId\":\"id\",\"strategyIds\":[\"strategyId\"]}, {\"type\":\"replaceStrategy\",\"portfolioId\":\"id\",\"targetStrategyId\":\"strategyId\",\"strategyObject\":{\"name\":\"...\",\"condition\":{...},\"action\":{\"type\":\"RebalanceOption\",\"positionScope\":\"portfolio\",...}}}, {\"type\":\"replaceStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...}}]}, {\"type\":\"setDeploymentFrequency\",\"portfolioId\":\"id\",\"deploymentFrequency\":\"Constant\"}, {\"type\":\"rename\",\"portfolioId\":\"id\",\"name\":\"New Portfolio Name\"}]"
    • addedInput schema / properties / operations / items / additionalProperties
      Added value: +false
    • addedInput schema / properties / operations / items / properties
      Added value: +{
      +  "confirmLive": {
      +    "type": "boolean"
      +  },
      +  "deploymentFrequency": {
      +    "enum": [
      +      "Constant",
      +      "OpenClose"
      +    ],
      +    "type": "string"
      +  },
      +  "name": {
      +    "type": "string"
      +  },
      +  "portfolioId": {
      +    "type": "string"
      +  },
      +  "strategyIds": {
      +    "items": {
      +      "type": "string"
      +    },
      +    "type": "array"
      +  },
      +  "strategyObject": {
      +    "additionalProperties": true,
      +    "description": "A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.",
      +    "properties": {
      +      "action": {
      +        "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).",
      +        "oneOf": [
      +          {
      +            "additionalProperties": true,
      +            "description": "Buy or Sell a stock/crypto position.",
      +            "properties": {
      +              "amount": {
      +                "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
      +                "properties": {
      +                  "amount": {
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "enum": [
      +                      "percent of portfolio",
      +                      "percent of buying power",
      +                      "percent of current positions",
      +                      "dollars",
      +                      "number of assets"
      +                    ],
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "amount"
      +                ],
      +                "type": "object"
      +              },
      +              "targetAsset": {
      +                "additionalProperties": true,
      +                "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                "properties": {
      +                  "name": {
      +                    "type": "string"
      +                  },
      +                  "symbol": {
      +                    "type": "string"
      +                  },
      +                  "type": {
      +                    "enum": [
      +                      "Stock",
      +                      "Cryptocurrency",
      +                      "Option",
      +                      "Other"
      +                    ],
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "symbol"
      +                ],
      +                "type": "object"
      +              },
      +              "type": {
      +                "enum": [
      +                  "Buy",
      +                  "Sell"
      +                ],
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "targetAsset",
      +              "amount"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": true,
      +            "description": "Send an alert message (no order).",
      +            "properties": {
      +              "message": {
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "Alert",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "message"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": true,
      +            "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
      +            "properties": {
      +              "allocationPolicy": {
      +                "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      +                "oneOf": [
      +                  {
      +                    "additionalProperties": false,
      +                    "properties": {
      +                      "covarianceShrinkage": {
      +                        "maximum": 1,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "estimatedTransactionCostBps": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "expectedReturnShrinkage": {
      +                        "maximum": 1,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "lookbackPeriods": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "minimumObservations": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "riskAversion": {
      +                        "maximum": 1000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "turnoverPenalty": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "MeanVariance",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "lookbackPeriods",
      +                      "minimumObservations",
      +                      "riskAversion",
      +                      "expectedReturnShrinkage",
      +                      "covarianceShrinkage",
      +                      "turnoverPenalty",
      +                      "estimatedTransactionCostBps"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": false,
      +                    "properties": {
      +                      "covarianceShrinkage": {
      +                        "maximum": 1,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "estimatedTransactionCostBps": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "lookbackPeriods": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "minimumObservations": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "turnoverPenalty": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "RiskParity",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "lookbackPeriods",
      +                      "minimumObservations",
      +                      "covarianceShrinkage",
      +                      "turnoverPenalty",
      +                      "estimatedTransactionCostBps"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": false,
      +                    "properties": {
      +                      "covarianceShrinkage": {
      +                        "maximum": 1,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "estimatedTransactionCostBps": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "lookbackPeriods": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "minimumObservations": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "turnoverPenalty": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "MaximumDiversification",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "lookbackPeriods",
      +                      "minimumObservations",
      +                      "covarianceShrinkage",
      +                      "turnoverPenalty",
      +                      "estimatedTransactionCostBps"
      +                    ],
      +                    "type": "object"
      +                  }
      +                ]
      +              },
      +              "canSell": {
      +                "$ref": "#/$defs/condition",
      +                "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
      +              },
      +              "deploymentPercent": {
      +                "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
      +                "maximum": 100,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "exposurePolicy": {
      +                "additionalProperties": false,
      +                "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      +                "properties": {
      +                  "covarianceShrinkage": {
      +                    "maximum": 1,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "estimatedTransactionCostBps": {
      +                    "maximum": 10000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "lookbackPeriods": {
      +                    "maximum": 5000,
      +                    "minimum": 2,
      +                    "type": "integer"
      +                  },
      +                  "minimumObservations": {
      +                    "maximum": 5000,
      +                    "minimum": 2,
      +                    "type": "integer"
      +                  },
      +                  "targetAnnualizedVolatilityPercent": {
      +                    "maximum": 1000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "const": "VolatilityTarget",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "lookbackPeriods",
      +                  "minimumObservations",
      +                  "covarianceShrinkage",
      +                  "targetAnnualizedVolatilityPercent",
      +                  "estimatedTransactionCostBps"
      +                ],
      +                "type": "object"
      +              },
      +              "limit": {
      +                "minimum": 1,
      +                "type": "number"
      +              },
      +              "perNameAllocation": {
      +                "additionalProperties": true,
      +                "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
      +                "properties": {
      +                  "amount": {
      +                    "exclusiveMinimum": 0,
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "enum": [
      +                      "percent of portfolio",
      +                      "dollars"
      +                    ],
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "amount"
      +                ],
      +                "type": "object"
      +              },
      +              "pipeline": {
      +                "items": {
      +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                  "oneOf": [
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "condition": {
      +                          "$ref": "#/$defs/condition"
      +                        },
      +                        "type": {
      +                          "const": "Filter",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "condition"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "Highest",
      +                            "Lowest"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "limit": {
      +                          "minimum": 1,
      +                          "type": "number"
      +                        },
      +                        "metric": {
      +                          "$ref": "#/$defs/indicator"
      +                        },
      +                        "type": {
      +                          "const": "SelectTop",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "metric",
      +                        "limit",
      +                        "direction"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "Highest",
      +                            "Lowest"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "metric": {
      +                          "$ref": "#/$defs/indicator"
      +                        },
      +                        "percentile": {
      +                          "maximum": 100,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "SelectPercentile",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "metric",
      +                        "percentile",
      +                        "direction"
      +                      ],
      +                      "type": "object"
      +                    }
      +                  ],
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "type": {
      +                "const": "DynamicRebalance",
      +                "type": "string"
      +              },
      +              "universe": {
      +                "additionalProperties": true,
      +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +                "properties": {
      +                  "assets": {
      +                    "items": {
      +                      "additionalProperties": true,
      +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                      "properties": {
      +                        "name": {
      +                          "type": "string"
      +                        },
      +                        "symbol": {
      +                          "type": "string"
      +                        },
      +                        "type": {
      +                          "enum": [
      +                            "Stock",
      +                            "Cryptocurrency",
      +                            "Option",
      +                            "Other"
      +                          ],
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "symbol"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "type": "array"
      +                  },
      +                  "source": {
      +                    "enum": [
      +                      "ALL_US_STOCKS",
      +                      "SP500",
      +                      "NASDAQ100",
      +                      "DJIA",
      +                      "CRYPTO",
      +                      "SPECIFIC_ASSETS"
      +                    ],
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "source"
      +                ],
      +                "type": "object"
      +              },
      +              "weightIndicator": {
      +                "$ref": "#/$defs/indicator"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "universe",
      +              "pipeline",
      +              "weightIndicator"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": true,
      +            "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
      +            "properties": {
      +              "continueExisting": {
      +                "type": "boolean"
      +              },
      +              "cooldownMinutes": {
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "executionModel": {
      +                "type": "string"
      +              },
      +              "includeMarketData": {
      +                "type": "boolean"
      +              },
      +              "initialMessage": {
      +                "type": "string"
      +              },
      +              "maxIterations": {
      +                "minimum": 1,
      +                "type": "number"
      +              },
      +              "planningModel": {
      +                "type": "string"
      +              },
      +              "skipPlanning": {
      +                "type": "boolean"
      +              },
      +              "type": {
      +                "const": "LaunchAgent",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "planningModel",
      +              "executionModel",
      +              "initialMessage",
      +              "maxIterations",
      +              "includeMarketData",
      +              "continueExisting",
      +              "skipPlanning"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": true,
      +            "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
      +            "properties": {
      +              "against": {
      +                "additionalProperties": true,
      +                "description": "Optional parent-position selector (e.g. for covered calls).",
      +                "type": "object"
      +              },
      +              "allocation": {
      +                "additionalProperties": true,
      +                "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +                "properties": {
      +                  "amount": {
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "enum": [
      +                      "dollars",
      +                      "percent of portfolio",
      +                      "percent of buying power",
      +                      "contracts"
      +                    ],
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "amount"
      +                ],
      +                "type": "object"
      +              },
      +              "builder": {
      +                "additionalProperties": true,
      +                "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
      +                "properties": {
      +                  "dynamicUnderlying": {
      +                    "additionalProperties": true,
      +                    "properties": {
      +                      "limit": {
      +                        "minimum": 1,
      +                        "type": "number"
      +                      },
      +                      "pipeline": {
      +                        "items": {
      +                          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                          "oneOf": [
      +                            {
      +                              "additionalProperties": true,
      +                              "properties": {
      +                                "condition": {
      +                                  "$ref": "#/$defs/condition"
      +                                },
      +                                "type": {
      +                                  "const": "Filter",
      +                                  "type": "string"
      +                                }
      +                              },
      +                              "required": [
      +                                "type",
      +                                "condition"
      +                              ],
      +                              "type": "object"
      +                            },
      +                            {
      +                              "additionalProperties": true,
      +                              "properties": {
      +                                "direction": {
      +                                  "enum": [
      +                                    "Highest",
      +                                    "Lowest"
      +                                  ],
      +                                  "type": "string"
      +                                },
      +                                "limit": {
      +                                  "minimum": 1,
      +                                  "type": "number"
      +                                },
      +                                "metric": {
      +                                  "$ref": "#/$defs/indicator"
      +                                },
      +                                "type": {
      +                                  "const": "SelectTop",
      +                                  "type": "string"
      +                                }
      +                              },
      +                              "required": [
      +                                "type",
      +                                "metric",
      +                                "limit",
      +                                "direction"
      +                              ],
      +                              "type": "object"
      +                            },
      +                            {
      +                              "additionalProperties": true,
      +                              "properties": {
      +                                "direction": {
      +                                  "enum": [
      +                                    "Highest",
      +                                    "Lowest"
      +                                  ],
      +                                  "type": "string"
      +                                },
      +                                "metric": {
      +                                  "$ref": "#/$defs/indicator"
      +                                },
      +                                "percentile": {
      +                                  "maximum": 100,
      +                                  "minimum": 0,
      +                                  "type": "number"
      +                                },
      +                                "type": {
      +                                  "const": "SelectPercentile",
      +                                  "type": "string"
      +                                }
      +                              },
      +                              "required": [
      +                                "type",
      +                                "metric",
      +                                "percentile",
      +                                "direction"
      +                              ],
      +                              "type": "object"
      +                            }
      +                          ],
      +                          "type": "object"
      +                        },
      +                        "type": "array"
      +                      },
      +                      "universe": {
      +                        "additionalProperties": true,
      +                        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +                        "properties": {
      +                          "assets": {
      +                            "items": {
      +                              "additionalProperties": true,
      +                              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                              "properties": {
      +                                "name": {
      +                                  "type": "string"
      +                                },
      +                                "symbol": {
      +                                  "type": "string"
      +                                },
      +                                "type": {
      +                                  "enum": [
      +                                    "Stock",
      +                                    "Cryptocurrency",
      +                                    "Option",
      +                                    "Other"
      +                                  ],
      +                                  "type": "string"
      +                                }
      +                              },
      +                              "required": [
      +                                "type",
      +                                "symbol"
      +                              ],
      +                              "type": "object"
      +                            },
      +                            "type": "array"
      +                          },
      +                          "source": {
      +                            "enum": [
      +                              "ALL_US_STOCKS",
      +                              "SP500",
      +                              "NASDAQ100",
      +                              "DJIA",
      +                              "CRYPTO",
      +                              "SPECIFIC_ASSETS"
      +                            ],
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "source"
      +                        ],
      +                        "type": "object"
      +                      }
      +                    },
      +                    "required": [
      +                      "universe"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "legs": {
      +                    "items": {
      +                      "additionalProperties": true,
      +                      "description": "Single leg of an option builder.",
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "long",
      +                            "short"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "expirationRange": {
      +                          "additionalProperties": true,
      +                          "type": "object"
      +                        },
      +                        "expirationSelector": {
      +                          "properties": {
      +                            "maxDaysToExpiration": {
      +                              "minimum": 0,
      +                              "type": "number"
      +                            },
      +                            "minDaysToExpiration": {
      +                              "minimum": 0,
      +                              "type": "number"
      +                            },
      +                            "preference": {
      +                              "enum": [
      +                                "nearest",
      +                                "middle",
      +                                "furthest"
      +                              ],
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "minDaysToExpiration",
      +                            "maxDaysToExpiration",
      +                            "preference"
      +                          ],
      +                          "type": "object"
      +                        },
      +                        "fallbackStrikeSelector": {
      +                          "additionalProperties": false,
      +                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                          "properties": {
      +                            "distance": {
      +                              "type": "number"
      +                            },
      +                            "distanceType": {
      +                              "enum": [
      +                                "percent",
      +                                "dollars"
      +                              ],
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "distanceType",
      +                            "distance"
      +                          ],
      +                          "type": "object"
      +                        },
      +                        "greekFilter": {
      +                          "additionalProperties": true,
      +                          "description": "Optional min/max constraints on Greeks during resolution.",
      +                          "type": "object"
      +                        },
      +                        "liquidityFilter": {
      +                          "additionalProperties": false,
      +                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                          "properties": {
      +                            "maxSpreadAbsolute": {
      +                              "type": "number"
      +                            },
      +                            "maxSpreadPct": {
      +                              "type": "number"
      +                            },
      +                            "minBid": {
      +                              "type": "number"
      +                            }
      +                          },
      +                          "type": "object"
      +                        },
      +                        "optionType": {
      +                          "enum": [
      +                            "call",
      +                            "put"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "ratio": {
      +                          "type": "number"
      +                        },
      +                        "strikeRange": {
      +                          "additionalProperties": true,
      +                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                          "type": "object"
      +                        },
      +                        "strikeSelector": {
      +                          "properties": {
      +                            "distance": {
      +                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                              "type": "number"
      +                            },
      +                            "distanceType": {
      +                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "distanceType",
      +                            "distance"
      +                          ],
      +                          "type": "object"
      +                        }
      +                      },
      +                      "required": [
      +                        "optionType",
      +                        "direction",
      +                        "expirationSelector",
      +                        "strikeSelector"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "minItems": 1,
      +                    "type": "array"
      +                  },
      +                  "spreadType": {
      +                    "enum": [
      +                      "vertical",
      +                      "calendar",
      +                      "diagonal",
      +                      "ironCondor",
      +                      "straddle",
      +                      "strangle",
      +                      "custom"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "underlyingSymbol": {
      +                    "type": "string"
      +                  },
      +                  "widthConstraint": {
      +                    "additionalProperties": false,
      +                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +                    "properties": {
      +                      "minWidthDollars": {
      +                        "exclusiveMinimum": 0,
      +                        "type": "number"
      +                      },
      +                      "minWidthPercent": {
      +                        "exclusiveMinimum": 0,
      +                        "type": "number"
      +                      }
      +                    },
      +                    "type": "object"
      +                  }
      +                },
      +                "required": [
      +                  "legs"
      +                ],
      +                "type": "object"
      +              },
      +              "type": {
      +                "const": "OpenOption",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "builder"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": true,
      +            "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
      +            "properties": {
      +              "allocationPolicy": {
      +                "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      +                "oneOf": [
      +                  {
      +                    "additionalProperties": false,
      +                    "properties": {
      +                      "covarianceShrinkage": {
      +                        "maximum": 1,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "estimatedTransactionCostBps": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "expectedReturnShrinkage": {
      +                        "maximum": 1,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "lookbackPeriods": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "minimumObservations": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "riskAversion": {
      +                        "maximum": 1000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "turnoverPenalty": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "MeanVariance",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "lookbackPeriods",
      +                      "minimumObservations",
      +                      "riskAversion",
      +                      "expectedReturnShrinkage",
      +                      "covarianceShrinkage",
      +                      "turnoverPenalty",
      +                      "estimatedTransactionCostBps"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": false,
      +                    "properties": {
      +                      "covarianceShrinkage": {
      +                        "maximum": 1,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "estimatedTransactionCostBps": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "lookbackPeriods": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "minimumObservations": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "turnoverPenalty": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "RiskParity",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "lookbackPeriods",
      +                      "minimumObservations",
      +                      "covarianceShrinkage",
      +                      "turnoverPenalty",
      +                      "estimatedTransactionCostBps"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": false,
      +                    "properties": {
      +                      "covarianceShrinkage": {
      +                        "maximum": 1,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "estimatedTransactionCostBps": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "lookbackPeriods": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "minimumObservations": {
      +                        "maximum": 5000,
      +                        "minimum": 2,
      +                        "type": "integer"
      +                      },
      +                      "turnoverPenalty": {
      +                        "maximum": 10000,
      +                        "minimum": 0,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "MaximumDiversification",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "lookbackPeriods",
      +                      "minimumObservations",
      +                      "covarianceShrinkage",
      +                      "turnoverPenalty",
      +                      "estimatedTransactionCostBps"
      +                    ],
      +                    "type": "object"
      +                  }
      +                ]
      +              },
      +              "exposurePolicy": {
      +                "additionalProperties": false,
      +                "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      +                "properties": {
      +                  "covarianceShrinkage": {
      +                    "maximum": 1,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "estimatedTransactionCostBps": {
      +                    "maximum": 10000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "lookbackPeriods": {
      +                    "maximum": 5000,
      +                    "minimum": 2,
      +                    "type": "integer"
      +                  },
      +                  "minimumObservations": {
      +                    "maximum": 5000,
      +                    "minimum": 2,
      +                    "type": "integer"
      +                  },
      +                  "targetAnnualizedVolatilityPercent": {
      +                    "maximum": 1000,
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "const": "VolatilityTarget",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "lookbackPeriods",
      +                  "minimumObservations",
      +                  "covarianceShrinkage",
      +                  "targetAnnualizedVolatilityPercent",
      +                  "estimatedTransactionCostBps"
      +                ],
      +                "type": "object"
      +              },
      +              "limit": {
      +                "minimum": 1,
      +                "type": "number"
      +              },
      +              "perNameAllocation": {
      +                "additionalProperties": true,
      +                "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +                "properties": {
      +                  "amount": {
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "enum": [
      +                      "dollars",
      +                      "percent of portfolio",
      +                      "percent of buying power",
      +                      "contracts"
      +                    ],
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "amount"
      +                ],
      +                "type": "object"
      +              },
      +              "pipeline": {
      +                "items": {
      +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                  "oneOf": [
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "condition": {
      +                          "$ref": "#/$defs/condition"
      +                        },
      +                        "type": {
      +                          "const": "Filter",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "condition"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "Highest",
      +                            "Lowest"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "limit": {
      +                          "minimum": 1,
      +                          "type": "number"
      +                        },
      +                        "metric": {
      +                          "$ref": "#/$defs/indicator"
      +                        },
      +                        "type": {
      +                          "const": "SelectTop",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "metric",
      +                        "limit",
      +                        "direction"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "direction": {
      +                          "enum": [
      +                            "Highest",
      +                            "Lowest"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "metric": {
      +                          "$ref": "#/$defs/indicator"
      +                        },
      +                        "percentile": {
      +                          "maximum": 100,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "SelectPercentile",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "metric",
      +                        "percentile",
      +                        "direction"
      +                      ],
      +                      "type": "object"
      +                    }
      +                  ],
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "positionScope": {
      +                "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
      +                "enum": [
      +                  "portfolio",
      +                  "strategy"
      +                ],
      +                "type": "string"
      +              },
      +              "sleeves": {
      +                "items": {
      +                  "additionalProperties": true,
      +                  "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
      +                  "properties": {
      +                    "limit": {
      +                      "minimum": 1,
      +                      "type": "number"
      +                    },
      +                    "name": {
      +                      "type": "string"
      +                    },
      +                    "perNameAllocation": {
      +                      "additionalProperties": true,
      +                      "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +                      "properties": {
      +                        "amount": {
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "enum": [
      +                            "dollars",
      +                            "percent of portfolio",
      +                            "percent of buying power",
      +                            "contracts"
      +                          ],
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "amount"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "pipeline": {
      +                      "items": {
      +                        "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                        "oneOf": [
      +                          {
      +                            "additionalProperties": true,
      +                            "properties": {
      +                              "condition": {
      +                                "$ref": "#/$defs/condition"
      +                              },
      +                              "type": {
      +                                "const": "Filter",
      +                                "type": "string"
      +                              }
      +                            },
      +                            "required": [
      +                              "type",
      +                              "condition"
      +                            ],
      +                            "type": "object"
      +                          },
      +                          {
      +                            "additionalProperties": true,
      +                            "properties": {
      +                              "direction": {
      +                                "enum": [
      +                                  "Highest",
      +                                  "Lowest"
      +                                ],
      +                                "type": "string"
      +                              },
      +                              "limit": {
      +                                "minimum": 1,
      +                                "type": "number"
      +                              },
      +                              "metric": {
      +                                "$ref": "#/$defs/indicator"
      +                              },
      +                              "type": {
      +                                "const": "SelectTop",
      +                                "type": "string"
      +                              }
      +                            },
      +                            "required": [
      +                              "type",
      +                              "metric",
      +                              "limit",
      +                              "direction"
      +                            ],
      +                            "type": "object"
      +                          },
      +                          {
      +                            "additionalProperties": true,
      +                            "properties": {
      +                              "direction": {
      +                                "enum": [
      +                                  "Highest",
      +                                  "Lowest"
      +                                ],
      +                                "type": "string"
      +                              },
      +                              "metric": {
      +                                "$ref": "#/$defs/indicator"
      +                              },
      +                              "percentile": {
      +                                "maximum": 100,
      +                                "minimum": 0,
      +                                "type": "number"
      +                              },
      +                              "type": {
      +                                "const": "SelectPercentile",
      +                                "type": "string"
      +                              }
      +                            },
      +                            "required": [
      +                              "type",
      +                              "metric",
      +                              "percentile",
      +                              "direction"
      +                            ],
      +                            "type": "object"
      +                          }
      +                        ],
      +                        "type": "object"
      +                      },
      +                      "type": "array"
      +                    },
      +                    "structureTemplates": {
      +                      "items": {
      +                        "additionalProperties": true,
      +                        "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      +                        "properties": {
      +                          "eligibility": {
      +                            "$ref": "#/$defs/condition"
      +                          },
      +                          "legs": {
      +                            "items": {
      +                              "additionalProperties": true,
      +                              "description": "Single leg of an option builder.",
      +                              "properties": {
      +                                "direction": {
      +                                  "enum": [
      +                                    "long",
      +                                    "short"
      +                                  ],
      +                                  "type": "string"
      +                                },
      +                                "expirationRange": {
      +                                  "additionalProperties": true,
      +                                  "type": "object"
      +                                },
      +                                "expirationSelector": {
      +                                  "properties": {
      +                                    "maxDaysToExpiration": {
      +                                      "minimum": 0,
      +                                      "type": "number"
      +                                    },
      +                                    "minDaysToExpiration": {
      +                                      "minimum": 0,
      +                                      "type": "number"
      +                                    },
      +                                    "preference": {
      +                                      "enum": [
      +                                        "nearest",
      +                                        "middle",
      +                                        "furthest"
      +                                      ],
      +                                      "type": "string"
      +                                    }
      +                                  },
      +                                  "required": [
      +                                    "minDaysToExpiration",
      +                                    "maxDaysToExpiration",
      +                                    "preference"
      +                                  ],
      +                                  "type": "object"
      +                                },
      +                                "fallbackStrikeSelector": {
      +                                  "additionalProperties": false,
      +                                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                                  "properties": {
      +                                    "distance": {
      +                                      "type": "number"
      +                                    },
      +                                    "distanceType": {
      +                                      "enum": [
      +                                        "percent",
      +                                        "dollars"
      +                                      ],
      +                                      "type": "string"
      +                                    }
      +                                  },
      +                                  "required": [
      +                                    "distanceType",
      +                                    "distance"
      +                                  ],
      +                                  "type": "object"
      +                                },
      +                                "greekFilter": {
      +                                  "additionalProperties": true,
      +                                  "description": "Optional min/max constraints on Greeks during resolution.",
      +                                  "type": "object"
      +                                },
      +                                "liquidityFilter": {
      +                                  "additionalProperties": false,
      +                                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                                  "properties": {
      +                                    "maxSpreadAbsolute": {
      +                                      "type": "number"
      +                                    },
      +                                    "maxSpreadPct": {
      +                                      "type": "number"
      +                                    },
      +                                    "minBid": {
      +                                      "type": "number"
      +                                    }
      +                                  },
      +                                  "type": "object"
      +                                },
      +                                "optionType": {
      +                                  "enum": [
      +                                    "call",
      +                                    "put"
      +                                  ],
      +                                  "type": "string"
      +                                },
      +                                "ratio": {
      +                                  "type": "number"
      +                                },
      +                                "strikeRange": {
      +                                  "additionalProperties": true,
      +                                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                                  "type": "object"
      +                                },
      +                                "strikeSelector": {
      +                                  "properties": {
      +                                    "distance": {
      +                                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                                      "type": "number"
      +                                    },
      +                                    "distanceType": {
      +                                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                                      "type": "string"
      +                                    }
      +                                  },
      +                                  "required": [
      +                                    "distanceType",
      +                                    "distance"
      +                                  ],
      +                                  "type": "object"
      +                                }
      +                              },
      +                              "required": [
      +                                "optionType",
      +                                "direction",
      +                                "expirationSelector",
      +                                "strikeSelector"
      +                              ],
      +                              "type": "object"
      +                            },
      +                            "minItems": 1,
      +                            "type": "array"
      +                          },
      +                          "name": {
      +                            "type": "string"
      +                          },
      +                          "spreadType": {
      +                            "enum": [
      +                              "vertical",
      +                              "calendar",
      +                              "diagonal",
      +                              "ironCondor",
      +                              "straddle",
      +                              "strangle",
      +                              "custom"
      +                            ],
      +                            "type": "string"
      +                          },
      +                          "widthConstraint": {
      +                            "additionalProperties": false,
      +                            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +                            "properties": {
      +                              "minWidthDollars": {
      +                                "exclusiveMinimum": 0,
      +                                "type": "number"
      +                              },
      +                              "minWidthPercent": {
      +                                "exclusiveMinimum": 0,
      +                                "type": "number"
      +                              }
      +                            },
      +                            "type": "object"
      +                          }
      +                        },
      +                        "required": [
      +                          "legs"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      "minItems": 1,
      +                      "type": "array"
      +                    },
      +                    "universe": {
      +                      "additionalProperties": true,
      +                      "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +                      "properties": {
      +                        "assets": {
      +                          "items": {
      +                            "additionalProperties": true,
      +                            "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                            "properties": {
      +                              "name": {
      +                                "type": "string"
      +                              },
      +                              "symbol": {
      +                                "type": "string"
      +                              },
      +                              "type": {
      +                                "enum": [
      +                                  "Stock",
      +                                  "Cryptocurrency",
      +                                  "Option",
      +                                  "Other"
      +                                ],
      +                                "type": "string"
      +                              }
      +                            },
      +                            "required": [
      +                              "type",
      +                              "symbol"
      +                            ],
      +                            "type": "object"
      +                          },
      +                          "type": "array"
      +                        },
      +                        "source": {
      +                          "enum": [
      +                            "ALL_US_STOCKS",
      +                            "SP500",
      +                            "NASDAQ100",
      +                            "DJIA",
      +                            "CRYPTO",
      +                            "SPECIFIC_ASSETS"
      +                          ],
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "source"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "weightIndicator": {
      +                      "$ref": "#/$defs/indicator"
      +                    }
      +                  },
      +                  "required": [
      +                    "name"
      +                  ],
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "structureTemplates": {
      +                "items": {
      +                  "additionalProperties": true,
      +                  "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      +                  "properties": {
      +                    "eligibility": {
      +                      "$ref": "#/$defs/condition"
      +                    },
      +                    "legs": {
      +                      "items": {
      +                        "additionalProperties": true,
      +                        "description": "Single leg of an option builder.",
      +                        "properties": {
      +                          "direction": {
      +                            "enum": [
      +                              "long",
      +                              "short"
      +                            ],
      +                            "type": "string"
      +                          },
      +                          "expirationRange": {
      +                            "additionalProperties": true,
      +                            "type": "object"
      +                          },
      +                          "expirationSelector": {
      +                            "properties": {
      +                              "maxDaysToExpiration": {
      +                                "minimum": 0,
      +                                "type": "number"
      +                              },
      +                              "minDaysToExpiration": {
      +                                "minimum": 0,
      +                                "type": "number"
      +                              },
      +                              "preference": {
      +                                "enum": [
      +                                  "nearest",
      +                                  "middle",
      +                                  "furthest"
      +                                ],
      +                                "type": "string"
      +                              }
      +                            },
      +                            "required": [
      +                              "minDaysToExpiration",
      +                              "maxDaysToExpiration",
      +                              "preference"
      +                            ],
      +                            "type": "object"
      +                          },
      +                          "fallbackStrikeSelector": {
      +                            "additionalProperties": false,
      +                            "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                            "properties": {
      +                              "distance": {
      +                                "type": "number"
      +                              },
      +                              "distanceType": {
      +                                "enum": [
      +                                  "percent",
      +                                  "dollars"
      +                                ],
      +                                "type": "string"
      +                              }
      +                            },
      +                            "required": [
      +                              "distanceType",
      +                              "distance"
      +                            ],
      +                            "type": "object"
      +                          },
      +                          "greekFilter": {
      +                            "additionalProperties": true,
      +                            "description": "Optional min/max constraints on Greeks during resolution.",
      +                            "type": "object"
      +                          },
      +                          "liquidityFilter": {
      +                            "additionalProperties": false,
      +                            "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                            "properties": {
      +                              "maxSpreadAbsolute": {
      +                                "type": "number"
      +                              },
      +                              "maxSpreadPct": {
      +                                "type": "number"
      +                              },
      +                              "minBid": {
      +                                "type": "number"
      +                              }
      +                            },
      +                            "type": "object"
      +                          },
      +                          "optionType": {
      +                            "enum": [
      +                              "call",
      +                              "put"
      +                            ],
      +                            "type": "string"
      +                          },
      +                          "ratio": {
      +                            "type": "number"
      +                          },
      +                          "strikeRange": {
      +                            "additionalProperties": true,
      +                            "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                            "type": "object"
      +                          },
      +                          "strikeSelector": {
      +                            "properties": {
      +                              "distance": {
      +                                "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                                "type": "number"
      +                              },
      +                              "distanceType": {
      +                                "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                                "type": "string"
      +                              }
      +                            },
      +                            "required": [
      +                              "distanceType",
      +                              "distance"
      +                            ],
      +                            "type": "object"
      +                          }
      +                        },
      +                        "required": [
      +                          "optionType",
      +                          "direction",
      +                          "expirationSelector",
      +                          "strikeSelector"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      "minItems": 1,
      +                      "type": "array"
      +                    },
      +                    "name": {
      +                      "type": "string"
      +                    },
      +                    "spreadType": {
      +                      "enum": [
      +                        "vertical",
      +                        "calendar",
      +                        "diagonal",
      +                        "ironCondor",
      +                        "straddle",
      +                        "strangle",
      +                        "custom"
      +                      ],
      +                      "type": "string"
      +                    },
      +                    "widthConstraint": {
      +                      "additionalProperties": false,
      +                      "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +                      "properties": {
      +                        "minWidthDollars": {
      +                          "exclusiveMinimum": 0,
      +                          "type": "number"
      +                        },
      +                        "minWidthPercent": {
      +                          "exclusiveMinimum": 0,
      +                          "type": "number"
      +                        }
      +                      },
      +                      "type": "object"
      +                    }
      +                  },
      +                  "required": [
      +                    "legs"
      +                  ],
      +                  "type": "object"
      +                },
      +                "minItems": 1,
      +                "type": "array"
      +              },
      +              "totalBudget": {
      +                "additionalProperties": true,
      +                "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
      +                "properties": {
      +                  "amount": {
      +                    "minimum": 0,
      +                    "type": "number"
      +                  },
      +                  "type": {
      +                    "enum": [
      +                      "dollars",
      +                      "percent of portfolio"
      +                    ],
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "type",
      +                  "amount"
      +                ],
      +                "type": "object"
      +              },
      +              "type": {
      +                "const": "RebalanceOption",
      +                "type": "string"
      +              },
      +              "universe": {
      +                "additionalProperties": true,
      +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +                "properties": {
      +                  "assets": {
      +                    "items": {
      +                      "additionalProperties": true,
      +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                      "properties": {
      +                        "name": {
      +                          "type": "string"
      +                        },
      +                        "symbol": {
      +                          "type": "string"
      +                        },
      +                        "type": {
      +                          "enum": [
      +                            "Stock",
      +                            "Cryptocurrency",
      +                            "Option",
      +                            "Other"
      +                          ],
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "symbol"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "type": "array"
      +                  },
      +                  "source": {
      +                    "enum": [
      +                      "ALL_US_STOCKS",
      +                      "SP500",
      +                      "NASDAQ100",
      +                      "DJIA",
      +                      "CRYPTO",
      +                      "SPECIFIC_ASSETS"
      +                    ],
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "source"
      +                ],
      +                "type": "object"
      +              },
      +              "weightIndicator": {
      +                "$ref": "#/$defs/indicator"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "universe",
      +              "pipeline",
      +              "weightIndicator",
      +              "structureTemplates"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": true,
      +            "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
      +            "properties": {
      +              "closeScope": {
      +                "enum": [
      +                  "spread",
      +                  "leg"
      +                ],
      +                "type": "string"
      +              },
      +              "direction": {
      +                "enum": [
      +                  "long",
      +                  "short"
      +                ],
      +                "type": "string"
      +              },
      +              "optionType": {
      +                "enum": [
      +                  "call",
      +                  "put"
      +                ],
      +                "type": "string"
      +              },
      +              "quantity": {
      +                "additionalProperties": true,
      +                "description": "How many contracts to close. Defaults to all matching when omitted.",
      +                "type": "object"
      +              },
      +              "spreadType": {
      +                "enum": [
      +                  "vertical",
      +                  "calendar",
      +                  "diagonal",
      +                  "ironCondor",
      +                  "straddle",
      +                  "strangle",
      +                  "custom"
      +                ],
      +                "type": "string"
      +              },
      +              "triggers": {
      +                "items": {
      +                  "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
      +                  "oneOf": [
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "maxPnlPercent": {
      +                          "type": "number"
      +                        },
      +                        "minPnlPercent": {
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "pnl",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "maxDte": {
      +                          "type": "number"
      +                        },
      +                        "minDte": {
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "dte",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "maxDaysHeld": {
      +                          "type": "number"
      +                        },
      +                        "minDaysHeld": {
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "daysHeld",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "maxIv": {
      +                          "type": "number"
      +                        },
      +                        "maxSpreadDelta": {
      +                          "type": "number"
      +                        },
      +                        "maxSpreadTheta": {
      +                          "type": "number"
      +                        },
      +                        "minIv": {
      +                          "type": "number"
      +                        },
      +                        "minSpreadDelta": {
      +                          "type": "number"
      +                        },
      +                        "minSpreadTheta": {
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "greeks",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type"
      +                      ],
      +                      "type": "object"
      +                    }
      +                  ],
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "type": {
      +                "const": "CloseOption",
      +                "type": "string"
      +              },
      +              "underlyings": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              }
      +            },
      +            "required": [
      +              "type"
      +            ],
      +            "type": "object"
      +          }
      +        ],
      +        "type": "object"
      +      },
      +      "active": {
      +        "description": "Whether the strategy is active (default true).",
      +        "type": "boolean"
      +      },
      +      "condition": {
      +        "$ref": "#/$defs/condition"
      +      },
      +      "name": {
      +        "description": "Human-readable strategy name.",
      +        "type": "string"
      +      },
      +      "orderExecution": {
      +        "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.",
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "type": {
      +                "const": "Market",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "price": {
      +                "oneOf": [
      +                  {
      +                    "additionalProperties": false,
      +                    "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
      +                    "properties": {
      +                      "amount": {
      +                        "minimum": 1e-8,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "UnitPrice",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "amount"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": false,
      +                    "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
      +                    "properties": {
      +                      "amount": {
      +                        "minimum": 1e-8,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "MinimumNetCredit",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "amount"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": false,
      +                    "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
      +                    "properties": {
      +                      "amount": {
      +                        "minimum": 1e-8,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "MaximumNetDebit",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "amount"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": false,
      +                    "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
      +                    "properties": {
      +                      "reference": {
      +                        "const": "Current",
      +                        "type": "string"
      +                      },
      +                      "type": {
      +                        "const": "QuoteRelative",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "reference"
      +                    ],
      +                    "type": "object"
      +                  }
      +                ]
      +              },
      +              "type": {
      +                "const": "Limit",
      +                "type": "string"
      +              },
      +              "workingTime": {
      +                "oneOf": [
      +                  {
      +                    "additionalProperties": false,
      +                    "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
      +                    "properties": {
      +                      "type": {
      +                        "const": "Day",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  {
      +                    "additionalProperties": false,
      +                    "properties": {
      +                      "minutes": {
      +                        "minimum": 1,
      +                        "type": "number"
      +                      },
      +                      "type": {
      +                        "const": "Minutes",
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "type",
      +                      "minutes"
      +                    ],
      +                    "type": "object"
      +                  }
      +                ]
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "price"
      +            ],
      +            "type": "object"
      +          }
      +        ],
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "name",
      +      "condition",
      +      "action"
      +    ],
      +    "type": "object"
      +  },
      +  "strategyObjects": {
      +    "items": {
      +      "additionalProperties": true,
      +      "description": "A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.",
      +      "properties": {
      +        "action": {
      +          "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).",
      +          "oneOf": [
      +            {
      +              "additionalProperties": true,
      +              "description": "Buy or Sell a stock/crypto position.",
      +              "properties": {
      +                "amount": {
      +                  "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
      +                  "properties": {
      +                    "amount": {
      +                      "type": "number"
      +                    },
      +                    "type": {
      +                      "enum": [
      +                        "percent of portfolio",
      +                        "percent of buying power",
      +                        "percent of current positions",
      +                        "dollars",
      +                        "number of assets"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type",
      +                    "amount"
      +                  ],
      +                  "type": "object"
      +                },
      +                "targetAsset": {
      +                  "additionalProperties": true,
      +                  "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                  "properties": {
      +                    "name": {
      +                      "type": "string"
      +                    },
      +                    "symbol": {
      +                      "type": "string"
      +                    },
      +                    "type": {
      +                      "enum": [
      +                        "Stock",
      +                        "Cryptocurrency",
      +                        "Option",
      +                        "Other"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type",
      +                    "symbol"
      +                  ],
      +                  "type": "object"
      +                },
      +                "type": {
      +                  "enum": [
      +                    "Buy",
      +                    "Sell"
      +                  ],
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "targetAsset",
      +                "amount"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "description": "Send an alert message (no order).",
      +              "properties": {
      +                "message": {
      +                  "type": "string"
      +                },
      +                "type": {
      +                  "const": "Alert",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "message"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
      +              "properties": {
      +                "allocationPolicy": {
      +                  "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      +                  "oneOf": [
      +                    {
      +                      "additionalProperties": false,
      +                      "properties": {
      +                        "covarianceShrinkage": {
      +                          "maximum": 1,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "estimatedTransactionCostBps": {
      +                          "maximum": 10000,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "expectedReturnShrinkage": {
      +                          "maximum": 1,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "lookbackPeriods": {
      +                          "maximum": 5000,
      +                          "minimum": 2,
      +                          "type": "integer"
      +                        },
      +                        "minimumObservations": {
      +                          "maximum": 5000,
      +                          "minimum": 2,
      +                          "type": "integer"
      +                        },
      +                        "riskAversion": {
      +                          "maximum": 1000,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "turnoverPenalty": {
      +                          "maximum": 10000,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "MeanVariance",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "lookbackPeriods",
      +                        "minimumObservations",
      +                        "riskAversion",
      +                        "expectedReturnShrinkage",
      +                        "covarianceShrinkage",
      +                        "turnoverPenalty",
      +                        "estimatedTransactionCostBps"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": false,
      +                      "properties": {
      +                        "covarianceShrinkage": {
      +                          "maximum": 1,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "estimatedTransactionCostBps": {
      +                          "maximum": 10000,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "lookbackPeriods": {
      +                          "maximum": 5000,
      +                          "minimum": 2,
      +                          "type": "integer"
      +                        },
      +                        "minimumObservations": {
      +                          "maximum": 5000,
      +                          "minimum": 2,
      +                          "type": "integer"
      +                        },
      +                        "turnoverPenalty": {
      +                          "maximum": 10000,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "RiskParity",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "lookbackPeriods",
      +                        "minimumObservations",
      +                        "covarianceShrinkage",
      +                        "turnoverPenalty",
      +                        "estimatedTransactionCostBps"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": false,
      +                      "properties": {
      +                        "covarianceShrinkage": {
      +                          "maximum": 1,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "estimatedTransactionCostBps": {
      +                          "maximum": 10000,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "lookbackPeriods": {
      +                          "maximum": 5000,
      +                          "minimum": 2,
      +                          "type": "integer"
      +                        },
      +                        "minimumObservations": {
      +                          "maximum": 5000,
      +                          "minimum": 2,
      +                          "type": "integer"
      +                        },
      +                        "turnoverPenalty": {
      +                          "maximum": 10000,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "MaximumDiversification",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "lookbackPeriods",
      +                        "minimumObservations",
      +                        "covarianceShrinkage",
      +                        "turnoverPenalty",
      +                        "estimatedTransactionCostBps"
      +                      ],
      +                      "type": "object"
      +                    }
      +                  ]
      +                },
      +                "canSell": {
      +                  "$ref": "#/$defs/condition",
      +                  "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
      +                },
      +                "deploymentPercent": {
      +                  "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
      +                  "maximum": 100,
      +                  "minimum": 0,
      +                  "type": "number"
      +                },
      +                "exposurePolicy": {
      +                  "additionalProperties": false,
      +                  "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      +                  "properties": {
      +                    "covarianceShrinkage": {
      +                      "maximum": 1,
      +                      "minimum": 0,
      +                      "type": "number"
      +                    },
      +                    "estimatedTransactionCostBps": {
      +                      "maximum": 10000,
      +                      "minimum": 0,
      +                      "type": "number"
      +                    },
      +                    "lookbackPeriods": {
      +                      "maximum": 5000,
      +                      "minimum": 2,
      +                      "type": "integer"
      +                    },
      +                    "minimumObservations": {
      +                      "maximum": 5000,
      +                      "minimum": 2,
      +                      "type": "integer"
      +                    },
      +                    "targetAnnualizedVolatilityPercent": {
      +                      "maximum": 1000,
      +                      "minimum": 0,
      +                      "type": "number"
      +                    },
      +                    "type": {
      +                      "const": "VolatilityTarget",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type",
      +                    "lookbackPeriods",
      +                    "minimumObservations",
      +                    "covarianceShrinkage",
      +                    "targetAnnualizedVolatilityPercent",
      +                    "estimatedTransactionCostBps"
      +                  ],
      +                  "type": "object"
      +                },
      +                "limit": {
      +                  "minimum": 1,
      +                  "type": "number"
      +                },
      +                "perNameAllocation": {
      +                  "additionalProperties": true,
      +                  "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
      +                  "properties": {
      +                    "amount": {
      +                      "exclusiveMinimum": 0,
      +                      "type": "number"
      +                    },
      +                    "type": {
      +                      "enum": [
      +                        "percent of portfolio",
      +                        "dollars"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type",
      +                    "amount"
      +                  ],
      +                  "type": "object"
      +                },
      +                "pipeline": {
      +                  "items": {
      +                    "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                    "oneOf": [
      +                      {
      +                        "additionalProperties": true,
      +                        "properties": {
      +                          "condition": {
      +                            "$ref": "#/$defs/condition"
      +                          },
      +                          "type": {
      +                            "const": "Filter",
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "type",
      +                          "condition"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      {
      +                        "additionalProperties": true,
      +                        "properties": {
      +                          "direction": {
      +                            "enum": [
      +                              "Highest",
      +                              "Lowest"
      +                            ],
      +                            "type": "string"
      +                          },
      +                          "limit": {
      +                            "minimum": 1,
      +                            "type": "number"
      +                          },
      +                          "metric": {
      +                            "$ref": "#/$defs/indicator"
      +                          },
      +                          "type": {
      +                            "const": "SelectTop",
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "type",
      +                          "metric",
      +                          "limit",
      +                          "direction"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      {
      +                        "additionalProperties": true,
      +                        "properties": {
      +                          "direction": {
      +                            "enum": [
      +                              "Highest",
      +                              "Lowest"
      +                            ],
      +                            "type": "string"
      +                          },
      +                          "metric": {
      +                            "$ref": "#/$defs/indicator"
      +                          },
      +                          "percentile": {
      +                            "maximum": 100,
      +                            "minimum": 0,
      +                            "type": "number"
      +                          },
      +                          "type": {
      +                            "const": "SelectPercentile",
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "type",
      +                          "metric",
      +                          "percentile",
      +                          "direction"
      +                        ],
      +                        "type": "object"
      +                      }
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "type": "array"
      +                },
      +                "type": {
      +                  "const": "DynamicRebalance",
      +                  "type": "string"
      +                },
      +                "universe": {
      +                  "additionalProperties": true,
      +                  "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +                  "properties": {
      +                    "assets": {
      +                      "items": {
      +                        "additionalProperties": true,
      +                        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                        "properties": {
      +                          "name": {
      +                            "type": "string"
      +                          },
      +                          "symbol": {
      +                            "type": "string"
      +                          },
      +                          "type": {
      +                            "enum": [
      +                              "Stock",
      +                              "Cryptocurrency",
      +                              "Option",
      +                              "Other"
      +                            ],
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "type",
      +                          "symbol"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      "type": "array"
      +                    },
      +                    "source": {
      +                      "enum": [
      +                        "ALL_US_STOCKS",
      +                        "SP500",
      +                        "NASDAQ100",
      +                        "DJIA",
      +                        "CRYPTO",
      +                        "SPECIFIC_ASSETS"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "source"
      +                  ],
      +                  "type": "object"
      +                },
      +                "weightIndicator": {
      +                  "$ref": "#/$defs/indicator"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "universe",
      +                "pipeline",
      +                "weightIndicator"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
      +              "properties": {
      +                "continueExisting": {
      +                  "type": "boolean"
      +                },
      +                "cooldownMinutes": {
      +                  "minimum": 0,
      +                  "type": "number"
      +                },
      +                "executionModel": {
      +                  "type": "string"
      +                },
      +                "includeMarketData": {
      +                  "type": "boolean"
      +                },
      +                "initialMessage": {
      +                  "type": "string"
      +                },
      +                "maxIterations": {
      +                  "minimum": 1,
      +                  "type": "number"
      +                },
      +                "planningModel": {
      +                  "type": "string"
      +                },
      +                "skipPlanning": {
      +                  "type": "boolean"
      +                },
      +                "type": {
      +                  "const": "LaunchAgent",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "planningModel",
      +                "executionModel",
      +                "initialMessage",
      +                "maxIterations",
      +                "includeMarketData",
      +                "continueExisting",
      +                "skipPlanning"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
      +              "properties": {
      +                "against": {
      +                  "additionalProperties": true,
      +                  "description": "Optional parent-position selector (e.g. for covered calls).",
      +                  "type": "object"
      +                },
      +                "allocation": {
      +                  "additionalProperties": true,
      +                  "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +                  "properties": {
      +                    "amount": {
      +                      "type": "number"
      +                    },
      +                    "type": {
      +                      "enum": [
      +                        "dollars",
      +                        "percent of portfolio",
      +                        "percent of buying power",
      +                        "contracts"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type",
      +                    "amount"
      +                  ],
      +                  "type": "object"
      +                },
      +                "builder": {
      +                  "additionalProperties": true,
      +                  "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
      +                  "properties": {
      +                    "dynamicUnderlying": {
      +                      "additionalProperties": true,
      +                      "properties": {
      +                        "limit": {
      +                          "minimum": 1,
      +                          "type": "number"
      +                        },
      +                        "pipeline": {
      +                          "items": {
      +                            "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                            "oneOf": [
      +                              {
      +                                "additionalProperties": true,
      +                                "properties": {
      +                                  "condition": {
      +                                    "$ref": "#/$defs/condition"
      +                                  },
      +                                  "type": {
      +                                    "const": "Filter",
      +                                    "type": "string"
      +                                  }
      +                                },
      +                                "required": [
      +                                  "type",
      +                                  "condition"
      +                                ],
      +                                "type": "object"
      +                              },
      +                              {
      +                                "additionalProperties": true,
      +                                "properties": {
      +                                  "direction": {
      +                                    "enum": [
      +                                      "Highest",
      +                                      "Lowest"
      +                                    ],
      +                                    "type": "string"
      +                                  },
      +                                  "limit": {
      +                                    "minimum": 1,
      +                                    "type": "number"
      +                                  },
      +                                  "metric": {
      +                                    "$ref": "#/$defs/indicator"
      +                                  },
      +                                  "type": {
      +                                    "const": "SelectTop",
      +                                    "type": "string"
      +                                  }
      +                                },
      +                                "required": [
      +                                  "type",
      +                                  "metric",
      +                                  "limit",
      +                                  "direction"
      +                                ],
      +                                "type": "object"
      +                              },
      +                              {
      +                                "additionalProperties": true,
      +                                "properties": {
      +                                  "direction": {
      +                                    "enum": [
      +                                      "Highest",
      +                                      "Lowest"
      +                                    ],
      +                                    "type": "string"
      +                                  },
      +                                  "metric": {
      +                                    "$ref": "#/$defs/indicator"
      +                                  },
      +                                  "percentile": {
      +                                    "maximum": 100,
      +                                    "minimum": 0,
      +                                    "type": "number"
      +                                  },
      +                                  "type": {
      +                                    "const": "SelectPercentile",
      +                                    "type": "string"
      +                                  }
      +                                },
      +                                "required": [
      +                                  "type",
      +                                  "metric",
      +                                  "percentile",
      +                                  "direction"
      +                                ],
      +                                "type": "object"
      +                              }
      +                            ],
      +                            "type": "object"
      +                          },
      +                          "type": "array"
      +                        },
      +                        "universe": {
      +                          "additionalProperties": true,
      +                          "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +                          "properties": {
      +                            "assets": {
      +                              "items": {
      +                                "additionalProperties": true,
      +                                "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                                "properties": {
      +                                  "name": {
      +                                    "type": "string"
      +                                  },
      +                                  "symbol": {
      +                                    "type": "string"
      +                                  },
      +                                  "type": {
      +                                    "enum": [
      +                                      "Stock",
      +                                      "Cryptocurrency",
      +                                      "Option",
      +                                      "Other"
      +                                    ],
      +                                    "type": "string"
      +                                  }
      +                                },
      +                                "required": [
      +                                  "type",
      +                                  "symbol"
      +                                ],
      +                                "type": "object"
      +                              },
      +                              "type": "array"
      +                            },
      +                            "source": {
      +                              "enum": [
      +                                "ALL_US_STOCKS",
      +                                "SP500",
      +                                "NASDAQ100",
      +                                "DJIA",
      +                                "CRYPTO",
      +                                "SPECIFIC_ASSETS"
      +                              ],
      +                              "type": "string"
      +                            }
      +                          },
      +                          "required": [
      +                            "source"
      +                          ],
      +                          "type": "object"
      +                        }
      +                      },
      +                      "required": [
      +                        "universe"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "legs": {
      +                      "items": {
      +                        "additionalProperties": true,
      +                        "description": "Single leg of an option builder.",
      +                        "properties": {
      +                          "direction": {
      +                            "enum": [
      +                              "long",
      +                              "short"
      +                            ],
      +                            "type": "string"
      +                          },
      +                          "expirationRange": {
      +                            "additionalProperties": true,
      +                            "type": "object"
      +                          },
      +                          "expirationSelector": {
      +                            "properties": {
      +                              "maxDaysToExpiration": {
      +                                "minimum": 0,
      +                                "type": "number"
      +                              },
      +                              "minDaysToExpiration": {
      +                                "minimum": 0,
      +                                "type": "number"
      +                              },
      +                              "preference": {
      +                                "enum": [
      +                                  "nearest",
      +                                  "middle",
      +                                  "furthest"
      +                                ],
      +                                "type": "string"
      +                              }
      +                            },
      +                            "required": [
      +                              "minDaysToExpiration",
      +                              "maxDaysToExpiration",
      +                              "preference"
      +                            ],
      +                            "type": "object"
      +                          },
      +                          "fallbackStrikeSelector": {
      +                            "additionalProperties": false,
      +                            "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                            "properties": {
      +                              "distance": {
      +                                "type": "number"
      +                              },
      +                              "distanceType": {
      +                                "enum": [
      +                                  "percent",
      +                                  "dollars"
      +                                ],
      +                                "type": "string"
      +                              }
      +                            },
      +                            "required": [
      +                              "distanceType",
      +                              "distance"
      +                            ],
      +                            "type": "object"
      +                          },
      +                          "greekFilter": {
      +                            "additionalProperties": true,
      +                            "description": "Optional min/max constraints on Greeks during resolution.",
      +                            "type": "object"
      +                          },
      +                          "liquidityFilter": {
      +                            "additionalProperties": false,
      +                            "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                            "properties": {
      +                              "maxSpreadAbsolute": {
      +                                "type": "number"
      +                              },
      +                              "maxSpreadPct": {
      +                                "type": "number"
      +                              },
      +                              "minBid": {
      +                                "type": "number"
      +                              }
      +                            },
      +                            "type": "object"
      +                          },
      +                          "optionType": {
      +                            "enum": [
      +                              "call",
      +                              "put"
      +                            ],
      +                            "type": "string"
      +                          },
      +                          "ratio": {
      +                            "type": "number"
      +                          },
      +                          "strikeRange": {
      +                            "additionalProperties": true,
      +                            "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                            "type": "object"
      +                          },
      +                          "strikeSelector": {
      +                            "properties": {
      +                              "distance": {
      +                                "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                                "type": "number"
      +                              },
      +                              "distanceType": {
      +                                "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                                "type": "string"
      +                              }
      +                            },
      +                            "required": [
      +                              "distanceType",
      +                              "distance"
      +                            ],
      +                            "type": "object"
      +                          }
      +                        },
      +                        "required": [
      +                          "optionType",
      +                          "direction",
      +                          "expirationSelector",
      +                          "strikeSelector"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      "minItems": 1,
      +                      "type": "array"
      +                    },
      +                    "spreadType": {
      +                      "enum": [
      +                        "vertical",
      +                        "calendar",
      +                        "diagonal",
      +                        "ironCondor",
      +                        "straddle",
      +                        "strangle",
      +                        "custom"
      +                      ],
      +                      "type": "string"
      +                    },
      +                    "underlyingSymbol": {
      +                      "type": "string"
      +                    },
      +                    "widthConstraint": {
      +                      "additionalProperties": false,
      +                      "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +                      "properties": {
      +                        "minWidthDollars": {
      +                          "exclusiveMinimum": 0,
      +                          "type": "number"
      +                        },
      +                        "minWidthPercent": {
      +                          "exclusiveMinimum": 0,
      +                          "type": "number"
      +                        }
      +                      },
      +                      "type": "object"
      +                    }
      +                  },
      +                  "required": [
      +                    "legs"
      +                  ],
      +                  "type": "object"
      +                },
      +                "type": {
      +                  "const": "OpenOption",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "builder"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
      +              "properties": {
      +                "allocationPolicy": {
      +                  "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
      +                  "oneOf": [
      +                    {
      +                      "additionalProperties": false,
      +                      "properties": {
      +                        "covarianceShrinkage": {
      +                          "maximum": 1,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "estimatedTransactionCostBps": {
      +                          "maximum": 10000,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "expectedReturnShrinkage": {
      +                          "maximum": 1,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "lookbackPeriods": {
      +                          "maximum": 5000,
      +                          "minimum": 2,
      +                          "type": "integer"
      +                        },
      +                        "minimumObservations": {
      +                          "maximum": 5000,
      +                          "minimum": 2,
      +                          "type": "integer"
      +                        },
      +                        "riskAversion": {
      +                          "maximum": 1000,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "turnoverPenalty": {
      +                          "maximum": 10000,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "MeanVariance",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "lookbackPeriods",
      +                        "minimumObservations",
      +                        "riskAversion",
      +                        "expectedReturnShrinkage",
      +                        "covarianceShrinkage",
      +                        "turnoverPenalty",
      +                        "estimatedTransactionCostBps"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": false,
      +                      "properties": {
      +                        "covarianceShrinkage": {
      +                          "maximum": 1,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "estimatedTransactionCostBps": {
      +                          "maximum": 10000,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "lookbackPeriods": {
      +                          "maximum": 5000,
      +                          "minimum": 2,
      +                          "type": "integer"
      +                        },
      +                        "minimumObservations": {
      +                          "maximum": 5000,
      +                          "minimum": 2,
      +                          "type": "integer"
      +                        },
      +                        "turnoverPenalty": {
      +                          "maximum": 10000,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "RiskParity",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "lookbackPeriods",
      +                        "minimumObservations",
      +                        "covarianceShrinkage",
      +                        "turnoverPenalty",
      +                        "estimatedTransactionCostBps"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": false,
      +                      "properties": {
      +                        "covarianceShrinkage": {
      +                          "maximum": 1,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "estimatedTransactionCostBps": {
      +                          "maximum": 10000,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "lookbackPeriods": {
      +                          "maximum": 5000,
      +                          "minimum": 2,
      +                          "type": "integer"
      +                        },
      +                        "minimumObservations": {
      +                          "maximum": 5000,
      +                          "minimum": 2,
      +                          "type": "integer"
      +                        },
      +                        "turnoverPenalty": {
      +                          "maximum": 10000,
      +                          "minimum": 0,
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "MaximumDiversification",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "lookbackPeriods",
      +                        "minimumObservations",
      +                        "covarianceShrinkage",
      +                        "turnoverPenalty",
      +                        "estimatedTransactionCostBps"
      +                      ],
      +                      "type": "object"
      +                    }
      +                  ]
      +                },
      +                "exposurePolicy": {
      +                  "additionalProperties": false,
      +                  "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
      +                  "properties": {
      +                    "covarianceShrinkage": {
      +                      "maximum": 1,
      +                      "minimum": 0,
      +                      "type": "number"
      +                    },
      +                    "estimatedTransactionCostBps": {
      +                      "maximum": 10000,
      +                      "minimum": 0,
      +                      "type": "number"
      +                    },
      +                    "lookbackPeriods": {
      +                      "maximum": 5000,
      +                      "minimum": 2,
      +                      "type": "integer"
      +                    },
      +                    "minimumObservations": {
      +                      "maximum": 5000,
      +                      "minimum": 2,
      +                      "type": "integer"
      +                    },
      +                    "targetAnnualizedVolatilityPercent": {
      +                      "maximum": 1000,
      +                      "minimum": 0,
      +                      "type": "number"
      +                    },
      +                    "type": {
      +                      "const": "VolatilityTarget",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type",
      +                    "lookbackPeriods",
      +                    "minimumObservations",
      +                    "covarianceShrinkage",
      +                    "targetAnnualizedVolatilityPercent",
      +                    "estimatedTransactionCostBps"
      +                  ],
      +                  "type": "object"
      +                },
      +                "limit": {
      +                  "minimum": 1,
      +                  "type": "number"
      +                },
      +                "perNameAllocation": {
      +                  "additionalProperties": true,
      +                  "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +                  "properties": {
      +                    "amount": {
      +                      "type": "number"
      +                    },
      +                    "type": {
      +                      "enum": [
      +                        "dollars",
      +                        "percent of portfolio",
      +                        "percent of buying power",
      +                        "contracts"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type",
      +                    "amount"
      +                  ],
      +                  "type": "object"
      +                },
      +                "pipeline": {
      +                  "items": {
      +                    "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                    "oneOf": [
      +                      {
      +                        "additionalProperties": true,
      +                        "properties": {
      +                          "condition": {
      +                            "$ref": "#/$defs/condition"
      +                          },
      +                          "type": {
      +                            "const": "Filter",
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "type",
      +                          "condition"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      {
      +                        "additionalProperties": true,
      +                        "properties": {
      +                          "direction": {
      +                            "enum": [
      +                              "Highest",
      +                              "Lowest"
      +                            ],
      +                            "type": "string"
      +                          },
      +                          "limit": {
      +                            "minimum": 1,
      +                            "type": "number"
      +                          },
      +                          "metric": {
      +                            "$ref": "#/$defs/indicator"
      +                          },
      +                          "type": {
      +                            "const": "SelectTop",
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "type",
      +                          "metric",
      +                          "limit",
      +                          "direction"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      {
      +                        "additionalProperties": true,
      +                        "properties": {
      +                          "direction": {
      +                            "enum": [
      +                              "Highest",
      +                              "Lowest"
      +                            ],
      +                            "type": "string"
      +                          },
      +                          "metric": {
      +                            "$ref": "#/$defs/indicator"
      +                          },
      +                          "percentile": {
      +                            "maximum": 100,
      +                            "minimum": 0,
      +                            "type": "number"
      +                          },
      +                          "type": {
      +                            "const": "SelectPercentile",
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "type",
      +                          "metric",
      +                          "percentile",
      +                          "direction"
      +                        ],
      +                        "type": "object"
      +                      }
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "type": "array"
      +                },
      +                "positionScope": {
      +                  "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
      +                  "enum": [
      +                    "portfolio",
      +                    "strategy"
      +                  ],
      +                  "type": "string"
      +                },
      +                "sleeves": {
      +                  "items": {
      +                    "additionalProperties": true,
      +                    "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
      +                    "properties": {
      +                      "limit": {
      +                        "minimum": 1,
      +                        "type": "number"
      +                      },
      +                      "name": {
      +                        "type": "string"
      +                      },
      +                      "perNameAllocation": {
      +                        "additionalProperties": true,
      +                        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
      +                        "properties": {
      +                          "amount": {
      +                            "type": "number"
      +                          },
      +                          "type": {
      +                            "enum": [
      +                              "dollars",
      +                              "percent of portfolio",
      +                              "percent of buying power",
      +                              "contracts"
      +                            ],
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "type",
      +                          "amount"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      "pipeline": {
      +                        "items": {
      +                          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
      +                          "oneOf": [
      +                            {
      +                              "additionalProperties": true,
      +                              "properties": {
      +                                "condition": {
      +                                  "$ref": "#/$defs/condition"
      +                                },
      +                                "type": {
      +                                  "const": "Filter",
      +                                  "type": "string"
      +                                }
      +                              },
      +                              "required": [
      +                                "type",
      +                                "condition"
      +                              ],
      +                              "type": "object"
      +                            },
      +                            {
      +                              "additionalProperties": true,
      +                              "properties": {
      +                                "direction": {
      +                                  "enum": [
      +                                    "Highest",
      +                                    "Lowest"
      +                                  ],
      +                                  "type": "string"
      +                                },
      +                                "limit": {
      +                                  "minimum": 1,
      +                                  "type": "number"
      +                                },
      +                                "metric": {
      +                                  "$ref": "#/$defs/indicator"
      +                                },
      +                                "type": {
      +                                  "const": "SelectTop",
      +                                  "type": "string"
      +                                }
      +                              },
      +                              "required": [
      +                                "type",
      +                                "metric",
      +                                "limit",
      +                                "direction"
      +                              ],
      +                              "type": "object"
      +                            },
      +                            {
      +                              "additionalProperties": true,
      +                              "properties": {
      +                                "direction": {
      +                                  "enum": [
      +                                    "Highest",
      +                                    "Lowest"
      +                                  ],
      +                                  "type": "string"
      +                                },
      +                                "metric": {
      +                                  "$ref": "#/$defs/indicator"
      +                                },
      +                                "percentile": {
      +                                  "maximum": 100,
      +                                  "minimum": 0,
      +                                  "type": "number"
      +                                },
      +                                "type": {
      +                                  "const": "SelectPercentile",
      +                                  "type": "string"
      +                                }
      +                              },
      +                              "required": [
      +                                "type",
      +                                "metric",
      +                                "percentile",
      +                                "direction"
      +                              ],
      +                              "type": "object"
      +                            }
      +                          ],
      +                          "type": "object"
      +                        },
      +                        "type": "array"
      +                      },
      +                      "structureTemplates": {
      +                        "items": {
      +                          "additionalProperties": true,
      +                          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      +                          "properties": {
      +                            "eligibility": {
      +                              "$ref": "#/$defs/condition"
      +                            },
      +                            "legs": {
      +                              "items": {
      +                                "additionalProperties": true,
      +                                "description": "Single leg of an option builder.",
      +                                "properties": {
      +                                  "direction": {
      +                                    "enum": [
      +                                      "long",
      +                                      "short"
      +                                    ],
      +                                    "type": "string"
      +                                  },
      +                                  "expirationRange": {
      +                                    "additionalProperties": true,
      +                                    "type": "object"
      +                                  },
      +                                  "expirationSelector": {
      +                                    "properties": {
      +                                      "maxDaysToExpiration": {
      +                                        "minimum": 0,
      +                                        "type": "number"
      +                                      },
      +                                      "minDaysToExpiration": {
      +                                        "minimum": 0,
      +                                        "type": "number"
      +                                      },
      +                                      "preference": {
      +                                        "enum": [
      +                                          "nearest",
      +                                          "middle",
      +                                          "furthest"
      +                                        ],
      +                                        "type": "string"
      +                                      }
      +                                    },
      +                                    "required": [
      +                                      "minDaysToExpiration",
      +                                      "maxDaysToExpiration",
      +                                      "preference"
      +                                    ],
      +                                    "type": "object"
      +                                  },
      +                                  "fallbackStrikeSelector": {
      +                                    "additionalProperties": false,
      +                                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                                    "properties": {
      +                                      "distance": {
      +                                        "type": "number"
      +                                      },
      +                                      "distanceType": {
      +                                        "enum": [
      +                                          "percent",
      +                                          "dollars"
      +                                        ],
      +                                        "type": "string"
      +                                      }
      +                                    },
      +                                    "required": [
      +                                      "distanceType",
      +                                      "distance"
      +                                    ],
      +                                    "type": "object"
      +                                  },
      +                                  "greekFilter": {
      +                                    "additionalProperties": true,
      +                                    "description": "Optional min/max constraints on Greeks during resolution.",
      +                                    "type": "object"
      +                                  },
      +                                  "liquidityFilter": {
      +                                    "additionalProperties": false,
      +                                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                                    "properties": {
      +                                      "maxSpreadAbsolute": {
      +                                        "type": "number"
      +                                      },
      +                                      "maxSpreadPct": {
      +                                        "type": "number"
      +                                      },
      +                                      "minBid": {
      +                                        "type": "number"
      +                                      }
      +                                    },
      +                                    "type": "object"
      +                                  },
      +                                  "optionType": {
      +                                    "enum": [
      +                                      "call",
      +                                      "put"
      +                                    ],
      +                                    "type": "string"
      +                                  },
      +                                  "ratio": {
      +                                    "type": "number"
      +                                  },
      +                                  "strikeRange": {
      +                                    "additionalProperties": true,
      +                                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                                    "type": "object"
      +                                  },
      +                                  "strikeSelector": {
      +                                    "properties": {
      +                                      "distance": {
      +                                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                                        "type": "number"
      +                                      },
      +                                      "distanceType": {
      +                                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                                        "type": "string"
      +                                      }
      +                                    },
      +                                    "required": [
      +                                      "distanceType",
      +                                      "distance"
      +                                    ],
      +                                    "type": "object"
      +                                  }
      +                                },
      +                                "required": [
      +                                  "optionType",
      +                                  "direction",
      +                                  "expirationSelector",
      +                                  "strikeSelector"
      +                                ],
      +                                "type": "object"
      +                              },
      +                              "minItems": 1,
      +                              "type": "array"
      +                            },
      +                            "name": {
      +                              "type": "string"
      +                            },
      +                            "spreadType": {
      +                              "enum": [
      +                                "vertical",
      +                                "calendar",
      +                                "diagonal",
      +                                "ironCondor",
      +                                "straddle",
      +                                "strangle",
      +                                "custom"
      +                              ],
      +                              "type": "string"
      +                            },
      +                            "widthConstraint": {
      +                              "additionalProperties": false,
      +                              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +                              "properties": {
      +                                "minWidthDollars": {
      +                                  "exclusiveMinimum": 0,
      +                                  "type": "number"
      +                                },
      +                                "minWidthPercent": {
      +                                  "exclusiveMinimum": 0,
      +                                  "type": "number"
      +                                }
      +                              },
      +                              "type": "object"
      +                            }
      +                          },
      +                          "required": [
      +                            "legs"
      +                          ],
      +                          "type": "object"
      +                        },
      +                        "minItems": 1,
      +                        "type": "array"
      +                      },
      +                      "universe": {
      +                        "additionalProperties": true,
      +                        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +                        "properties": {
      +                          "assets": {
      +                            "items": {
      +                              "additionalProperties": true,
      +                              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                              "properties": {
      +                                "name": {
      +                                  "type": "string"
      +                                },
      +                                "symbol": {
      +                                  "type": "string"
      +                                },
      +                                "type": {
      +                                  "enum": [
      +                                    "Stock",
      +                                    "Cryptocurrency",
      +                                    "Option",
      +                                    "Other"
      +                                  ],
      +                                  "type": "string"
      +                                }
      +                              },
      +                              "required": [
      +                                "type",
      +                                "symbol"
      +                              ],
      +                              "type": "object"
      +                            },
      +                            "type": "array"
      +                          },
      +                          "source": {
      +                            "enum": [
      +                              "ALL_US_STOCKS",
      +                              "SP500",
      +                              "NASDAQ100",
      +                              "DJIA",
      +                              "CRYPTO",
      +                              "SPECIFIC_ASSETS"
      +                            ],
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "source"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      "weightIndicator": {
      +                        "$ref": "#/$defs/indicator"
      +                      }
      +                    },
      +                    "required": [
      +                      "name"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "type": "array"
      +                },
      +                "structureTemplates": {
      +                  "items": {
      +                    "additionalProperties": true,
      +                    "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
      +                    "properties": {
      +                      "eligibility": {
      +                        "$ref": "#/$defs/condition"
      +                      },
      +                      "legs": {
      +                        "items": {
      +                          "additionalProperties": true,
      +                          "description": "Single leg of an option builder.",
      +                          "properties": {
      +                            "direction": {
      +                              "enum": [
      +                                "long",
      +                                "short"
      +                              ],
      +                              "type": "string"
      +                            },
      +                            "expirationRange": {
      +                              "additionalProperties": true,
      +                              "type": "object"
      +                            },
      +                            "expirationSelector": {
      +                              "properties": {
      +                                "maxDaysToExpiration": {
      +                                  "minimum": 0,
      +                                  "type": "number"
      +                                },
      +                                "minDaysToExpiration": {
      +                                  "minimum": 0,
      +                                  "type": "number"
      +                                },
      +                                "preference": {
      +                                  "enum": [
      +                                    "nearest",
      +                                    "middle",
      +                                    "furthest"
      +                                  ],
      +                                  "type": "string"
      +                                }
      +                              },
      +                              "required": [
      +                                "minDaysToExpiration",
      +                                "maxDaysToExpiration",
      +                                "preference"
      +                              ],
      +                              "type": "object"
      +                            },
      +                            "fallbackStrikeSelector": {
      +                              "additionalProperties": false,
      +                              "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
      +                              "properties": {
      +                                "distance": {
      +                                  "type": "number"
      +                                },
      +                                "distanceType": {
      +                                  "enum": [
      +                                    "percent",
      +                                    "dollars"
      +                                  ],
      +                                  "type": "string"
      +                                }
      +                              },
      +                              "required": [
      +                                "distanceType",
      +                                "distance"
      +                              ],
      +                              "type": "object"
      +                            },
      +                            "greekFilter": {
      +                              "additionalProperties": true,
      +                              "description": "Optional min/max constraints on Greeks during resolution.",
      +                              "type": "object"
      +                            },
      +                            "liquidityFilter": {
      +                              "additionalProperties": false,
      +                              "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
      +                              "properties": {
      +                                "maxSpreadAbsolute": {
      +                                  "type": "number"
      +                                },
      +                                "maxSpreadPct": {
      +                                  "type": "number"
      +                                },
      +                                "minBid": {
      +                                  "type": "number"
      +                                }
      +                              },
      +                              "type": "object"
      +                            },
      +                            "optionType": {
      +                              "enum": [
      +                                "call",
      +                                "put"
      +                              ],
      +                              "type": "string"
      +                            },
      +                            "ratio": {
      +                              "type": "number"
      +                            },
      +                            "strikeRange": {
      +                              "additionalProperties": true,
      +                              "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
      +                              "type": "object"
      +                            },
      +                            "strikeSelector": {
      +                              "properties": {
      +                                "distance": {
      +                                  "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
      +                                  "type": "number"
      +                                },
      +                                "distanceType": {
      +                                  "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
      +                                  "type": "string"
      +                                }
      +                              },
      +                              "required": [
      +                                "distanceType",
      +                                "distance"
      +                              ],
      +                              "type": "object"
      +                            }
      +                          },
      +                          "required": [
      +                            "optionType",
      +                            "direction",
      +                            "expirationSelector",
      +                            "strikeSelector"
      +                          ],
      +                          "type": "object"
      +                        },
      +                        "minItems": 1,
      +                        "type": "array"
      +                      },
      +                      "name": {
      +                        "type": "string"
      +                      },
      +                      "spreadType": {
      +                        "enum": [
      +                          "vertical",
      +                          "calendar",
      +                          "diagonal",
      +                          "ironCondor",
      +                          "straddle",
      +                          "strangle",
      +                          "custom"
      +                        ],
      +                        "type": "string"
      +                      },
      +                      "widthConstraint": {
      +                        "additionalProperties": false,
      +                        "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
      +                        "properties": {
      +                          "minWidthDollars": {
      +                            "exclusiveMinimum": 0,
      +                            "type": "number"
      +                          },
      +                          "minWidthPercent": {
      +                            "exclusiveMinimum": 0,
      +                            "type": "number"
      +                          }
      +                        },
      +                        "type": "object"
      +                      }
      +                    },
      +                    "required": [
      +                      "legs"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "minItems": 1,
      +                  "type": "array"
      +                },
      +                "totalBudget": {
      +                  "additionalProperties": true,
      +                  "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
      +                  "properties": {
      +                    "amount": {
      +                      "minimum": 0,
      +                      "type": "number"
      +                    },
      +                    "type": {
      +                      "enum": [
      +                        "dollars",
      +                        "percent of portfolio"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type",
      +                    "amount"
      +                  ],
      +                  "type": "object"
      +                },
      +                "type": {
      +                  "const": "RebalanceOption",
      +                  "type": "string"
      +                },
      +                "universe": {
      +                  "additionalProperties": true,
      +                  "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
      +                  "properties": {
      +                    "assets": {
      +                      "items": {
      +                        "additionalProperties": true,
      +                        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
      +                        "properties": {
      +                          "name": {
      +                            "type": "string"
      +                          },
      +                          "symbol": {
      +                            "type": "string"
      +                          },
      +                          "type": {
      +                            "enum": [
      +                              "Stock",
      +                              "Cryptocurrency",
      +                              "Option",
      +                              "Other"
      +                            ],
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "type",
      +                          "symbol"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      "type": "array"
      +                    },
      +                    "source": {
      +                      "enum": [
      +                        "ALL_US_STOCKS",
      +                        "SP500",
      +                        "NASDAQ100",
      +                        "DJIA",
      +                        "CRYPTO",
      +                        "SPECIFIC_ASSETS"
      +                      ],
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "source"
      +                  ],
      +                  "type": "object"
      +                },
      +                "weightIndicator": {
      +                  "$ref": "#/$defs/indicator"
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "universe",
      +                "pipeline",
      +                "weightIndicator",
      +                "structureTemplates"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": true,
      +              "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
      +              "properties": {
      +                "closeScope": {
      +                  "enum": [
      +                    "spread",
      +                    "leg"
      +                  ],
      +                  "type": "string"
      +                },
      +                "direction": {
      +                  "enum": [
      +                    "long",
      +                    "short"
      +                  ],
      +                  "type": "string"
      +                },
      +                "optionType": {
      +                  "enum": [
      +                    "call",
      +                    "put"
      +                  ],
      +                  "type": "string"
      +                },
      +                "quantity": {
      +                  "additionalProperties": true,
      +                  "description": "How many contracts to close. Defaults to all matching when omitted.",
      +                  "type": "object"
      +                },
      +                "spreadType": {
      +                  "enum": [
      +                    "vertical",
      +                    "calendar",
      +                    "diagonal",
      +                    "ironCondor",
      +                    "straddle",
      +                    "strangle",
      +                    "custom"
      +                  ],
      +                  "type": "string"
      +                },
      +                "triggers": {
      +                  "items": {
      +                    "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
      +                    "oneOf": [
      +                      {
      +                        "additionalProperties": true,
      +                        "properties": {
      +                          "maxPnlPercent": {
      +                            "type": "number"
      +                          },
      +                          "minPnlPercent": {
      +                            "type": "number"
      +                          },
      +                          "type": {
      +                            "const": "pnl",
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "type"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      {
      +                        "additionalProperties": true,
      +                        "properties": {
      +                          "maxDte": {
      +                            "type": "number"
      +                          },
      +                          "minDte": {
      +                            "type": "number"
      +                          },
      +                          "type": {
      +                            "const": "dte",
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "type"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      {
      +                        "additionalProperties": true,
      +                        "properties": {
      +                          "maxDaysHeld": {
      +                            "type": "number"
      +                          },
      +                          "minDaysHeld": {
      +                            "type": "number"
      +                          },
      +                          "type": {
      +                            "const": "daysHeld",
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "type"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      {
      +                        "additionalProperties": true,
      +                        "properties": {
      +                          "maxIv": {
      +                            "type": "number"
      +                          },
      +                          "maxSpreadDelta": {
      +                            "type": "number"
      +                          },
      +                          "maxSpreadTheta": {
      +                            "type": "number"
      +                          },
      +                          "minIv": {
      +                            "type": "number"
      +                          },
      +                          "minSpreadDelta": {
      +                            "type": "number"
      +                          },
      +                          "minSpreadTheta": {
      +                            "type": "number"
      +                          },
      +                          "type": {
      +                            "const": "greeks",
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "type"
      +                        ],
      +                        "type": "object"
      +                      }
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "type": "array"
      +                },
      +                "type": {
      +                  "const": "CloseOption",
      +                  "type": "string"
      +                },
      +                "underlyings": {
      +                  "items": {
      +                    "type": "string"
      +                  },
      +                  "type": "array"
      +                }
      +              },
      +              "required": [
      +                "type"
      +              ],
      +              "type": "object"
      +            }
      +          ],
      +          "type": "object"
      +        },
      +        "active": {
      +          "description": "Whether the strategy is active (default true).",
      +          "type": "boolean"
      +        },
      +        "condition": {
      +          "$ref": "#/$defs/condition"
      +        },
      +        "name": {
      +          "description": "Human-readable strategy name.",
      +          "type": "string"
      +        },
      +        "orderExecution": {
      +          "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.",
      +          "oneOf": [
      +            {
      +              "additionalProperties": false,
      +              "properties": {
      +                "type": {
      +                  "const": "Market",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "type"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": false,
      +              "properties": {
      +                "price": {
      +                  "oneOf": [
      +                    {
      +                      "additionalProperties": false,
      +                      "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
      +                      "properties": {
      +                        "amount": {
      +                          "minimum": 1e-8,
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "UnitPrice",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "amount"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": false,
      +                      "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
      +                      "properties": {
      +                        "amount": {
      +                          "minimum": 1e-8,
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "MinimumNetCredit",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "amount"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": false,
      +                      "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
      +                      "properties": {
      +                        "amount": {
      +                          "minimum": 1e-8,
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "MaximumNetDebit",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "amount"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": false,
      +                      "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
      +                      "properties": {
      +                        "reference": {
      +                          "const": "Current",
      +                          "type": "string"
      +                        },
      +                        "type": {
      +                          "const": "QuoteRelative",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "reference"
      +                      ],
      +                      "type": "object"
      +                    }
      +                  ]
      +                },
      +                "type": {
      +                  "const": "Limit",
      +                  "type": "string"
      +                },
      +                "workingTime": {
      +                  "oneOf": [
      +                    {
      +                      "additionalProperties": false,
      +                      "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
      +                      "properties": {
      +                        "type": {
      +                          "const": "Day",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "additionalProperties": false,
      +                      "properties": {
      +                        "minutes": {
      +                          "minimum": 1,
      +                          "type": "number"
      +                        },
      +                        "type": {
      +                          "const": "Minutes",
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "type",
      +                        "minutes"
      +                      ],
      +                      "type": "object"
      +                    }
      +                  ]
      +                }
      +              },
      +              "required": [
      +                "type",
      +                "price"
      +              ],
      +              "type": "object"
      +            }
      +          ],
      +          "type": "object"
      +        }
      +      },
      +      "required": [
      +        "name",
      +        "condition",
      +        "action"
      +      ],
      +      "type": "object"
      +    },
      +    "type": "array"
      +  },
      +  "targetStrategyId": {
      +    "type": "string"
      +  },
      +  "targetStrategyName": {
      +    "type": "string"
      +  },
      +  "type": {
      +    "enum": [
      +      "deploy",
      +      "undeploy",
      +      "addStrategies",
      +      "removeStrategies",
      +      "replaceStrategy",
      +      "replaceStrategies",
      +      "setDeploymentFrequency",
      +      "rename",
      +      "delete"
      +    ],
      +    "type": "string"
      +  }
      +}
    • addedInput schema / properties / operations / items / required
      Added value: +[
      +  "type",
      +  "portfolioId"
      +]
  8. First observed

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and discharges it thoroughly: delete permanently removes and archives linked deployments, confirmLive:true is required only after explicit user confirmation, deploying a chat portfolio creates a simulated paper portfolio that can never place a real broker order, and the LLM-cost implications of both the structured path and LaunchAgent are disclosed. Mutation, side effects, safety gates, and cost are all covered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but every sentence earns its place given the tool's eight-operation complexity. It front-loads the operation inventory and interleaves safety-critical notes (confirmLive, delete semantics, paper-vs-live) with execution semantics. It could marginally improve with paragraph breaks and avoids re-stating orderExecution text that already appears in the schema, but as a single dense block it remains readable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a highly complex, destructive mutation tool with zero annotations and no output schema, the description is complete: per-operation requirements, deletion side effects, confirmation gates, deployment safety boundaries, cost disclosure, and strategy-object semantics are all present. The one minor gap — no return-value description — is acceptable for a mutation tool, and the deep condition/indicator structure is already fully documented in the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds genuine value beyond the schema: it cross-references the create_portfolio strategy shape, clarifies that orderExecution defaults to Market and QuoteRelative executes immediately, and explains the RebalanceOption positionScope portfolio-vs-strategy choice. The setDeploymentFrequency enum values remain unexplained, but the schema-level descriptions already carry most of the burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening line enumerates eight precise verb+resource operations — deploy, undeploy, rename, delete, add/remove/replace strategies, set deployment frequency — leaving zero ambiguity about scope. The tool's span of mutations cleanly distinguishes it from creation (create_portfolio) and read (get_portfolio) siblings without needing to name them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear workflow context: fetch the portfolio first and use IDs from the returned strategies array for removals, pass finished strategy objects via strategyObjects for deterministic zero-cost ingestion, and prefer the structured operations path. It also draws a sharp boundary on when deploy creates a paper vs live portfolio. It stops short of explicitly naming sibling alternatives to avoid, so it gets a 4 rather than a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.