Skip to main content
Glama

NexusTrade Financial MCP

build_portfolio

Preview/builder twin of create_portfolio. Runs the SAME construction + per-strategy validation (Portfolio/Strategy/Condition/Indicator) as create_portfolio but PERSISTS NOTHING. Accepts the same IPortfolio JSON (all fields optional so partial drafts can be checked). Returns the canonicalized portfolio plus a per-component issue list (path + component + message) so you can see exactly which strategy/condition/indicator is wrong before committing. A draft that previews clean cannot fail on create_portfolio. Zero research token cost.

Custom data sources: none yet. Create one with run_compute (pass name and point_kind to promote its signal output directly), or use dataset_to_indicator with a saved dataset; then reference customIndicatorId in create_portfolio.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
mainNoMark as main portfolio (optional).
nameNoPortfolio name (required).
messageNoOPTIONAL natural-language fallback. If provided WITHOUT name/strategies, the server runs a paid LLM to translate NL→portfolio. Prefer the structured fields (no LLM cost).
strategiesNoArray of strategies. Each strategy is { name, condition, action, orderExecution? }. RebalanceOption actions may include action.positionScope (portfolio | strategy). 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. See $defs.strategy / $defs.condition / $defs/indicator.
initialValueNoStarting cash (default 10000). Use 0 for agent-only / LaunchAgent portfolios that never trade capital.
alertsEnabledNo
supportsCryptoNo
supportsFractionalSharesNo

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. Changed11 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 / strategies / description
      Previous value: -"Array of strategies. Each strategy is { name, condition, action, orderExecution? }. RebalanceOption actions may include action.positionScope (portfolio | strategy). 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. See $defs.strategy / $defs.condition / $defs/indicator."New value: +"Array of strategies. Each strategy is { name, condition, action, orderExecution? }. RebalanceOption actions may include action.positionScope (portfolio | strategy). 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. See $defs.strategy / $defs.condition / $defs/indicator."
    • changedInput schema / properties / strategies / 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 / strategies / 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 / strategies / 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. Changed8 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 / strategies / 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. Changed6 schema fields changed
    • addedInput schema / $defs / orderExecution
      Added value: +{
      +  "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"
      +}
    • changedInput schema / $defs / strategy / description
      Previous value: -"A trading strategy: a trigger condition + an action to take when the condition is true."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. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
    • addedInput schema / $defs / strategy / properties / orderExecution
      Added value: +{
      +  "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"
      +}
    • changedInput schema / properties / strategies / description
      Previous value: -"Array of strategies. Each strategy is { name, condition, action }. RebalanceOption actions may include action.positionScope (portfolio | strategy). See $defs.strategy / $defs.condition / $defs.indicator."New value: +"Array of strategies. Each strategy is { name, condition, action, orderExecution? }. RebalanceOption actions may include action.positionScope (portfolio | strategy). 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. See $defs.strategy / $defs.condition / $defs/indicator."
    • changedInput schema / properties / strategies / items / description
      Previous value: -"A trading strategy: a trigger condition + an action to take when the condition is true."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. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
    • addedInput schema / properties / strategies / items / properties / orderExecution
      Added value: +{
      +  "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"
      +}
  8. Changed6 schema fields changed
    • changedInput schema / $defs / condition / description
      Previous value: -"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)."New value: +"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."
    • changedInput schema / $defs / condition / properties / conditions / description
      Previous value: -"And / Or / Multi only: nested conditions."New value: +"And / Or / Multi / Then only: nested conditions. Then reads them in order (at least 2)."
    • changedInput schema / $defs / condition / properties / type / enum
      Previous value: -[
      -  "And",
      -  "Or",
      -  "Base",
      -  "Multi"
      -]New value: +[
      +  "And",
      +  "Or",
      +  "Base",
      +  "Multi",
      +  "Then"
      +]
    • addedInput schema / $defs / condition / properties / window
      Added value: +{
      +  "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"
      +}
    • 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), 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), 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."
    • 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",
      -  "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",
      +  "OptionGrossExposurePercent"
      +]
  9. First observed

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations provided, the description carries the full burden and delivers: it discloses the non-persisting side effect, validation equivalence with create_portfolio, the exact return payload (canonicalized portfolio + per-component issue list with path/component/message), the commit-safety guarantee, and 'Zero research token cost.' This is rich behavioral disclosure beyond any structured field.

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?

Two tight paragraphs; the first front-loads identity, behavior, input, output, and cost in six dense sentences. The second paragraph on custom data sources is slightly tangential to build_portfolio itself but is relevant to validation coverage. Overall high signal density with little waste.

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

Completeness4/5

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

Given no output schema and no annotations, the description still explains the return value (canonicalized portfolio + issue list) and the absence of side effects. Minor gaps: it does not explicitly state that no portfolio ID is returned because nothing persists, and success/failure is implied rather than stated. Near-complete for a preview tool.

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 63%, so the schema does not fully document every parameter, but the description adds the critical orientation: 'Accepts the same IPortfolio JSON' and 'all fields optional so partial drafts can be checked.' The cross-reference to create_portfolio's schema plus the partial-draft permission is meaning the schema alone does not provide.

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?

States a specific verb and resource: 'Preview/builder twin of create_portfolio', 'Runs the SAME construction + per-strategy validation', 'PERSISTS NOTHING.' This clearly differentiates it from the sibling create_portfolio and other portfolio tools. An agent can tell exactly what the tool does without opening the schema.

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 establishes when to use the tool: check a draft 'before committing' to see 'exactly which strategy/condition/indicator is wrong,' and guarantees that 'a draft that previews clean cannot fail on create_portfolio.' This maps the preview→create workflow clearly, though it does not explicitly enumerate when-not cases or name alternatives like backtest_portfolio.

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.