NexusTrade Financial MCP
Server Details
Quant research, backtesting, marketplace subscriptions, editable forks, copy trading, and execution.
Glama couldn't complete the latest health check. If this server requires authentication, missing or expired test credentials may be the cause. A test profile lets Glama authenticate for health checks and discover tools; it is separate from your personal connections.
If you are the author, claim ownership, then add or update a test profile under Admin → Test Profile.
- Status
- Unhealthy
- Uptime
- 3.2% over 59 days
- OAuth
- Works in Glama
- Last Tested
- Transport
- Streamable HTTP
- URL
- Repository
- austin-starks/nexustrade-ts
- GitHub Stars
- 8
- Server Listing
- NexusTrade Financial MCP
TDQS
Scored across 24 tools
Several tools share the same underlying intent: create_portfolio, build_portfolio, create_portfolio_variant, clone_strategies_to_portfolio, fork_shared_portfolio and update_portfolio all create or mutate portfolios, and send_chat_message vs send_agent_message / get_agent vs get_agent_trajectory also sit close together. The verbose descriptions do help an agent pick correctly, but the boundaries require careful reading rather than being self-evident.
All 24 tools use snake_case, verb-leading names (create_/get_/list_/query_/send_/approve_/reject_/archive_), so the pattern is predictable and easy to scan. Minor deviations are longer three-part names like approve_agent_plan and send_agent_message and the build/create synonym pair, but nothing breaks the convention.
At 24 tools the server lands in the heavy range; while it legitimately spans two sub-domains (portfolio/backtest and Aurora agent management), each sub-domain could be tightened. The count is defensible but borderline, with visible redundancy among the portfolio-creation tools.
The surface covers the domain well: portfolios have create/preview/read/list/update/delete/clone/fork, agents have create/read/list/archive/unarchive/star/stop/message/trajectory, and backtests have submit/status/history. Gaps are minor edge cases only — no backtest cancel/delete and no hard agent delete — which agents can work around.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
- Changed
build_portfolio1 field changed- changed
Input schema / $defs / indicator / properties / metric / descriptionPrevious 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."New value: +"PoliticalTrades: NetAmount, BuyAmount, SellAmount, BuyCount, SellCount, DistinctBuyers, Held. InstitutionalHoldings: HolderCount, TotalShares, TotalValue, BookSharePercent, 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."
- Changed
create_portfolio1 field changed- changed
Input schema / $defs / indicator / properties / metric / descriptionPrevious 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."New value: +"PoliticalTrades: NetAmount, BuyAmount, SellAmount, BuyCount, SellCount, DistinctBuyers, Held. InstitutionalHoldings: HolderCount, TotalShares, TotalValue, BookSharePercent, 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."
- Changed
update_portfolio1 field changed- changed
Input schema / $defs / indicator / properties / metric / descriptionPrevious 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."New value: +"PoliticalTrades: NetAmount, BuyAmount, SellAmount, BuyCount, SellCount, DistinctBuyers, Held. InstitutionalHoldings: HolderCount, TotalShares, TotalValue, BookSharePercent, 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."
4 tool updates
- Changed
build_portfolio12 fields changed- changed
Input schema / $defs / action / oneOfPrevious 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" - } -]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 the deploymentPercent indicator (0–100; use Value for a constant). 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": { + "$ref": "#/$defs/indicator", + "description": "Indicator returning percent of portfolio NAV to deploy, 0–100 (remainder cash). Use Value for a constant, or PoliticalPurchaseShare with memberId and instrument Equity. Do not use totalBudget here." + }, + "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, then allocate option premium under totalBudget. sizingMode fixedPerName (default) uses weightIndicator only to rank names and perNameAllocation to size each. sizingMode proportionalToWeight splits totalBudget among selected names in proportion to positive weightIndicator values; perNameAllocation is ignored, and sleeves/allocationPolicy/exposurePolicy cannot be combined with it. allocationPolicy may jointly size selected names in fixedPerName mode; exposurePolicy may scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder for shared cadence. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies.", + "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" + }, + "sizingMode": { + "enum": [ + "fixedPerName", + "proportionalToWeight" + ], + "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: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", + "properties": { + "amount": { + "$ref": "#/$defs/indicator", + "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." + }, + "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" + } +] - changed
Input schema / $defs / deploymentBudget / descriptionPrevious value: -"Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars."New value: +"Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires." - added
Input schema / $defs / deploymentBudget / properties / amount / $refAdded value: +"#/$defs/indicator" - added
Input schema / $defs / deploymentBudget / properties / amount / descriptionAdded value: +"Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." - removed
Input schema / $defs / deploymentBudget / properties / amount / minimumRemoved value: -0 - removed
Input schema / $defs / deploymentBudget / properties / amount / typeRemoved value: -"number" - changed
Input schema / $defs / indicator / properties / amountBasis / descriptionPrevious value: -"PoliticalTrades disclosed range endpoint. LowerBound is conservative."New value: +"Disclosed transaction range endpoint. PoliticalPurchaseShare defaults to Midpoint; PoliticalTrades amount metrics default to LowerBound." - changed
Input schema / $defs / indicator / properties / instrument / descriptionPrevious value: -"PoliticalTrades instrument class. Equity excludes confirmed options."New value: +"PoliticalTrades instrument class (Equity, Option, All). PoliticalPurchaseShare requires Equity or Option and returns that side's percent of member-wide public purchases." - changed
Input schema / $defs / indicator / properties / memberId / descriptionPrevious value: -"PoliticalTrades member bioguide id (e.g. P000197). Matches exactly and overrides filer; prefer it when known, because names collide."New value: +"Bioguide member id (e.g. P000197). Required for PoliticalPurchaseShare, whose member-wide public purchase amounts include symbols outside the trading universe; also selects an exact PoliticalTrades member and overrides filer." - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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", - "MinuteBarHigh", - "HeikinAshi", - "MinuteBarLow", - "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" -]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", + "MinuteBarHigh", + "HeikinAshi", + "MinuteBarLow", + "PreviousClosingPrice", + "HighOfDay", + "LowOfDay", + "MinutesUntilClose", + "PriceChangeSinceOpen", + "GapSize", + "GapPercentage", + "TrueRange", + "AverageTrueRange", + "Volume", + "VWAP", + "BullishFairValueGap", + "BearishFairValueGap", + "IndicatorAtMinutesAfterOpen", + "IndicatorWindowAgo", + "IndicatorAtEntry", + "IsIndexMember", + "PoliticalTrades", + "PoliticalPurchaseShare", + "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" +] - changed
Input schema / $defs / strategy / properties / action / oneOfPrevious 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" - } -]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 the deploymentPercent indicator (0–100; use Value for a constant). 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": { + "$ref": "#/$defs/indicator", + "description": "Indicator returning percent of portfolio NAV to deploy, 0–100 (remainder cash). Use Value for a constant, or PoliticalPurchaseShare with memberId and instrument Equity. Do not use totalBudget here." + }, + "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, then allocate option premium under totalBudget. sizingMode fixedPerName (default) uses weightIndicator only to rank names and perNameAllocation to size each. sizingMode proportionalToWeight splits totalBudget among selected names in proportion to positive weightIndicator values; perNameAllocation is ignored, and sleeves/allocationPolicy/exposurePolicy cannot be combined with it. allocationPolicy may jointly size selected names in fixedPerName mode; exposurePolicy may scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder for shared cadence. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies.", + "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" + }, + "sizingMode": { + "enum": [ + "fixedPerName", + "proportionalToWeight" + ], + "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: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", + "properties": { + "amount": { + "$ref": "#/$defs/indicator", + "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." + }, + "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" + } +] - changed
Input schema / properties / strategies / items / properties / action / oneOfPrevious 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" - } -]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 the deploymentPercent indicator (0–100; use Value for a constant). 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": { + "$ref": "#/$defs/indicator", + "description": "Indicator returning percent of portfolio NAV to deploy, 0–100 (remainder cash). Use Value for a constant, or PoliticalPurchaseShare with memberId and instrument Equity. Do not use totalBudget here." + }, + "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, then allocate option premium under totalBudget. sizingMode fixedPerName (default) uses weightIndicator only to rank names and perNameAllocation to size each. sizingMode proportionalToWeight splits totalBudget among selected names in proportion to positive weightIndicator values; perNameAllocation is ignored, and sleeves/allocationPolicy/exposurePolicy cannot be combined with it. allocationPolicy may jointly size selected names in fixedPerName mode; exposurePolicy may scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder for shared cadence. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies.", + "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" + }, + "sizingMode": { + "enum": [ + "fixedPerName", + "proportionalToWeight" + ], + "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: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", + "properties": { + "amount": { + "$ref": "#/$defs/indicator", + "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." + }, + "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" + } +]
- Changed
create_portfolio12 fields changed- changed
Input schema / $defs / action / oneOfPrevious 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" - } -]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 the deploymentPercent indicator (0–100; use Value for a constant). 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": { + "$ref": "#/$defs/indicator", + "description": "Indicator returning percent of portfolio NAV to deploy, 0–100 (remainder cash). Use Value for a constant, or PoliticalPurchaseShare with memberId and instrument Equity. Do not use totalBudget here." + }, + "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, then allocate option premium under totalBudget. sizingMode fixedPerName (default) uses weightIndicator only to rank names and perNameAllocation to size each. sizingMode proportionalToWeight splits totalBudget among selected names in proportion to positive weightIndicator values; perNameAllocation is ignored, and sleeves/allocationPolicy/exposurePolicy cannot be combined with it. allocationPolicy may jointly size selected names in fixedPerName mode; exposurePolicy may scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder for shared cadence. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies.", + "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" + }, + "sizingMode": { + "enum": [ + "fixedPerName", + "proportionalToWeight" + ], + "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: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", + "properties": { + "amount": { + "$ref": "#/$defs/indicator", + "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." + }, + "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" + } +] - changed
Input schema / $defs / deploymentBudget / descriptionPrevious value: -"Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars."New value: +"Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires." - added
Input schema / $defs / deploymentBudget / properties / amount / $refAdded value: +"#/$defs/indicator" - added
Input schema / $defs / deploymentBudget / properties / amount / descriptionAdded value: +"Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." - removed
Input schema / $defs / deploymentBudget / properties / amount / minimumRemoved value: -0 - removed
Input schema / $defs / deploymentBudget / properties / amount / typeRemoved value: -"number" - changed
Input schema / $defs / indicator / properties / amountBasis / descriptionPrevious value: -"PoliticalTrades disclosed range endpoint. LowerBound is conservative."New value: +"Disclosed transaction range endpoint. PoliticalPurchaseShare defaults to Midpoint; PoliticalTrades amount metrics default to LowerBound." - changed
Input schema / $defs / indicator / properties / instrument / descriptionPrevious value: -"PoliticalTrades instrument class. Equity excludes confirmed options."New value: +"PoliticalTrades instrument class (Equity, Option, All). PoliticalPurchaseShare requires Equity or Option and returns that side's percent of member-wide public purchases." - changed
Input schema / $defs / indicator / properties / memberId / descriptionPrevious value: -"PoliticalTrades member bioguide id (e.g. P000197). Matches exactly and overrides filer; prefer it when known, because names collide."New value: +"Bioguide member id (e.g. P000197). Required for PoliticalPurchaseShare, whose member-wide public purchase amounts include symbols outside the trading universe; also selects an exact PoliticalTrades member and overrides filer." - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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", - "MinuteBarHigh", - "HeikinAshi", - "MinuteBarLow", - "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" -]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", + "MinuteBarHigh", + "HeikinAshi", + "MinuteBarLow", + "PreviousClosingPrice", + "HighOfDay", + "LowOfDay", + "MinutesUntilClose", + "PriceChangeSinceOpen", + "GapSize", + "GapPercentage", + "TrueRange", + "AverageTrueRange", + "Volume", + "VWAP", + "BullishFairValueGap", + "BearishFairValueGap", + "IndicatorAtMinutesAfterOpen", + "IndicatorWindowAgo", + "IndicatorAtEntry", + "IsIndexMember", + "PoliticalTrades", + "PoliticalPurchaseShare", + "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" +] - changed
Input schema / $defs / strategy / properties / action / oneOfPrevious 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" - } -]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 the deploymentPercent indicator (0–100; use Value for a constant). 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": { + "$ref": "#/$defs/indicator", + "description": "Indicator returning percent of portfolio NAV to deploy, 0–100 (remainder cash). Use Value for a constant, or PoliticalPurchaseShare with memberId and instrument Equity. Do not use totalBudget here." + }, + "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, then allocate option premium under totalBudget. sizingMode fixedPerName (default) uses weightIndicator only to rank names and perNameAllocation to size each. sizingMode proportionalToWeight splits totalBudget among selected names in proportion to positive weightIndicator values; perNameAllocation is ignored, and sleeves/allocationPolicy/exposurePolicy cannot be combined with it. allocationPolicy may jointly size selected names in fixedPerName mode; exposurePolicy may scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder for shared cadence. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies.", + "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" + }, + "sizingMode": { + "enum": [ + "fixedPerName", + "proportionalToWeight" + ], + "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: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", + "properties": { + "amount": { + "$ref": "#/$defs/indicator", + "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." + }, + "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" + } +] - changed
Input schema / properties / strategies / items / properties / action / oneOfPrevious 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" - } -]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 the deploymentPercent indicator (0–100; use Value for a constant). 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": { + "$ref": "#/$defs/indicator", + "description": "Indicator returning percent of portfolio NAV to deploy, 0–100 (remainder cash). Use Value for a constant, or PoliticalPurchaseShare with memberId and instrument Equity. Do not use totalBudget here." + }, + "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, then allocate option premium under totalBudget. sizingMode fixedPerName (default) uses weightIndicator only to rank names and perNameAllocation to size each. sizingMode proportionalToWeight splits totalBudget among selected names in proportion to positive weightIndicator values; perNameAllocation is ignored, and sleeves/allocationPolicy/exposurePolicy cannot be combined with it. allocationPolicy may jointly size selected names in fixedPerName mode; exposurePolicy may scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder for shared cadence. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies.", + "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" + }, + "sizingMode": { + "enum": [ + "fixedPerName", + "proportionalToWeight" + ], + "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: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", + "properties": { + "amount": { + "$ref": "#/$defs/indicator", + "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." + }, + "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" + } +]
- Changed
create_portfolio_variant1 field changed- changed
Input schema / properties / patches / descriptionPrevious value: -"Optional RFC6902-style ops against canonical IPortfolio JSON. Omit or pass [] for an exact semantic clone. Sizing fields are action-type-specific: DynamicRebalance uses /strategies/N/action/deploymentPercent (0–100 number); RebalanceOption uses /strategies/N/action/totalBudget/amount. Do not patch totalBudget onto DynamicRebalance or deploymentPercent onto RebalanceOption."New value: +"Optional RFC6902-style ops against canonical IPortfolio JSON. Omit or pass [] for an exact semantic clone. Sizing fields are action-type-specific: DynamicRebalance uses /strategies/N/action/deploymentPercent (indicator returning 0–100); RebalanceOption uses /strategies/N/action/totalBudget/amount (indicator). Use Value for a constant or PoliticalPurchaseShare with a Bioguide memberId for a dynamic equity/option purchase mix. Do not patch totalBudget onto DynamicRebalance or deploymentPercent onto RebalanceOption."
- Changed
update_portfolio13 fields changed- changed
Input schema / $defs / action / oneOfPrevious 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" - } -]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 the deploymentPercent indicator (0–100; use Value for a constant). 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": { + "$ref": "#/$defs/indicator", + "description": "Indicator returning percent of portfolio NAV to deploy, 0–100 (remainder cash). Use Value for a constant, or PoliticalPurchaseShare with memberId and instrument Equity. Do not use totalBudget here." + }, + "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, then allocate option premium under totalBudget. sizingMode fixedPerName (default) uses weightIndicator only to rank names and perNameAllocation to size each. sizingMode proportionalToWeight splits totalBudget among selected names in proportion to positive weightIndicator values; perNameAllocation is ignored, and sleeves/allocationPolicy/exposurePolicy cannot be combined with it. allocationPolicy may jointly size selected names in fixedPerName mode; exposurePolicy may scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder for shared cadence. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies.", + "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" + }, + "sizingMode": { + "enum": [ + "fixedPerName", + "proportionalToWeight" + ], + "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: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", + "properties": { + "amount": { + "$ref": "#/$defs/indicator", + "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." + }, + "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" + } +] - changed
Input schema / $defs / deploymentBudget / descriptionPrevious value: -"Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars."New value: +"Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires." - added
Input schema / $defs / deploymentBudget / properties / amount / $refAdded value: +"#/$defs/indicator" - added
Input schema / $defs / deploymentBudget / properties / amount / descriptionAdded value: +"Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." - removed
Input schema / $defs / deploymentBudget / properties / amount / minimumRemoved value: -0 - removed
Input schema / $defs / deploymentBudget / properties / amount / typeRemoved value: -"number" - changed
Input schema / $defs / indicator / properties / amountBasis / descriptionPrevious value: -"PoliticalTrades disclosed range endpoint. LowerBound is conservative."New value: +"Disclosed transaction range endpoint. PoliticalPurchaseShare defaults to Midpoint; PoliticalTrades amount metrics default to LowerBound." - changed
Input schema / $defs / indicator / properties / instrument / descriptionPrevious value: -"PoliticalTrades instrument class. Equity excludes confirmed options."New value: +"PoliticalTrades instrument class (Equity, Option, All). PoliticalPurchaseShare requires Equity or Option and returns that side's percent of member-wide public purchases." - changed
Input schema / $defs / indicator / properties / memberId / descriptionPrevious value: -"PoliticalTrades member bioguide id (e.g. P000197). Matches exactly and overrides filer; prefer it when known, because names collide."New value: +"Bioguide member id (e.g. P000197). Required for PoliticalPurchaseShare, whose member-wide public purchase amounts include symbols outside the trading universe; also selects an exact PoliticalTrades member and overrides filer." - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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", - "MinuteBarHigh", - "HeikinAshi", - "MinuteBarLow", - "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" -]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", + "MinuteBarHigh", + "HeikinAshi", + "MinuteBarLow", + "PreviousClosingPrice", + "HighOfDay", + "LowOfDay", + "MinutesUntilClose", + "PriceChangeSinceOpen", + "GapSize", + "GapPercentage", + "TrueRange", + "AverageTrueRange", + "Volume", + "VWAP", + "BullishFairValueGap", + "BearishFairValueGap", + "IndicatorAtMinutesAfterOpen", + "IndicatorWindowAgo", + "IndicatorAtEntry", + "IsIndexMember", + "PoliticalTrades", + "PoliticalPurchaseShare", + "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" +] - changed
Input schema / $defs / strategy / properties / action / oneOfPrevious 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" - } -]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 the deploymentPercent indicator (0–100; use Value for a constant). 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": { + "$ref": "#/$defs/indicator", + "description": "Indicator returning percent of portfolio NAV to deploy, 0–100 (remainder cash). Use Value for a constant, or PoliticalPurchaseShare with memberId and instrument Equity. Do not use totalBudget here." + }, + "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, then allocate option premium under totalBudget. sizingMode fixedPerName (default) uses weightIndicator only to rank names and perNameAllocation to size each. sizingMode proportionalToWeight splits totalBudget among selected names in proportion to positive weightIndicator values; perNameAllocation is ignored, and sleeves/allocationPolicy/exposurePolicy cannot be combined with it. allocationPolicy may jointly size selected names in fixedPerName mode; exposurePolicy may scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder for shared cadence. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies.", + "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" + }, + "sizingMode": { + "enum": [ + "fixedPerName", + "proportionalToWeight" + ], + "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: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", + "properties": { + "amount": { + "$ref": "#/$defs/indicator", + "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." + }, + "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" + } +] - changed
Input schema / properties / operations / items / properties / strategyObject / properties / action / oneOfPrevious 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" - } -]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 the deploymentPercent indicator (0–100; use Value for a constant). 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": { + "$ref": "#/$defs/indicator", + "description": "Indicator returning percent of portfolio NAV to deploy, 0–100 (remainder cash). Use Value for a constant, or PoliticalPurchaseShare with memberId and instrument Equity. Do not use totalBudget here." + }, + "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, then allocate option premium under totalBudget. sizingMode fixedPerName (default) uses weightIndicator only to rank names and perNameAllocation to size each. sizingMode proportionalToWeight splits totalBudget among selected names in proportion to positive weightIndicator values; perNameAllocation is ignored, and sleeves/allocationPolicy/exposurePolicy cannot be combined with it. allocationPolicy may jointly size selected names in fixedPerName mode; exposurePolicy may scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder for shared cadence. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies.", + "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" + }, + "sizingMode": { + "enum": [ + "fixedPerName", + "proportionalToWeight" + ], + "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: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", + "properties": { + "amount": { + "$ref": "#/$defs/indicator", + "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." + }, + "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" + } +] - changed
Input schema / properties / operations / items / properties / strategyObjects / items / properties / action / oneOfPrevious 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" - } -]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 the deploymentPercent indicator (0–100; use Value for a constant). 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": { + "$ref": "#/$defs/indicator", + "description": "Indicator returning percent of portfolio NAV to deploy, 0–100 (remainder cash). Use Value for a constant, or PoliticalPurchaseShare with memberId and instrument Equity. Do not use totalBudget here." + }, + "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, then allocate option premium under totalBudget. sizingMode fixedPerName (default) uses weightIndicator only to rank names and perNameAllocation to size each. sizingMode proportionalToWeight splits totalBudget among selected names in proportion to positive weightIndicator values; perNameAllocation is ignored, and sleeves/allocationPolicy/exposurePolicy cannot be combined with it. allocationPolicy may jointly size selected names in fixedPerName mode; exposurePolicy may scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder for shared cadence. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies.", + "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" + }, + "sizingMode": { + "enum": [ + "fixedPerName", + "proportionalToWeight" + ], + "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: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", + "properties": { + "amount": { + "$ref": "#/$defs/indicator", + "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." + }, + "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" + } +]
3 tool updates
- Changed
build_portfolio2 fields changed- changed
Input schema / $defs / indicator / descriptionPrevious 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."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), HeikinAshi (needs targetAsset + line open|high|low|close|streak; candles from completed one-minute regular-session bars, identical in backtests and live; streak is the signed length of the current same-color run since the last color change, 0 on a doji or once the run shows an opposite-direction wick, so three clean same-color candles are streak >= 3 or <= -3), 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." - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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" -]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", + "MinuteBarHigh", + "HeikinAshi", + "MinuteBarLow", + "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" +]
- Changed
create_portfolio2 fields changed- changed
Input schema / $defs / indicator / descriptionPrevious 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."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), HeikinAshi (needs targetAsset + line open|high|low|close|streak; candles from completed one-minute regular-session bars, identical in backtests and live; streak is the signed length of the current same-color run since the last color change, 0 on a doji or once the run shows an opposite-direction wick, so three clean same-color candles are streak >= 3 or <= -3), 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." - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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" -]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", + "MinuteBarHigh", + "HeikinAshi", + "MinuteBarLow", + "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" +]
- Changed
update_portfolio2 fields changed- changed
Input schema / $defs / indicator / descriptionPrevious 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."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), HeikinAshi (needs targetAsset + line open|high|low|close|streak; candles from completed one-minute regular-session bars, identical in backtests and live; streak is the signed length of the current same-color run since the last color change, 0 on a doji or once the run shows an opposite-direction wick, so three clean same-color candles are streak >= 3 or <= -3), 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." - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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" -]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", + "MinuteBarHigh", + "HeikinAshi", + "MinuteBarLow", + "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" +]
3 tool updates
- Changed
build_portfolio1 field changed- added
Input schema / properties / policyAdded value: +{ + "additionalProperties": false, + "description": "OPTIONAL. Which stocks the portfolio's dynamic universes may select. Only stockEligibility is accepted; omitted fields take the defaults. Automated trading can never be set here: it starts off and only the owner enables it in the NexusTrade UI.", + "properties": { + "stockEligibility": { + "additionalProperties": false, + "properties": { + "industryFilter": { + "additionalProperties": false, + "properties": { + "industries": { + "items": { + "type": "string" + }, + "type": "array" + }, + "match": { + "enum": [ + "ANY", + "ALL" + ], + "type": "string" + }, + "mode": { + "enum": [ + "ALL", + "INCLUDE_ONLY" + ], + "type": "string" + } + }, + "required": [ + "mode", + "match", + "industries" + ], + "type": "object" + }, + "maximumMarketCapUsd": { + "description": "Largest market cap allowed, or null for no ceiling (default).", + "oneOf": [ + { + "minimum": 0, + "type": "integer" + }, + { + "type": "null" + } + ] + }, + "minimumMarketCapUsd": { + "description": "Smallest market cap a dynamic-universe candidate may have. Default 1000000000 ($1B); lower it for a small-cap strategy.", + "minimum": 0, + "type": "integer" + }, + "missingMarketCapBehavior": { + "description": "EXCLUDE (default) drops a dynamic-universe candidate with no known market cap (most ETFs, some filers). INCLUDE keeps it; the cap bounds then apply only to names whose cap is known. Omit to keep the portfolio's current setting.", + "enum": [ + "EXCLUDE", + "INCLUDE" + ], + "type": "string" + }, + "shareClassBehavior": { + "description": "ONE_PER_COMPANY (default) keeps one share class per company in a dynamic-universe selection, so a top-5 holds five companies (GOOGL over GOOG on a tie). ALL_CLASSES lets every class through, for a book that trades share classes against each other (a GOOG/GOOGL pair). Omit to keep the portfolio's current setting.", + "enum": [ + "ONE_PER_COMPANY", + "ALL_CLASSES" + ], + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "stockEligibility" + ], + "type": "object" +}
- Changed
create_portfolio1 field changed- added
Input schema / properties / policyAdded value: +{ + "additionalProperties": false, + "description": "OPTIONAL. Which stocks the portfolio's dynamic universes may select. Only stockEligibility is accepted; omitted fields take the defaults. Automated trading can never be set here: it starts off and only the owner enables it in the NexusTrade UI.", + "properties": { + "stockEligibility": { + "additionalProperties": false, + "properties": { + "industryFilter": { + "additionalProperties": false, + "properties": { + "industries": { + "items": { + "type": "string" + }, + "type": "array" + }, + "match": { + "enum": [ + "ANY", + "ALL" + ], + "type": "string" + }, + "mode": { + "enum": [ + "ALL", + "INCLUDE_ONLY" + ], + "type": "string" + } + }, + "required": [ + "mode", + "match", + "industries" + ], + "type": "object" + }, + "maximumMarketCapUsd": { + "description": "Largest market cap allowed, or null for no ceiling (default).", + "oneOf": [ + { + "minimum": 0, + "type": "integer" + }, + { + "type": "null" + } + ] + }, + "minimumMarketCapUsd": { + "description": "Smallest market cap a dynamic-universe candidate may have. Default 1000000000 ($1B); lower it for a small-cap strategy.", + "minimum": 0, + "type": "integer" + }, + "missingMarketCapBehavior": { + "description": "EXCLUDE (default) drops a dynamic-universe candidate with no known market cap (most ETFs, some filers). INCLUDE keeps it; the cap bounds then apply only to names whose cap is known. Omit to keep the portfolio's current setting.", + "enum": [ + "EXCLUDE", + "INCLUDE" + ], + "type": "string" + }, + "shareClassBehavior": { + "description": "ONE_PER_COMPANY (default) keeps one share class per company in a dynamic-universe selection, so a top-5 holds five companies (GOOGL over GOOG on a tie). ALL_CLASSES lets every class through, for a book that trades share classes against each other (a GOOG/GOOGL pair). Omit to keep the portfolio's current setting.", + "enum": [ + "ONE_PER_COMPANY", + "ALL_CLASSES" + ], + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "stockEligibility" + ], + "type": "object" +}
- Changed
update_portfolio3 fields changed- changed
Input schema / properties / operations / descriptionPrevious value: -"Array of edit operations. Each operation needs \"portfolioId\" (live, paper, or chat — server resolves automatically). Supported types include \"rename\" (requires non-empty \"name\"), \"delete\" (permanently remove a chat/paper/live portfolio; archives deployed books; pass confirmLive:true only after explicit user confirmation when deleting an active live portfolio). DEPLOY SAFETY: deploying a chat portfolio ID creates a NEW PAPER-TRADING portfolio (simulated money, no broker order ever placed). It cannot place real-money trades. A LIVE/real-brokerage deployment only happens when the target is an EXISTING real-brokerage portfolio (re-activating it, or addStrategies/replaceStrategies on a portfolio already connected to a live broker). You cannot create a live brokerage account from a chat portfolio through this tool. Fetch the portfolio first and use strategy IDs from the returned \"strategies\" array for removals. To add/replace strategies, pass FINISHED strategy objects ({name, condition, action, orderExecution?} — same shape as create_portfolio.strategies) via \"strategyObjects\" (or \"strategyObject\" for replaceStrategy). These are ingested deterministically with zero LLM cost; prefer them. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. RebalanceOption `action.positionScope`: `\"portfolio\"` (default for single-book portfolios — rotation-close and open-skip span all option spreads in the portfolio) or `\"strategy\"` (only spreads this strategy opened; use when multiple RebalanceOption strategies share one portfolio). Set on `create_portfolio` strategies[].action or on `update_portfolio` replaceStrategy/replaceStrategies `strategyObject.action`. Examples: [{\"type\":\"deploy\",\"portfolioId\":\"id\"}, {\"type\":\"undeploy\",\"portfolioId\":\"id\"}, {\"type\":\"delete\",\"portfolioId\":\"id\"}, {\"type\":\"addStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...},\"orderExecution\":{\"type\":\"Limit\",\"price\":{\"type\":\"UnitPrice\",\"amount\":150},\"workingTime\":{\"type\":\"Day\"}}}]}, {\"type\":\"removeStrategies\",\"portfolioId\":\"id\",\"strategyIds\":[\"strategyId\"]}, {\"type\":\"replaceStrategy\",\"portfolioId\":\"id\",\"targetStrategyId\":\"strategyId\",\"strategyObject\":{\"name\":\"...\",\"condition\":{...},\"action\":{\"type\":\"RebalanceOption\",\"positionScope\":\"portfolio\",...}}}, {\"type\":\"replaceStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...}}]}, {\"type\":\"setDeploymentFrequency\",\"portfolioId\":\"id\",\"deploymentFrequency\":\"Constant\"}, {\"type\":\"rename\",\"portfolioId\":\"id\",\"name\":\"New Portfolio Name\"}]"New value: +"Array of edit operations. Each operation needs \"portfolioId\" (live, paper, or chat — server resolves automatically). Supported types include \"rename\" (requires non-empty \"name\"), \"delete\" (permanently remove a chat/paper/live portfolio; archives deployed books; pass confirmLive:true only after explicit user confirmation when deleting an active live portfolio). DEPLOY SAFETY: deploying a chat portfolio ID creates a NEW PAPER-TRADING portfolio (simulated money, no broker order ever placed). It cannot place real-money trades. A LIVE/real-brokerage deployment only happens when the target is an EXISTING real-brokerage portfolio (re-activating it, or addStrategies/replaceStrategies on a portfolio already connected to a live broker). You cannot create a live brokerage account from a chat portfolio through this tool. Fetch the portfolio first and use strategy IDs from the returned \"strategies\" array for removals. To add/replace strategies, pass FINISHED strategy objects ({name, condition, action, orderExecution?} — same shape as create_portfolio.strategies) via \"strategyObjects\" (or \"strategyObject\" for replaceStrategy). These are ingested deterministically with zero LLM cost; prefer them. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. RebalanceOption `action.positionScope`: `\"portfolio\"` (default for single-book portfolios — rotation-close and open-skip span all option spreads in the portfolio) or `\"strategy\"` (only spreads this strategy opened; use when multiple RebalanceOption strategies share one portfolio). Set on `create_portfolio` strategies[].action or on `update_portfolio` replaceStrategy/replaceStrategies `strategyObject.action`. Examples: [{\"type\":\"deploy\",\"portfolioId\":\"id\"}, {\"type\":\"undeploy\",\"portfolioId\":\"id\"}, {\"type\":\"delete\",\"portfolioId\":\"id\"}, {\"type\":\"addStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...},\"orderExecution\":{\"type\":\"Limit\",\"price\":{\"type\":\"UnitPrice\",\"amount\":150},\"workingTime\":{\"type\":\"Day\"}}}]}, {\"type\":\"removeStrategies\",\"portfolioId\":\"id\",\"strategyIds\":[\"strategyId\"]}, {\"type\":\"replaceStrategy\",\"portfolioId\":\"id\",\"targetStrategyId\":\"strategyId\",\"strategyObject\":{\"name\":\"...\",\"condition\":{...},\"action\":{\"type\":\"RebalanceOption\",\"positionScope\":\"portfolio\",...}}}, {\"type\":\"replaceStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...}}]}, {\"type\":\"setDeploymentFrequency\",\"portfolioId\":\"id\",\"deploymentFrequency\":\"Constant\"}, {\"type\":\"rename\",\"portfolioId\":\"id\",\"name\":\"New Portfolio Name\"}, {\"type\":\"setStockEligibility\",\"portfolioId\":\"id\",\"stockEligibility\":{\"shareClassBehavior\":\"ALL_CLASSES\"}}]. \"setStockEligibility\" changes only stock eligibility (market-cap bounds, industry filter, missingMarketCapBehavior, shareClassBehavior); automated trading can never be changed through MCP." - added
Input schema / properties / operations / items / properties / stockEligibilityAdded value: +{ + "additionalProperties": false, + "description": "setStockEligibility only: the stock-eligibility fields to change on the portfolio's policy. Omitted fields keep their current values. Automated trading can never be changed through MCP.", + "properties": { + "industryFilter": { + "additionalProperties": false, + "properties": { + "industries": { + "items": { + "type": "string" + }, + "type": "array" + }, + "match": { + "enum": [ + "ANY", + "ALL" + ], + "type": "string" + }, + "mode": { + "enum": [ + "ALL", + "INCLUDE_ONLY" + ], + "type": "string" + } + }, + "required": [ + "mode", + "match", + "industries" + ], + "type": "object" + }, + "maximumMarketCapUsd": { + "description": "Largest market cap allowed, or null for no ceiling (default).", + "oneOf": [ + { + "minimum": 0, + "type": "integer" + }, + { + "type": "null" + } + ] + }, + "minimumMarketCapUsd": { + "description": "Smallest market cap a dynamic-universe candidate may have. Default 1000000000 ($1B); lower it for a small-cap strategy.", + "minimum": 0, + "type": "integer" + }, + "missingMarketCapBehavior": { + "description": "EXCLUDE (default) drops a dynamic-universe candidate with no known market cap (most ETFs, some filers). INCLUDE keeps it; the cap bounds then apply only to names whose cap is known. Omit to keep the portfolio's current setting.", + "enum": [ + "EXCLUDE", + "INCLUDE" + ], + "type": "string" + }, + "shareClassBehavior": { + "description": "ONE_PER_COMPANY (default) keeps one share class per company in a dynamic-universe selection, so a top-5 holds five companies (GOOGL over GOOG on a tie). ALL_CLASSES lets every class through, for a book that trades share classes against each other (a GOOG/GOOGL pair). Omit to keep the portfolio's current setting.", + "enum": [ + "ONE_PER_COMPANY", + "ALL_CLASSES" + ], + "type": "string" + } + }, + "type": "object" +} - changed
Input schema / properties / operations / items / properties / type / enumPrevious value: -[ - "deploy", - "undeploy", - "addStrategies", - "removeStrategies", - "replaceStrategy", - "replaceStrategies", - "setDeploymentFrequency", - "rename", - "delete" -]New value: +[ + "deploy", + "undeploy", + "addStrategies", + "removeStrategies", + "replaceStrategy", + "replaceStrategies", + "setDeploymentFrequency", + "rename", + "delete", + "setStockEligibility" +]
3 tool updates
- Changed
build_portfolio6 fields changed- changed
Input schema / $defs / indicator / descriptionPrevious 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." - added
Input schema / $defs / indicator / properties / managerAdded 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" +} - added
Input schema / $defs / indicator / properties / memberIdAdded value: +{ + "description": "PoliticalTrades member bioguide id (e.g. P000197). Matches exactly and overrides filer; prefer it when known, because names collide.", + "type": "string" +} - changed
Input schema / $defs / indicator / properties / metric / descriptionPrevious 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." - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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" +] - changed
Input schema / $defs / indicator / properties / windowDays / descriptionPrevious 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."
- Changed
create_portfolio6 fields changed- changed
Input schema / $defs / indicator / descriptionPrevious 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." - added
Input schema / $defs / indicator / properties / managerAdded 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" +} - added
Input schema / $defs / indicator / properties / memberIdAdded value: +{ + "description": "PoliticalTrades member bioguide id (e.g. P000197). Matches exactly and overrides filer; prefer it when known, because names collide.", + "type": "string" +} - changed
Input schema / $defs / indicator / properties / metric / descriptionPrevious 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." - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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" +] - changed
Input schema / $defs / indicator / properties / windowDays / descriptionPrevious 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."
- Changed
update_portfolio6 fields changed- changed
Input schema / $defs / indicator / descriptionPrevious 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." - added
Input schema / $defs / indicator / properties / managerAdded 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" +} - added
Input schema / $defs / indicator / properties / memberIdAdded value: +{ + "description": "PoliticalTrades member bioguide id (e.g. P000197). Matches exactly and overrides filer; prefer it when known, because names collide.", + "type": "string" +} - changed
Input schema / $defs / indicator / properties / metric / descriptionPrevious 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." - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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" +] - changed
Input schema / $defs / indicator / properties / windowDays / descriptionPrevious 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."
3 tool updates
- Changed
build_portfolio2 fields changed- changed
Input schema / $defs / indicator / descriptionPrevious 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." - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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" +]
- Changed
create_portfolio2 fields changed- changed
Input schema / $defs / indicator / descriptionPrevious 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." - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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" +]
- Changed
update_portfolio2 fields changed- changed
Input schema / $defs / indicator / descriptionPrevious 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." - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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 tool updates
- Changed
build_portfolio2 fields changed- changed
Input schema / $defs / indicator / descriptionPrevious 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." - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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" +]
- Changed
create_portfolio2 fields changed- changed
Input schema / $defs / indicator / descriptionPrevious 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." - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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" +]
- Changed
update_portfolio2 fields changed- changed
Input schema / $defs / indicator / descriptionPrevious 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." - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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" +]
3 tool updates
- Changed
build_portfolio7 fields changed- changed
Input schema / $defs / indicator / descriptionPrevious 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." - added
Input schema / $defs / indicator / properties / amountBasisAdded value: +{ + "description": "PoliticalTrades disclosed range endpoint. LowerBound is conservative.", + "enum": [ + "LowerBound", + "Midpoint", + "UpperBound" + ], + "type": "string" +} - added
Input schema / $defs / indicator / properties / chamberAdded value: +{ + "description": "PoliticalTrades optional cohort filter. All combines House and Senate.", + "enum": [ + "All", + "House", + "Senate" + ], + "type": "string" +} - added
Input schema / $defs / indicator / properties / filerAdded value: +{ + "description": "PoliticalTrades member full or last name; empty means all members.", + "type": "string" +} - added
Input schema / $defs / indicator / properties / instrumentAdded value: +{ + "description": "PoliticalTrades instrument class. Equity excludes confirmed options.", + "enum": [ + "Equity", + "Option", + "All" + ], + "type": "string" +} - changed
Input schema / $defs / indicator / properties / metric / descriptionPrevious 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." - added
Input schema / $defs / indicator / properties / windowDaysAdded value: +{ + "description": "PoliticalTrades / InsiderTrades trailing calendar days.", + "maximum": 3650, + "minimum": 1, + "type": "integer" +}
- Changed
create_portfolio7 fields changed- changed
Input schema / $defs / indicator / descriptionPrevious 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." - added
Input schema / $defs / indicator / properties / amountBasisAdded value: +{ + "description": "PoliticalTrades disclosed range endpoint. LowerBound is conservative.", + "enum": [ + "LowerBound", + "Midpoint", + "UpperBound" + ], + "type": "string" +} - added
Input schema / $defs / indicator / properties / chamberAdded value: +{ + "description": "PoliticalTrades optional cohort filter. All combines House and Senate.", + "enum": [ + "All", + "House", + "Senate" + ], + "type": "string" +} - added
Input schema / $defs / indicator / properties / filerAdded value: +{ + "description": "PoliticalTrades member full or last name; empty means all members.", + "type": "string" +} - added
Input schema / $defs / indicator / properties / instrumentAdded value: +{ + "description": "PoliticalTrades instrument class. Equity excludes confirmed options.", + "enum": [ + "Equity", + "Option", + "All" + ], + "type": "string" +} - changed
Input schema / $defs / indicator / properties / metric / descriptionPrevious 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." - added
Input schema / $defs / indicator / properties / windowDaysAdded value: +{ + "description": "PoliticalTrades / InsiderTrades trailing calendar days.", + "maximum": 3650, + "minimum": 1, + "type": "integer" +}
- Changed
update_portfolio7 fields changed- changed
Input schema / $defs / indicator / descriptionPrevious 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." - added
Input schema / $defs / indicator / properties / amountBasisAdded value: +{ + "description": "PoliticalTrades disclosed range endpoint. LowerBound is conservative.", + "enum": [ + "LowerBound", + "Midpoint", + "UpperBound" + ], + "type": "string" +} - added
Input schema / $defs / indicator / properties / chamberAdded value: +{ + "description": "PoliticalTrades optional cohort filter. All combines House and Senate.", + "enum": [ + "All", + "House", + "Senate" + ], + "type": "string" +} - added
Input schema / $defs / indicator / properties / filerAdded value: +{ + "description": "PoliticalTrades member full or last name; empty means all members.", + "type": "string" +} - added
Input schema / $defs / indicator / properties / instrumentAdded value: +{ + "description": "PoliticalTrades instrument class. Equity excludes confirmed options.", + "enum": [ + "Equity", + "Option", + "All" + ], + "type": "string" +} - changed
Input schema / $defs / indicator / properties / metric / descriptionPrevious 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." - added
Input schema / $defs / indicator / properties / windowDaysAdded value: +{ + "description": "PoliticalTrades / InsiderTrades trailing calendar days.", + "maximum": 3650, + "minimum": 1, + "type": "integer" +}
3 tool updates
- Changed
build_portfolio11 fields changed- changed
Input schema / $defs / indicator / descriptionPrevious 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." - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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" +] - changed
Input schema / $defs / orderExecution / descriptionPrevious 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." - changed
Input schema / $defs / orderExecution / oneOfPrevious 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" + } +] - changed
Input schema / $defs / strategy / descriptionPrevious 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." - changed
Input schema / $defs / strategy / properties / orderExecution / descriptionPrevious 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." - changed
Input schema / $defs / strategy / properties / orderExecution / oneOfPrevious 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" + } +] - changed
Input schema / properties / strategies / descriptionPrevious 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." - changed
Input schema / properties / strategies / items / descriptionPrevious 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." - changed
Input schema / properties / strategies / items / properties / orderExecution / descriptionPrevious 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." - changed
Input schema / properties / strategies / items / properties / orderExecution / oneOfPrevious 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" + } +]
- Changed
create_portfolio11 fields changed- changed
Input schema / $defs / indicator / descriptionPrevious 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." - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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" +] - changed
Input schema / $defs / orderExecution / descriptionPrevious 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." - changed
Input schema / $defs / orderExecution / oneOfPrevious 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" + } +] - changed
Input schema / $defs / strategy / descriptionPrevious 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." - changed
Input schema / $defs / strategy / properties / orderExecution / descriptionPrevious 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." - changed
Input schema / $defs / strategy / properties / orderExecution / oneOfPrevious 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" + } +] - changed
Input schema / properties / strategies / descriptionPrevious 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." - changed
Input schema / properties / strategies / items / descriptionPrevious 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." - changed
Input schema / properties / strategies / items / properties / orderExecution / descriptionPrevious 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." - changed
Input schema / properties / strategies / items / properties / orderExecution / oneOfPrevious 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" + } +]
- Changed
update_portfolio14 fields changed- changed
Input schema / $defs / indicator / descriptionPrevious 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." - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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" +] - changed
Input schema / $defs / orderExecution / descriptionPrevious 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." - changed
Input schema / $defs / orderExecution / oneOfPrevious 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" + } +] - changed
Input schema / $defs / strategy / descriptionPrevious 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." - changed
Input schema / $defs / strategy / properties / orderExecution / descriptionPrevious 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." - changed
Input schema / $defs / strategy / properties / orderExecution / oneOfPrevious 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" + } +] - changed
Input schema / properties / operations / descriptionPrevious value: -"Array of edit operations. Each operation needs \"portfolioId\" (live, paper, or chat — server resolves automatically). Supported types include \"rename\" (requires non-empty \"name\"), \"delete\" (permanently remove a chat/paper/live portfolio; archives deployed books; pass confirmLive:true only after explicit user confirmation when deleting an active live portfolio). DEPLOY SAFETY: deploying a chat portfolio ID creates a NEW PAPER-TRADING portfolio (simulated money, no broker order ever placed). It cannot place real-money trades. A LIVE/real-brokerage deployment only happens when the target is an EXISTING real-brokerage portfolio (re-activating it, or addStrategies/replaceStrategies on a portfolio already connected to a live broker). You cannot create a live brokerage account from a chat portfolio through this tool. Fetch the portfolio first and use strategy IDs from the returned \"strategies\" array for removals. To add/replace strategies, pass FINISHED strategy objects ({name, condition, action, orderExecution?} — same shape as create_portfolio.strategies) via \"strategyObjects\" (or \"strategyObject\" for replaceStrategy). These are ingested deterministically with zero LLM cost; prefer them. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. RebalanceOption `action.positionScope`: `\"portfolio\"` (default for single-book portfolios — rotation-close and open-skip span all option spreads in the portfolio) or `\"strategy\"` (only spreads this strategy opened; use when multiple RebalanceOption strategies share one portfolio). Set on `create_portfolio` strategies[].action or on `update_portfolio` replaceStrategy/replaceStrategies `strategyObject.action`. Examples: [{\"type\":\"deploy\",\"portfolioId\":\"id\"}, {\"type\":\"undeploy\",\"portfolioId\":\"id\"}, {\"type\":\"delete\",\"portfolioId\":\"id\"}, {\"type\":\"addStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...},\"orderExecution\":{\"type\":\"Limit\",\"price\":{\"type\":\"UnitPrice\",\"amount\":150},\"workingTime\":{\"type\":\"Day\"}}}]}, {\"type\":\"removeStrategies\",\"portfolioId\":\"id\",\"strategyIds\":[\"strategyId\"]}, {\"type\":\"replaceStrategy\",\"portfolioId\":\"id\",\"targetStrategyId\":\"strategyId\",\"strategyObject\":{\"name\":\"...\",\"condition\":{...},\"action\":{\"type\":\"RebalanceOption\",\"positionScope\":\"portfolio\",...}}}, {\"type\":\"replaceStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...}}]}, {\"type\":\"setDeploymentFrequency\",\"portfolioId\":\"id\",\"deploymentFrequency\":\"Constant\"}, {\"type\":\"rename\",\"portfolioId\":\"id\",\"name\":\"New Portfolio Name\"}]"New value: +"Array of edit operations. Each operation needs \"portfolioId\" (live, paper, or chat — server resolves automatically). Supported types include \"rename\" (requires non-empty \"name\"), \"delete\" (permanently remove a chat/paper/live portfolio; archives deployed books; pass confirmLive:true only after explicit user confirmation when deleting an active live portfolio). DEPLOY SAFETY: deploying a chat portfolio ID creates a NEW PAPER-TRADING portfolio (simulated money, no broker order ever placed). It cannot place real-money trades. A LIVE/real-brokerage deployment only happens when the target is an EXISTING real-brokerage portfolio (re-activating it, or addStrategies/replaceStrategies on a portfolio already connected to a live broker). You cannot create a live brokerage account from a chat portfolio through this tool. Fetch the portfolio first and use strategy IDs from the returned \"strategies\" array for removals. To add/replace strategies, pass FINISHED strategy objects ({name, condition, action, orderExecution?} — same shape as create_portfolio.strategies) via \"strategyObjects\" (or \"strategyObject\" for replaceStrategy). These are ingested deterministically with zero LLM cost; prefer them. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. RebalanceOption `action.positionScope`: `\"portfolio\"` (default for single-book portfolios — rotation-close and open-skip span all option spreads in the portfolio) or `\"strategy\"` (only spreads this strategy opened; use when multiple RebalanceOption strategies share one portfolio). Set on `create_portfolio` strategies[].action or on `update_portfolio` replaceStrategy/replaceStrategies `strategyObject.action`. Examples: [{\"type\":\"deploy\",\"portfolioId\":\"id\"}, {\"type\":\"undeploy\",\"portfolioId\":\"id\"}, {\"type\":\"delete\",\"portfolioId\":\"id\"}, {\"type\":\"addStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...},\"orderExecution\":{\"type\":\"Limit\",\"price\":{\"type\":\"UnitPrice\",\"amount\":150},\"workingTime\":{\"type\":\"Day\"}}}]}, {\"type\":\"removeStrategies\",\"portfolioId\":\"id\",\"strategyIds\":[\"strategyId\"]}, {\"type\":\"replaceStrategy\",\"portfolioId\":\"id\",\"targetStrategyId\":\"strategyId\",\"strategyObject\":{\"name\":\"...\",\"condition\":{...},\"action\":{\"type\":\"RebalanceOption\",\"positionScope\":\"portfolio\",...}}}, {\"type\":\"replaceStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...}}]}, {\"type\":\"setDeploymentFrequency\",\"portfolioId\":\"id\",\"deploymentFrequency\":\"Constant\"}, {\"type\":\"rename\",\"portfolioId\":\"id\",\"name\":\"New Portfolio Name\"}]" - changed
Input schema / properties / operations / items / properties / strategyObject / descriptionPrevious 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." - changed
Input schema / properties / operations / items / properties / strategyObject / properties / orderExecution / descriptionPrevious 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." - changed
Input schema / properties / operations / items / properties / strategyObject / properties / orderExecution / oneOfPrevious 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" + } +] - changed
Input schema / properties / operations / items / properties / strategyObjects / items / descriptionPrevious 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." - changed
Input schema / properties / operations / items / properties / strategyObjects / items / properties / orderExecution / descriptionPrevious 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." - changed
Input schema / properties / operations / items / properties / strategyObjects / items / properties / orderExecution / oneOfPrevious 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" + } +]
3 tool updates
- Changed
build_portfolio8 fields changed- changed
Input schema / $defs / action / oneOfPrevious 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" + } +] - changed
Input schema / $defs / indicator / descriptionPrevious 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." - added
Input schema / $defs / indicator / properties / lookbackDaysAdded 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" +} - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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" +] - changed
Input schema / $defs / rebalanceOptionSleeve / properties / perNameAllocation / descriptionPrevious 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'." - changed
Input schema / $defs / rebalanceOptionSleeve / properties / perNameAllocation / properties / type / enumPrevious 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" +] - changed
Input schema / $defs / strategy / properties / action / oneOfPrevious 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" + } +] - changed
Input schema / properties / strategies / items / properties / action / oneOfPrevious 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" + } +]
- Changed
create_portfolio8 fields changed- changed
Input schema / $defs / action / oneOfPrevious 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" + } +] - changed
Input schema / $defs / indicator / descriptionPrevious 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." - added
Input schema / $defs / indicator / properties / lookbackDaysAdded 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" +} - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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" +] - changed
Input schema / $defs / rebalanceOptionSleeve / properties / perNameAllocation / descriptionPrevious 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'." - changed
Input schema / $defs / rebalanceOptionSleeve / properties / perNameAllocation / properties / type / enumPrevious 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" +] - changed
Input schema / $defs / strategy / properties / action / oneOfPrevious 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" + } +] - changed
Input schema / properties / strategies / items / properties / action / oneOfPrevious 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" + } +]
- Changed
update_portfolio9 fields changed- changed
Input schema / $defs / action / oneOfPrevious 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" + } +] - changed
Input schema / $defs / indicator / descriptionPrevious 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." - added
Input schema / $defs / indicator / properties / lookbackDaysAdded 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" +} - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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" +] - changed
Input schema / $defs / rebalanceOptionSleeve / properties / perNameAllocation / descriptionPrevious 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'." - changed
Input schema / $defs / rebalanceOptionSleeve / properties / perNameAllocation / properties / type / enumPrevious 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" +] - changed
Input schema / $defs / strategy / properties / action / oneOfPrevious 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" + } +] - changed
Input schema / properties / operations / items / properties / strategyObject / properties / action / oneOfPrevious 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" + } +] - changed
Input schema / properties / operations / items / properties / strategyObjects / items / properties / action / oneOfPrevious 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" + } +]
1 tool update
- Changed
backtest_portfolio3 fields changed- changed
Input schema / properties / end_date / descriptionPrevious value: -"Backtest end date (ISO format, e.g. 2024-12-31). Minute hard max is 365 days from start_date; extend a survivor in a later run instead of splitting into yearly Minute jobs."New value: +"Backtest end date (ISO format, e.g. 2024-12-31). Minute allows up to 730 days of minute data from start_date, counting minute-indicator warmup; never split a longer span into yearly Minute jobs." - changed
Input schema / properties / interval / descriptionPrevious value: -"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 365 days is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year is a normal second backtest, not an escalation."New value: +"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 730 days of minute data (selected range plus warmup) is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year or two is a normal second backtest, not an escalation." - changed
Input schema / properties / start_date / descriptionPrevious value: -"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range cannot exceed 365 days. Do not use 2010-01-01 or a multi-year span on Minute."New value: +"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range plus minute-indicator warmup cannot exceed 730 days of minute data. Do not use 2010-01-01 on Minute."
1 tool update
- Changed
backtest_portfolio3 fields changed- changed
Input schema / properties / end_date / descriptionPrevious value: -"Backtest end date (ISO format, e.g. 2024-12-31). Minute allows up to 730 days of minute data from start_date, counting minute-indicator warmup; never split a longer span into yearly Minute jobs."New value: +"Backtest end date (ISO format, e.g. 2024-12-31). Minute hard max is 365 days from start_date; extend a survivor in a later run instead of splitting into yearly Minute jobs." - changed
Input schema / properties / interval / descriptionPrevious value: -"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 730 days of minute data (selected range plus warmup) is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year or two is a normal second backtest, not an escalation."New value: +"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 365 days is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year is a normal second backtest, not an escalation." - changed
Input schema / properties / start_date / descriptionPrevious value: -"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range plus minute-indicator warmup cannot exceed 730 days of minute data. Do not use 2010-01-01 on Minute."New value: +"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range cannot exceed 365 days. Do not use 2010-01-01 or a multi-year span on Minute."
1 tool update
- Changed
backtest_portfolio3 fields changed- changed
Input schema / properties / end_date / descriptionPrevious value: -"Backtest end date (ISO format, e.g. 2024-12-31). Minute hard max is 365 days from start_date; extend a survivor in a later run instead of splitting into yearly Minute jobs."New value: +"Backtest end date (ISO format, e.g. 2024-12-31). Minute allows up to 730 days of minute data from start_date, counting minute-indicator warmup; never split a longer span into yearly Minute jobs." - changed
Input schema / properties / interval / descriptionPrevious value: -"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 365 days is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year is a normal second backtest, not an escalation."New value: +"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 730 days of minute data (selected range plus warmup) is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year or two is a normal second backtest, not an escalation." - changed
Input schema / properties / start_date / descriptionPrevious value: -"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range cannot exceed 365 days. Do not use 2010-01-01 or a multi-year span on Minute."New value: +"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range plus minute-indicator warmup cannot exceed 730 days of minute data. Do not use 2010-01-01 on Minute."
1 tool update
- Changed
backtest_portfolio3 fields changed- changed
Input schema / properties / end_date / descriptionPrevious value: -"Backtest end date (ISO format, e.g. 2024-12-31). Minute allows up to 730 days of minute data from start_date, counting minute-indicator warmup; never split a longer span into yearly Minute jobs."New value: +"Backtest end date (ISO format, e.g. 2024-12-31). Minute hard max is 365 days from start_date; extend a survivor in a later run instead of splitting into yearly Minute jobs." - changed
Input schema / properties / interval / descriptionPrevious value: -"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 730 days of minute data (selected range plus warmup) is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year or two is a normal second backtest, not an escalation."New value: +"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 365 days is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year is a normal second backtest, not an escalation." - changed
Input schema / properties / start_date / descriptionPrevious value: -"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range plus minute-indicator warmup cannot exceed 730 days of minute data. Do not use 2010-01-01 on Minute."New value: +"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range cannot exceed 365 days. Do not use 2010-01-01 or a multi-year span on Minute."
1 tool update
- Changed
backtest_portfolio3 fields changed- changed
Input schema / properties / end_date / descriptionPrevious value: -"Backtest end date (ISO format, e.g. 2024-12-31). Minute hard max is 365 days from start_date; extend a survivor in a later run instead of splitting into yearly Minute jobs."New value: +"Backtest end date (ISO format, e.g. 2024-12-31). Minute allows up to 730 days of minute data from start_date, counting minute-indicator warmup; never split a longer span into yearly Minute jobs." - changed
Input schema / properties / interval / descriptionPrevious value: -"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 365 days is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year is a normal second backtest, not an escalation."New value: +"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 730 days of minute data (selected range plus warmup) is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year or two is a normal second backtest, not an escalation." - changed
Input schema / properties / start_date / descriptionPrevious value: -"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range cannot exceed 365 days. Do not use 2010-01-01 or a multi-year span on Minute."New value: +"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range plus minute-indicator warmup cannot exceed 730 days of minute data. Do not use 2010-01-01 on Minute."
1 tool update
- Changed
backtest_portfolio3 fields changed- changed
Input schema / properties / end_date / descriptionPrevious value: -"Backtest end date (ISO format, e.g. 2024-12-31). Minute allows up to 730 days of minute data from start_date, counting minute-indicator warmup; never split a longer span into yearly Minute jobs."New value: +"Backtest end date (ISO format, e.g. 2024-12-31). Minute hard max is 365 days from start_date; extend a survivor in a later run instead of splitting into yearly Minute jobs." - changed
Input schema / properties / interval / descriptionPrevious value: -"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 730 days of minute data (selected range plus warmup) is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year or two is a normal second backtest, not an escalation."New value: +"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 365 days is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year is a normal second backtest, not an escalation." - changed
Input schema / properties / start_date / descriptionPrevious value: -"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range plus minute-indicator warmup cannot exceed 730 days of minute data. Do not use 2010-01-01 on Minute."New value: +"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range cannot exceed 365 days. Do not use 2010-01-01 or a multi-year span on Minute."
1 tool update
- Changed
backtest_portfolio3 fields changed- changed
Input schema / properties / end_date / descriptionPrevious value: -"Backtest end date (ISO format, e.g. 2024-12-31). Minute hard max is 365 days from start_date; extend a survivor in a later run instead of splitting into yearly Minute jobs."New value: +"Backtest end date (ISO format, e.g. 2024-12-31). Minute allows up to 730 days of minute data from start_date, counting minute-indicator warmup; never split a longer span into yearly Minute jobs." - changed
Input schema / properties / interval / descriptionPrevious value: -"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 365 days is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year is a normal second backtest, not an escalation."New value: +"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 730 days of minute data (selected range plus warmup) is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year or two is a normal second backtest, not an escalation." - changed
Input schema / properties / start_date / descriptionPrevious value: -"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range cannot exceed 365 days. Do not use 2010-01-01 or a multi-year span on Minute."New value: +"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range plus minute-indicator warmup cannot exceed 730 days of minute data. Do not use 2010-01-01 on Minute."
4 tool updates
- Changed
backtest_portfolio1 field changed- changed
Input schema / properties / interval / descriptionPrevious value: -"Time interval: Day or Minute (default Day). Minute is a daytrade tape — first-look 90 days, hard max 365 days."New value: +"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 365 days is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year is a normal second backtest, not an escalation."
- Changed
build_portfolio6 fields changed- added
Input schema / $defs / orderExecutionAdded 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" +} - changed
Input schema / $defs / strategy / descriptionPrevious 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." - added
Input schema / $defs / strategy / properties / orderExecutionAdded 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" +} - changed
Input schema / properties / strategies / descriptionPrevious 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." - changed
Input schema / properties / strategies / items / descriptionPrevious 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." - added
Input schema / properties / strategies / items / properties / orderExecutionAdded 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" +}
- Added
create_portfolio - Changed
update_portfolio5 fields changed- added
Input schema / $defsAdded value: +{ + "action": { + "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).", + "oneOf": [ + { + "additionalProperties": true, + "description": "Buy or Sell a stock/crypto position.", + "properties": { + "amount": { + "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').", + "properties": { + "amount": { + "type": "number" + }, + "type": { + "enum": [ + "percent of portfolio", + "percent of buying power", + "percent of current positions", + "dollars", + "number of assets" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "targetAsset": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": { + "enum": [ + "Buy", + "Sell" + ], + "type": "string" + } + }, + "required": [ + "type", + "targetAsset", + "amount" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "Send an alert message (no order).", + "properties": { + "message": { + "type": "string" + }, + "type": { + "const": "Alert", + "type": "string" + } + }, + "required": [ + "type", + "message" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.", + "properties": { + "allocationPolicy": { + "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", + "oneOf": [ + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "expectedReturnShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "riskAversion": { + "maximum": 1000, + "minimum": 0, + "type": "number" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "MeanVariance", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "riskAversion", + "expectedReturnShrinkage", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "RiskParity", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "MaximumDiversification", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + } + ] + }, + "canSell": { + "$ref": "#/$defs/condition", + "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out." + }, + "deploymentPercent": { + "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "exposurePolicy": { + "additionalProperties": false, + "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "targetAnnualizedVolatilityPercent": { + "maximum": 1000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "VolatilityTarget", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "targetAnnualizedVolatilityPercent", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "perNameAllocation": { + "additionalProperties": true, + "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.", + "properties": { + "amount": { + "exclusiveMinimum": 0, + "type": "number" + }, + "type": { + "enum": [ + "percent of portfolio", + "dollars" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "pipeline": { + "items": { + "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", + "oneOf": [ + { + "additionalProperties": true, + "properties": { + "condition": { + "$ref": "#/$defs/condition" + }, + "type": { + "const": "Filter", + "type": "string" + } + }, + "required": [ + "type", + "condition" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "type": { + "const": "SelectTop", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "limit", + "direction" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "percentile": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "SelectPercentile", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "percentile", + "direction" + ], + "type": "object" + } + ], + "type": "object" + }, + "type": "array" + }, + "type": { + "const": "DynamicRebalance", + "type": "string" + }, + "universe": { + "additionalProperties": true, + "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", + "properties": { + "assets": { + "items": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": "array" + }, + "source": { + "enum": [ + "ALL_US_STOCKS", + "SP500", + "NASDAQ100", + "DJIA", + "CRYPTO", + "SPECIFIC_ASSETS" + ], + "type": "string" + } + }, + "required": [ + "source" + ], + "type": "object" + }, + "weightIndicator": { + "$ref": "#/$defs/indicator" + } + }, + "required": [ + "type", + "universe", + "pipeline", + "weightIndicator" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).", + "properties": { + "continueExisting": { + "type": "boolean" + }, + "cooldownMinutes": { + "minimum": 0, + "type": "number" + }, + "executionModel": { + "type": "string" + }, + "includeMarketData": { + "type": "boolean" + }, + "initialMessage": { + "type": "string" + }, + "maxIterations": { + "minimum": 1, + "type": "number" + }, + "planningModel": { + "type": "string" + }, + "skipPlanning": { + "type": "boolean" + }, + "type": { + "const": "LaunchAgent", + "type": "string" + } + }, + "required": [ + "type", + "planningModel", + "executionModel", + "initialMessage", + "maxIterations", + "includeMarketData", + "continueExisting", + "skipPlanning" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.", + "properties": { + "against": { + "additionalProperties": true, + "description": "Optional parent-position selector (e.g. for covered calls).", + "type": "object" + }, + "allocation": { + "additionalProperties": true, + "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", + "properties": { + "amount": { + "type": "number" + }, + "type": { + "enum": [ + "dollars", + "percent of portfolio", + "percent of buying power", + "contracts" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "builder": { + "additionalProperties": true, + "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.", + "properties": { + "dynamicUnderlying": { + "additionalProperties": true, + "properties": { + "limit": { + "minimum": 1, + "type": "number" + }, + "pipeline": { + "items": { + "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", + "oneOf": [ + { + "additionalProperties": true, + "properties": { + "condition": { + "$ref": "#/$defs/condition" + }, + "type": { + "const": "Filter", + "type": "string" + } + }, + "required": [ + "type", + "condition" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "type": { + "const": "SelectTop", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "limit", + "direction" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "percentile": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "SelectPercentile", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "percentile", + "direction" + ], + "type": "object" + } + ], + "type": "object" + }, + "type": "array" + }, + "universe": { + "additionalProperties": true, + "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", + "properties": { + "assets": { + "items": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": "array" + }, + "source": { + "enum": [ + "ALL_US_STOCKS", + "SP500", + "NASDAQ100", + "DJIA", + "CRYPTO", + "SPECIFIC_ASSETS" + ], + "type": "string" + } + }, + "required": [ + "source" + ], + "type": "object" + } + }, + "required": [ + "universe" + ], + "type": "object" + }, + "legs": { + "items": { + "additionalProperties": true, + "description": "Single leg of an option builder.", + "properties": { + "direction": { + "enum": [ + "long", + "short" + ], + "type": "string" + }, + "expirationRange": { + "additionalProperties": true, + "type": "object" + }, + "expirationSelector": { + "properties": { + "maxDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "minDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "preference": { + "enum": [ + "nearest", + "middle", + "furthest" + ], + "type": "string" + } + }, + "required": [ + "minDaysToExpiration", + "maxDaysToExpiration", + "preference" + ], + "type": "object" + }, + "fallbackStrikeSelector": { + "additionalProperties": false, + "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", + "properties": { + "distance": { + "type": "number" + }, + "distanceType": { + "enum": [ + "percent", + "dollars" + ], + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + }, + "greekFilter": { + "additionalProperties": true, + "description": "Optional min/max constraints on Greeks during resolution.", + "type": "object" + }, + "liquidityFilter": { + "additionalProperties": false, + "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", + "properties": { + "maxSpreadAbsolute": { + "type": "number" + }, + "maxSpreadPct": { + "type": "number" + }, + "minBid": { + "type": "number" + } + }, + "type": "object" + }, + "optionType": { + "enum": [ + "call", + "put" + ], + "type": "string" + }, + "ratio": { + "type": "number" + }, + "strikeRange": { + "additionalProperties": true, + "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", + "type": "object" + }, + "strikeSelector": { + "properties": { + "distance": { + "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", + "type": "number" + }, + "distanceType": { + "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + } + }, + "required": [ + "optionType", + "direction", + "expirationSelector", + "strikeSelector" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "spreadType": { + "enum": [ + "vertical", + "calendar", + "diagonal", + "ironCondor", + "straddle", + "strangle", + "custom" + ], + "type": "string" + }, + "underlyingSymbol": { + "type": "string" + }, + "widthConstraint": { + "additionalProperties": false, + "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", + "properties": { + "minWidthDollars": { + "exclusiveMinimum": 0, + "type": "number" + }, + "minWidthPercent": { + "exclusiveMinimum": 0, + "type": "number" + } + }, + "type": "object" + } + }, + "required": [ + "legs" + ], + "type": "object" + }, + "type": { + "const": "OpenOption", + "type": "string" + } + }, + "required": [ + "type", + "builder" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.", + "properties": { + "allocationPolicy": { + "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", + "oneOf": [ + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "expectedReturnShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "riskAversion": { + "maximum": 1000, + "minimum": 0, + "type": "number" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "MeanVariance", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "riskAversion", + "expectedReturnShrinkage", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "RiskParity", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "MaximumDiversification", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + } + ] + }, + "exposurePolicy": { + "additionalProperties": false, + "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "targetAnnualizedVolatilityPercent": { + "maximum": 1000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "VolatilityTarget", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "targetAnnualizedVolatilityPercent", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "perNameAllocation": { + "additionalProperties": true, + "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", + "properties": { + "amount": { + "type": "number" + }, + "type": { + "enum": [ + "dollars", + "percent of portfolio", + "percent of buying power", + "contracts" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "pipeline": { + "items": { + "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", + "oneOf": [ + { + "additionalProperties": true, + "properties": { + "condition": { + "$ref": "#/$defs/condition" + }, + "type": { + "const": "Filter", + "type": "string" + } + }, + "required": [ + "type", + "condition" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "type": { + "const": "SelectTop", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "limit", + "direction" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "percentile": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "SelectPercentile", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "percentile", + "direction" + ], + "type": "object" + } + ], + "type": "object" + }, + "type": "array" + }, + "positionScope": { + "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.", + "enum": [ + "portfolio", + "strategy" + ], + "type": "string" + }, + "sleeves": { + "items": { + "additionalProperties": true, + "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).", + "properties": { + "limit": { + "minimum": 1, + "type": "number" + }, + "name": { + "type": "string" + }, + "perNameAllocation": { + "additionalProperties": true, + "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", + "properties": { + "amount": { + "type": "number" + }, + "type": { + "enum": [ + "dollars", + "percent of portfolio", + "percent of buying power", + "contracts" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "pipeline": { + "items": { + "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", + "oneOf": [ + { + "additionalProperties": true, + "properties": { + "condition": { + "$ref": "#/$defs/condition" + }, + "type": { + "const": "Filter", + "type": "string" + } + }, + "required": [ + "type", + "condition" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "type": { + "const": "SelectTop", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "limit", + "direction" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "percentile": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "SelectPercentile", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "percentile", + "direction" + ], + "type": "object" + } + ], + "type": "object" + }, + "type": "array" + }, + "structureTemplates": { + "items": { + "additionalProperties": true, + "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", + "properties": { + "eligibility": { + "$ref": "#/$defs/condition" + }, + "legs": { + "items": { + "additionalProperties": true, + "description": "Single leg of an option builder.", + "properties": { + "direction": { + "enum": [ + "long", + "short" + ], + "type": "string" + }, + "expirationRange": { + "additionalProperties": true, + "type": "object" + }, + "expirationSelector": { + "properties": { + "maxDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "minDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "preference": { + "enum": [ + "nearest", + "middle", + "furthest" + ], + "type": "string" + } + }, + "required": [ + "minDaysToExpiration", + "maxDaysToExpiration", + "preference" + ], + "type": "object" + }, + "fallbackStrikeSelector": { + "additionalProperties": false, + "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", + "properties": { + "distance": { + "type": "number" + }, + "distanceType": { + "enum": [ + "percent", + "dollars" + ], + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + }, + "greekFilter": { + "additionalProperties": true, + "description": "Optional min/max constraints on Greeks during resolution.", + "type": "object" + }, + "liquidityFilter": { + "additionalProperties": false, + "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", + "properties": { + "maxSpreadAbsolute": { + "type": "number" + }, + "maxSpreadPct": { + "type": "number" + }, + "minBid": { + "type": "number" + } + }, + "type": "object" + }, + "optionType": { + "enum": [ + "call", + "put" + ], + "type": "string" + }, + "ratio": { + "type": "number" + }, + "strikeRange": { + "additionalProperties": true, + "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", + "type": "object" + }, + "strikeSelector": { + "properties": { + "distance": { + "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", + "type": "number" + }, + "distanceType": { + "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + } + }, + "required": [ + "optionType", + "direction", + "expirationSelector", + "strikeSelector" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "name": { + "type": "string" + }, + "spreadType": { + "enum": [ + "vertical", + "calendar", + "diagonal", + "ironCondor", + "straddle", + "strangle", + "custom" + ], + "type": "string" + }, + "widthConstraint": { + "additionalProperties": false, + "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", + "properties": { + "minWidthDollars": { + "exclusiveMinimum": 0, + "type": "number" + }, + "minWidthPercent": { + "exclusiveMinimum": 0, + "type": "number" + } + }, + "type": "object" + } + }, + "required": [ + "legs" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "universe": { + "additionalProperties": true, + "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", + "properties": { + "assets": { + "items": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": "array" + }, + "source": { + "enum": [ + "ALL_US_STOCKS", + "SP500", + "NASDAQ100", + "DJIA", + "CRYPTO", + "SPECIFIC_ASSETS" + ], + "type": "string" + } + }, + "required": [ + "source" + ], + "type": "object" + }, + "weightIndicator": { + "$ref": "#/$defs/indicator" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array" + }, + "structureTemplates": { + "items": { + "additionalProperties": true, + "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", + "properties": { + "eligibility": { + "$ref": "#/$defs/condition" + }, + "legs": { + "items": { + "additionalProperties": true, + "description": "Single leg of an option builder.", + "properties": { + "direction": { + "enum": [ + "long", + "short" + ], + "type": "string" + }, + "expirationRange": { + "additionalProperties": true, + "type": "object" + }, + "expirationSelector": { + "properties": { + "maxDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "minDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "preference": { + "enum": [ + "nearest", + "middle", + "furthest" + ], + "type": "string" + } + }, + "required": [ + "minDaysToExpiration", + "maxDaysToExpiration", + "preference" + ], + "type": "object" + }, + "fallbackStrikeSelector": { + "additionalProperties": false, + "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", + "properties": { + "distance": { + "type": "number" + }, + "distanceType": { + "enum": [ + "percent", + "dollars" + ], + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + }, + "greekFilter": { + "additionalProperties": true, + "description": "Optional min/max constraints on Greeks during resolution.", + "type": "object" + }, + "liquidityFilter": { + "additionalProperties": false, + "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", + "properties": { + "maxSpreadAbsolute": { + "type": "number" + }, + "maxSpreadPct": { + "type": "number" + }, + "minBid": { + "type": "number" + } + }, + "type": "object" + }, + "optionType": { + "enum": [ + "call", + "put" + ], + "type": "string" + }, + "ratio": { + "type": "number" + }, + "strikeRange": { + "additionalProperties": true, + "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", + "type": "object" + }, + "strikeSelector": { + "properties": { + "distance": { + "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", + "type": "number" + }, + "distanceType": { + "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + } + }, + "required": [ + "optionType", + "direction", + "expirationSelector", + "strikeSelector" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "name": { + "type": "string" + }, + "spreadType": { + "enum": [ + "vertical", + "calendar", + "diagonal", + "ironCondor", + "straddle", + "strangle", + "custom" + ], + "type": "string" + }, + "widthConstraint": { + "additionalProperties": false, + "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", + "properties": { + "minWidthDollars": { + "exclusiveMinimum": 0, + "type": "number" + }, + "minWidthPercent": { + "exclusiveMinimum": 0, + "type": "number" + } + }, + "type": "object" + } + }, + "required": [ + "legs" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "totalBudget": { + "additionalProperties": true, + "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.", + "properties": { + "amount": { + "minimum": 0, + "type": "number" + }, + "type": { + "enum": [ + "dollars", + "percent of portfolio" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "type": { + "const": "RebalanceOption", + "type": "string" + }, + "universe": { + "additionalProperties": true, + "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", + "properties": { + "assets": { + "items": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": "array" + }, + "source": { + "enum": [ + "ALL_US_STOCKS", + "SP500", + "NASDAQ100", + "DJIA", + "CRYPTO", + "SPECIFIC_ASSETS" + ], + "type": "string" + } + }, + "required": [ + "source" + ], + "type": "object" + }, + "weightIndicator": { + "$ref": "#/$defs/indicator" + } + }, + "required": [ + "type", + "universe", + "pipeline", + "weightIndicator", + "structureTemplates" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.", + "properties": { + "closeScope": { + "enum": [ + "spread", + "leg" + ], + "type": "string" + }, + "direction": { + "enum": [ + "long", + "short" + ], + "type": "string" + }, + "optionType": { + "enum": [ + "call", + "put" + ], + "type": "string" + }, + "quantity": { + "additionalProperties": true, + "description": "How many contracts to close. Defaults to all matching when omitted.", + "type": "object" + }, + "spreadType": { + "enum": [ + "vertical", + "calendar", + "diagonal", + "ironCondor", + "straddle", + "strangle", + "custom" + ], + "type": "string" + }, + "triggers": { + "items": { + "description": "Close trigger for an options exit. Triggers within an array are OR-gated.", + "oneOf": [ + { + "additionalProperties": true, + "properties": { + "maxPnlPercent": { + "type": "number" + }, + "minPnlPercent": { + "type": "number" + }, + "type": { + "const": "pnl", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "maxDte": { + "type": "number" + }, + "minDte": { + "type": "number" + }, + "type": { + "const": "dte", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "maxDaysHeld": { + "type": "number" + }, + "minDaysHeld": { + "type": "number" + }, + "type": { + "const": "daysHeld", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "maxIv": { + "type": "number" + }, + "maxSpreadDelta": { + "type": "number" + }, + "maxSpreadTheta": { + "type": "number" + }, + "minIv": { + "type": "number" + }, + "minSpreadDelta": { + "type": "number" + }, + "minSpreadTheta": { + "type": "number" + }, + "type": { + "const": "greeks", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } + ], + "type": "object" + }, + "type": "array" + }, + "type": { + "const": "CloseOption", + "type": "string" + }, + "underlyings": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "type" + ], + "type": "object" + } + ], + "type": "object" + }, + "asset": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "condition": { + "additionalProperties": true, + "description": "A condition tree (Bridge pattern). type='Base' compares lhs vs rhs with a comparator; type='And'/'Or' combine an array of nested conditions; type='Multi' fires when N nested conditions are true (count vs threshold); type='Then' is sequential — it fires when the last nested condition is true now and each earlier one was true at a strictly earlier tick within 'window' of the next, so it needs at least 2 conditions and a window with length > 0.", + "properties": { + "comparison": { + "description": "Base / Multi only: how to compare.", + "enum": [ + "lessThan", + "greaterThan", + "lessThanOrEqual", + "greaterThanOrEqual", + "equal", + "notEqual" + ], + "type": "string" + }, + "conditions": { + "description": "And / Or / Multi / Then only: nested conditions. Then reads them in order (at least 2).", + "items": { + "$ref": "#/$defs/condition" + }, + "type": "array" + }, + "lhs": { + "$ref": "#/$defs/indicator", + "description": "Base only: left-hand indicator." + }, + "name": { + "description": "Optional name; auto-derived if omitted.", + "type": "string" + }, + "rhs": { + "$ref": "#/$defs/indicator", + "description": "Base only: right-hand indicator." + }, + "type": { + "enum": [ + "And", + "Or", + "Base", + "Multi", + "Then" + ], + "type": "string" + }, + "value": { + "description": "Multi only: threshold count (>=1).", + "type": "number" + }, + "window": { + "description": "Then only: how long each step has to be followed by the next one, e.g. {length: 30, interval: 'Minute'}. length must be > 0.", + "properties": { + "interval": { + "enum": [ + "Day", + "Hour", + "Minute" + ], + "type": "string" + }, + "length": { + "type": "number" + } + }, + "required": [ + "length", + "interval" + ], + "type": "object" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + "deploymentBudget": { + "additionalProperties": true, + "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.", + "properties": { + "amount": { + "minimum": 0, + "type": "number" + }, + "type": { + "enum": [ + "dollars", + "percent of portfolio" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "indicator": { + "additionalProperties": true, + "description": "An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), Option* indicators (need underlying + optionType + direction + spreadType), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown.", + "properties": { + "assetType": { + "description": "IsAssetType: e.g. 'Stock', 'Cryptocurrency'.", + "type": "string" + }, + "base": { + "description": "Log: logarithm base (>0, ≠1).", + "type": "number" + }, + "compound": { + "type": "boolean" + }, + "condition": { + "$ref": "#/$defs/condition", + "description": "ConsecutiveTrue / CountTrue: the condition to evaluate over the window." + }, + "customIndicatorId": { + "description": "REQUIRED when type is CustomIndicator. Mongo ObjectId hex string for the owned custom data source (see list_custom_indicators or MCP session instructions). Never omit — display name alone is rejected.", + "type": "string" + }, + "customIndicatorName": { + "description": "Optional display label for CustomIndicator. Ignored for lookup; customIndicatorId is authoritative.", + "type": "string" + }, + "direction": { + "description": "Option* indicators: long or short.", + "enum": [ + "long", + "short" + ], + "type": "string" + }, + "exponent": { + "description": "Exponentiation: power exponent.", + "type": "number" + }, + "form": { + "additionalProperties": true, + "description": "Optional auto-generated form metadata. Usually omit; the server fills this.", + "type": "object" + }, + "index": { + "description": "IsIndexMember: point-in-time index id ('SP500', 'NASDAQ100', or 'DJIA').", + "enum": [ + "SP500", + "NASDAQ100", + "DJIA" + ], + "type": "string" + }, + "indicators": { + "description": "Sub-indicators for compound types (Plus, CrossAbove, etc.).", + "items": { + "$ref": "#/$defs/indicator" + }, + "type": "array" + }, + "industry": { + "description": "IsIndustry: industry tag.", + "type": "string" + }, + "length": { + "description": "TrailingSum and similar — window length in days.", + "type": "number" + }, + "matchAsset": { + "additionalProperties": true, + "description": "IsAsset / IsNotAsset: the asset to match against.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "maxDte": { + "description": "Option* indicators: max days to expiration.", + "type": "number" + }, + "message": { + "description": "DaysSinceAlert / MinutesSinceAlert: alert message to match.", + "type": "string" + }, + "metric": { + "description": "Fundamental/CompoundAnnualGrowthRate: financial metric (e.g. 'peRatio'). Economic: economic indicator (e.g. 'UNRATE'). Index: index symbol (e.g. 'VIX', 'SPX'). RebalanceDecisionMetric: allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit.", + "type": "string" + }, + "minDte": { + "description": "Option* indicators: min days to expiration.", + "type": "number" + }, + "minOrMax": { + "description": "OptionDaysToExpiration / OptionDaysHeld: aggregate selector.", + "enum": [ + "min", + "max" + ], + "type": "string" + }, + "minutesAfterOpen": { + "description": "IndicatorAtMinutesAfterOpen: 0–390.", + "maximum": 390, + "minimum": 0, + "type": "number" + }, + "name": { + "description": "Optional human-readable name. Auto-derived if omitted.", + "type": "string" + }, + "numStandardDeviations": { + "description": "BollingerBand: e.g. 2.", + "type": "number" + }, + "optionType": { + "description": "Option* indicators: call or put.", + "enum": [ + "call", + "put" + ], + "type": "string" + }, + "orderStatus": { + "description": "Order-side indicators: filter by status.", + "enum": [ + "Pending", + "Accepted", + "Pending User Approval", + "Canceled", + "Filled", + "Partially Filled" + ], + "type": "string" + }, + "positionEffect": { + "description": "Option* indicators: open or close.", + "type": "string" + }, + "side": { + "description": "Order-side indicators: Buy or Sell.", + "enum": [ + "Buy", + "Sell" + ], + "type": "string" + }, + "spreadType": { + "description": "Option* indicators: vertical, ironCondor, etc.", + "enum": [ + "vertical", + "calendar", + "diagonal", + "ironCondor", + "straddle", + "strangle", + "custom" + ], + "type": "string" + }, + "targetAsset": { + "additionalProperties": true, + "description": "The asset this indicator measures (most price/option indicators).", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "targetAssets": { + "description": "Multi-asset variant (position / order indicators).", + "items": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": "array" + }, + "transactionStatus": { + "description": "DaysSinceTransaction: transaction status.", + "enum": [ + "Pending", + "Canceled", + "Completed" + ], + "type": "string" + }, + "transactionType": { + "description": "DaysSinceTransaction: Deposit or Withdraw.", + "enum": [ + "Deposit", + "Withdraw" + ], + "type": "string" + }, + "type": { + "enum": [ + "DaysSinceAgent", + "MinutesSinceAgent", + "DaysSinceAlert", + "MinutesSinceAlert", + "StockReport", + "DaysUntilEarnings", + "DaysSinceEarnings", + "ImpliedVolatility", + "IVRank", + "IVPercentile", + "IVHVRatio", + "LastOrderPrice", + "Fundamental", + "Economic", + "CustomIndicator", + "Index", + "BollingerBand", + "RelativeStrengthIndex", + "PriceMeanAbsoluteDeviation", + "ExponentialMovingAverage", + "SimpleMovingAverage", + "PriceStandardDeviation", + "PriceRateOfChange", + "MaxDrawdown", + "MaxDrawup", + "MinimumPrice", + "MaximumPrice", + "IndicatorMeanAbsoluteDeviation", + "IndicatorExponentialMovingAverage", + "IndicatorSimpleMovingAverage", + "IndicatorStandardDeviation", + "IndicatorRateOfChange", + "DaysSinceOrder", + "DaysSinceOptionOrder", + "DaysSinceStrategyFired", + "DaysSinceLastRebalanceOptionOrder", + "MinutesSinceOptionOrder", + "MinutesSinceOrder", + "DaysSinceTransaction", + "InitialValue", + "BuyingPower", + "PositionValue", + "PositionPercentChange", + "PortfolioValue", + "RebalanceDecisionMetric", + "Value", + "Price", + "Plus", + "Minus", + "Multiply", + "Divide", + "Negative", + "AbsoluteValue", + "SquareRoot", + "Max", + "Min", + "Day", + "Month", + "Date", + "Year", + "CurrentTimeSeconds", + "CurrentTimeMinutes", + "CurrentTimeHours", + "TrailingSum", + "CompoundAnnualGrowthRate", + "Log", + "Exponentiation", + "SumOrderQuantity", + "SumOrderAmount", + "MinutesAfterOpen", + "OpeningPrice", + "PreviousClosingPrice", + "HighOfDay", + "LowOfDay", + "MinutesUntilClose", + "PriceChangeSinceOpen", + "GapSize", + "GapPercentage", + "TrueRange", + "AverageTrueRange", + "Volume", + "VWAP", + "BullishFairValueGap", + "BearishFairValueGap", + "IndicatorAtMinutesAfterOpen", + "IndicatorWindowAgo", + "IndicatorAtEntry", + "IsIndexMember", + "IsIndustry", + "IsAssetType", + "IsAsset", + "IsNotAsset", + "CrossAbove", + "CrossBelow", + "PositionMaxDrawdown", + "PositionMaxDrawup", + "UnderlyingMaxDrawdown", + "ConsecutiveTrue", + "CountTrue", + "OptionPositionValue", + "OptionPositionCount", + "OptionPositionPercentChange", + "OptionPositionMaxDrawdown", + "OptionDaysToExpiration", + "OptionDaysHeld", + "OptionCollateral", + "OptionSpreadCount", + "OptionUnrealizedPnL", + "OptionGrossExposurePercent" + ], + "type": "string" + }, + "underlying": { + "description": "Option* indicators: underlying ticker (e.g. 'SPY').", + "type": "string" + }, + "value": { + "description": "Required for Value indicators (numeric constant).", + "type": "number" + }, + "window": { + "description": "Rolling time window. e.g. {length:14, interval:'Day'} = trailing 14 trading days.", + "properties": { + "interval": { + "enum": [ + "Day", + "Hour", + "Minute" + ], + "type": "string" + }, + "length": { + "minimum": 1, + "type": "number" + } + }, + "required": [ + "length", + "interval" + ], + "type": "object" + }, + "years": { + "description": "CompoundAnnualGrowthRate: years over which to compute CAGR.", + "type": "number" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + "optionStructureTemplate": { + "additionalProperties": true, + "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", + "properties": { + "eligibility": { + "$ref": "#/$defs/condition" + }, + "legs": { + "items": { + "additionalProperties": true, + "description": "Single leg of an option builder.", + "properties": { + "direction": { + "enum": [ + "long", + "short" + ], + "type": "string" + }, + "expirationRange": { + "additionalProperties": true, + "type": "object" + }, + "expirationSelector": { + "properties": { + "maxDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "minDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "preference": { + "enum": [ + "nearest", + "middle", + "furthest" + ], + "type": "string" + } + }, + "required": [ + "minDaysToExpiration", + "maxDaysToExpiration", + "preference" + ], + "type": "object" + }, + "fallbackStrikeSelector": { + "additionalProperties": false, + "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", + "properties": { + "distance": { + "type": "number" + }, + "distanceType": { + "enum": [ + "percent", + "dollars" + ], + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + }, + "greekFilter": { + "additionalProperties": true, + "description": "Optional min/max constraints on Greeks during resolution.", + "type": "object" + }, + "liquidityFilter": { + "additionalProperties": false, + "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", + "properties": { + "maxSpreadAbsolute": { + "type": "number" + }, + "maxSpreadPct": { + "type": "number" + }, + "minBid": { + "type": "number" + } + }, + "type": "object" + }, + "optionType": { + "enum": [ + "call", + "put" + ], + "type": "string" + }, + "ratio": { + "type": "number" + }, + "strikeRange": { + "additionalProperties": true, + "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", + "type": "object" + }, + "strikeSelector": { + "properties": { + "distance": { + "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", + "type": "number" + }, + "distanceType": { + "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + } + }, + "required": [ + "optionType", + "direction", + "expirationSelector", + "strikeSelector" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "name": { + "type": "string" + }, + "spreadType": { + "enum": [ + "vertical", + "calendar", + "diagonal", + "ironCondor", + "straddle", + "strangle", + "custom" + ], + "type": "string" + }, + "widthConstraint": { + "additionalProperties": false, + "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", + "properties": { + "minWidthDollars": { + "exclusiveMinimum": 0, + "type": "number" + }, + "minWidthPercent": { + "exclusiveMinimum": 0, + "type": "number" + } + }, + "type": "object" + } + }, + "required": [ + "legs" + ], + "type": "object" + }, + "orderExecution": { + "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", + "oneOf": [ + { + "additionalProperties": false, + "properties": { + "type": { + "const": "Market", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "price": { + "oneOf": [ + { + "additionalProperties": false, + "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.", + "properties": { + "amount": { + "minimum": 1e-8, + "type": "number" + }, + "type": { + "const": "UnitPrice", + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.", + "properties": { + "amount": { + "minimum": 1e-8, + "type": "number" + }, + "type": { + "const": "MinimumNetCredit", + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.", + "properties": { + "amount": { + "minimum": 1e-8, + "type": "number" + }, + "type": { + "const": "MaximumNetDebit", + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.", + "properties": { + "reference": { + "const": "Current", + "type": "string" + }, + "type": { + "const": "QuoteRelative", + "type": "string" + } + }, + "required": [ + "type", + "reference" + ], + "type": "object" + } + ] + }, + "type": { + "const": "Limit", + "type": "string" + }, + "workingTime": { + "oneOf": [ + { + "additionalProperties": false, + "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.", + "properties": { + "type": { + "const": "Day", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "minutes": { + "minimum": 1, + "type": "number" + }, + "type": { + "const": "Minutes", + "type": "string" + } + }, + "required": [ + "type", + "minutes" + ], + "type": "object" + } + ] + } + }, + "required": [ + "type", + "price" + ], + "type": "object" + } + ], + "type": "object" + }, + "rebalanceOptionSleeve": { + "additionalProperties": true, + "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).", + "properties": { + "limit": { + "minimum": 1, + "type": "number" + }, + "name": { + "type": "string" + }, + "perNameAllocation": { + "additionalProperties": true, + "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", + "properties": { + "amount": { + "type": "number" + }, + "type": { + "enum": [ + "dollars", + "percent of portfolio", + "percent of buying power", + "contracts" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "pipeline": { + "items": { + "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", + "oneOf": [ + { + "additionalProperties": true, + "properties": { + "condition": { + "$ref": "#/$defs/condition" + }, + "type": { + "const": "Filter", + "type": "string" + } + }, + "required": [ + "type", + "condition" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "type": { + "const": "SelectTop", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "limit", + "direction" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "percentile": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "SelectPercentile", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "percentile", + "direction" + ], + "type": "object" + } + ], + "type": "object" + }, + "type": "array" + }, + "structureTemplates": { + "items": { + "additionalProperties": true, + "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", + "properties": { + "eligibility": { + "$ref": "#/$defs/condition" + }, + "legs": { + "items": { + "additionalProperties": true, + "description": "Single leg of an option builder.", + "properties": { + "direction": { + "enum": [ + "long", + "short" + ], + "type": "string" + }, + "expirationRange": { + "additionalProperties": true, + "type": "object" + }, + "expirationSelector": { + "properties": { + "maxDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "minDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "preference": { + "enum": [ + "nearest", + "middle", + "furthest" + ], + "type": "string" + } + }, + "required": [ + "minDaysToExpiration", + "maxDaysToExpiration", + "preference" + ], + "type": "object" + }, + "fallbackStrikeSelector": { + "additionalProperties": false, + "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", + "properties": { + "distance": { + "type": "number" + }, + "distanceType": { + "enum": [ + "percent", + "dollars" + ], + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + }, + "greekFilter": { + "additionalProperties": true, + "description": "Optional min/max constraints on Greeks during resolution.", + "type": "object" + }, + "liquidityFilter": { + "additionalProperties": false, + "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", + "properties": { + "maxSpreadAbsolute": { + "type": "number" + }, + "maxSpreadPct": { + "type": "number" + }, + "minBid": { + "type": "number" + } + }, + "type": "object" + }, + "optionType": { + "enum": [ + "call", + "put" + ], + "type": "string" + }, + "ratio": { + "type": "number" + }, + "strikeRange": { + "additionalProperties": true, + "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", + "type": "object" + }, + "strikeSelector": { + "properties": { + "distance": { + "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", + "type": "number" + }, + "distanceType": { + "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + } + }, + "required": [ + "optionType", + "direction", + "expirationSelector", + "strikeSelector" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "name": { + "type": "string" + }, + "spreadType": { + "enum": [ + "vertical", + "calendar", + "diagonal", + "ironCondor", + "straddle", + "strangle", + "custom" + ], + "type": "string" + }, + "widthConstraint": { + "additionalProperties": false, + "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", + "properties": { + "minWidthDollars": { + "exclusiveMinimum": 0, + "type": "number" + }, + "minWidthPercent": { + "exclusiveMinimum": 0, + "type": "number" + } + }, + "type": "object" + } + }, + "required": [ + "legs" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "universe": { + "additionalProperties": true, + "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", + "properties": { + "assets": { + "items": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": "array" + }, + "source": { + "enum": [ + "ALL_US_STOCKS", + "SP500", + "NASDAQ100", + "DJIA", + "CRYPTO", + "SPECIFIC_ASSETS" + ], + "type": "string" + } + }, + "required": [ + "source" + ], + "type": "object" + }, + "weightIndicator": { + "$ref": "#/$defs/indicator" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "strategy": { + "additionalProperties": true, + "description": "A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", + "properties": { + "action": { + "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).", + "oneOf": [ + { + "additionalProperties": true, + "description": "Buy or Sell a stock/crypto position.", + "properties": { + "amount": { + "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').", + "properties": { + "amount": { + "type": "number" + }, + "type": { + "enum": [ + "percent of portfolio", + "percent of buying power", + "percent of current positions", + "dollars", + "number of assets" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "targetAsset": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": { + "enum": [ + "Buy", + "Sell" + ], + "type": "string" + } + }, + "required": [ + "type", + "targetAsset", + "amount" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "Send an alert message (no order).", + "properties": { + "message": { + "type": "string" + }, + "type": { + "const": "Alert", + "type": "string" + } + }, + "required": [ + "type", + "message" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.", + "properties": { + "allocationPolicy": { + "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", + "oneOf": [ + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "expectedReturnShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "riskAversion": { + "maximum": 1000, + "minimum": 0, + "type": "number" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "MeanVariance", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "riskAversion", + "expectedReturnShrinkage", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "RiskParity", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "MaximumDiversification", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + } + ] + }, + "canSell": { + "$ref": "#/$defs/condition", + "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out." + }, + "deploymentPercent": { + "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "exposurePolicy": { + "additionalProperties": false, + "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "targetAnnualizedVolatilityPercent": { + "maximum": 1000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "VolatilityTarget", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "targetAnnualizedVolatilityPercent", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "perNameAllocation": { + "additionalProperties": true, + "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.", + "properties": { + "amount": { + "exclusiveMinimum": 0, + "type": "number" + }, + "type": { + "enum": [ + "percent of portfolio", + "dollars" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "pipeline": { + "items": { + "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", + "oneOf": [ + { + "additionalProperties": true, + "properties": { + "condition": { + "$ref": "#/$defs/condition" + }, + "type": { + "const": "Filter", + "type": "string" + } + }, + "required": [ + "type", + "condition" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "type": { + "const": "SelectTop", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "limit", + "direction" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "percentile": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "SelectPercentile", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "percentile", + "direction" + ], + "type": "object" + } + ], + "type": "object" + }, + "type": "array" + }, + "type": { + "const": "DynamicRebalance", + "type": "string" + }, + "universe": { + "additionalProperties": true, + "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", + "properties": { + "assets": { + "items": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": "array" + }, + "source": { + "enum": [ + "ALL_US_STOCKS", + "SP500", + "NASDAQ100", + "DJIA", + "CRYPTO", + "SPECIFIC_ASSETS" + ], + "type": "string" + } + }, + "required": [ + "source" + ], + "type": "object" + }, + "weightIndicator": { + "$ref": "#/$defs/indicator" + } + }, + "required": [ + "type", + "universe", + "pipeline", + "weightIndicator" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).", + "properties": { + "continueExisting": { + "type": "boolean" + }, + "cooldownMinutes": { + "minimum": 0, + "type": "number" + }, + "executionModel": { + "type": "string" + }, + "includeMarketData": { + "type": "boolean" + }, + "initialMessage": { + "type": "string" + }, + "maxIterations": { + "minimum": 1, + "type": "number" + }, + "planningModel": { + "type": "string" + }, + "skipPlanning": { + "type": "boolean" + }, + "type": { + "const": "LaunchAgent", + "type": "string" + } + }, + "required": [ + "type", + "planningModel", + "executionModel", + "initialMessage", + "maxIterations", + "includeMarketData", + "continueExisting", + "skipPlanning" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.", + "properties": { + "against": { + "additionalProperties": true, + "description": "Optional parent-position selector (e.g. for covered calls).", + "type": "object" + }, + "allocation": { + "additionalProperties": true, + "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", + "properties": { + "amount": { + "type": "number" + }, + "type": { + "enum": [ + "dollars", + "percent of portfolio", + "percent of buying power", + "contracts" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "builder": { + "additionalProperties": true, + "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.", + "properties": { + "dynamicUnderlying": { + "additionalProperties": true, + "properties": { + "limit": { + "minimum": 1, + "type": "number" + }, + "pipeline": { + "items": { + "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", + "oneOf": [ + { + "additionalProperties": true, + "properties": { + "condition": { + "$ref": "#/$defs/condition" + }, + "type": { + "const": "Filter", + "type": "string" + } + }, + "required": [ + "type", + "condition" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "type": { + "const": "SelectTop", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "limit", + "direction" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "percentile": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "SelectPercentile", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "percentile", + "direction" + ], + "type": "object" + } + ], + "type": "object" + }, + "type": "array" + }, + "universe": { + "additionalProperties": true, + "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", + "properties": { + "assets": { + "items": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": "array" + }, + "source": { + "enum": [ + "ALL_US_STOCKS", + "SP500", + "NASDAQ100", + "DJIA", + "CRYPTO", + "SPECIFIC_ASSETS" + ], + "type": "string" + } + }, + "required": [ + "source" + ], + "type": "object" + } + }, + "required": [ + "universe" + ], + "type": "object" + }, + "legs": { + "items": { + "additionalProperties": true, + "description": "Single leg of an option builder.", + "properties": { + "direction": { + "enum": [ + "long", + "short" + ], + "type": "string" + }, + "expirationRange": { + "additionalProperties": true, + "type": "object" + }, + "expirationSelector": { + "properties": { + "maxDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "minDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "preference": { + "enum": [ + "nearest", + "middle", + "furthest" + ], + "type": "string" + } + }, + "required": [ + "minDaysToExpiration", + "maxDaysToExpiration", + "preference" + ], + "type": "object" + }, + "fallbackStrikeSelector": { + "additionalProperties": false, + "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", + "properties": { + "distance": { + "type": "number" + }, + "distanceType": { + "enum": [ + "percent", + "dollars" + ], + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + }, + "greekFilter": { + "additionalProperties": true, + "description": "Optional min/max constraints on Greeks during resolution.", + "type": "object" + }, + "liquidityFilter": { + "additionalProperties": false, + "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", + "properties": { + "maxSpreadAbsolute": { + "type": "number" + }, + "maxSpreadPct": { + "type": "number" + }, + "minBid": { + "type": "number" + } + }, + "type": "object" + }, + "optionType": { + "enum": [ + "call", + "put" + ], + "type": "string" + }, + "ratio": { + "type": "number" + }, + "strikeRange": { + "additionalProperties": true, + "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", + "type": "object" + }, + "strikeSelector": { + "properties": { + "distance": { + "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", + "type": "number" + }, + "distanceType": { + "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + } + }, + "required": [ + "optionType", + "direction", + "expirationSelector", + "strikeSelector" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "spreadType": { + "enum": [ + "vertical", + "calendar", + "diagonal", + "ironCondor", + "straddle", + "strangle", + "custom" + ], + "type": "string" + }, + "underlyingSymbol": { + "type": "string" + }, + "widthConstraint": { + "additionalProperties": false, + "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", + "properties": { + "minWidthDollars": { + "exclusiveMinimum": 0, + "type": "number" + }, + "minWidthPercent": { + "exclusiveMinimum": 0, + "type": "number" + } + }, + "type": "object" + } + }, + "required": [ + "legs" + ], + "type": "object" + }, + "type": { + "const": "OpenOption", + "type": "string" + } + }, + "required": [ + "type", + "builder" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.", + "properties": { + "allocationPolicy": { + "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", + "oneOf": [ + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "expectedReturnShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "riskAversion": { + "maximum": 1000, + "minimum": 0, + "type": "number" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "MeanVariance", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "riskAversion", + "expectedReturnShrinkage", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "RiskParity", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "MaximumDiversification", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + } + ] + }, + "exposurePolicy": { + "additionalProperties": false, + "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "targetAnnualizedVolatilityPercent": { + "maximum": 1000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "VolatilityTarget", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "targetAnnualizedVolatilityPercent", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "perNameAllocation": { + "additionalProperties": true, + "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", + "properties": { + "amount": { + "type": "number" + }, + "type": { + "enum": [ + "dollars", + "percent of portfolio", + "percent of buying power", + "contracts" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "pipeline": { + "items": { + "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", + "oneOf": [ + { + "additionalProperties": true, + "properties": { + "condition": { + "$ref": "#/$defs/condition" + }, + "type": { + "const": "Filter", + "type": "string" + } + }, + "required": [ + "type", + "condition" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "type": { + "const": "SelectTop", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "limit", + "direction" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "percentile": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "SelectPercentile", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "percentile", + "direction" + ], + "type": "object" + } + ], + "type": "object" + }, + "type": "array" + }, + "positionScope": { + "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.", + "enum": [ + "portfolio", + "strategy" + ], + "type": "string" + }, + "sleeves": { + "items": { + "additionalProperties": true, + "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).", + "properties": { + "limit": { + "minimum": 1, + "type": "number" + }, + "name": { + "type": "string" + }, + "perNameAllocation": { + "additionalProperties": true, + "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", + "properties": { + "amount": { + "type": "number" + }, + "type": { + "enum": [ + "dollars", + "percent of portfolio", + "percent of buying power", + "contracts" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "pipeline": { + "items": { + "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", + "oneOf": [ + { + "additionalProperties": true, + "properties": { + "condition": { + "$ref": "#/$defs/condition" + }, + "type": { + "const": "Filter", + "type": "string" + } + }, + "required": [ + "type", + "condition" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "type": { + "const": "SelectTop", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "limit", + "direction" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "percentile": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "SelectPercentile", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "percentile", + "direction" + ], + "type": "object" + } + ], + "type": "object" + }, + "type": "array" + }, + "structureTemplates": { + "items": { + "additionalProperties": true, + "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", + "properties": { + "eligibility": { + "$ref": "#/$defs/condition" + }, + "legs": { + "items": { + "additionalProperties": true, + "description": "Single leg of an option builder.", + "properties": { + "direction": { + "enum": [ + "long", + "short" + ], + "type": "string" + }, + "expirationRange": { + "additionalProperties": true, + "type": "object" + }, + "expirationSelector": { + "properties": { + "maxDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "minDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "preference": { + "enum": [ + "nearest", + "middle", + "furthest" + ], + "type": "string" + } + }, + "required": [ + "minDaysToExpiration", + "maxDaysToExpiration", + "preference" + ], + "type": "object" + }, + "fallbackStrikeSelector": { + "additionalProperties": false, + "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", + "properties": { + "distance": { + "type": "number" + }, + "distanceType": { + "enum": [ + "percent", + "dollars" + ], + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + }, + "greekFilter": { + "additionalProperties": true, + "description": "Optional min/max constraints on Greeks during resolution.", + "type": "object" + }, + "liquidityFilter": { + "additionalProperties": false, + "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", + "properties": { + "maxSpreadAbsolute": { + "type": "number" + }, + "maxSpreadPct": { + "type": "number" + }, + "minBid": { + "type": "number" + } + }, + "type": "object" + }, + "optionType": { + "enum": [ + "call", + "put" + ], + "type": "string" + }, + "ratio": { + "type": "number" + }, + "strikeRange": { + "additionalProperties": true, + "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", + "type": "object" + }, + "strikeSelector": { + "properties": { + "distance": { + "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", + "type": "number" + }, + "distanceType": { + "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + } + }, + "required": [ + "optionType", + "direction", + "expirationSelector", + "strikeSelector" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "name": { + "type": "string" + }, + "spreadType": { + "enum": [ + "vertical", + "calendar", + "diagonal", + "ironCondor", + "straddle", + "strangle", + "custom" + ], + "type": "string" + }, + "widthConstraint": { + "additionalProperties": false, + "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", + "properties": { + "minWidthDollars": { + "exclusiveMinimum": 0, + "type": "number" + }, + "minWidthPercent": { + "exclusiveMinimum": 0, + "type": "number" + } + }, + "type": "object" + } + }, + "required": [ + "legs" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "universe": { + "additionalProperties": true, + "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", + "properties": { + "assets": { + "items": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": "array" + }, + "source": { + "enum": [ + "ALL_US_STOCKS", + "SP500", + "NASDAQ100", + "DJIA", + "CRYPTO", + "SPECIFIC_ASSETS" + ], + "type": "string" + } + }, + "required": [ + "source" + ], + "type": "object" + }, + "weightIndicator": { + "$ref": "#/$defs/indicator" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array" + }, + "structureTemplates": { + "items": { + "additionalProperties": true, + "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", + "properties": { + "eligibility": { + "$ref": "#/$defs/condition" + }, + "legs": { + "items": { + "additionalProperties": true, + "description": "Single leg of an option builder.", + "properties": { + "direction": { + "enum": [ + "long", + "short" + ], + "type": "string" + }, + "expirationRange": { + "additionalProperties": true, + "type": "object" + }, + "expirationSelector": { + "properties": { + "maxDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "minDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "preference": { + "enum": [ + "nearest", + "middle", + "furthest" + ], + "type": "string" + } + }, + "required": [ + "minDaysToExpiration", + "maxDaysToExpiration", + "preference" + ], + "type": "object" + }, + "fallbackStrikeSelector": { + "additionalProperties": false, + "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", + "properties": { + "distance": { + "type": "number" + }, + "distanceType": { + "enum": [ + "percent", + "dollars" + ], + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + }, + "greekFilter": { + "additionalProperties": true, + "description": "Optional min/max constraints on Greeks during resolution.", + "type": "object" + }, + "liquidityFilter": { + "additionalProperties": false, + "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", + "properties": { + "maxSpreadAbsolute": { + "type": "number" + }, + "maxSpreadPct": { + "type": "number" + }, + "minBid": { + "type": "number" + } + }, + "type": "object" + }, + "optionType": { + "enum": [ + "call", + "put" + ], + "type": "string" + }, + "ratio": { + "type": "number" + }, + "strikeRange": { + "additionalProperties": true, + "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", + "type": "object" + }, + "strikeSelector": { + "properties": { + "distance": { + "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", + "type": "number" + }, + "distanceType": { + "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + } + }, + "required": [ + "optionType", + "direction", + "expirationSelector", + "strikeSelector" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "name": { + "type": "string" + }, + "spreadType": { + "enum": [ + "vertical", + "calendar", + "diagonal", + "ironCondor", + "straddle", + "strangle", + "custom" + ], + "type": "string" + }, + "widthConstraint": { + "additionalProperties": false, + "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", + "properties": { + "minWidthDollars": { + "exclusiveMinimum": 0, + "type": "number" + }, + "minWidthPercent": { + "exclusiveMinimum": 0, + "type": "number" + } + }, + "type": "object" + } + }, + "required": [ + "legs" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "totalBudget": { + "additionalProperties": true, + "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.", + "properties": { + "amount": { + "minimum": 0, + "type": "number" + }, + "type": { + "enum": [ + "dollars", + "percent of portfolio" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "type": { + "const": "RebalanceOption", + "type": "string" + }, + "universe": { + "additionalProperties": true, + "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", + "properties": { + "assets": { + "items": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": "array" + }, + "source": { + "enum": [ + "ALL_US_STOCKS", + "SP500", + "NASDAQ100", + "DJIA", + "CRYPTO", + "SPECIFIC_ASSETS" + ], + "type": "string" + } + }, + "required": [ + "source" + ], + "type": "object" + }, + "weightIndicator": { + "$ref": "#/$defs/indicator" + } + }, + "required": [ + "type", + "universe", + "pipeline", + "weightIndicator", + "structureTemplates" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.", + "properties": { + "closeScope": { + "enum": [ + "spread", + "leg" + ], + "type": "string" + }, + "direction": { + "enum": [ + "long", + "short" + ], + "type": "string" + }, + "optionType": { + "enum": [ + "call", + "put" + ], + "type": "string" + }, + "quantity": { + "additionalProperties": true, + "description": "How many contracts to close. Defaults to all matching when omitted.", + "type": "object" + }, + "spreadType": { + "enum": [ + "vertical", + "calendar", + "diagonal", + "ironCondor", + "straddle", + "strangle", + "custom" + ], + "type": "string" + }, + "triggers": { + "items": { + "description": "Close trigger for an options exit. Triggers within an array are OR-gated.", + "oneOf": [ + { + "additionalProperties": true, + "properties": { + "maxPnlPercent": { + "type": "number" + }, + "minPnlPercent": { + "type": "number" + }, + "type": { + "const": "pnl", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "maxDte": { + "type": "number" + }, + "minDte": { + "type": "number" + }, + "type": { + "const": "dte", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "maxDaysHeld": { + "type": "number" + }, + "minDaysHeld": { + "type": "number" + }, + "type": { + "const": "daysHeld", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "maxIv": { + "type": "number" + }, + "maxSpreadDelta": { + "type": "number" + }, + "maxSpreadTheta": { + "type": "number" + }, + "minIv": { + "type": "number" + }, + "minSpreadDelta": { + "type": "number" + }, + "minSpreadTheta": { + "type": "number" + }, + "type": { + "const": "greeks", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } + ], + "type": "object" + }, + "type": "array" + }, + "type": { + "const": "CloseOption", + "type": "string" + }, + "underlyings": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "type" + ], + "type": "object" + } + ], + "type": "object" + }, + "active": { + "description": "Whether the strategy is active (default true).", + "type": "boolean" + }, + "condition": { + "$ref": "#/$defs/condition" + }, + "name": { + "description": "Human-readable strategy name.", + "type": "string" + }, + "orderExecution": { + "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", + "oneOf": [ + { + "additionalProperties": false, + "properties": { + "type": { + "const": "Market", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "price": { + "oneOf": [ + { + "additionalProperties": false, + "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.", + "properties": { + "amount": { + "minimum": 1e-8, + "type": "number" + }, + "type": { + "const": "UnitPrice", + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.", + "properties": { + "amount": { + "minimum": 1e-8, + "type": "number" + }, + "type": { + "const": "MinimumNetCredit", + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.", + "properties": { + "amount": { + "minimum": 1e-8, + "type": "number" + }, + "type": { + "const": "MaximumNetDebit", + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.", + "properties": { + "reference": { + "const": "Current", + "type": "string" + }, + "type": { + "const": "QuoteRelative", + "type": "string" + } + }, + "required": [ + "type", + "reference" + ], + "type": "object" + } + ] + }, + "type": { + "const": "Limit", + "type": "string" + }, + "workingTime": { + "oneOf": [ + { + "additionalProperties": false, + "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.", + "properties": { + "type": { + "const": "Day", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "minutes": { + "minimum": 1, + "type": "number" + }, + "type": { + "const": "Minutes", + "type": "string" + } + }, + "required": [ + "type", + "minutes" + ], + "type": "object" + } + ] + } + }, + "required": [ + "type", + "price" + ], + "type": "object" + } + ], + "type": "object" + } + }, + "required": [ + "name", + "condition", + "action" + ], + "type": "object" + }, + "window": { + "description": "Rolling time window. e.g. {length:14, interval:'Day'} = trailing 14 trading days.", + "properties": { + "interval": { + "enum": [ + "Day", + "Hour", + "Minute" + ], + "type": "string" + }, + "length": { + "minimum": 1, + "type": "number" + } + }, + "required": [ + "length", + "interval" + ], + "type": "object" + } +} - changed
Input schema / properties / operations / descriptionPrevious value: -"Array of edit operations. Each operation needs \"portfolioId\" (live, paper, or chat — server resolves automatically). Supported types include \"rename\" (requires non-empty \"name\"), \"delete\" (permanently remove a chat/paper/live portfolio; archives deployed books; pass confirmLive:true only after explicit user confirmation when deleting an active live portfolio). DEPLOY SAFETY: deploying a chat portfolio ID creates a NEW PAPER-TRADING portfolio (simulated money, no broker order ever placed). It cannot place real-money trades. A LIVE/real-brokerage deployment only happens when the target is an EXISTING real-brokerage portfolio (re-activating it, or addStrategies/replaceStrategies on a portfolio already connected to a live broker). You cannot create a live brokerage account from a chat portfolio through this tool. Fetch the portfolio first and use strategy IDs from the returned \"strategies\" array for removals. To add/replace strategies, pass FINISHED strategy objects ({name, condition, action} — same shape as create_portfolio.strategies) via \"strategyObjects\" (or \"strategyObject\" for replaceStrategy). These are ingested deterministically with zero LLM cost; prefer them. RebalanceOption `action.positionScope`: `\"portfolio\"` (default for single-book portfolios — rotation-close and open-skip span all option spreads in the portfolio) or `\"strategy\"` (only spreads this strategy opened; use when multiple RebalanceOption strategies share one portfolio). Set on `create_portfolio` strategies[].action or on `update_portfolio` replaceStrategy/replaceStrategies `strategyObject.action`. Examples: [{\"type\":\"deploy\",\"portfolioId\":\"id\"}, {\"type\":\"undeploy\",\"portfolioId\":\"id\"}, {\"type\":\"delete\",\"portfolioId\":\"id\"}, {\"type\":\"addStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...}}]}, {\"type\":\"removeStrategies\",\"portfolioId\":\"id\",\"strategyIds\":[\"strategyId\"]}, {\"type\":\"replaceStrategy\",\"portfolioId\":\"id\",\"targetStrategyId\":\"strategyId\",\"strategyObject\":{\"name\":\"...\",\"condition\":{...},\"action\":{\"type\":\"RebalanceOption\",\"positionScope\":\"portfolio\",...}}}, {\"type\":\"replaceStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...}}]}, {\"type\":\"setDeploymentFrequency\",\"portfolioId\":\"id\",\"deploymentFrequency\":\"Constant\"}, {\"type\":\"rename\",\"portfolioId\":\"id\",\"name\":\"New Portfolio Name\"}]"New value: +"Array of edit operations. Each operation needs \"portfolioId\" (live, paper, or chat — server resolves automatically). Supported types include \"rename\" (requires non-empty \"name\"), \"delete\" (permanently remove a chat/paper/live portfolio; archives deployed books; pass confirmLive:true only after explicit user confirmation when deleting an active live portfolio). DEPLOY SAFETY: deploying a chat portfolio ID creates a NEW PAPER-TRADING portfolio (simulated money, no broker order ever placed). It cannot place real-money trades. A LIVE/real-brokerage deployment only happens when the target is an EXISTING real-brokerage portfolio (re-activating it, or addStrategies/replaceStrategies on a portfolio already connected to a live broker). You cannot create a live brokerage account from a chat portfolio through this tool. Fetch the portfolio first and use strategy IDs from the returned \"strategies\" array for removals. To add/replace strategies, pass FINISHED strategy objects ({name, condition, action, orderExecution?} — same shape as create_portfolio.strategies) via \"strategyObjects\" (or \"strategyObject\" for replaceStrategy). These are ingested deterministically with zero LLM cost; prefer them. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. RebalanceOption `action.positionScope`: `\"portfolio\"` (default for single-book portfolios — rotation-close and open-skip span all option spreads in the portfolio) or `\"strategy\"` (only spreads this strategy opened; use when multiple RebalanceOption strategies share one portfolio). Set on `create_portfolio` strategies[].action or on `update_portfolio` replaceStrategy/replaceStrategies `strategyObject.action`. Examples: [{\"type\":\"deploy\",\"portfolioId\":\"id\"}, {\"type\":\"undeploy\",\"portfolioId\":\"id\"}, {\"type\":\"delete\",\"portfolioId\":\"id\"}, {\"type\":\"addStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...},\"orderExecution\":{\"type\":\"Limit\",\"price\":{\"type\":\"UnitPrice\",\"amount\":150},\"workingTime\":{\"type\":\"Day\"}}}]}, {\"type\":\"removeStrategies\",\"portfolioId\":\"id\",\"strategyIds\":[\"strategyId\"]}, {\"type\":\"replaceStrategy\",\"portfolioId\":\"id\",\"targetStrategyId\":\"strategyId\",\"strategyObject\":{\"name\":\"...\",\"condition\":{...},\"action\":{\"type\":\"RebalanceOption\",\"positionScope\":\"portfolio\",...}}}, {\"type\":\"replaceStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...}}]}, {\"type\":\"setDeploymentFrequency\",\"portfolioId\":\"id\",\"deploymentFrequency\":\"Constant\"}, {\"type\":\"rename\",\"portfolioId\":\"id\",\"name\":\"New Portfolio Name\"}]" - added
Input schema / properties / operations / items / additionalPropertiesAdded value: +false - added
Input schema / properties / operations / items / propertiesAdded value: +{ + "confirmLive": { + "type": "boolean" + }, + "deploymentFrequency": { + "enum": [ + "Constant", + "OpenClose" + ], + "type": "string" + }, + "name": { + "type": "string" + }, + "portfolioId": { + "type": "string" + }, + "strategyIds": { + "items": { + "type": "string" + }, + "type": "array" + }, + "strategyObject": { + "additionalProperties": true, + "description": "A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", + "properties": { + "action": { + "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).", + "oneOf": [ + { + "additionalProperties": true, + "description": "Buy or Sell a stock/crypto position.", + "properties": { + "amount": { + "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').", + "properties": { + "amount": { + "type": "number" + }, + "type": { + "enum": [ + "percent of portfolio", + "percent of buying power", + "percent of current positions", + "dollars", + "number of assets" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "targetAsset": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": { + "enum": [ + "Buy", + "Sell" + ], + "type": "string" + } + }, + "required": [ + "type", + "targetAsset", + "amount" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "Send an alert message (no order).", + "properties": { + "message": { + "type": "string" + }, + "type": { + "const": "Alert", + "type": "string" + } + }, + "required": [ + "type", + "message" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.", + "properties": { + "allocationPolicy": { + "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", + "oneOf": [ + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "expectedReturnShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "riskAversion": { + "maximum": 1000, + "minimum": 0, + "type": "number" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "MeanVariance", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "riskAversion", + "expectedReturnShrinkage", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "RiskParity", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "MaximumDiversification", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + } + ] + }, + "canSell": { + "$ref": "#/$defs/condition", + "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out." + }, + "deploymentPercent": { + "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "exposurePolicy": { + "additionalProperties": false, + "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "targetAnnualizedVolatilityPercent": { + "maximum": 1000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "VolatilityTarget", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "targetAnnualizedVolatilityPercent", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "perNameAllocation": { + "additionalProperties": true, + "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.", + "properties": { + "amount": { + "exclusiveMinimum": 0, + "type": "number" + }, + "type": { + "enum": [ + "percent of portfolio", + "dollars" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "pipeline": { + "items": { + "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", + "oneOf": [ + { + "additionalProperties": true, + "properties": { + "condition": { + "$ref": "#/$defs/condition" + }, + "type": { + "const": "Filter", + "type": "string" + } + }, + "required": [ + "type", + "condition" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "type": { + "const": "SelectTop", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "limit", + "direction" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "percentile": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "SelectPercentile", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "percentile", + "direction" + ], + "type": "object" + } + ], + "type": "object" + }, + "type": "array" + }, + "type": { + "const": "DynamicRebalance", + "type": "string" + }, + "universe": { + "additionalProperties": true, + "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", + "properties": { + "assets": { + "items": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": "array" + }, + "source": { + "enum": [ + "ALL_US_STOCKS", + "SP500", + "NASDAQ100", + "DJIA", + "CRYPTO", + "SPECIFIC_ASSETS" + ], + "type": "string" + } + }, + "required": [ + "source" + ], + "type": "object" + }, + "weightIndicator": { + "$ref": "#/$defs/indicator" + } + }, + "required": [ + "type", + "universe", + "pipeline", + "weightIndicator" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).", + "properties": { + "continueExisting": { + "type": "boolean" + }, + "cooldownMinutes": { + "minimum": 0, + "type": "number" + }, + "executionModel": { + "type": "string" + }, + "includeMarketData": { + "type": "boolean" + }, + "initialMessage": { + "type": "string" + }, + "maxIterations": { + "minimum": 1, + "type": "number" + }, + "planningModel": { + "type": "string" + }, + "skipPlanning": { + "type": "boolean" + }, + "type": { + "const": "LaunchAgent", + "type": "string" + } + }, + "required": [ + "type", + "planningModel", + "executionModel", + "initialMessage", + "maxIterations", + "includeMarketData", + "continueExisting", + "skipPlanning" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.", + "properties": { + "against": { + "additionalProperties": true, + "description": "Optional parent-position selector (e.g. for covered calls).", + "type": "object" + }, + "allocation": { + "additionalProperties": true, + "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", + "properties": { + "amount": { + "type": "number" + }, + "type": { + "enum": [ + "dollars", + "percent of portfolio", + "percent of buying power", + "contracts" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "builder": { + "additionalProperties": true, + "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.", + "properties": { + "dynamicUnderlying": { + "additionalProperties": true, + "properties": { + "limit": { + "minimum": 1, + "type": "number" + }, + "pipeline": { + "items": { + "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", + "oneOf": [ + { + "additionalProperties": true, + "properties": { + "condition": { + "$ref": "#/$defs/condition" + }, + "type": { + "const": "Filter", + "type": "string" + } + }, + "required": [ + "type", + "condition" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "type": { + "const": "SelectTop", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "limit", + "direction" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "percentile": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "SelectPercentile", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "percentile", + "direction" + ], + "type": "object" + } + ], + "type": "object" + }, + "type": "array" + }, + "universe": { + "additionalProperties": true, + "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", + "properties": { + "assets": { + "items": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": "array" + }, + "source": { + "enum": [ + "ALL_US_STOCKS", + "SP500", + "NASDAQ100", + "DJIA", + "CRYPTO", + "SPECIFIC_ASSETS" + ], + "type": "string" + } + }, + "required": [ + "source" + ], + "type": "object" + } + }, + "required": [ + "universe" + ], + "type": "object" + }, + "legs": { + "items": { + "additionalProperties": true, + "description": "Single leg of an option builder.", + "properties": { + "direction": { + "enum": [ + "long", + "short" + ], + "type": "string" + }, + "expirationRange": { + "additionalProperties": true, + "type": "object" + }, + "expirationSelector": { + "properties": { + "maxDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "minDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "preference": { + "enum": [ + "nearest", + "middle", + "furthest" + ], + "type": "string" + } + }, + "required": [ + "minDaysToExpiration", + "maxDaysToExpiration", + "preference" + ], + "type": "object" + }, + "fallbackStrikeSelector": { + "additionalProperties": false, + "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", + "properties": { + "distance": { + "type": "number" + }, + "distanceType": { + "enum": [ + "percent", + "dollars" + ], + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + }, + "greekFilter": { + "additionalProperties": true, + "description": "Optional min/max constraints on Greeks during resolution.", + "type": "object" + }, + "liquidityFilter": { + "additionalProperties": false, + "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", + "properties": { + "maxSpreadAbsolute": { + "type": "number" + }, + "maxSpreadPct": { + "type": "number" + }, + "minBid": { + "type": "number" + } + }, + "type": "object" + }, + "optionType": { + "enum": [ + "call", + "put" + ], + "type": "string" + }, + "ratio": { + "type": "number" + }, + "strikeRange": { + "additionalProperties": true, + "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", + "type": "object" + }, + "strikeSelector": { + "properties": { + "distance": { + "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", + "type": "number" + }, + "distanceType": { + "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + } + }, + "required": [ + "optionType", + "direction", + "expirationSelector", + "strikeSelector" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "spreadType": { + "enum": [ + "vertical", + "calendar", + "diagonal", + "ironCondor", + "straddle", + "strangle", + "custom" + ], + "type": "string" + }, + "underlyingSymbol": { + "type": "string" + }, + "widthConstraint": { + "additionalProperties": false, + "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", + "properties": { + "minWidthDollars": { + "exclusiveMinimum": 0, + "type": "number" + }, + "minWidthPercent": { + "exclusiveMinimum": 0, + "type": "number" + } + }, + "type": "object" + } + }, + "required": [ + "legs" + ], + "type": "object" + }, + "type": { + "const": "OpenOption", + "type": "string" + } + }, + "required": [ + "type", + "builder" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.", + "properties": { + "allocationPolicy": { + "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", + "oneOf": [ + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "expectedReturnShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "riskAversion": { + "maximum": 1000, + "minimum": 0, + "type": "number" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "MeanVariance", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "riskAversion", + "expectedReturnShrinkage", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "RiskParity", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "MaximumDiversification", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + } + ] + }, + "exposurePolicy": { + "additionalProperties": false, + "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "targetAnnualizedVolatilityPercent": { + "maximum": 1000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "VolatilityTarget", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "targetAnnualizedVolatilityPercent", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "perNameAllocation": { + "additionalProperties": true, + "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", + "properties": { + "amount": { + "type": "number" + }, + "type": { + "enum": [ + "dollars", + "percent of portfolio", + "percent of buying power", + "contracts" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "pipeline": { + "items": { + "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", + "oneOf": [ + { + "additionalProperties": true, + "properties": { + "condition": { + "$ref": "#/$defs/condition" + }, + "type": { + "const": "Filter", + "type": "string" + } + }, + "required": [ + "type", + "condition" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "type": { + "const": "SelectTop", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "limit", + "direction" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "percentile": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "SelectPercentile", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "percentile", + "direction" + ], + "type": "object" + } + ], + "type": "object" + }, + "type": "array" + }, + "positionScope": { + "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.", + "enum": [ + "portfolio", + "strategy" + ], + "type": "string" + }, + "sleeves": { + "items": { + "additionalProperties": true, + "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).", + "properties": { + "limit": { + "minimum": 1, + "type": "number" + }, + "name": { + "type": "string" + }, + "perNameAllocation": { + "additionalProperties": true, + "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", + "properties": { + "amount": { + "type": "number" + }, + "type": { + "enum": [ + "dollars", + "percent of portfolio", + "percent of buying power", + "contracts" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "pipeline": { + "items": { + "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", + "oneOf": [ + { + "additionalProperties": true, + "properties": { + "condition": { + "$ref": "#/$defs/condition" + }, + "type": { + "const": "Filter", + "type": "string" + } + }, + "required": [ + "type", + "condition" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "type": { + "const": "SelectTop", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "limit", + "direction" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "percentile": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "SelectPercentile", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "percentile", + "direction" + ], + "type": "object" + } + ], + "type": "object" + }, + "type": "array" + }, + "structureTemplates": { + "items": { + "additionalProperties": true, + "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", + "properties": { + "eligibility": { + "$ref": "#/$defs/condition" + }, + "legs": { + "items": { + "additionalProperties": true, + "description": "Single leg of an option builder.", + "properties": { + "direction": { + "enum": [ + "long", + "short" + ], + "type": "string" + }, + "expirationRange": { + "additionalProperties": true, + "type": "object" + }, + "expirationSelector": { + "properties": { + "maxDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "minDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "preference": { + "enum": [ + "nearest", + "middle", + "furthest" + ], + "type": "string" + } + }, + "required": [ + "minDaysToExpiration", + "maxDaysToExpiration", + "preference" + ], + "type": "object" + }, + "fallbackStrikeSelector": { + "additionalProperties": false, + "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", + "properties": { + "distance": { + "type": "number" + }, + "distanceType": { + "enum": [ + "percent", + "dollars" + ], + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + }, + "greekFilter": { + "additionalProperties": true, + "description": "Optional min/max constraints on Greeks during resolution.", + "type": "object" + }, + "liquidityFilter": { + "additionalProperties": false, + "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", + "properties": { + "maxSpreadAbsolute": { + "type": "number" + }, + "maxSpreadPct": { + "type": "number" + }, + "minBid": { + "type": "number" + } + }, + "type": "object" + }, + "optionType": { + "enum": [ + "call", + "put" + ], + "type": "string" + }, + "ratio": { + "type": "number" + }, + "strikeRange": { + "additionalProperties": true, + "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", + "type": "object" + }, + "strikeSelector": { + "properties": { + "distance": { + "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", + "type": "number" + }, + "distanceType": { + "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + } + }, + "required": [ + "optionType", + "direction", + "expirationSelector", + "strikeSelector" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "name": { + "type": "string" + }, + "spreadType": { + "enum": [ + "vertical", + "calendar", + "diagonal", + "ironCondor", + "straddle", + "strangle", + "custom" + ], + "type": "string" + }, + "widthConstraint": { + "additionalProperties": false, + "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", + "properties": { + "minWidthDollars": { + "exclusiveMinimum": 0, + "type": "number" + }, + "minWidthPercent": { + "exclusiveMinimum": 0, + "type": "number" + } + }, + "type": "object" + } + }, + "required": [ + "legs" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "universe": { + "additionalProperties": true, + "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", + "properties": { + "assets": { + "items": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": "array" + }, + "source": { + "enum": [ + "ALL_US_STOCKS", + "SP500", + "NASDAQ100", + "DJIA", + "CRYPTO", + "SPECIFIC_ASSETS" + ], + "type": "string" + } + }, + "required": [ + "source" + ], + "type": "object" + }, + "weightIndicator": { + "$ref": "#/$defs/indicator" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array" + }, + "structureTemplates": { + "items": { + "additionalProperties": true, + "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", + "properties": { + "eligibility": { + "$ref": "#/$defs/condition" + }, + "legs": { + "items": { + "additionalProperties": true, + "description": "Single leg of an option builder.", + "properties": { + "direction": { + "enum": [ + "long", + "short" + ], + "type": "string" + }, + "expirationRange": { + "additionalProperties": true, + "type": "object" + }, + "expirationSelector": { + "properties": { + "maxDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "minDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "preference": { + "enum": [ + "nearest", + "middle", + "furthest" + ], + "type": "string" + } + }, + "required": [ + "minDaysToExpiration", + "maxDaysToExpiration", + "preference" + ], + "type": "object" + }, + "fallbackStrikeSelector": { + "additionalProperties": false, + "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", + "properties": { + "distance": { + "type": "number" + }, + "distanceType": { + "enum": [ + "percent", + "dollars" + ], + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + }, + "greekFilter": { + "additionalProperties": true, + "description": "Optional min/max constraints on Greeks during resolution.", + "type": "object" + }, + "liquidityFilter": { + "additionalProperties": false, + "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", + "properties": { + "maxSpreadAbsolute": { + "type": "number" + }, + "maxSpreadPct": { + "type": "number" + }, + "minBid": { + "type": "number" + } + }, + "type": "object" + }, + "optionType": { + "enum": [ + "call", + "put" + ], + "type": "string" + }, + "ratio": { + "type": "number" + }, + "strikeRange": { + "additionalProperties": true, + "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", + "type": "object" + }, + "strikeSelector": { + "properties": { + "distance": { + "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", + "type": "number" + }, + "distanceType": { + "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + } + }, + "required": [ + "optionType", + "direction", + "expirationSelector", + "strikeSelector" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "name": { + "type": "string" + }, + "spreadType": { + "enum": [ + "vertical", + "calendar", + "diagonal", + "ironCondor", + "straddle", + "strangle", + "custom" + ], + "type": "string" + }, + "widthConstraint": { + "additionalProperties": false, + "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", + "properties": { + "minWidthDollars": { + "exclusiveMinimum": 0, + "type": "number" + }, + "minWidthPercent": { + "exclusiveMinimum": 0, + "type": "number" + } + }, + "type": "object" + } + }, + "required": [ + "legs" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "totalBudget": { + "additionalProperties": true, + "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.", + "properties": { + "amount": { + "minimum": 0, + "type": "number" + }, + "type": { + "enum": [ + "dollars", + "percent of portfolio" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "type": { + "const": "RebalanceOption", + "type": "string" + }, + "universe": { + "additionalProperties": true, + "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", + "properties": { + "assets": { + "items": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": "array" + }, + "source": { + "enum": [ + "ALL_US_STOCKS", + "SP500", + "NASDAQ100", + "DJIA", + "CRYPTO", + "SPECIFIC_ASSETS" + ], + "type": "string" + } + }, + "required": [ + "source" + ], + "type": "object" + }, + "weightIndicator": { + "$ref": "#/$defs/indicator" + } + }, + "required": [ + "type", + "universe", + "pipeline", + "weightIndicator", + "structureTemplates" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.", + "properties": { + "closeScope": { + "enum": [ + "spread", + "leg" + ], + "type": "string" + }, + "direction": { + "enum": [ + "long", + "short" + ], + "type": "string" + }, + "optionType": { + "enum": [ + "call", + "put" + ], + "type": "string" + }, + "quantity": { + "additionalProperties": true, + "description": "How many contracts to close. Defaults to all matching when omitted.", + "type": "object" + }, + "spreadType": { + "enum": [ + "vertical", + "calendar", + "diagonal", + "ironCondor", + "straddle", + "strangle", + "custom" + ], + "type": "string" + }, + "triggers": { + "items": { + "description": "Close trigger for an options exit. Triggers within an array are OR-gated.", + "oneOf": [ + { + "additionalProperties": true, + "properties": { + "maxPnlPercent": { + "type": "number" + }, + "minPnlPercent": { + "type": "number" + }, + "type": { + "const": "pnl", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "maxDte": { + "type": "number" + }, + "minDte": { + "type": "number" + }, + "type": { + "const": "dte", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "maxDaysHeld": { + "type": "number" + }, + "minDaysHeld": { + "type": "number" + }, + "type": { + "const": "daysHeld", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "maxIv": { + "type": "number" + }, + "maxSpreadDelta": { + "type": "number" + }, + "maxSpreadTheta": { + "type": "number" + }, + "minIv": { + "type": "number" + }, + "minSpreadDelta": { + "type": "number" + }, + "minSpreadTheta": { + "type": "number" + }, + "type": { + "const": "greeks", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } + ], + "type": "object" + }, + "type": "array" + }, + "type": { + "const": "CloseOption", + "type": "string" + }, + "underlyings": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "type" + ], + "type": "object" + } + ], + "type": "object" + }, + "active": { + "description": "Whether the strategy is active (default true).", + "type": "boolean" + }, + "condition": { + "$ref": "#/$defs/condition" + }, + "name": { + "description": "Human-readable strategy name.", + "type": "string" + }, + "orderExecution": { + "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", + "oneOf": [ + { + "additionalProperties": false, + "properties": { + "type": { + "const": "Market", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "price": { + "oneOf": [ + { + "additionalProperties": false, + "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.", + "properties": { + "amount": { + "minimum": 1e-8, + "type": "number" + }, + "type": { + "const": "UnitPrice", + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.", + "properties": { + "amount": { + "minimum": 1e-8, + "type": "number" + }, + "type": { + "const": "MinimumNetCredit", + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.", + "properties": { + "amount": { + "minimum": 1e-8, + "type": "number" + }, + "type": { + "const": "MaximumNetDebit", + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.", + "properties": { + "reference": { + "const": "Current", + "type": "string" + }, + "type": { + "const": "QuoteRelative", + "type": "string" + } + }, + "required": [ + "type", + "reference" + ], + "type": "object" + } + ] + }, + "type": { + "const": "Limit", + "type": "string" + }, + "workingTime": { + "oneOf": [ + { + "additionalProperties": false, + "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.", + "properties": { + "type": { + "const": "Day", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "minutes": { + "minimum": 1, + "type": "number" + }, + "type": { + "const": "Minutes", + "type": "string" + } + }, + "required": [ + "type", + "minutes" + ], + "type": "object" + } + ] + } + }, + "required": [ + "type", + "price" + ], + "type": "object" + } + ], + "type": "object" + } + }, + "required": [ + "name", + "condition", + "action" + ], + "type": "object" + }, + "strategyObjects": { + "items": { + "additionalProperties": true, + "description": "A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", + "properties": { + "action": { + "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).", + "oneOf": [ + { + "additionalProperties": true, + "description": "Buy or Sell a stock/crypto position.", + "properties": { + "amount": { + "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').", + "properties": { + "amount": { + "type": "number" + }, + "type": { + "enum": [ + "percent of portfolio", + "percent of buying power", + "percent of current positions", + "dollars", + "number of assets" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "targetAsset": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": { + "enum": [ + "Buy", + "Sell" + ], + "type": "string" + } + }, + "required": [ + "type", + "targetAsset", + "amount" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "Send an alert message (no order).", + "properties": { + "message": { + "type": "string" + }, + "type": { + "const": "Alert", + "type": "string" + } + }, + "required": [ + "type", + "message" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.", + "properties": { + "allocationPolicy": { + "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", + "oneOf": [ + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "expectedReturnShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "riskAversion": { + "maximum": 1000, + "minimum": 0, + "type": "number" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "MeanVariance", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "riskAversion", + "expectedReturnShrinkage", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "RiskParity", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "MaximumDiversification", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + } + ] + }, + "canSell": { + "$ref": "#/$defs/condition", + "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out." + }, + "deploymentPercent": { + "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "exposurePolicy": { + "additionalProperties": false, + "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "targetAnnualizedVolatilityPercent": { + "maximum": 1000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "VolatilityTarget", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "targetAnnualizedVolatilityPercent", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "perNameAllocation": { + "additionalProperties": true, + "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.", + "properties": { + "amount": { + "exclusiveMinimum": 0, + "type": "number" + }, + "type": { + "enum": [ + "percent of portfolio", + "dollars" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "pipeline": { + "items": { + "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", + "oneOf": [ + { + "additionalProperties": true, + "properties": { + "condition": { + "$ref": "#/$defs/condition" + }, + "type": { + "const": "Filter", + "type": "string" + } + }, + "required": [ + "type", + "condition" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "type": { + "const": "SelectTop", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "limit", + "direction" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "percentile": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "SelectPercentile", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "percentile", + "direction" + ], + "type": "object" + } + ], + "type": "object" + }, + "type": "array" + }, + "type": { + "const": "DynamicRebalance", + "type": "string" + }, + "universe": { + "additionalProperties": true, + "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", + "properties": { + "assets": { + "items": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": "array" + }, + "source": { + "enum": [ + "ALL_US_STOCKS", + "SP500", + "NASDAQ100", + "DJIA", + "CRYPTO", + "SPECIFIC_ASSETS" + ], + "type": "string" + } + }, + "required": [ + "source" + ], + "type": "object" + }, + "weightIndicator": { + "$ref": "#/$defs/indicator" + } + }, + "required": [ + "type", + "universe", + "pipeline", + "weightIndicator" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).", + "properties": { + "continueExisting": { + "type": "boolean" + }, + "cooldownMinutes": { + "minimum": 0, + "type": "number" + }, + "executionModel": { + "type": "string" + }, + "includeMarketData": { + "type": "boolean" + }, + "initialMessage": { + "type": "string" + }, + "maxIterations": { + "minimum": 1, + "type": "number" + }, + "planningModel": { + "type": "string" + }, + "skipPlanning": { + "type": "boolean" + }, + "type": { + "const": "LaunchAgent", + "type": "string" + } + }, + "required": [ + "type", + "planningModel", + "executionModel", + "initialMessage", + "maxIterations", + "includeMarketData", + "continueExisting", + "skipPlanning" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.", + "properties": { + "against": { + "additionalProperties": true, + "description": "Optional parent-position selector (e.g. for covered calls).", + "type": "object" + }, + "allocation": { + "additionalProperties": true, + "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", + "properties": { + "amount": { + "type": "number" + }, + "type": { + "enum": [ + "dollars", + "percent of portfolio", + "percent of buying power", + "contracts" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "builder": { + "additionalProperties": true, + "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.", + "properties": { + "dynamicUnderlying": { + "additionalProperties": true, + "properties": { + "limit": { + "minimum": 1, + "type": "number" + }, + "pipeline": { + "items": { + "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", + "oneOf": [ + { + "additionalProperties": true, + "properties": { + "condition": { + "$ref": "#/$defs/condition" + }, + "type": { + "const": "Filter", + "type": "string" + } + }, + "required": [ + "type", + "condition" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "type": { + "const": "SelectTop", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "limit", + "direction" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "percentile": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "SelectPercentile", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "percentile", + "direction" + ], + "type": "object" + } + ], + "type": "object" + }, + "type": "array" + }, + "universe": { + "additionalProperties": true, + "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", + "properties": { + "assets": { + "items": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": "array" + }, + "source": { + "enum": [ + "ALL_US_STOCKS", + "SP500", + "NASDAQ100", + "DJIA", + "CRYPTO", + "SPECIFIC_ASSETS" + ], + "type": "string" + } + }, + "required": [ + "source" + ], + "type": "object" + } + }, + "required": [ + "universe" + ], + "type": "object" + }, + "legs": { + "items": { + "additionalProperties": true, + "description": "Single leg of an option builder.", + "properties": { + "direction": { + "enum": [ + "long", + "short" + ], + "type": "string" + }, + "expirationRange": { + "additionalProperties": true, + "type": "object" + }, + "expirationSelector": { + "properties": { + "maxDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "minDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "preference": { + "enum": [ + "nearest", + "middle", + "furthest" + ], + "type": "string" + } + }, + "required": [ + "minDaysToExpiration", + "maxDaysToExpiration", + "preference" + ], + "type": "object" + }, + "fallbackStrikeSelector": { + "additionalProperties": false, + "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", + "properties": { + "distance": { + "type": "number" + }, + "distanceType": { + "enum": [ + "percent", + "dollars" + ], + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + }, + "greekFilter": { + "additionalProperties": true, + "description": "Optional min/max constraints on Greeks during resolution.", + "type": "object" + }, + "liquidityFilter": { + "additionalProperties": false, + "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", + "properties": { + "maxSpreadAbsolute": { + "type": "number" + }, + "maxSpreadPct": { + "type": "number" + }, + "minBid": { + "type": "number" + } + }, + "type": "object" + }, + "optionType": { + "enum": [ + "call", + "put" + ], + "type": "string" + }, + "ratio": { + "type": "number" + }, + "strikeRange": { + "additionalProperties": true, + "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", + "type": "object" + }, + "strikeSelector": { + "properties": { + "distance": { + "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", + "type": "number" + }, + "distanceType": { + "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + } + }, + "required": [ + "optionType", + "direction", + "expirationSelector", + "strikeSelector" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "spreadType": { + "enum": [ + "vertical", + "calendar", + "diagonal", + "ironCondor", + "straddle", + "strangle", + "custom" + ], + "type": "string" + }, + "underlyingSymbol": { + "type": "string" + }, + "widthConstraint": { + "additionalProperties": false, + "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", + "properties": { + "minWidthDollars": { + "exclusiveMinimum": 0, + "type": "number" + }, + "minWidthPercent": { + "exclusiveMinimum": 0, + "type": "number" + } + }, + "type": "object" + } + }, + "required": [ + "legs" + ], + "type": "object" + }, + "type": { + "const": "OpenOption", + "type": "string" + } + }, + "required": [ + "type", + "builder" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.", + "properties": { + "allocationPolicy": { + "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", + "oneOf": [ + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "expectedReturnShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "riskAversion": { + "maximum": 1000, + "minimum": 0, + "type": "number" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "MeanVariance", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "riskAversion", + "expectedReturnShrinkage", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "RiskParity", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "turnoverPenalty": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "MaximumDiversification", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "turnoverPenalty", + "estimatedTransactionCostBps" + ], + "type": "object" + } + ] + }, + "exposurePolicy": { + "additionalProperties": false, + "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", + "properties": { + "covarianceShrinkage": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "estimatedTransactionCostBps": { + "maximum": 10000, + "minimum": 0, + "type": "number" + }, + "lookbackPeriods": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "minimumObservations": { + "maximum": 5000, + "minimum": 2, + "type": "integer" + }, + "targetAnnualizedVolatilityPercent": { + "maximum": 1000, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "VolatilityTarget", + "type": "string" + } + }, + "required": [ + "type", + "lookbackPeriods", + "minimumObservations", + "covarianceShrinkage", + "targetAnnualizedVolatilityPercent", + "estimatedTransactionCostBps" + ], + "type": "object" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "perNameAllocation": { + "additionalProperties": true, + "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", + "properties": { + "amount": { + "type": "number" + }, + "type": { + "enum": [ + "dollars", + "percent of portfolio", + "percent of buying power", + "contracts" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "pipeline": { + "items": { + "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", + "oneOf": [ + { + "additionalProperties": true, + "properties": { + "condition": { + "$ref": "#/$defs/condition" + }, + "type": { + "const": "Filter", + "type": "string" + } + }, + "required": [ + "type", + "condition" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "type": { + "const": "SelectTop", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "limit", + "direction" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "percentile": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "SelectPercentile", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "percentile", + "direction" + ], + "type": "object" + } + ], + "type": "object" + }, + "type": "array" + }, + "positionScope": { + "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.", + "enum": [ + "portfolio", + "strategy" + ], + "type": "string" + }, + "sleeves": { + "items": { + "additionalProperties": true, + "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).", + "properties": { + "limit": { + "minimum": 1, + "type": "number" + }, + "name": { + "type": "string" + }, + "perNameAllocation": { + "additionalProperties": true, + "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", + "properties": { + "amount": { + "type": "number" + }, + "type": { + "enum": [ + "dollars", + "percent of portfolio", + "percent of buying power", + "contracts" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "pipeline": { + "items": { + "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", + "oneOf": [ + { + "additionalProperties": true, + "properties": { + "condition": { + "$ref": "#/$defs/condition" + }, + "type": { + "const": "Filter", + "type": "string" + } + }, + "required": [ + "type", + "condition" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "limit": { + "minimum": 1, + "type": "number" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "type": { + "const": "SelectTop", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "limit", + "direction" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "direction": { + "enum": [ + "Highest", + "Lowest" + ], + "type": "string" + }, + "metric": { + "$ref": "#/$defs/indicator" + }, + "percentile": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "SelectPercentile", + "type": "string" + } + }, + "required": [ + "type", + "metric", + "percentile", + "direction" + ], + "type": "object" + } + ], + "type": "object" + }, + "type": "array" + }, + "structureTemplates": { + "items": { + "additionalProperties": true, + "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", + "properties": { + "eligibility": { + "$ref": "#/$defs/condition" + }, + "legs": { + "items": { + "additionalProperties": true, + "description": "Single leg of an option builder.", + "properties": { + "direction": { + "enum": [ + "long", + "short" + ], + "type": "string" + }, + "expirationRange": { + "additionalProperties": true, + "type": "object" + }, + "expirationSelector": { + "properties": { + "maxDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "minDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "preference": { + "enum": [ + "nearest", + "middle", + "furthest" + ], + "type": "string" + } + }, + "required": [ + "minDaysToExpiration", + "maxDaysToExpiration", + "preference" + ], + "type": "object" + }, + "fallbackStrikeSelector": { + "additionalProperties": false, + "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", + "properties": { + "distance": { + "type": "number" + }, + "distanceType": { + "enum": [ + "percent", + "dollars" + ], + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + }, + "greekFilter": { + "additionalProperties": true, + "description": "Optional min/max constraints on Greeks during resolution.", + "type": "object" + }, + "liquidityFilter": { + "additionalProperties": false, + "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", + "properties": { + "maxSpreadAbsolute": { + "type": "number" + }, + "maxSpreadPct": { + "type": "number" + }, + "minBid": { + "type": "number" + } + }, + "type": "object" + }, + "optionType": { + "enum": [ + "call", + "put" + ], + "type": "string" + }, + "ratio": { + "type": "number" + }, + "strikeRange": { + "additionalProperties": true, + "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", + "type": "object" + }, + "strikeSelector": { + "properties": { + "distance": { + "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", + "type": "number" + }, + "distanceType": { + "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + } + }, + "required": [ + "optionType", + "direction", + "expirationSelector", + "strikeSelector" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "name": { + "type": "string" + }, + "spreadType": { + "enum": [ + "vertical", + "calendar", + "diagonal", + "ironCondor", + "straddle", + "strangle", + "custom" + ], + "type": "string" + }, + "widthConstraint": { + "additionalProperties": false, + "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", + "properties": { + "minWidthDollars": { + "exclusiveMinimum": 0, + "type": "number" + }, + "minWidthPercent": { + "exclusiveMinimum": 0, + "type": "number" + } + }, + "type": "object" + } + }, + "required": [ + "legs" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "universe": { + "additionalProperties": true, + "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", + "properties": { + "assets": { + "items": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": "array" + }, + "source": { + "enum": [ + "ALL_US_STOCKS", + "SP500", + "NASDAQ100", + "DJIA", + "CRYPTO", + "SPECIFIC_ASSETS" + ], + "type": "string" + } + }, + "required": [ + "source" + ], + "type": "object" + }, + "weightIndicator": { + "$ref": "#/$defs/indicator" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array" + }, + "structureTemplates": { + "items": { + "additionalProperties": true, + "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", + "properties": { + "eligibility": { + "$ref": "#/$defs/condition" + }, + "legs": { + "items": { + "additionalProperties": true, + "description": "Single leg of an option builder.", + "properties": { + "direction": { + "enum": [ + "long", + "short" + ], + "type": "string" + }, + "expirationRange": { + "additionalProperties": true, + "type": "object" + }, + "expirationSelector": { + "properties": { + "maxDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "minDaysToExpiration": { + "minimum": 0, + "type": "number" + }, + "preference": { + "enum": [ + "nearest", + "middle", + "furthest" + ], + "type": "string" + } + }, + "required": [ + "minDaysToExpiration", + "maxDaysToExpiration", + "preference" + ], + "type": "object" + }, + "fallbackStrikeSelector": { + "additionalProperties": false, + "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", + "properties": { + "distance": { + "type": "number" + }, + "distanceType": { + "enum": [ + "percent", + "dollars" + ], + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + }, + "greekFilter": { + "additionalProperties": true, + "description": "Optional min/max constraints on Greeks during resolution.", + "type": "object" + }, + "liquidityFilter": { + "additionalProperties": false, + "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", + "properties": { + "maxSpreadAbsolute": { + "type": "number" + }, + "maxSpreadPct": { + "type": "number" + }, + "minBid": { + "type": "number" + } + }, + "type": "object" + }, + "optionType": { + "enum": [ + "call", + "put" + ], + "type": "string" + }, + "ratio": { + "type": "number" + }, + "strikeRange": { + "additionalProperties": true, + "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", + "type": "object" + }, + "strikeSelector": { + "properties": { + "distance": { + "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", + "type": "number" + }, + "distanceType": { + "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", + "type": "string" + } + }, + "required": [ + "distanceType", + "distance" + ], + "type": "object" + } + }, + "required": [ + "optionType", + "direction", + "expirationSelector", + "strikeSelector" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "name": { + "type": "string" + }, + "spreadType": { + "enum": [ + "vertical", + "calendar", + "diagonal", + "ironCondor", + "straddle", + "strangle", + "custom" + ], + "type": "string" + }, + "widthConstraint": { + "additionalProperties": false, + "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", + "properties": { + "minWidthDollars": { + "exclusiveMinimum": 0, + "type": "number" + }, + "minWidthPercent": { + "exclusiveMinimum": 0, + "type": "number" + } + }, + "type": "object" + } + }, + "required": [ + "legs" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "totalBudget": { + "additionalProperties": true, + "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.", + "properties": { + "amount": { + "minimum": 0, + "type": "number" + }, + "type": { + "enum": [ + "dollars", + "percent of portfolio" + ], + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + "type": { + "const": "RebalanceOption", + "type": "string" + }, + "universe": { + "additionalProperties": true, + "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", + "properties": { + "assets": { + "items": { + "additionalProperties": true, + "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "type": { + "enum": [ + "Stock", + "Cryptocurrency", + "Option", + "Other" + ], + "type": "string" + } + }, + "required": [ + "type", + "symbol" + ], + "type": "object" + }, + "type": "array" + }, + "source": { + "enum": [ + "ALL_US_STOCKS", + "SP500", + "NASDAQ100", + "DJIA", + "CRYPTO", + "SPECIFIC_ASSETS" + ], + "type": "string" + } + }, + "required": [ + "source" + ], + "type": "object" + }, + "weightIndicator": { + "$ref": "#/$defs/indicator" + } + }, + "required": [ + "type", + "universe", + "pipeline", + "weightIndicator", + "structureTemplates" + ], + "type": "object" + }, + { + "additionalProperties": true, + "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.", + "properties": { + "closeScope": { + "enum": [ + "spread", + "leg" + ], + "type": "string" + }, + "direction": { + "enum": [ + "long", + "short" + ], + "type": "string" + }, + "optionType": { + "enum": [ + "call", + "put" + ], + "type": "string" + }, + "quantity": { + "additionalProperties": true, + "description": "How many contracts to close. Defaults to all matching when omitted.", + "type": "object" + }, + "spreadType": { + "enum": [ + "vertical", + "calendar", + "diagonal", + "ironCondor", + "straddle", + "strangle", + "custom" + ], + "type": "string" + }, + "triggers": { + "items": { + "description": "Close trigger for an options exit. Triggers within an array are OR-gated.", + "oneOf": [ + { + "additionalProperties": true, + "properties": { + "maxPnlPercent": { + "type": "number" + }, + "minPnlPercent": { + "type": "number" + }, + "type": { + "const": "pnl", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "maxDte": { + "type": "number" + }, + "minDte": { + "type": "number" + }, + "type": { + "const": "dte", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "maxDaysHeld": { + "type": "number" + }, + "minDaysHeld": { + "type": "number" + }, + "type": { + "const": "daysHeld", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "maxIv": { + "type": "number" + }, + "maxSpreadDelta": { + "type": "number" + }, + "maxSpreadTheta": { + "type": "number" + }, + "minIv": { + "type": "number" + }, + "minSpreadDelta": { + "type": "number" + }, + "minSpreadTheta": { + "type": "number" + }, + "type": { + "const": "greeks", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } + ], + "type": "object" + }, + "type": "array" + }, + "type": { + "const": "CloseOption", + "type": "string" + }, + "underlyings": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "type" + ], + "type": "object" + } + ], + "type": "object" + }, + "active": { + "description": "Whether the strategy is active (default true).", + "type": "boolean" + }, + "condition": { + "$ref": "#/$defs/condition" + }, + "name": { + "description": "Human-readable strategy name.", + "type": "string" + }, + "orderExecution": { + "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", + "oneOf": [ + { + "additionalProperties": false, + "properties": { + "type": { + "const": "Market", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "price": { + "oneOf": [ + { + "additionalProperties": false, + "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.", + "properties": { + "amount": { + "minimum": 1e-8, + "type": "number" + }, + "type": { + "const": "UnitPrice", + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.", + "properties": { + "amount": { + "minimum": 1e-8, + "type": "number" + }, + "type": { + "const": "MinimumNetCredit", + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.", + "properties": { + "amount": { + "minimum": 1e-8, + "type": "number" + }, + "type": { + "const": "MaximumNetDebit", + "type": "string" + } + }, + "required": [ + "type", + "amount" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.", + "properties": { + "reference": { + "const": "Current", + "type": "string" + }, + "type": { + "const": "QuoteRelative", + "type": "string" + } + }, + "required": [ + "type", + "reference" + ], + "type": "object" + } + ] + }, + "type": { + "const": "Limit", + "type": "string" + }, + "workingTime": { + "oneOf": [ + { + "additionalProperties": false, + "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.", + "properties": { + "type": { + "const": "Day", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "minutes": { + "minimum": 1, + "type": "number" + }, + "type": { + "const": "Minutes", + "type": "string" + } + }, + "required": [ + "type", + "minutes" + ], + "type": "object" + } + ] + } + }, + "required": [ + "type", + "price" + ], + "type": "object" + } + ], + "type": "object" + } + }, + "required": [ + "name", + "condition", + "action" + ], + "type": "object" + }, + "type": "array" + }, + "targetStrategyId": { + "type": "string" + }, + "targetStrategyName": { + "type": "string" + }, + "type": { + "enum": [ + "deploy", + "undeploy", + "addStrategies", + "removeStrategies", + "replaceStrategy", + "replaceStrategies", + "setDeploymentFrequency", + "rename", + "delete" + ], + "type": "string" + } +} - added
Input schema / properties / operations / items / requiredAdded value: +[ + "type", + "portfolioId" +]
1 tool update
- Changed
build_portfolio6 fields changed- changed
Input schema / $defs / condition / descriptionPrevious 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." - changed
Input schema / $defs / condition / properties / conditions / descriptionPrevious value: -"And / Or / Multi only: nested conditions."New value: +"And / Or / Multi / Then only: nested conditions. Then reads them in order (at least 2)." - changed
Input schema / $defs / condition / properties / type / enumPrevious value: -[ - "And", - "Or", - "Base", - "Multi" -]New value: +[ + "And", + "Or", + "Base", + "Multi", + "Then" +] - added
Input schema / $defs / condition / properties / windowAdded 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" +} - changed
Input schema / $defs / indicator / descriptionPrevious 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." - changed
Input schema / $defs / indicator / properties / type / enumPrevious 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" +]
23 tool updates
- First observed
approve_agent_plan - First observed
archive_agent - First observed
backtest_portfolio - First observed
build_portfolio - First observed
clone_strategies_to_portfolio - First observed
create_agent - First observed
create_portfolio_variant - First observed
fetch_portfolios - First observed
fork_shared_portfolio - First observed
get_agent - First observed
get_agent_trajectory - First observed
get_portfolio - First observed
list_agents - First observed
query_backtest_history - First observed
query_backtest_status - First observed
reject_agent_action - First observed
search_public_portfolios - First observed
send_agent_message - First observed
send_chat_message - First observed
star_agent - First observed
stop_agent - First observed
unarchive_agent - First observed
update_portfolio
Related MCP Connectors
- CPZAIOAuthcom.cpz-lab.mcp
Build, backtest, and deploy quantitative trading strategies from your AI agent.
Mine, validate and paper-trade quantitative trading strategies. The engine runs on your machine.
Validated trading edges across futures, equities, crypto. Live signals, full audit trail.
- QuantGPTOAuthco.quantgpt
The data and trading platform for AI: decades of US market data, backtests in seconds.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables quant research, strategy development, backtesting, and paper trading through natural language prompts, integrated with 20+ AI agents.134-
- FlicenseNot gradedqualityBmaintenanceEnables AI agents to mine, validate, and paper-trade quantitative trading strategies via chat, with the engine running locally on the user's own machine.1-

Tickerbot MCP Serverofficial
AlicenseAqualityBmaintenanceEnables scanning and querying stock market data across thousands of US tickers and top cryptos, with tools for signal analysis, historical replay, and webhook subscriptions.3525 npmMIT- AlicenseAqualityFmaintenanceQuantContext turns plain-English strategy descriptions into executable quant research by screening stocks, backtesting, and performing factor analysis using real market data.374 PyPI9MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.