changedInput schema / $defs / action / oneOf
Previous value: -[
- {
- "additionalProperties": true,
- "description": "Buy or Sell a stock/crypto position.",
- "properties": {
- "amount": {
- "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
- "properties": {
- "amount": {
- "type": "number"
- },
- "type": {
- "enum": [
- "percent of portfolio",
- "percent of buying power",
- "percent of current positions",
- "dollars",
- "number of assets"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "amount"
- ],
- "type": "object"
- },
- "targetAsset": {
- "additionalProperties": true,
- "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
- "properties": {
- "name": {
- "type": "string"
- },
- "symbol": {
- "type": "string"
- },
- "type": {
- "enum": [
- "Stock",
- "Cryptocurrency",
- "Option",
- "Other"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "symbol"
- ],
- "type": "object"
- },
- "type": {
- "enum": [
- "Buy",
- "Sell"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "targetAsset",
- "amount"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "description": "Send an alert message (no order).",
- "properties": {
- "message": {
- "type": "string"
- },
- "type": {
- "const": "Alert",
- "type": "string"
- }
- },
- "required": [
- "type",
- "message"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
- "properties": {
- "allocationPolicy": {
- "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
- "oneOf": [
- {
- "additionalProperties": false,
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "expectedReturnShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "riskAversion": {
- "maximum": 1000,
- "minimum": 0,
- "type": "number"
- },
- "turnoverPenalty": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "MeanVariance",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "riskAversion",
- "expectedReturnShrinkage",
- "covarianceShrinkage",
- "turnoverPenalty",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "turnoverPenalty": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "RiskParity",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "covarianceShrinkage",
- "turnoverPenalty",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "turnoverPenalty": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "MaximumDiversification",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "covarianceShrinkage",
- "turnoverPenalty",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- }
- ]
- },
- "canSell": {
- "$ref": "#/$defs/condition",
- "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
- },
- "deploymentPercent": {
- "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
- "maximum": 100,
- "minimum": 0,
- "type": "number"
- },
- "exposurePolicy": {
- "additionalProperties": false,
- "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "targetAnnualizedVolatilityPercent": {
- "maximum": 1000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "VolatilityTarget",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "covarianceShrinkage",
- "targetAnnualizedVolatilityPercent",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- },
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "perNameAllocation": {
- "additionalProperties": true,
- "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
- "properties": {
- "amount": {
- "exclusiveMinimum": 0,
- "type": "number"
- },
- "type": {
- "enum": [
- "percent of portfolio",
- "dollars"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "amount"
- ],
- "type": "object"
- },
- "pipeline": {
- "items": {
- "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
- "oneOf": [
- {
- "additionalProperties": true,
- "properties": {
- "condition": {
- "$ref": "#/$defs/condition"
- },
- "type": {
- "const": "Filter",
- "type": "string"
- }
- },
- "required": [
- "type",
- "condition"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "type": {
- "const": "SelectTop",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "limit",
- "direction"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "percentile": {
- "maximum": 100,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "SelectPercentile",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "percentile",
- "direction"
- ],
- "type": "object"
- }
- ],
- "type": "object"
- },
- "type": "array"
- },
- "type": {
- "const": "DynamicRebalance",
- "type": "string"
- },
- "universe": {
- "additionalProperties": true,
- "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
- "properties": {
- "assets": {
- "items": {
- "additionalProperties": true,
- "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
- "properties": {
- "name": {
- "type": "string"
- },
- "symbol": {
- "type": "string"
- },
- "type": {
- "enum": [
- "Stock",
- "Cryptocurrency",
- "Option",
- "Other"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "symbol"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "source": {
- "enum": [
- "ALL_US_STOCKS",
- "SP500",
- "NASDAQ100",
- "DJIA",
- "CRYPTO",
- "SPECIFIC_ASSETS"
- ],
- "type": "string"
- }
- },
- "required": [
- "source"
- ],
- "type": "object"
- },
- "weightIndicator": {
- "$ref": "#/$defs/indicator"
- }
- },
- "required": [
- "type",
- "universe",
- "pipeline",
- "weightIndicator"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
- "properties": {
- "continueExisting": {
- "type": "boolean"
- },
- "cooldownMinutes": {
- "minimum": 0,
- "type": "number"
- },
- "executionModel": {
- "type": "string"
- },
- "includeMarketData": {
- "type": "boolean"
- },
- "initialMessage": {
- "type": "string"
- },
- "maxIterations": {
- "minimum": 1,
- "type": "number"
- },
- "planningModel": {
- "type": "string"
- },
- "skipPlanning": {
- "type": "boolean"
- },
- "type": {
- "const": "LaunchAgent",
- "type": "string"
- }
- },
- "required": [
- "type",
- "planningModel",
- "executionModel",
- "initialMessage",
- "maxIterations",
- "includeMarketData",
- "continueExisting",
- "skipPlanning"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
- "properties": {
- "against": {
- "additionalProperties": true,
- "description": "Optional parent-position selector (e.g. for covered calls).",
- "type": "object"
- },
- "allocation": {
- "additionalProperties": true,
- "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
- "properties": {
- "amount": {
- "type": "number"
- },
- "type": {
- "enum": [
- "dollars",
- "percent of portfolio",
- "percent of buying power",
- "contracts"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "amount"
- ],
- "type": "object"
- },
- "builder": {
- "additionalProperties": true,
- "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
- "properties": {
- "dynamicUnderlying": {
- "additionalProperties": true,
- "properties": {
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "pipeline": {
- "items": {
- "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
- "oneOf": [
- {
- "additionalProperties": true,
- "properties": {
- "condition": {
- "$ref": "#/$defs/condition"
- },
- "type": {
- "const": "Filter",
- "type": "string"
- }
- },
- "required": [
- "type",
- "condition"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "type": {
- "const": "SelectTop",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "limit",
- "direction"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "percentile": {
- "maximum": 100,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "SelectPercentile",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "percentile",
- "direction"
- ],
- "type": "object"
- }
- ],
- "type": "object"
- },
- "type": "array"
- },
- "universe": {
- "additionalProperties": true,
- "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
- "properties": {
- "assets": {
- "items": {
- "additionalProperties": true,
- "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
- "properties": {
- "name": {
- "type": "string"
- },
- "symbol": {
- "type": "string"
- },
- "type": {
- "enum": [
- "Stock",
- "Cryptocurrency",
- "Option",
- "Other"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "symbol"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "source": {
- "enum": [
- "ALL_US_STOCKS",
- "SP500",
- "NASDAQ100",
- "DJIA",
- "CRYPTO",
- "SPECIFIC_ASSETS"
- ],
- "type": "string"
- }
- },
- "required": [
- "source"
- ],
- "type": "object"
- }
- },
- "required": [
- "universe"
- ],
- "type": "object"
- },
- "legs": {
- "items": {
- "additionalProperties": true,
- "description": "Single leg of an option builder.",
- "properties": {
- "direction": {
- "enum": [
- "long",
- "short"
- ],
- "type": "string"
- },
- "expirationRange": {
- "additionalProperties": true,
- "type": "object"
- },
- "expirationSelector": {
- "properties": {
- "maxDaysToExpiration": {
- "minimum": 0,
- "type": "number"
- },
- "minDaysToExpiration": {
- "minimum": 0,
- "type": "number"
- },
- "preference": {
- "enum": [
- "nearest",
- "middle",
- "furthest"
- ],
- "type": "string"
- }
- },
- "required": [
- "minDaysToExpiration",
- "maxDaysToExpiration",
- "preference"
- ],
- "type": "object"
- },
- "fallbackStrikeSelector": {
- "additionalProperties": false,
- "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
- "properties": {
- "distance": {
- "type": "number"
- },
- "distanceType": {
- "enum": [
- "percent",
- "dollars"
- ],
- "type": "string"
- }
- },
- "required": [
- "distanceType",
- "distance"
- ],
- "type": "object"
- },
- "greekFilter": {
- "additionalProperties": true,
- "description": "Optional min/max constraints on Greeks during resolution.",
- "type": "object"
- },
- "liquidityFilter": {
- "additionalProperties": false,
- "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
- "properties": {
- "maxSpreadAbsolute": {
- "type": "number"
- },
- "maxSpreadPct": {
- "type": "number"
- },
- "minBid": {
- "type": "number"
- }
- },
- "type": "object"
- },
- "optionType": {
- "enum": [
- "call",
- "put"
- ],
- "type": "string"
- },
- "ratio": {
- "type": "number"
- },
- "strikeRange": {
- "additionalProperties": true,
- "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
- "type": "object"
- },
- "strikeSelector": {
- "properties": {
- "distance": {
- "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
- "type": "number"
- },
- "distanceType": {
- "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
- "type": "string"
- }
- },
- "required": [
- "distanceType",
- "distance"
- ],
- "type": "object"
- }
- },
- "required": [
- "optionType",
- "direction",
- "expirationSelector",
- "strikeSelector"
- ],
- "type": "object"
- },
- "minItems": 1,
- "type": "array"
- },
- "spreadType": {
- "enum": [
- "vertical",
- "calendar",
- "diagonal",
- "ironCondor",
- "straddle",
- "strangle",
- "custom"
- ],
- "type": "string"
- },
- "underlyingSymbol": {
- "type": "string"
- },
- "widthConstraint": {
- "additionalProperties": false,
- "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
- "properties": {
- "minWidthDollars": {
- "exclusiveMinimum": 0,
- "type": "number"
- },
- "minWidthPercent": {
- "exclusiveMinimum": 0,
- "type": "number"
- }
- },
- "type": "object"
- }
- },
- "required": [
- "legs"
- ],
- "type": "object"
- },
- "type": {
- "const": "OpenOption",
- "type": "string"
- }
- },
- "required": [
- "type",
- "builder"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
- "properties": {
- "allocationPolicy": {
- "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
- "oneOf": [
- {
- "additionalProperties": false,
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "expectedReturnShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "riskAversion": {
- "maximum": 1000,
- "minimum": 0,
- "type": "number"
- },
- "turnoverPenalty": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "MeanVariance",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "riskAversion",
- "expectedReturnShrinkage",
- "covarianceShrinkage",
- "turnoverPenalty",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "turnoverPenalty": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "RiskParity",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "covarianceShrinkage",
- "turnoverPenalty",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "turnoverPenalty": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "MaximumDiversification",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "covarianceShrinkage",
- "turnoverPenalty",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- }
- ]
- },
- "exposurePolicy": {
- "additionalProperties": false,
- "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "targetAnnualizedVolatilityPercent": {
- "maximum": 1000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "VolatilityTarget",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "covarianceShrinkage",
- "targetAnnualizedVolatilityPercent",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- },
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "perNameAllocation": {
- "additionalProperties": true,
- "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
- "properties": {
- "amount": {
- "type": "number"
- },
- "type": {
- "enum": [
- "dollars",
- "percent of portfolio",
- "percent of buying power",
- "contracts"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "amount"
- ],
- "type": "object"
- },
- "pipeline": {
- "items": {
- "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
- "oneOf": [
- {
- "additionalProperties": true,
- "properties": {
- "condition": {
- "$ref": "#/$defs/condition"
- },
- "type": {
- "const": "Filter",
- "type": "string"
- }
- },
- "required": [
- "type",
- "condition"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "type": {
- "const": "SelectTop",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "limit",
- "direction"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "percentile": {
- "maximum": 100,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "SelectPercentile",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "percentile",
- "direction"
- ],
- "type": "object"
- }
- ],
- "type": "object"
- },
- "type": "array"
- },
- "positionScope": {
- "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
- "enum": [
- "portfolio",
- "strategy"
- ],
- "type": "string"
- },
- "sleeves": {
- "items": {
- "additionalProperties": true,
- "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
- "properties": {
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "name": {
- "type": "string"
- },
- "perNameAllocation": {
- "additionalProperties": true,
- "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
- "properties": {
- "amount": {
- "type": "number"
- },
- "type": {
- "enum": [
- "dollars",
- "percent of portfolio",
- "percent of buying power",
- "contracts"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "amount"
- ],
- "type": "object"
- },
- "pipeline": {
- "items": {
- "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
- "oneOf": [
- {
- "additionalProperties": true,
- "properties": {
- "condition": {
- "$ref": "#/$defs/condition"
- },
- "type": {
- "const": "Filter",
- "type": "string"
- }
- },
- "required": [
- "type",
- "condition"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "type": {
- "const": "SelectTop",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "limit",
- "direction"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "percentile": {
- "maximum": 100,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "SelectPercentile",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "percentile",
- "direction"
- ],
- "type": "object"
- }
- ],
- "type": "object"
- },
- "type": "array"
- },
- "structureTemplates": {
- "items": {
- "additionalProperties": true,
- "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
- "properties": {
- "eligibility": {
- "$ref": "#/$defs/condition"
- },
- "legs": {
- "items": {
- "additionalProperties": true,
- "description": "Single leg of an option builder.",
- "properties": {
- "direction": {
- "enum": [
- "long",
- "short"
- ],
- "type": "string"
- },
- "expirationRange": {
- "additionalProperties": true,
- "type": "object"
- },
- "expirationSelector": {
- "properties": {
- "maxDaysToExpiration": {
- "minimum": 0,
- "type": "number"
- },
- "minDaysToExpiration": {
- "minimum": 0,
- "type": "number"
- },
- "preference": {
- "enum": [
- "nearest",
- "middle",
- "furthest"
- ],
- "type": "string"
- }
- },
- "required": [
- "minDaysToExpiration",
- "maxDaysToExpiration",
- "preference"
- ],
- "type": "object"
- },
- "fallbackStrikeSelector": {
- "additionalProperties": false,
- "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
- "properties": {
- "distance": {
- "type": "number"
- },
- "distanceType": {
- "enum": [
- "percent",
- "dollars"
- ],
- "type": "string"
- }
- },
- "required": [
- "distanceType",
- "distance"
- ],
- "type": "object"
- },
- "greekFilter": {
- "additionalProperties": true,
- "description": "Optional min/max constraints on Greeks during resolution.",
- "type": "object"
- },
- "liquidityFilter": {
- "additionalProperties": false,
- "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
- "properties": {
- "maxSpreadAbsolute": {
- "type": "number"
- },
- "maxSpreadPct": {
- "type": "number"
- },
- "minBid": {
- "type": "number"
- }
- },
- "type": "object"
- },
- "optionType": {
- "enum": [
- "call",
- "put"
- ],
- "type": "string"
- },
- "ratio": {
- "type": "number"
- },
- "strikeRange": {
- "additionalProperties": true,
- "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
- "type": "object"
- },
- "strikeSelector": {
- "properties": {
- "distance": {
- "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
- "type": "number"
- },
- "distanceType": {
- "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
- "type": "string"
- }
- },
- "required": [
- "distanceType",
- "distance"
- ],
- "type": "object"
- }
- },
- "required": [
- "optionType",
- "direction",
- "expirationSelector",
- "strikeSelector"
- ],
- "type": "object"
- },
- "minItems": 1,
- "type": "array"
- },
- "name": {
- "type": "string"
- },
- "spreadType": {
- "enum": [
- "vertical",
- "calendar",
- "diagonal",
- "ironCondor",
- "straddle",
- "strangle",
- "custom"
- ],
- "type": "string"
- },
- "widthConstraint": {
- "additionalProperties": false,
- "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
- "properties": {
- "minWidthDollars": {
- "exclusiveMinimum": 0,
- "type": "number"
- },
- "minWidthPercent": {
- "exclusiveMinimum": 0,
- "type": "number"
- }
- },
- "type": "object"
- }
- },
- "required": [
- "legs"
- ],
- "type": "object"
- },
- "minItems": 1,
- "type": "array"
- },
- "universe": {
- "additionalProperties": true,
- "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
- "properties": {
- "assets": {
- "items": {
- "additionalProperties": true,
- "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
- "properties": {
- "name": {
- "type": "string"
- },
- "symbol": {
- "type": "string"
- },
- "type": {
- "enum": [
- "Stock",
- "Cryptocurrency",
- "Option",
- "Other"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "symbol"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "source": {
- "enum": [
- "ALL_US_STOCKS",
- "SP500",
- "NASDAQ100",
- "DJIA",
- "CRYPTO",
- "SPECIFIC_ASSETS"
- ],
- "type": "string"
- }
- },
- "required": [
- "source"
- ],
- "type": "object"
- },
- "weightIndicator": {
- "$ref": "#/$defs/indicator"
- }
- },
- "required": [
- "name"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "structureTemplates": {
- "items": {
- "additionalProperties": true,
- "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
- "properties": {
- "eligibility": {
- "$ref": "#/$defs/condition"
- },
- "legs": {
- "items": {
- "additionalProperties": true,
- "description": "Single leg of an option builder.",
- "properties": {
- "direction": {
- "enum": [
- "long",
- "short"
- ],
- "type": "string"
- },
- "expirationRange": {
- "additionalProperties": true,
- "type": "object"
- },
- "expirationSelector": {
- "properties": {
- "maxDaysToExpiration": {
- "minimum": 0,
- "type": "number"
- },
- "minDaysToExpiration": {
- "minimum": 0,
- "type": "number"
- },
- "preference": {
- "enum": [
- "nearest",
- "middle",
- "furthest"
- ],
- "type": "string"
- }
- },
- "required": [
- "minDaysToExpiration",
- "maxDaysToExpiration",
- "preference"
- ],
- "type": "object"
- },
- "fallbackStrikeSelector": {
- "additionalProperties": false,
- "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
- "properties": {
- "distance": {
- "type": "number"
- },
- "distanceType": {
- "enum": [
- "percent",
- "dollars"
- ],
- "type": "string"
- }
- },
- "required": [
- "distanceType",
- "distance"
- ],
- "type": "object"
- },
- "greekFilter": {
- "additionalProperties": true,
- "description": "Optional min/max constraints on Greeks during resolution.",
- "type": "object"
- },
- "liquidityFilter": {
- "additionalProperties": false,
- "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
- "properties": {
- "maxSpreadAbsolute": {
- "type": "number"
- },
- "maxSpreadPct": {
- "type": "number"
- },
- "minBid": {
- "type": "number"
- }
- },
- "type": "object"
- },
- "optionType": {
- "enum": [
- "call",
- "put"
- ],
- "type": "string"
- },
- "ratio": {
- "type": "number"
- },
- "strikeRange": {
- "additionalProperties": true,
- "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
- "type": "object"
- },
- "strikeSelector": {
- "properties": {
- "distance": {
- "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
- "type": "number"
- },
- "distanceType": {
- "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
- "type": "string"
- }
- },
- "required": [
- "distanceType",
- "distance"
- ],
- "type": "object"
- }
- },
- "required": [
- "optionType",
- "direction",
- "expirationSelector",
- "strikeSelector"
- ],
- "type": "object"
- },
- "minItems": 1,
- "type": "array"
- },
- "name": {
- "type": "string"
- },
- "spreadType": {
- "enum": [
- "vertical",
- "calendar",
- "diagonal",
- "ironCondor",
- "straddle",
- "strangle",
- "custom"
- ],
- "type": "string"
- },
- "widthConstraint": {
- "additionalProperties": false,
- "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
- "properties": {
- "minWidthDollars": {
- "exclusiveMinimum": 0,
- "type": "number"
- },
- "minWidthPercent": {
- "exclusiveMinimum": 0,
- "type": "number"
- }
- },
- "type": "object"
- }
- },
- "required": [
- "legs"
- ],
- "type": "object"
- },
- "minItems": 1,
- "type": "array"
- },
- "totalBudget": {
- "additionalProperties": true,
- "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
- "properties": {
- "amount": {
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "enum": [
- "dollars",
- "percent of portfolio"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "amount"
- ],
- "type": "object"
- },
- "type": {
- "const": "RebalanceOption",
- "type": "string"
- },
- "universe": {
- "additionalProperties": true,
- "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
- "properties": {
- "assets": {
- "items": {
- "additionalProperties": true,
- "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
- "properties": {
- "name": {
- "type": "string"
- },
- "symbol": {
- "type": "string"
- },
- "type": {
- "enum": [
- "Stock",
- "Cryptocurrency",
- "Option",
- "Other"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "symbol"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "source": {
- "enum": [
- "ALL_US_STOCKS",
- "SP500",
- "NASDAQ100",
- "DJIA",
- "CRYPTO",
- "SPECIFIC_ASSETS"
- ],
- "type": "string"
- }
- },
- "required": [
- "source"
- ],
- "type": "object"
- },
- "weightIndicator": {
- "$ref": "#/$defs/indicator"
- }
- },
- "required": [
- "type",
- "universe",
- "pipeline",
- "weightIndicator",
- "structureTemplates"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
- "properties": {
- "closeScope": {
- "enum": [
- "spread",
- "leg"
- ],
- "type": "string"
- },
- "direction": {
- "enum": [
- "long",
- "short"
- ],
- "type": "string"
- },
- "optionType": {
- "enum": [
- "call",
- "put"
- ],
- "type": "string"
- },
- "quantity": {
- "additionalProperties": true,
- "description": "How many contracts to close. Defaults to all matching when omitted.",
- "type": "object"
- },
- "spreadType": {
- "enum": [
- "vertical",
- "calendar",
- "diagonal",
- "ironCondor",
- "straddle",
- "strangle",
- "custom"
- ],
- "type": "string"
- },
- "triggers": {
- "items": {
- "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
- "oneOf": [
- {
- "additionalProperties": true,
- "properties": {
- "maxPnlPercent": {
- "type": "number"
- },
- "minPnlPercent": {
- "type": "number"
- },
- "type": {
- "const": "pnl",
- "type": "string"
- }
- },
- "required": [
- "type"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "maxDte": {
- "type": "number"
- },
- "minDte": {
- "type": "number"
- },
- "type": {
- "const": "dte",
- "type": "string"
- }
- },
- "required": [
- "type"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "maxDaysHeld": {
- "type": "number"
- },
- "minDaysHeld": {
- "type": "number"
- },
- "type": {
- "const": "daysHeld",
- "type": "string"
- }
- },
- "required": [
- "type"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "maxIv": {
- "type": "number"
- },
- "maxSpreadDelta": {
- "type": "number"
- },
- "maxSpreadTheta": {
- "type": "number"
- },
- "minIv": {
- "type": "number"
- },
- "minSpreadDelta": {
- "type": "number"
- },
- "minSpreadTheta": {
- "type": "number"
- },
- "type": {
- "const": "greeks",
- "type": "string"
- }
- },
- "required": [
- "type"
- ],
- "type": "object"
- }
- ],
- "type": "object"
- },
- "type": "array"
- },
- "type": {
- "const": "CloseOption",
- "type": "string"
- },
- "underlyings": {
- "items": {
- "type": "string"
- },
- "type": "array"
- }
- },
- "required": [
- "type"
- ],
- "type": "object"
- }
-]New value: +[
+ {
+ "additionalProperties": true,
+ "description": "Buy or Sell a stock/crypto position.",
+ "properties": {
+ "amount": {
+ "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
+ "properties": {
+ "amount": {
+ "type": "number"
+ },
+ "type": {
+ "enum": [
+ "percent of portfolio",
+ "percent of buying power",
+ "percent of current positions",
+ "dollars",
+ "number of assets"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "amount"
+ ],
+ "type": "object"
+ },
+ "targetAsset": {
+ "additionalProperties": true,
+ "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "symbol": {
+ "type": "string"
+ },
+ "type": {
+ "enum": [
+ "Stock",
+ "Cryptocurrency",
+ "Option",
+ "Other"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "symbol"
+ ],
+ "type": "object"
+ },
+ "type": {
+ "enum": [
+ "Buy",
+ "Sell"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "targetAsset",
+ "amount"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "description": "Send an alert message (no order).",
+ "properties": {
+ "message": {
+ "type": "string"
+ },
+ "type": {
+ "const": "Alert",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "message"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
+ "properties": {
+ "allocationPolicy": {
+ "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
+ "oneOf": [
+ {
+ "additionalProperties": false,
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "expectedReturnShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "riskAversion": {
+ "maximum": 1000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "turnoverPenalty": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "MeanVariance",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "riskAversion",
+ "expectedReturnShrinkage",
+ "covarianceShrinkage",
+ "turnoverPenalty",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "turnoverPenalty": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "RiskParity",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "covarianceShrinkage",
+ "turnoverPenalty",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "turnoverPenalty": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "MaximumDiversification",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "covarianceShrinkage",
+ "turnoverPenalty",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ }
+ ]
+ },
+ "canSell": {
+ "$ref": "#/$defs/condition",
+ "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
+ },
+ "deploymentPercent": {
+ "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
+ "maximum": 100,
+ "minimum": 0,
+ "type": "number"
+ },
+ "exposurePolicy": {
+ "additionalProperties": false,
+ "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "targetAnnualizedVolatilityPercent": {
+ "maximum": 1000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "VolatilityTarget",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "covarianceShrinkage",
+ "targetAnnualizedVolatilityPercent",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ },
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "perNameAllocation": {
+ "additionalProperties": true,
+ "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.",
+ "properties": {
+ "amount": {
+ "exclusiveMinimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "enum": [
+ "percent of portfolio",
+ "dollars"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "amount"
+ ],
+ "type": "object"
+ },
+ "pipeline": {
+ "items": {
+ "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
+ "oneOf": [
+ {
+ "additionalProperties": true,
+ "properties": {
+ "condition": {
+ "$ref": "#/$defs/condition"
+ },
+ "type": {
+ "const": "Filter",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "condition"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "type": {
+ "const": "SelectTop",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "limit",
+ "direction"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "percentile": {
+ "maximum": 100,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "SelectPercentile",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "percentile",
+ "direction"
+ ],
+ "type": "object"
+ }
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "type": {
+ "const": "DynamicRebalance",
+ "type": "string"
+ },
+ "universe": {
+ "additionalProperties": true,
+ "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
+ "properties": {
+ "assets": {
+ "items": {
+ "additionalProperties": true,
+ "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "symbol": {
+ "type": "string"
+ },
+ "type": {
+ "enum": [
+ "Stock",
+ "Cryptocurrency",
+ "Option",
+ "Other"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "symbol"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "source": {
+ "enum": [
+ "ALL_US_STOCKS",
+ "SP500",
+ "NASDAQ100",
+ "DJIA",
+ "CRYPTO",
+ "SPECIFIC_ASSETS"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "source"
+ ],
+ "type": "object"
+ },
+ "weightIndicator": {
+ "$ref": "#/$defs/indicator"
+ }
+ },
+ "required": [
+ "type",
+ "universe",
+ "pipeline",
+ "weightIndicator"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
+ "properties": {
+ "continueExisting": {
+ "type": "boolean"
+ },
+ "cooldownMinutes": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "executionModel": {
+ "type": "string"
+ },
+ "includeMarketData": {
+ "type": "boolean"
+ },
+ "initialMessage": {
+ "type": "string"
+ },
+ "maxIterations": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "planningModel": {
+ "type": "string"
+ },
+ "skipPlanning": {
+ "type": "boolean"
+ },
+ "type": {
+ "const": "LaunchAgent",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "planningModel",
+ "executionModel",
+ "initialMessage",
+ "maxIterations",
+ "includeMarketData",
+ "continueExisting",
+ "skipPlanning"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
+ "properties": {
+ "against": {
+ "additionalProperties": true,
+ "description": "Optional parent-position selector (e.g. for covered calls).",
+ "type": "object"
+ },
+ "allocation": {
+ "additionalProperties": true,
+ "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
+ "properties": {
+ "amount": {
+ "type": "number"
+ },
+ "type": {
+ "enum": [
+ "dollars",
+ "percent of portfolio",
+ "percent of buying power",
+ "contracts",
+ "percent of realized premium"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "amount"
+ ],
+ "type": "object"
+ },
+ "builder": {
+ "additionalProperties": true,
+ "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
+ "properties": {
+ "dynamicUnderlying": {
+ "additionalProperties": true,
+ "properties": {
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "pipeline": {
+ "items": {
+ "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
+ "oneOf": [
+ {
+ "additionalProperties": true,
+ "properties": {
+ "condition": {
+ "$ref": "#/$defs/condition"
+ },
+ "type": {
+ "const": "Filter",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "condition"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "type": {
+ "const": "SelectTop",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "limit",
+ "direction"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "percentile": {
+ "maximum": 100,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "SelectPercentile",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "percentile",
+ "direction"
+ ],
+ "type": "object"
+ }
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "universe": {
+ "additionalProperties": true,
+ "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
+ "properties": {
+ "assets": {
+ "items": {
+ "additionalProperties": true,
+ "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "symbol": {
+ "type": "string"
+ },
+ "type": {
+ "enum": [
+ "Stock",
+ "Cryptocurrency",
+ "Option",
+ "Other"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "symbol"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "source": {
+ "enum": [
+ "ALL_US_STOCKS",
+ "SP500",
+ "NASDAQ100",
+ "DJIA",
+ "CRYPTO",
+ "SPECIFIC_ASSETS"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "source"
+ ],
+ "type": "object"
+ }
+ },
+ "required": [
+ "universe"
+ ],
+ "type": "object"
+ },
+ "legs": {
+ "items": {
+ "additionalProperties": true,
+ "description": "Single leg of an option builder.",
+ "properties": {
+ "direction": {
+ "enum": [
+ "long",
+ "short"
+ ],
+ "type": "string"
+ },
+ "expirationRange": {
+ "additionalProperties": true,
+ "type": "object"
+ },
+ "expirationSelector": {
+ "properties": {
+ "maxDaysToExpiration": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "minDaysToExpiration": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "preference": {
+ "enum": [
+ "nearest",
+ "middle",
+ "furthest"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "minDaysToExpiration",
+ "maxDaysToExpiration",
+ "preference"
+ ],
+ "type": "object"
+ },
+ "fallbackStrikeSelector": {
+ "additionalProperties": false,
+ "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
+ "properties": {
+ "distance": {
+ "type": "number"
+ },
+ "distanceType": {
+ "enum": [
+ "percent",
+ "dollars"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "distanceType",
+ "distance"
+ ],
+ "type": "object"
+ },
+ "greekFilter": {
+ "additionalProperties": true,
+ "description": "Optional min/max constraints on Greeks during resolution.",
+ "type": "object"
+ },
+ "liquidityFilter": {
+ "additionalProperties": false,
+ "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
+ "properties": {
+ "maxSpreadAbsolute": {
+ "type": "number"
+ },
+ "maxSpreadPct": {
+ "type": "number"
+ },
+ "minBid": {
+ "type": "number"
+ }
+ },
+ "type": "object"
+ },
+ "optionType": {
+ "enum": [
+ "call",
+ "put"
+ ],
+ "type": "string"
+ },
+ "ratio": {
+ "type": "number"
+ },
+ "strikeRange": {
+ "additionalProperties": true,
+ "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
+ "type": "object"
+ },
+ "strikeSelector": {
+ "properties": {
+ "distance": {
+ "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
+ "type": "number"
+ },
+ "distanceType": {
+ "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "distanceType",
+ "distance"
+ ],
+ "type": "object"
+ }
+ },
+ "required": [
+ "optionType",
+ "direction",
+ "expirationSelector",
+ "strikeSelector"
+ ],
+ "type": "object"
+ },
+ "minItems": 1,
+ "type": "array"
+ },
+ "spreadType": {
+ "enum": [
+ "vertical",
+ "calendar",
+ "diagonal",
+ "ironCondor",
+ "straddle",
+ "strangle",
+ "custom"
+ ],
+ "type": "string"
+ },
+ "underlyingSymbol": {
+ "type": "string"
+ },
+ "widthConstraint": {
+ "additionalProperties": false,
+ "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
+ "properties": {
+ "minWidthDollars": {
+ "exclusiveMinimum": 0,
+ "type": "number"
+ },
+ "minWidthPercent": {
+ "exclusiveMinimum": 0,
+ "type": "number"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "required": [
+ "legs"
+ ],
+ "type": "object"
+ },
+ "type": {
+ "const": "OpenOption",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "builder"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
+ "properties": {
+ "allocationPolicy": {
+ "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
+ "oneOf": [
+ {
+ "additionalProperties": false,
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "expectedReturnShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "riskAversion": {
+ "maximum": 1000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "turnoverPenalty": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "MeanVariance",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "riskAversion",
+ "expectedReturnShrinkage",
+ "covarianceShrinkage",
+ "turnoverPenalty",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "turnoverPenalty": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "RiskParity",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "covarianceShrinkage",
+ "turnoverPenalty",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "turnoverPenalty": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "MaximumDiversification",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "covarianceShrinkage",
+ "turnoverPenalty",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ }
+ ]
+ },
+ "exposurePolicy": {
+ "additionalProperties": false,
+ "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "targetAnnualizedVolatilityPercent": {
+ "maximum": 1000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "VolatilityTarget",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "covarianceShrinkage",
+ "targetAnnualizedVolatilityPercent",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ },
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "perNameAllocation": {
+ "additionalProperties": true,
+ "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
+ "properties": {
+ "amount": {
+ "type": "number"
+ },
+ "type": {
+ "enum": [
+ "dollars",
+ "percent of portfolio",
+ "percent of buying power",
+ "contracts",
+ "percent of realized premium"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "amount"
+ ],
+ "type": "object"
+ },
+ "pipeline": {
+ "items": {
+ "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
+ "oneOf": [
+ {
+ "additionalProperties": true,
+ "properties": {
+ "condition": {
+ "$ref": "#/$defs/condition"
+ },
+ "type": {
+ "const": "Filter",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "condition"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "type": {
+ "const": "SelectTop",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "limit",
+ "direction"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "percentile": {
+ "maximum": 100,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "SelectPercentile",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "percentile",
+ "direction"
+ ],
+ "type": "object"
+ }
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "positionScope": {
+ "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
+ "enum": [
+ "portfolio",
+ "strategy"
+ ],
+ "type": "string"
+ },
+ "sleeves": {
+ "items": {
+ "additionalProperties": true,
+ "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
+ "properties": {
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "name": {
+ "type": "string"
+ },
+ "perNameAllocation": {
+ "additionalProperties": true,
+ "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
+ "properties": {
+ "amount": {
+ "type": "number"
+ },
+ "type": {
+ "enum": [
+ "dollars",
+ "percent of portfolio",
+ "percent of buying power",
+ "contracts",
+ "percent of realized premium"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "amount"
+ ],
+ "type": "object"
+ },
+ "pipeline": {
+ "items": {
+ "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
+ "oneOf": [
+ {
+ "additionalProperties": true,
+ "properties": {
+ "condition": {
+ "$ref": "#/$defs/condition"
+ },
+ "type": {
+ "const": "Filter",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "condition"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "type": {
+ "const": "SelectTop",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "limit",
+ "direction"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "percentile": {
+ "maximum": 100,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "SelectPercentile",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "percentile",
+ "direction"
+ ],
+ "type": "object"
+ }
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "structureTemplates": {
+ "items": {
+ "additionalProperties": true,
+ "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
+ "properties": {
+ "eligibility": {
+ "$ref": "#/$defs/condition"
+ },
+ "legs": {
+ "items": {
+ "additionalProperties": true,
+ "description": "Single leg of an option builder.",
+ "properties": {
+ "direction": {
+ "enum": [
+ "long",
+ "short"
+ ],
+ "type": "string"
+ },
+ "expirationRange": {
+ "additionalProperties": true,
+ "type": "object"
+ },
+ "expirationSelector": {
+ "properties": {
+ "maxDaysToExpiration": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "minDaysToExpiration": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "preference": {
+ "enum": [
+ "nearest",
+ "middle",
+ "furthest"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "minDaysToExpiration",
+ "maxDaysToExpiration",
+ "preference"
+ ],
+ "type": "object"
+ },
+ "fallbackStrikeSelector": {
+ "additionalProperties": false,
+ "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
+ "properties": {
+ "distance": {
+ "type": "number"
+ },
+ "distanceType": {
+ "enum": [
+ "percent",
+ "dollars"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "distanceType",
+ "distance"
+ ],
+ "type": "object"
+ },
+ "greekFilter": {
+ "additionalProperties": true,
+ "description": "Optional min/max constraints on Greeks during resolution.",
+ "type": "object"
+ },
+ "liquidityFilter": {
+ "additionalProperties": false,
+ "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
+ "properties": {
+ "maxSpreadAbsolute": {
+ "type": "number"
+ },
+ "maxSpreadPct": {
+ "type": "number"
+ },
+ "minBid": {
+ "type": "number"
+ }
+ },
+ "type": "object"
+ },
+ "optionType": {
+ "enum": [
+ "call",
+ "put"
+ ],
+ "type": "string"
+ },
+ "ratio": {
+ "type": "number"
+ },
+ "strikeRange": {
+ "additionalProperties": true,
+ "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
+ "type": "object"
+ },
+ "strikeSelector": {
+ "properties": {
+ "distance": {
+ "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
+ "type": "number"
+ },
+ "distanceType": {
+ "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "distanceType",
+ "distance"
+ ],
+ "type": "object"
+ }
+ },
+ "required": [
+ "optionType",
+ "direction",
+ "expirationSelector",
+ "strikeSelector"
+ ],
+ "type": "object"
+ },
+ "minItems": 1,
+ "type": "array"
+ },
+ "name": {
+ "type": "string"
+ },
+ "spreadType": {
+ "enum": [
+ "vertical",
+ "calendar",
+ "diagonal",
+ "ironCondor",
+ "straddle",
+ "strangle",
+ "custom"
+ ],
+ "type": "string"
+ },
+ "widthConstraint": {
+ "additionalProperties": false,
+ "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
+ "properties": {
+ "minWidthDollars": {
+ "exclusiveMinimum": 0,
+ "type": "number"
+ },
+ "minWidthPercent": {
+ "exclusiveMinimum": 0,
+ "type": "number"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "required": [
+ "legs"
+ ],
+ "type": "object"
+ },
+ "minItems": 1,
+ "type": "array"
+ },
+ "universe": {
+ "additionalProperties": true,
+ "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
+ "properties": {
+ "assets": {
+ "items": {
+ "additionalProperties": true,
+ "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "symbol": {
+ "type": "string"
+ },
+ "type": {
+ "enum": [
+ "Stock",
+ "Cryptocurrency",
+ "Option",
+ "Other"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "symbol"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "source": {
+ "enum": [
+ "ALL_US_STOCKS",
+ "SP500",
+ "NASDAQ100",
+ "DJIA",
+ "CRYPTO",
+ "SPECIFIC_ASSETS"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "source"
+ ],
+ "type": "object"
+ },
+ "weightIndicator": {
+ "$ref": "#/$defs/indicator"
+ }
+ },
+ "required": [
+ "name"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "structureTemplates": {
+ "items": {
+ "additionalProperties": true,
+ "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
+ "properties": {
+ "eligibility": {
+ "$ref": "#/$defs/condition"
+ },
+ "legs": {
+ "items": {
+ "additionalProperties": true,
+ "description": "Single leg of an option builder.",
+ "properties": {
+ "direction": {
+ "enum": [
+ "long",
+ "short"
+ ],
+ "type": "string"
+ },
+ "expirationRange": {
+ "additionalProperties": true,
+ "type": "object"
+ },
+ "expirationSelector": {
+ "properties": {
+ "maxDaysToExpiration": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "minDaysToExpiration": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "preference": {
+ "enum": [
+ "nearest",
+ "middle",
+ "furthest"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "minDaysToExpiration",
+ "maxDaysToExpiration",
+ "preference"
+ ],
+ "type": "object"
+ },
+ "fallbackStrikeSelector": {
+ "additionalProperties": false,
+ "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
+ "properties": {
+ "distance": {
+ "type": "number"
+ },
+ "distanceType": {
+ "enum": [
+ "percent",
+ "dollars"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "distanceType",
+ "distance"
+ ],
+ "type": "object"
+ },
+ "greekFilter": {
+ "additionalProperties": true,
+ "description": "Optional min/max constraints on Greeks during resolution.",
+ "type": "object"
+ },
+ "liquidityFilter": {
+ "additionalProperties": false,
+ "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
+ "properties": {
+ "maxSpreadAbsolute": {
+ "type": "number"
+ },
+ "maxSpreadPct": {
+ "type": "number"
+ },
+ "minBid": {
+ "type": "number"
+ }
+ },
+ "type": "object"
+ },
+ "optionType": {
+ "enum": [
+ "call",
+ "put"
+ ],
+ "type": "string"
+ },
+ "ratio": {
+ "type": "number"
+ },
+ "strikeRange": {
+ "additionalProperties": true,
+ "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
+ "type": "object"
+ },
+ "strikeSelector": {
+ "properties": {
+ "distance": {
+ "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
+ "type": "number"
+ },
+ "distanceType": {
+ "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "distanceType",
+ "distance"
+ ],
+ "type": "object"
+ }
+ },
+ "required": [
+ "optionType",
+ "direction",
+ "expirationSelector",
+ "strikeSelector"
+ ],
+ "type": "object"
+ },
+ "minItems": 1,
+ "type": "array"
+ },
+ "name": {
+ "type": "string"
+ },
+ "spreadType": {
+ "enum": [
+ "vertical",
+ "calendar",
+ "diagonal",
+ "ironCondor",
+ "straddle",
+ "strangle",
+ "custom"
+ ],
+ "type": "string"
+ },
+ "widthConstraint": {
+ "additionalProperties": false,
+ "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
+ "properties": {
+ "minWidthDollars": {
+ "exclusiveMinimum": 0,
+ "type": "number"
+ },
+ "minWidthPercent": {
+ "exclusiveMinimum": 0,
+ "type": "number"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "required": [
+ "legs"
+ ],
+ "type": "object"
+ },
+ "minItems": 1,
+ "type": "array"
+ },
+ "totalBudget": {
+ "additionalProperties": true,
+ "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
+ "properties": {
+ "amount": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "enum": [
+ "dollars",
+ "percent of portfolio"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "amount"
+ ],
+ "type": "object"
+ },
+ "type": {
+ "const": "RebalanceOption",
+ "type": "string"
+ },
+ "universe": {
+ "additionalProperties": true,
+ "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
+ "properties": {
+ "assets": {
+ "items": {
+ "additionalProperties": true,
+ "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "symbol": {
+ "type": "string"
+ },
+ "type": {
+ "enum": [
+ "Stock",
+ "Cryptocurrency",
+ "Option",
+ "Other"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "symbol"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "source": {
+ "enum": [
+ "ALL_US_STOCKS",
+ "SP500",
+ "NASDAQ100",
+ "DJIA",
+ "CRYPTO",
+ "SPECIFIC_ASSETS"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "source"
+ ],
+ "type": "object"
+ },
+ "weightIndicator": {
+ "$ref": "#/$defs/indicator"
+ }
+ },
+ "required": [
+ "type",
+ "universe",
+ "pipeline",
+ "weightIndicator",
+ "structureTemplates"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
+ "properties": {
+ "closeScope": {
+ "enum": [
+ "spread",
+ "leg"
+ ],
+ "type": "string"
+ },
+ "direction": {
+ "enum": [
+ "long",
+ "short"
+ ],
+ "type": "string"
+ },
+ "optionType": {
+ "enum": [
+ "call",
+ "put"
+ ],
+ "type": "string"
+ },
+ "quantity": {
+ "additionalProperties": true,
+ "description": "How many contracts to close. Defaults to all matching when omitted.",
+ "type": "object"
+ },
+ "spreadType": {
+ "enum": [
+ "vertical",
+ "calendar",
+ "diagonal",
+ "ironCondor",
+ "straddle",
+ "strangle",
+ "custom"
+ ],
+ "type": "string"
+ },
+ "triggers": {
+ "items": {
+ "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
+ "oneOf": [
+ {
+ "additionalProperties": true,
+ "properties": {
+ "maxPnlPercent": {
+ "type": "number"
+ },
+ "minPnlPercent": {
+ "type": "number"
+ },
+ "type": {
+ "const": "pnl",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "maxDte": {
+ "type": "number"
+ },
+ "minDte": {
+ "type": "number"
+ },
+ "type": {
+ "const": "dte",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "maxDaysHeld": {
+ "type": "number"
+ },
+ "minDaysHeld": {
+ "type": "number"
+ },
+ "type": {
+ "const": "daysHeld",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "maxIv": {
+ "type": "number"
+ },
+ "maxSpreadDelta": {
+ "type": "number"
+ },
+ "maxSpreadTheta": {
+ "type": "number"
+ },
+ "minIv": {
+ "type": "number"
+ },
+ "minSpreadDelta": {
+ "type": "number"
+ },
+ "minSpreadTheta": {
+ "type": "number"
+ },
+ "type": {
+ "const": "greeks",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "type": "object"
+ }
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "type": {
+ "const": "CloseOption",
+ "type": "string"
+ },
+ "underlyings": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "type": "object"
+ }
+]
changedInput schema / $defs / indicator / description
Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), Option* indicators (need underlying + optionType + direction + spreadType), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
addedInput schema / $defs / indicator / properties / lookbackDays
Added value: +{
+ "description": "OptionRealizedPnL / OptionRealizedPremium: only count activity within this many days of the evaluation date. Omit for the whole life of the book.",
+ "maximum": 36500,
+ "minimum": 1,
+ "type": "integer"
+}
changedInput schema / $defs / indicator / properties / type / enum
Previous value: -[
- "DaysSinceAgent",
- "MinutesSinceAgent",
- "DaysSinceAlert",
- "MinutesSinceAlert",
- "StockReport",
- "DaysUntilEarnings",
- "DaysSinceEarnings",
- "ImpliedVolatility",
- "IVRank",
- "IVPercentile",
- "IVHVRatio",
- "LastOrderPrice",
- "Fundamental",
- "Economic",
- "CustomIndicator",
- "Index",
- "BollingerBand",
- "RelativeStrengthIndex",
- "PriceMeanAbsoluteDeviation",
- "ExponentialMovingAverage",
- "SimpleMovingAverage",
- "PriceStandardDeviation",
- "PriceRateOfChange",
- "MaxDrawdown",
- "MaxDrawup",
- "MinimumPrice",
- "MaximumPrice",
- "IndicatorMeanAbsoluteDeviation",
- "IndicatorExponentialMovingAverage",
- "IndicatorSimpleMovingAverage",
- "IndicatorStandardDeviation",
- "IndicatorRateOfChange",
- "DaysSinceOrder",
- "DaysSinceOptionOrder",
- "DaysSinceStrategyFired",
- "DaysSinceLastRebalanceOptionOrder",
- "MinutesSinceOptionOrder",
- "MinutesSinceOrder",
- "DaysSinceTransaction",
- "InitialValue",
- "BuyingPower",
- "PositionValue",
- "PositionPercentChange",
- "PortfolioValue",
- "RebalanceDecisionMetric",
- "Value",
- "Price",
- "Plus",
- "Minus",
- "Multiply",
- "Divide",
- "Negative",
- "AbsoluteValue",
- "SquareRoot",
- "Max",
- "Min",
- "Day",
- "Month",
- "Date",
- "Year",
- "CurrentTimeSeconds",
- "CurrentTimeMinutes",
- "CurrentTimeHours",
- "TrailingSum",
- "CompoundAnnualGrowthRate",
- "Log",
- "Exponentiation",
- "SumOrderQuantity",
- "SumOrderAmount",
- "MinutesAfterOpen",
- "OpeningPrice",
- "PreviousClosingPrice",
- "HighOfDay",
- "LowOfDay",
- "MinutesUntilClose",
- "PriceChangeSinceOpen",
- "GapSize",
- "GapPercentage",
- "TrueRange",
- "AverageTrueRange",
- "Volume",
- "VWAP",
- "BullishFairValueGap",
- "BearishFairValueGap",
- "IndicatorAtMinutesAfterOpen",
- "IndicatorWindowAgo",
- "IndicatorAtEntry",
- "IsIndexMember",
- "IsIndustry",
- "IsAssetType",
- "IsAsset",
- "IsNotAsset",
- "CrossAbove",
- "CrossBelow",
- "PositionMaxDrawdown",
- "PositionMaxDrawup",
- "UnderlyingMaxDrawdown",
- "ConsecutiveTrue",
- "CountTrue",
- "OptionPositionValue",
- "OptionPositionCount",
- "OptionPositionPercentChange",
- "OptionPositionMaxDrawdown",
- "OptionDaysToExpiration",
- "OptionDaysHeld",
- "OptionCollateral",
- "OptionSpreadCount",
- "OptionUnrealizedPnL",
- "OptionGrossExposurePercent"
-]New value: +[
+ "DaysSinceAgent",
+ "MinutesSinceAgent",
+ "DaysSinceAlert",
+ "MinutesSinceAlert",
+ "StockReport",
+ "DaysUntilEarnings",
+ "DaysSinceEarnings",
+ "ImpliedVolatility",
+ "IVRank",
+ "IVPercentile",
+ "IVHVRatio",
+ "LastOrderPrice",
+ "Fundamental",
+ "Economic",
+ "CustomIndicator",
+ "Index",
+ "BollingerBand",
+ "RelativeStrengthIndex",
+ "PriceMeanAbsoluteDeviation",
+ "ExponentialMovingAverage",
+ "SimpleMovingAverage",
+ "PriceStandardDeviation",
+ "PriceRateOfChange",
+ "MaxDrawdown",
+ "MaxDrawup",
+ "MinimumPrice",
+ "MaximumPrice",
+ "IndicatorMeanAbsoluteDeviation",
+ "IndicatorExponentialMovingAverage",
+ "IndicatorSimpleMovingAverage",
+ "IndicatorStandardDeviation",
+ "IndicatorRateOfChange",
+ "DaysSinceOrder",
+ "DaysSinceOptionOrder",
+ "DaysSinceStrategyFired",
+ "DaysSinceLastRebalanceOptionOrder",
+ "MinutesSinceOptionOrder",
+ "MinutesSinceOrder",
+ "DaysSinceTransaction",
+ "InitialValue",
+ "BuyingPower",
+ "PositionValue",
+ "PositionPercentChange",
+ "PortfolioValue",
+ "RebalanceDecisionMetric",
+ "Value",
+ "Price",
+ "Plus",
+ "Minus",
+ "Multiply",
+ "Divide",
+ "Negative",
+ "AbsoluteValue",
+ "SquareRoot",
+ "Max",
+ "Min",
+ "Day",
+ "Month",
+ "Date",
+ "Year",
+ "CurrentTimeSeconds",
+ "CurrentTimeMinutes",
+ "CurrentTimeHours",
+ "TrailingSum",
+ "CompoundAnnualGrowthRate",
+ "Log",
+ "Exponentiation",
+ "SumOrderQuantity",
+ "SumOrderAmount",
+ "MinutesAfterOpen",
+ "OpeningPrice",
+ "PreviousClosingPrice",
+ "HighOfDay",
+ "LowOfDay",
+ "MinutesUntilClose",
+ "PriceChangeSinceOpen",
+ "GapSize",
+ "GapPercentage",
+ "TrueRange",
+ "AverageTrueRange",
+ "Volume",
+ "VWAP",
+ "BullishFairValueGap",
+ "BearishFairValueGap",
+ "IndicatorAtMinutesAfterOpen",
+ "IndicatorWindowAgo",
+ "IndicatorAtEntry",
+ "IsIndexMember",
+ "IsIndustry",
+ "IsAssetType",
+ "IsAsset",
+ "IsNotAsset",
+ "CrossAbove",
+ "CrossBelow",
+ "PositionMaxDrawdown",
+ "PositionMaxDrawup",
+ "UnderlyingMaxDrawdown",
+ "ConsecutiveTrue",
+ "CountTrue",
+ "OptionPositionValue",
+ "OptionPositionCount",
+ "OptionPositionPercentChange",
+ "OptionPositionMaxDrawdown",
+ "OptionDaysToExpiration",
+ "OptionDaysHeld",
+ "OptionCollateral",
+ "OptionSpreadCount",
+ "OptionUnrealizedPnL",
+ "OptionRealizedPnL",
+ "OptionRealizedPremium",
+ "OptionGrossExposurePercent"
+]
changedInput schema / $defs / rebalanceOptionSleeve / properties / perNameAllocation / description
Previous value: -"Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'."New value: +"Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'."
changedInput schema / $defs / rebalanceOptionSleeve / properties / perNameAllocation / properties / type / enum
Previous value: -[
- "dollars",
- "percent of portfolio",
- "percent of buying power",
- "contracts"
-]New value: +[
+ "dollars",
+ "percent of portfolio",
+ "percent of buying power",
+ "contracts",
+ "percent of realized premium"
+]
changedInput schema / $defs / strategy / properties / action / oneOf
Previous value: -[
- {
- "additionalProperties": true,
- "description": "Buy or Sell a stock/crypto position.",
- "properties": {
- "amount": {
- "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
- "properties": {
- "amount": {
- "type": "number"
- },
- "type": {
- "enum": [
- "percent of portfolio",
- "percent of buying power",
- "percent of current positions",
- "dollars",
- "number of assets"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "amount"
- ],
- "type": "object"
- },
- "targetAsset": {
- "additionalProperties": true,
- "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
- "properties": {
- "name": {
- "type": "string"
- },
- "symbol": {
- "type": "string"
- },
- "type": {
- "enum": [
- "Stock",
- "Cryptocurrency",
- "Option",
- "Other"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "symbol"
- ],
- "type": "object"
- },
- "type": {
- "enum": [
- "Buy",
- "Sell"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "targetAsset",
- "amount"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "description": "Send an alert message (no order).",
- "properties": {
- "message": {
- "type": "string"
- },
- "type": {
- "const": "Alert",
- "type": "string"
- }
- },
- "required": [
- "type",
- "message"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
- "properties": {
- "allocationPolicy": {
- "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
- "oneOf": [
- {
- "additionalProperties": false,
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "expectedReturnShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "riskAversion": {
- "maximum": 1000,
- "minimum": 0,
- "type": "number"
- },
- "turnoverPenalty": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "MeanVariance",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "riskAversion",
- "expectedReturnShrinkage",
- "covarianceShrinkage",
- "turnoverPenalty",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "turnoverPenalty": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "RiskParity",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "covarianceShrinkage",
- "turnoverPenalty",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "turnoverPenalty": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "MaximumDiversification",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "covarianceShrinkage",
- "turnoverPenalty",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- }
- ]
- },
- "canSell": {
- "$ref": "#/$defs/condition",
- "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
- },
- "deploymentPercent": {
- "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
- "maximum": 100,
- "minimum": 0,
- "type": "number"
- },
- "exposurePolicy": {
- "additionalProperties": false,
- "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "targetAnnualizedVolatilityPercent": {
- "maximum": 1000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "VolatilityTarget",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "covarianceShrinkage",
- "targetAnnualizedVolatilityPercent",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- },
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "perNameAllocation": {
- "additionalProperties": true,
- "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
- "properties": {
- "amount": {
- "exclusiveMinimum": 0,
- "type": "number"
- },
- "type": {
- "enum": [
- "percent of portfolio",
- "dollars"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "amount"
- ],
- "type": "object"
- },
- "pipeline": {
- "items": {
- "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
- "oneOf": [
- {
- "additionalProperties": true,
- "properties": {
- "condition": {
- "$ref": "#/$defs/condition"
- },
- "type": {
- "const": "Filter",
- "type": "string"
- }
- },
- "required": [
- "type",
- "condition"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "type": {
- "const": "SelectTop",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "limit",
- "direction"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "percentile": {
- "maximum": 100,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "SelectPercentile",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "percentile",
- "direction"
- ],
- "type": "object"
- }
- ],
- "type": "object"
- },
- "type": "array"
- },
- "type": {
- "const": "DynamicRebalance",
- "type": "string"
- },
- "universe": {
- "additionalProperties": true,
- "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
- "properties": {
- "assets": {
- "items": {
- "additionalProperties": true,
- "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
- "properties": {
- "name": {
- "type": "string"
- },
- "symbol": {
- "type": "string"
- },
- "type": {
- "enum": [
- "Stock",
- "Cryptocurrency",
- "Option",
- "Other"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "symbol"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "source": {
- "enum": [
- "ALL_US_STOCKS",
- "SP500",
- "NASDAQ100",
- "DJIA",
- "CRYPTO",
- "SPECIFIC_ASSETS"
- ],
- "type": "string"
- }
- },
- "required": [
- "source"
- ],
- "type": "object"
- },
- "weightIndicator": {
- "$ref": "#/$defs/indicator"
- }
- },
- "required": [
- "type",
- "universe",
- "pipeline",
- "weightIndicator"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
- "properties": {
- "continueExisting": {
- "type": "boolean"
- },
- "cooldownMinutes": {
- "minimum": 0,
- "type": "number"
- },
- "executionModel": {
- "type": "string"
- },
- "includeMarketData": {
- "type": "boolean"
- },
- "initialMessage": {
- "type": "string"
- },
- "maxIterations": {
- "minimum": 1,
- "type": "number"
- },
- "planningModel": {
- "type": "string"
- },
- "skipPlanning": {
- "type": "boolean"
- },
- "type": {
- "const": "LaunchAgent",
- "type": "string"
- }
- },
- "required": [
- "type",
- "planningModel",
- "executionModel",
- "initialMessage",
- "maxIterations",
- "includeMarketData",
- "continueExisting",
- "skipPlanning"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
- "properties": {
- "against": {
- "additionalProperties": true,
- "description": "Optional parent-position selector (e.g. for covered calls).",
- "type": "object"
- },
- "allocation": {
- "additionalProperties": true,
- "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
- "properties": {
- "amount": {
- "type": "number"
- },
- "type": {
- "enum": [
- "dollars",
- "percent of portfolio",
- "percent of buying power",
- "contracts"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "amount"
- ],
- "type": "object"
- },
- "builder": {
- "additionalProperties": true,
- "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
- "properties": {
- "dynamicUnderlying": {
- "additionalProperties": true,
- "properties": {
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "pipeline": {
- "items": {
- "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
- "oneOf": [
- {
- "additionalProperties": true,
- "properties": {
- "condition": {
- "$ref": "#/$defs/condition"
- },
- "type": {
- "const": "Filter",
- "type": "string"
- }
- },
- "required": [
- "type",
- "condition"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "type": {
- "const": "SelectTop",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "limit",
- "direction"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "percentile": {
- "maximum": 100,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "SelectPercentile",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "percentile",
- "direction"
- ],
- "type": "object"
- }
- ],
- "type": "object"
- },
- "type": "array"
- },
- "universe": {
- "additionalProperties": true,
- "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
- "properties": {
- "assets": {
- "items": {
- "additionalProperties": true,
- "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
- "properties": {
- "name": {
- "type": "string"
- },
- "symbol": {
- "type": "string"
- },
- "type": {
- "enum": [
- "Stock",
- "Cryptocurrency",
- "Option",
- "Other"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "symbol"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "source": {
- "enum": [
- "ALL_US_STOCKS",
- "SP500",
- "NASDAQ100",
- "DJIA",
- "CRYPTO",
- "SPECIFIC_ASSETS"
- ],
- "type": "string"
- }
- },
- "required": [
- "source"
- ],
- "type": "object"
- }
- },
- "required": [
- "universe"
- ],
- "type": "object"
- },
- "legs": {
- "items": {
- "additionalProperties": true,
- "description": "Single leg of an option builder.",
- "properties": {
- "direction": {
- "enum": [
- "long",
- "short"
- ],
- "type": "string"
- },
- "expirationRange": {
- "additionalProperties": true,
- "type": "object"
- },
- "expirationSelector": {
- "properties": {
- "maxDaysToExpiration": {
- "minimum": 0,
- "type": "number"
- },
- "minDaysToExpiration": {
- "minimum": 0,
- "type": "number"
- },
- "preference": {
- "enum": [
- "nearest",
- "middle",
- "furthest"
- ],
- "type": "string"
- }
- },
- "required": [
- "minDaysToExpiration",
- "maxDaysToExpiration",
- "preference"
- ],
- "type": "object"
- },
- "fallbackStrikeSelector": {
- "additionalProperties": false,
- "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
- "properties": {
- "distance": {
- "type": "number"
- },
- "distanceType": {
- "enum": [
- "percent",
- "dollars"
- ],
- "type": "string"
- }
- },
- "required": [
- "distanceType",
- "distance"
- ],
- "type": "object"
- },
- "greekFilter": {
- "additionalProperties": true,
- "description": "Optional min/max constraints on Greeks during resolution.",
- "type": "object"
- },
- "liquidityFilter": {
- "additionalProperties": false,
- "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
- "properties": {
- "maxSpreadAbsolute": {
- "type": "number"
- },
- "maxSpreadPct": {
- "type": "number"
- },
- "minBid": {
- "type": "number"
- }
- },
- "type": "object"
- },
- "optionType": {
- "enum": [
- "call",
- "put"
- ],
- "type": "string"
- },
- "ratio": {
- "type": "number"
- },
- "strikeRange": {
- "additionalProperties": true,
- "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
- "type": "object"
- },
- "strikeSelector": {
- "properties": {
- "distance": {
- "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
- "type": "number"
- },
- "distanceType": {
- "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
- "type": "string"
- }
- },
- "required": [
- "distanceType",
- "distance"
- ],
- "type": "object"
- }
- },
- "required": [
- "optionType",
- "direction",
- "expirationSelector",
- "strikeSelector"
- ],
- "type": "object"
- },
- "minItems": 1,
- "type": "array"
- },
- "spreadType": {
- "enum": [
- "vertical",
- "calendar",
- "diagonal",
- "ironCondor",
- "straddle",
- "strangle",
- "custom"
- ],
- "type": "string"
- },
- "underlyingSymbol": {
- "type": "string"
- },
- "widthConstraint": {
- "additionalProperties": false,
- "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
- "properties": {
- "minWidthDollars": {
- "exclusiveMinimum": 0,
- "type": "number"
- },
- "minWidthPercent": {
- "exclusiveMinimum": 0,
- "type": "number"
- }
- },
- "type": "object"
- }
- },
- "required": [
- "legs"
- ],
- "type": "object"
- },
- "type": {
- "const": "OpenOption",
- "type": "string"
- }
- },
- "required": [
- "type",
- "builder"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
- "properties": {
- "allocationPolicy": {
- "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
- "oneOf": [
- {
- "additionalProperties": false,
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "expectedReturnShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "riskAversion": {
- "maximum": 1000,
- "minimum": 0,
- "type": "number"
- },
- "turnoverPenalty": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "MeanVariance",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "riskAversion",
- "expectedReturnShrinkage",
- "covarianceShrinkage",
- "turnoverPenalty",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "turnoverPenalty": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "RiskParity",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "covarianceShrinkage",
- "turnoverPenalty",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "turnoverPenalty": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "MaximumDiversification",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "covarianceShrinkage",
- "turnoverPenalty",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- }
- ]
- },
- "exposurePolicy": {
- "additionalProperties": false,
- "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "targetAnnualizedVolatilityPercent": {
- "maximum": 1000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "VolatilityTarget",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "covarianceShrinkage",
- "targetAnnualizedVolatilityPercent",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- },
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "perNameAllocation": {
- "additionalProperties": true,
- "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
- "properties": {
- "amount": {
- "type": "number"
- },
- "type": {
- "enum": [
- "dollars",
- "percent of portfolio",
- "percent of buying power",
- "contracts"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "amount"
- ],
- "type": "object"
- },
- "pipeline": {
- "items": {
- "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
- "oneOf": [
- {
- "additionalProperties": true,
- "properties": {
- "condition": {
- "$ref": "#/$defs/condition"
- },
- "type": {
- "const": "Filter",
- "type": "string"
- }
- },
- "required": [
- "type",
- "condition"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "type": {
- "const": "SelectTop",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "limit",
- "direction"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "percentile": {
- "maximum": 100,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "SelectPercentile",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "percentile",
- "direction"
- ],
- "type": "object"
- }
- ],
- "type": "object"
- },
- "type": "array"
- },
- "positionScope": {
- "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
- "enum": [
- "portfolio",
- "strategy"
- ],
- "type": "string"
- },
- "sleeves": {
- "items": {
- "additionalProperties": true,
- "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
- "properties": {
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "name": {
- "type": "string"
- },
- "perNameAllocation": {
- "additionalProperties": true,
- "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
- "properties": {
- "amount": {
- "type": "number"
- },
- "type": {
- "enum": [
- "dollars",
- "percent of portfolio",
- "percent of buying power",
- "contracts"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "amount"
- ],
- "type": "object"
- },
- "pipeline": {
- "items": {
- "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
- "oneOf": [
- {
- "additionalProperties": true,
- "properties": {
- "condition": {
- "$ref": "#/$defs/condition"
- },
- "type": {
- "const": "Filter",
- "type": "string"
- }
- },
- "required": [
- "type",
- "condition"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "type": {
- "const": "SelectTop",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "limit",
- "direction"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "percentile": {
- "maximum": 100,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "SelectPercentile",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "percentile",
- "direction"
- ],
- "type": "object"
- }
- ],
- "type": "object"
- },
- "type": "array"
- },
- "structureTemplates": {
- "items": {
- "additionalProperties": true,
- "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
- "properties": {
- "eligibility": {
- "$ref": "#/$defs/condition"
- },
- "legs": {
- "items": {
- "additionalProperties": true,
- "description": "Single leg of an option builder.",
- "properties": {
- "direction": {
- "enum": [
- "long",
- "short"
- ],
- "type": "string"
- },
- "expirationRange": {
- "additionalProperties": true,
- "type": "object"
- },
- "expirationSelector": {
- "properties": {
- "maxDaysToExpiration": {
- "minimum": 0,
- "type": "number"
- },
- "minDaysToExpiration": {
- "minimum": 0,
- "type": "number"
- },
- "preference": {
- "enum": [
- "nearest",
- "middle",
- "furthest"
- ],
- "type": "string"
- }
- },
- "required": [
- "minDaysToExpiration",
- "maxDaysToExpiration",
- "preference"
- ],
- "type": "object"
- },
- "fallbackStrikeSelector": {
- "additionalProperties": false,
- "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
- "properties": {
- "distance": {
- "type": "number"
- },
- "distanceType": {
- "enum": [
- "percent",
- "dollars"
- ],
- "type": "string"
- }
- },
- "required": [
- "distanceType",
- "distance"
- ],
- "type": "object"
- },
- "greekFilter": {
- "additionalProperties": true,
- "description": "Optional min/max constraints on Greeks during resolution.",
- "type": "object"
- },
- "liquidityFilter": {
- "additionalProperties": false,
- "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
- "properties": {
- "maxSpreadAbsolute": {
- "type": "number"
- },
- "maxSpreadPct": {
- "type": "number"
- },
- "minBid": {
- "type": "number"
- }
- },
- "type": "object"
- },
- "optionType": {
- "enum": [
- "call",
- "put"
- ],
- "type": "string"
- },
- "ratio": {
- "type": "number"
- },
- "strikeRange": {
- "additionalProperties": true,
- "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
- "type": "object"
- },
- "strikeSelector": {
- "properties": {
- "distance": {
- "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
- "type": "number"
- },
- "distanceType": {
- "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
- "type": "string"
- }
- },
- "required": [
- "distanceType",
- "distance"
- ],
- "type": "object"
- }
- },
- "required": [
- "optionType",
- "direction",
- "expirationSelector",
- "strikeSelector"
- ],
- "type": "object"
- },
- "minItems": 1,
- "type": "array"
- },
- "name": {
- "type": "string"
- },
- "spreadType": {
- "enum": [
- "vertical",
- "calendar",
- "diagonal",
- "ironCondor",
- "straddle",
- "strangle",
- "custom"
- ],
- "type": "string"
- },
- "widthConstraint": {
- "additionalProperties": false,
- "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
- "properties": {
- "minWidthDollars": {
- "exclusiveMinimum": 0,
- "type": "number"
- },
- "minWidthPercent": {
- "exclusiveMinimum": 0,
- "type": "number"
- }
- },
- "type": "object"
- }
- },
- "required": [
- "legs"
- ],
- "type": "object"
- },
- "minItems": 1,
- "type": "array"
- },
- "universe": {
- "additionalProperties": true,
- "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
- "properties": {
- "assets": {
- "items": {
- "additionalProperties": true,
- "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
- "properties": {
- "name": {
- "type": "string"
- },
- "symbol": {
- "type": "string"
- },
- "type": {
- "enum": [
- "Stock",
- "Cryptocurrency",
- "Option",
- "Other"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "symbol"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "source": {
- "enum": [
- "ALL_US_STOCKS",
- "SP500",
- "NASDAQ100",
- "DJIA",
- "CRYPTO",
- "SPECIFIC_ASSETS"
- ],
- "type": "string"
- }
- },
- "required": [
- "source"
- ],
- "type": "object"
- },
- "weightIndicator": {
- "$ref": "#/$defs/indicator"
- }
- },
- "required": [
- "name"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "structureTemplates": {
- "items": {
- "additionalProperties": true,
- "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
- "properties": {
- "eligibility": {
- "$ref": "#/$defs/condition"
- },
- "legs": {
- "items": {
- "additionalProperties": true,
- "description": "Single leg of an option builder.",
- "properties": {
- "direction": {
- "enum": [
- "long",
- "short"
- ],
- "type": "string"
- },
- "expirationRange": {
- "additionalProperties": true,
- "type": "object"
- },
- "expirationSelector": {
- "properties": {
- "maxDaysToExpiration": {
- "minimum": 0,
- "type": "number"
- },
- "minDaysToExpiration": {
- "minimum": 0,
- "type": "number"
- },
- "preference": {
- "enum": [
- "nearest",
- "middle",
- "furthest"
- ],
- "type": "string"
- }
- },
- "required": [
- "minDaysToExpiration",
- "maxDaysToExpiration",
- "preference"
- ],
- "type": "object"
- },
- "fallbackStrikeSelector": {
- "additionalProperties": false,
- "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
- "properties": {
- "distance": {
- "type": "number"
- },
- "distanceType": {
- "enum": [
- "percent",
- "dollars"
- ],
- "type": "string"
- }
- },
- "required": [
- "distanceType",
- "distance"
- ],
- "type": "object"
- },
- "greekFilter": {
- "additionalProperties": true,
- "description": "Optional min/max constraints on Greeks during resolution.",
- "type": "object"
- },
- "liquidityFilter": {
- "additionalProperties": false,
- "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
- "properties": {
- "maxSpreadAbsolute": {
- "type": "number"
- },
- "maxSpreadPct": {
- "type": "number"
- },
- "minBid": {
- "type": "number"
- }
- },
- "type": "object"
- },
- "optionType": {
- "enum": [
- "call",
- "put"
- ],
- "type": "string"
- },
- "ratio": {
- "type": "number"
- },
- "strikeRange": {
- "additionalProperties": true,
- "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
- "type": "object"
- },
- "strikeSelector": {
- "properties": {
- "distance": {
- "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
- "type": "number"
- },
- "distanceType": {
- "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
- "type": "string"
- }
- },
- "required": [
- "distanceType",
- "distance"
- ],
- "type": "object"
- }
- },
- "required": [
- "optionType",
- "direction",
- "expirationSelector",
- "strikeSelector"
- ],
- "type": "object"
- },
- "minItems": 1,
- "type": "array"
- },
- "name": {
- "type": "string"
- },
- "spreadType": {
- "enum": [
- "vertical",
- "calendar",
- "diagonal",
- "ironCondor",
- "straddle",
- "strangle",
- "custom"
- ],
- "type": "string"
- },
- "widthConstraint": {
- "additionalProperties": false,
- "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
- "properties": {
- "minWidthDollars": {
- "exclusiveMinimum": 0,
- "type": "number"
- },
- "minWidthPercent": {
- "exclusiveMinimum": 0,
- "type": "number"
- }
- },
- "type": "object"
- }
- },
- "required": [
- "legs"
- ],
- "type": "object"
- },
- "minItems": 1,
- "type": "array"
- },
- "totalBudget": {
- "additionalProperties": true,
- "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
- "properties": {
- "amount": {
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "enum": [
- "dollars",
- "percent of portfolio"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "amount"
- ],
- "type": "object"
- },
- "type": {
- "const": "RebalanceOption",
- "type": "string"
- },
- "universe": {
- "additionalProperties": true,
- "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
- "properties": {
- "assets": {
- "items": {
- "additionalProperties": true,
- "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
- "properties": {
- "name": {
- "type": "string"
- },
- "symbol": {
- "type": "string"
- },
- "type": {
- "enum": [
- "Stock",
- "Cryptocurrency",
- "Option",
- "Other"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "symbol"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "source": {
- "enum": [
- "ALL_US_STOCKS",
- "SP500",
- "NASDAQ100",
- "DJIA",
- "CRYPTO",
- "SPECIFIC_ASSETS"
- ],
- "type": "string"
- }
- },
- "required": [
- "source"
- ],
- "type": "object"
- },
- "weightIndicator": {
- "$ref": "#/$defs/indicator"
- }
- },
- "required": [
- "type",
- "universe",
- "pipeline",
- "weightIndicator",
- "structureTemplates"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
- "properties": {
- "closeScope": {
- "enum": [
- "spread",
- "leg"
- ],
- "type": "string"
- },
- "direction": {
- "enum": [
- "long",
- "short"
- ],
- "type": "string"
- },
- "optionType": {
- "enum": [
- "call",
- "put"
- ],
- "type": "string"
- },
- "quantity": {
- "additionalProperties": true,
- "description": "How many contracts to close. Defaults to all matching when omitted.",
- "type": "object"
- },
- "spreadType": {
- "enum": [
- "vertical",
- "calendar",
- "diagonal",
- "ironCondor",
- "straddle",
- "strangle",
- "custom"
- ],
- "type": "string"
- },
- "triggers": {
- "items": {
- "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
- "oneOf": [
- {
- "additionalProperties": true,
- "properties": {
- "maxPnlPercent": {
- "type": "number"
- },
- "minPnlPercent": {
- "type": "number"
- },
- "type": {
- "const": "pnl",
- "type": "string"
- }
- },
- "required": [
- "type"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "maxDte": {
- "type": "number"
- },
- "minDte": {
- "type": "number"
- },
- "type": {
- "const": "dte",
- "type": "string"
- }
- },
- "required": [
- "type"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "maxDaysHeld": {
- "type": "number"
- },
- "minDaysHeld": {
- "type": "number"
- },
- "type": {
- "const": "daysHeld",
- "type": "string"
- }
- },
- "required": [
- "type"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "maxIv": {
- "type": "number"
- },
- "maxSpreadDelta": {
- "type": "number"
- },
- "maxSpreadTheta": {
- "type": "number"
- },
- "minIv": {
- "type": "number"
- },
- "minSpreadDelta": {
- "type": "number"
- },
- "minSpreadTheta": {
- "type": "number"
- },
- "type": {
- "const": "greeks",
- "type": "string"
- }
- },
- "required": [
- "type"
- ],
- "type": "object"
- }
- ],
- "type": "object"
- },
- "type": "array"
- },
- "type": {
- "const": "CloseOption",
- "type": "string"
- },
- "underlyings": {
- "items": {
- "type": "string"
- },
- "type": "array"
- }
- },
- "required": [
- "type"
- ],
- "type": "object"
- }
-]New value: +[
+ {
+ "additionalProperties": true,
+ "description": "Buy or Sell a stock/crypto position.",
+ "properties": {
+ "amount": {
+ "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
+ "properties": {
+ "amount": {
+ "type": "number"
+ },
+ "type": {
+ "enum": [
+ "percent of portfolio",
+ "percent of buying power",
+ "percent of current positions",
+ "dollars",
+ "number of assets"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "amount"
+ ],
+ "type": "object"
+ },
+ "targetAsset": {
+ "additionalProperties": true,
+ "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "symbol": {
+ "type": "string"
+ },
+ "type": {
+ "enum": [
+ "Stock",
+ "Cryptocurrency",
+ "Option",
+ "Other"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "symbol"
+ ],
+ "type": "object"
+ },
+ "type": {
+ "enum": [
+ "Buy",
+ "Sell"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "targetAsset",
+ "amount"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "description": "Send an alert message (no order).",
+ "properties": {
+ "message": {
+ "type": "string"
+ },
+ "type": {
+ "const": "Alert",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "message"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
+ "properties": {
+ "allocationPolicy": {
+ "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
+ "oneOf": [
+ {
+ "additionalProperties": false,
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "expectedReturnShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "riskAversion": {
+ "maximum": 1000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "turnoverPenalty": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "MeanVariance",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "riskAversion",
+ "expectedReturnShrinkage",
+ "covarianceShrinkage",
+ "turnoverPenalty",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "turnoverPenalty": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "RiskParity",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "covarianceShrinkage",
+ "turnoverPenalty",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "turnoverPenalty": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "MaximumDiversification",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "covarianceShrinkage",
+ "turnoverPenalty",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ }
+ ]
+ },
+ "canSell": {
+ "$ref": "#/$defs/condition",
+ "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
+ },
+ "deploymentPercent": {
+ "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
+ "maximum": 100,
+ "minimum": 0,
+ "type": "number"
+ },
+ "exposurePolicy": {
+ "additionalProperties": false,
+ "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "targetAnnualizedVolatilityPercent": {
+ "maximum": 1000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "VolatilityTarget",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "covarianceShrinkage",
+ "targetAnnualizedVolatilityPercent",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ },
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "perNameAllocation": {
+ "additionalProperties": true,
+ "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.",
+ "properties": {
+ "amount": {
+ "exclusiveMinimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "enum": [
+ "percent of portfolio",
+ "dollars"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "amount"
+ ],
+ "type": "object"
+ },
+ "pipeline": {
+ "items": {
+ "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
+ "oneOf": [
+ {
+ "additionalProperties": true,
+ "properties": {
+ "condition": {
+ "$ref": "#/$defs/condition"
+ },
+ "type": {
+ "const": "Filter",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "condition"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "type": {
+ "const": "SelectTop",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "limit",
+ "direction"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "percentile": {
+ "maximum": 100,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "SelectPercentile",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "percentile",
+ "direction"
+ ],
+ "type": "object"
+ }
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "type": {
+ "const": "DynamicRebalance",
+ "type": "string"
+ },
+ "universe": {
+ "additionalProperties": true,
+ "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
+ "properties": {
+ "assets": {
+ "items": {
+ "additionalProperties": true,
+ "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "symbol": {
+ "type": "string"
+ },
+ "type": {
+ "enum": [
+ "Stock",
+ "Cryptocurrency",
+ "Option",
+ "Other"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "symbol"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "source": {
+ "enum": [
+ "ALL_US_STOCKS",
+ "SP500",
+ "NASDAQ100",
+ "DJIA",
+ "CRYPTO",
+ "SPECIFIC_ASSETS"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "source"
+ ],
+ "type": "object"
+ },
+ "weightIndicator": {
+ "$ref": "#/$defs/indicator"
+ }
+ },
+ "required": [
+ "type",
+ "universe",
+ "pipeline",
+ "weightIndicator"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
+ "properties": {
+ "continueExisting": {
+ "type": "boolean"
+ },
+ "cooldownMinutes": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "executionModel": {
+ "type": "string"
+ },
+ "includeMarketData": {
+ "type": "boolean"
+ },
+ "initialMessage": {
+ "type": "string"
+ },
+ "maxIterations": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "planningModel": {
+ "type": "string"
+ },
+ "skipPlanning": {
+ "type": "boolean"
+ },
+ "type": {
+ "const": "LaunchAgent",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "planningModel",
+ "executionModel",
+ "initialMessage",
+ "maxIterations",
+ "includeMarketData",
+ "continueExisting",
+ "skipPlanning"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
+ "properties": {
+ "against": {
+ "additionalProperties": true,
+ "description": "Optional parent-position selector (e.g. for covered calls).",
+ "type": "object"
+ },
+ "allocation": {
+ "additionalProperties": true,
+ "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
+ "properties": {
+ "amount": {
+ "type": "number"
+ },
+ "type": {
+ "enum": [
+ "dollars",
+ "percent of portfolio",
+ "percent of buying power",
+ "contracts",
+ "percent of realized premium"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "amount"
+ ],
+ "type": "object"
+ },
+ "builder": {
+ "additionalProperties": true,
+ "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
+ "properties": {
+ "dynamicUnderlying": {
+ "additionalProperties": true,
+ "properties": {
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "pipeline": {
+ "items": {
+ "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
+ "oneOf": [
+ {
+ "additionalProperties": true,
+ "properties": {
+ "condition": {
+ "$ref": "#/$defs/condition"
+ },
+ "type": {
+ "const": "Filter",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "condition"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "type": {
+ "const": "SelectTop",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "limit",
+ "direction"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "percentile": {
+ "maximum": 100,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "SelectPercentile",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "percentile",
+ "direction"
+ ],
+ "type": "object"
+ }
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "universe": {
+ "additionalProperties": true,
+ "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
+ "properties": {
+ "assets": {
+ "items": {
+ "additionalProperties": true,
+ "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "symbol": {
+ "type": "string"
+ },
+ "type": {
+ "enum": [
+ "Stock",
+ "Cryptocurrency",
+ "Option",
+ "Other"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "symbol"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "source": {
+ "enum": [
+ "ALL_US_STOCKS",
+ "SP500",
+ "NASDAQ100",
+ "DJIA",
+ "CRYPTO",
+ "SPECIFIC_ASSETS"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "source"
+ ],
+ "type": "object"
+ }
+ },
+ "required": [
+ "universe"
+ ],
+ "type": "object"
+ },
+ "legs": {
+ "items": {
+ "additionalProperties": true,
+ "description": "Single leg of an option builder.",
+ "properties": {
+ "direction": {
+ "enum": [
+ "long",
+ "short"
+ ],
+ "type": "string"
+ },
+ "expirationRange": {
+ "additionalProperties": true,
+ "type": "object"
+ },
+ "expirationSelector": {
+ "properties": {
+ "maxDaysToExpiration": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "minDaysToExpiration": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "preference": {
+ "enum": [
+ "nearest",
+ "middle",
+ "furthest"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "minDaysToExpiration",
+ "maxDaysToExpiration",
+ "preference"
+ ],
+ "type": "object"
+ },
+ "fallbackStrikeSelector": {
+ "additionalProperties": false,
+ "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
+ "properties": {
+ "distance": {
+ "type": "number"
+ },
+ "distanceType": {
+ "enum": [
+ "percent",
+ "dollars"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "distanceType",
+ "distance"
+ ],
+ "type": "object"
+ },
+ "greekFilter": {
+ "additionalProperties": true,
+ "description": "Optional min/max constraints on Greeks during resolution.",
+ "type": "object"
+ },
+ "liquidityFilter": {
+ "additionalProperties": false,
+ "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
+ "properties": {
+ "maxSpreadAbsolute": {
+ "type": "number"
+ },
+ "maxSpreadPct": {
+ "type": "number"
+ },
+ "minBid": {
+ "type": "number"
+ }
+ },
+ "type": "object"
+ },
+ "optionType": {
+ "enum": [
+ "call",
+ "put"
+ ],
+ "type": "string"
+ },
+ "ratio": {
+ "type": "number"
+ },
+ "strikeRange": {
+ "additionalProperties": true,
+ "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
+ "type": "object"
+ },
+ "strikeSelector": {
+ "properties": {
+ "distance": {
+ "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
+ "type": "number"
+ },
+ "distanceType": {
+ "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "distanceType",
+ "distance"
+ ],
+ "type": "object"
+ }
+ },
+ "required": [
+ "optionType",
+ "direction",
+ "expirationSelector",
+ "strikeSelector"
+ ],
+ "type": "object"
+ },
+ "minItems": 1,
+ "type": "array"
+ },
+ "spreadType": {
+ "enum": [
+ "vertical",
+ "calendar",
+ "diagonal",
+ "ironCondor",
+ "straddle",
+ "strangle",
+ "custom"
+ ],
+ "type": "string"
+ },
+ "underlyingSymbol": {
+ "type": "string"
+ },
+ "widthConstraint": {
+ "additionalProperties": false,
+ "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
+ "properties": {
+ "minWidthDollars": {
+ "exclusiveMinimum": 0,
+ "type": "number"
+ },
+ "minWidthPercent": {
+ "exclusiveMinimum": 0,
+ "type": "number"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "required": [
+ "legs"
+ ],
+ "type": "object"
+ },
+ "type": {
+ "const": "OpenOption",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "builder"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
+ "properties": {
+ "allocationPolicy": {
+ "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
+ "oneOf": [
+ {
+ "additionalProperties": false,
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "expectedReturnShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "riskAversion": {
+ "maximum": 1000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "turnoverPenalty": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "MeanVariance",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "riskAversion",
+ "expectedReturnShrinkage",
+ "covarianceShrinkage",
+ "turnoverPenalty",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "turnoverPenalty": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "RiskParity",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "covarianceShrinkage",
+ "turnoverPenalty",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "turnoverPenalty": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "MaximumDiversification",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "covarianceShrinkage",
+ "turnoverPenalty",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ }
+ ]
+ },
+ "exposurePolicy": {
+ "additionalProperties": false,
+ "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "targetAnnualizedVolatilityPercent": {
+ "maximum": 1000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "VolatilityTarget",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "covarianceShrinkage",
+ "targetAnnualizedVolatilityPercent",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ },
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "perNameAllocation": {
+ "additionalProperties": true,
+ "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
+ "properties": {
+ "amount": {
+ "type": "number"
+ },
+ "type": {
+ "enum": [
+ "dollars",
+ "percent of portfolio",
+ "percent of buying power",
+ "contracts",
+ "percent of realized premium"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "amount"
+ ],
+ "type": "object"
+ },
+ "pipeline": {
+ "items": {
+ "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
+ "oneOf": [
+ {
+ "additionalProperties": true,
+ "properties": {
+ "condition": {
+ "$ref": "#/$defs/condition"
+ },
+ "type": {
+ "const": "Filter",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "condition"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "type": {
+ "const": "SelectTop",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "limit",
+ "direction"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "percentile": {
+ "maximum": 100,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "SelectPercentile",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "percentile",
+ "direction"
+ ],
+ "type": "object"
+ }
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "positionScope": {
+ "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
+ "enum": [
+ "portfolio",
+ "strategy"
+ ],
+ "type": "string"
+ },
+ "sleeves": {
+ "items": {
+ "additionalProperties": true,
+ "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
+ "properties": {
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "name": {
+ "type": "string"
+ },
+ "perNameAllocation": {
+ "additionalProperties": true,
+ "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
+ "properties": {
+ "amount": {
+ "type": "number"
+ },
+ "type": {
+ "enum": [
+ "dollars",
+ "percent of portfolio",
+ "percent of buying power",
+ "contracts",
+ "percent of realized premium"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "amount"
+ ],
+ "type": "object"
+ },
+ "pipeline": {
+ "items": {
+ "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
+ "oneOf": [
+ {
+ "additionalProperties": true,
+ "properties": {
+ "condition": {
+ "$ref": "#/$defs/condition"
+ },
+ "type": {
+ "const": "Filter",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "condition"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "type": {
+ "const": "SelectTop",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "limit",
+ "direction"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "percentile": {
+ "maximum": 100,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "SelectPercentile",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "percentile",
+ "direction"
+ ],
+ "type": "object"
+ }
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "structureTemplates": {
+ "items": {
+ "additionalProperties": true,
+ "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
+ "properties": {
+ "eligibility": {
+ "$ref": "#/$defs/condition"
+ },
+ "legs": {
+ "items": {
+ "additionalProperties": true,
+ "description": "Single leg of an option builder.",
+ "properties": {
+ "direction": {
+ "enum": [
+ "long",
+ "short"
+ ],
+ "type": "string"
+ },
+ "expirationRange": {
+ "additionalProperties": true,
+ "type": "object"
+ },
+ "expirationSelector": {
+ "properties": {
+ "maxDaysToExpiration": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "minDaysToExpiration": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "preference": {
+ "enum": [
+ "nearest",
+ "middle",
+ "furthest"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "minDaysToExpiration",
+ "maxDaysToExpiration",
+ "preference"
+ ],
+ "type": "object"
+ },
+ "fallbackStrikeSelector": {
+ "additionalProperties": false,
+ "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
+ "properties": {
+ "distance": {
+ "type": "number"
+ },
+ "distanceType": {
+ "enum": [
+ "percent",
+ "dollars"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "distanceType",
+ "distance"
+ ],
+ "type": "object"
+ },
+ "greekFilter": {
+ "additionalProperties": true,
+ "description": "Optional min/max constraints on Greeks during resolution.",
+ "type": "object"
+ },
+ "liquidityFilter": {
+ "additionalProperties": false,
+ "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
+ "properties": {
+ "maxSpreadAbsolute": {
+ "type": "number"
+ },
+ "maxSpreadPct": {
+ "type": "number"
+ },
+ "minBid": {
+ "type": "number"
+ }
+ },
+ "type": "object"
+ },
+ "optionType": {
+ "enum": [
+ "call",
+ "put"
+ ],
+ "type": "string"
+ },
+ "ratio": {
+ "type": "number"
+ },
+ "strikeRange": {
+ "additionalProperties": true,
+ "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
+ "type": "object"
+ },
+ "strikeSelector": {
+ "properties": {
+ "distance": {
+ "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
+ "type": "number"
+ },
+ "distanceType": {
+ "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "distanceType",
+ "distance"
+ ],
+ "type": "object"
+ }
+ },
+ "required": [
+ "optionType",
+ "direction",
+ "expirationSelector",
+ "strikeSelector"
+ ],
+ "type": "object"
+ },
+ "minItems": 1,
+ "type": "array"
+ },
+ "name": {
+ "type": "string"
+ },
+ "spreadType": {
+ "enum": [
+ "vertical",
+ "calendar",
+ "diagonal",
+ "ironCondor",
+ "straddle",
+ "strangle",
+ "custom"
+ ],
+ "type": "string"
+ },
+ "widthConstraint": {
+ "additionalProperties": false,
+ "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
+ "properties": {
+ "minWidthDollars": {
+ "exclusiveMinimum": 0,
+ "type": "number"
+ },
+ "minWidthPercent": {
+ "exclusiveMinimum": 0,
+ "type": "number"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "required": [
+ "legs"
+ ],
+ "type": "object"
+ },
+ "minItems": 1,
+ "type": "array"
+ },
+ "universe": {
+ "additionalProperties": true,
+ "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
+ "properties": {
+ "assets": {
+ "items": {
+ "additionalProperties": true,
+ "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "symbol": {
+ "type": "string"
+ },
+ "type": {
+ "enum": [
+ "Stock",
+ "Cryptocurrency",
+ "Option",
+ "Other"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "symbol"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "source": {
+ "enum": [
+ "ALL_US_STOCKS",
+ "SP500",
+ "NASDAQ100",
+ "DJIA",
+ "CRYPTO",
+ "SPECIFIC_ASSETS"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "source"
+ ],
+ "type": "object"
+ },
+ "weightIndicator": {
+ "$ref": "#/$defs/indicator"
+ }
+ },
+ "required": [
+ "name"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "structureTemplates": {
+ "items": {
+ "additionalProperties": true,
+ "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
+ "properties": {
+ "eligibility": {
+ "$ref": "#/$defs/condition"
+ },
+ "legs": {
+ "items": {
+ "additionalProperties": true,
+ "description": "Single leg of an option builder.",
+ "properties": {
+ "direction": {
+ "enum": [
+ "long",
+ "short"
+ ],
+ "type": "string"
+ },
+ "expirationRange": {
+ "additionalProperties": true,
+ "type": "object"
+ },
+ "expirationSelector": {
+ "properties": {
+ "maxDaysToExpiration": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "minDaysToExpiration": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "preference": {
+ "enum": [
+ "nearest",
+ "middle",
+ "furthest"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "minDaysToExpiration",
+ "maxDaysToExpiration",
+ "preference"
+ ],
+ "type": "object"
+ },
+ "fallbackStrikeSelector": {
+ "additionalProperties": false,
+ "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
+ "properties": {
+ "distance": {
+ "type": "number"
+ },
+ "distanceType": {
+ "enum": [
+ "percent",
+ "dollars"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "distanceType",
+ "distance"
+ ],
+ "type": "object"
+ },
+ "greekFilter": {
+ "additionalProperties": true,
+ "description": "Optional min/max constraints on Greeks during resolution.",
+ "type": "object"
+ },
+ "liquidityFilter": {
+ "additionalProperties": false,
+ "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
+ "properties": {
+ "maxSpreadAbsolute": {
+ "type": "number"
+ },
+ "maxSpreadPct": {
+ "type": "number"
+ },
+ "minBid": {
+ "type": "number"
+ }
+ },
+ "type": "object"
+ },
+ "optionType": {
+ "enum": [
+ "call",
+ "put"
+ ],
+ "type": "string"
+ },
+ "ratio": {
+ "type": "number"
+ },
+ "strikeRange": {
+ "additionalProperties": true,
+ "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
+ "type": "object"
+ },
+ "strikeSelector": {
+ "properties": {
+ "distance": {
+ "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
+ "type": "number"
+ },
+ "distanceType": {
+ "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "distanceType",
+ "distance"
+ ],
+ "type": "object"
+ }
+ },
+ "required": [
+ "optionType",
+ "direction",
+ "expirationSelector",
+ "strikeSelector"
+ ],
+ "type": "object"
+ },
+ "minItems": 1,
+ "type": "array"
+ },
+ "name": {
+ "type": "string"
+ },
+ "spreadType": {
+ "enum": [
+ "vertical",
+ "calendar",
+ "diagonal",
+ "ironCondor",
+ "straddle",
+ "strangle",
+ "custom"
+ ],
+ "type": "string"
+ },
+ "widthConstraint": {
+ "additionalProperties": false,
+ "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
+ "properties": {
+ "minWidthDollars": {
+ "exclusiveMinimum": 0,
+ "type": "number"
+ },
+ "minWidthPercent": {
+ "exclusiveMinimum": 0,
+ "type": "number"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "required": [
+ "legs"
+ ],
+ "type": "object"
+ },
+ "minItems": 1,
+ "type": "array"
+ },
+ "totalBudget": {
+ "additionalProperties": true,
+ "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
+ "properties": {
+ "amount": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "enum": [
+ "dollars",
+ "percent of portfolio"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "amount"
+ ],
+ "type": "object"
+ },
+ "type": {
+ "const": "RebalanceOption",
+ "type": "string"
+ },
+ "universe": {
+ "additionalProperties": true,
+ "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
+ "properties": {
+ "assets": {
+ "items": {
+ "additionalProperties": true,
+ "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "symbol": {
+ "type": "string"
+ },
+ "type": {
+ "enum": [
+ "Stock",
+ "Cryptocurrency",
+ "Option",
+ "Other"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "symbol"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "source": {
+ "enum": [
+ "ALL_US_STOCKS",
+ "SP500",
+ "NASDAQ100",
+ "DJIA",
+ "CRYPTO",
+ "SPECIFIC_ASSETS"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "source"
+ ],
+ "type": "object"
+ },
+ "weightIndicator": {
+ "$ref": "#/$defs/indicator"
+ }
+ },
+ "required": [
+ "type",
+ "universe",
+ "pipeline",
+ "weightIndicator",
+ "structureTemplates"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
+ "properties": {
+ "closeScope": {
+ "enum": [
+ "spread",
+ "leg"
+ ],
+ "type": "string"
+ },
+ "direction": {
+ "enum": [
+ "long",
+ "short"
+ ],
+ "type": "string"
+ },
+ "optionType": {
+ "enum": [
+ "call",
+ "put"
+ ],
+ "type": "string"
+ },
+ "quantity": {
+ "additionalProperties": true,
+ "description": "How many contracts to close. Defaults to all matching when omitted.",
+ "type": "object"
+ },
+ "spreadType": {
+ "enum": [
+ "vertical",
+ "calendar",
+ "diagonal",
+ "ironCondor",
+ "straddle",
+ "strangle",
+ "custom"
+ ],
+ "type": "string"
+ },
+ "triggers": {
+ "items": {
+ "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
+ "oneOf": [
+ {
+ "additionalProperties": true,
+ "properties": {
+ "maxPnlPercent": {
+ "type": "number"
+ },
+ "minPnlPercent": {
+ "type": "number"
+ },
+ "type": {
+ "const": "pnl",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "maxDte": {
+ "type": "number"
+ },
+ "minDte": {
+ "type": "number"
+ },
+ "type": {
+ "const": "dte",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "maxDaysHeld": {
+ "type": "number"
+ },
+ "minDaysHeld": {
+ "type": "number"
+ },
+ "type": {
+ "const": "daysHeld",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "maxIv": {
+ "type": "number"
+ },
+ "maxSpreadDelta": {
+ "type": "number"
+ },
+ "maxSpreadTheta": {
+ "type": "number"
+ },
+ "minIv": {
+ "type": "number"
+ },
+ "minSpreadDelta": {
+ "type": "number"
+ },
+ "minSpreadTheta": {
+ "type": "number"
+ },
+ "type": {
+ "const": "greeks",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "type": "object"
+ }
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "type": {
+ "const": "CloseOption",
+ "type": "string"
+ },
+ "underlyings": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "type": "object"
+ }
+]
changedInput schema / properties / strategies / items / properties / action / oneOf
Previous value: -[
- {
- "additionalProperties": true,
- "description": "Buy or Sell a stock/crypto position.",
- "properties": {
- "amount": {
- "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
- "properties": {
- "amount": {
- "type": "number"
- },
- "type": {
- "enum": [
- "percent of portfolio",
- "percent of buying power",
- "percent of current positions",
- "dollars",
- "number of assets"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "amount"
- ],
- "type": "object"
- },
- "targetAsset": {
- "additionalProperties": true,
- "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
- "properties": {
- "name": {
- "type": "string"
- },
- "symbol": {
- "type": "string"
- },
- "type": {
- "enum": [
- "Stock",
- "Cryptocurrency",
- "Option",
- "Other"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "symbol"
- ],
- "type": "object"
- },
- "type": {
- "enum": [
- "Buy",
- "Sell"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "targetAsset",
- "amount"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "description": "Send an alert message (no order).",
- "properties": {
- "message": {
- "type": "string"
- },
- "type": {
- "const": "Alert",
- "type": "string"
- }
- },
- "required": [
- "type",
- "message"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
- "properties": {
- "allocationPolicy": {
- "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
- "oneOf": [
- {
- "additionalProperties": false,
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "expectedReturnShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "riskAversion": {
- "maximum": 1000,
- "minimum": 0,
- "type": "number"
- },
- "turnoverPenalty": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "MeanVariance",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "riskAversion",
- "expectedReturnShrinkage",
- "covarianceShrinkage",
- "turnoverPenalty",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "turnoverPenalty": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "RiskParity",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "covarianceShrinkage",
- "turnoverPenalty",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "turnoverPenalty": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "MaximumDiversification",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "covarianceShrinkage",
- "turnoverPenalty",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- }
- ]
- },
- "canSell": {
- "$ref": "#/$defs/condition",
- "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
- },
- "deploymentPercent": {
- "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
- "maximum": 100,
- "minimum": 0,
- "type": "number"
- },
- "exposurePolicy": {
- "additionalProperties": false,
- "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "targetAnnualizedVolatilityPercent": {
- "maximum": 1000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "VolatilityTarget",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "covarianceShrinkage",
- "targetAnnualizedVolatilityPercent",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- },
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "perNameAllocation": {
- "additionalProperties": true,
- "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
- "properties": {
- "amount": {
- "exclusiveMinimum": 0,
- "type": "number"
- },
- "type": {
- "enum": [
- "percent of portfolio",
- "dollars"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "amount"
- ],
- "type": "object"
- },
- "pipeline": {
- "items": {
- "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
- "oneOf": [
- {
- "additionalProperties": true,
- "properties": {
- "condition": {
- "$ref": "#/$defs/condition"
- },
- "type": {
- "const": "Filter",
- "type": "string"
- }
- },
- "required": [
- "type",
- "condition"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "type": {
- "const": "SelectTop",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "limit",
- "direction"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "percentile": {
- "maximum": 100,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "SelectPercentile",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "percentile",
- "direction"
- ],
- "type": "object"
- }
- ],
- "type": "object"
- },
- "type": "array"
- },
- "type": {
- "const": "DynamicRebalance",
- "type": "string"
- },
- "universe": {
- "additionalProperties": true,
- "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
- "properties": {
- "assets": {
- "items": {
- "additionalProperties": true,
- "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
- "properties": {
- "name": {
- "type": "string"
- },
- "symbol": {
- "type": "string"
- },
- "type": {
- "enum": [
- "Stock",
- "Cryptocurrency",
- "Option",
- "Other"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "symbol"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "source": {
- "enum": [
- "ALL_US_STOCKS",
- "SP500",
- "NASDAQ100",
- "DJIA",
- "CRYPTO",
- "SPECIFIC_ASSETS"
- ],
- "type": "string"
- }
- },
- "required": [
- "source"
- ],
- "type": "object"
- },
- "weightIndicator": {
- "$ref": "#/$defs/indicator"
- }
- },
- "required": [
- "type",
- "universe",
- "pipeline",
- "weightIndicator"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
- "properties": {
- "continueExisting": {
- "type": "boolean"
- },
- "cooldownMinutes": {
- "minimum": 0,
- "type": "number"
- },
- "executionModel": {
- "type": "string"
- },
- "includeMarketData": {
- "type": "boolean"
- },
- "initialMessage": {
- "type": "string"
- },
- "maxIterations": {
- "minimum": 1,
- "type": "number"
- },
- "planningModel": {
- "type": "string"
- },
- "skipPlanning": {
- "type": "boolean"
- },
- "type": {
- "const": "LaunchAgent",
- "type": "string"
- }
- },
- "required": [
- "type",
- "planningModel",
- "executionModel",
- "initialMessage",
- "maxIterations",
- "includeMarketData",
- "continueExisting",
- "skipPlanning"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
- "properties": {
- "against": {
- "additionalProperties": true,
- "description": "Optional parent-position selector (e.g. for covered calls).",
- "type": "object"
- },
- "allocation": {
- "additionalProperties": true,
- "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
- "properties": {
- "amount": {
- "type": "number"
- },
- "type": {
- "enum": [
- "dollars",
- "percent of portfolio",
- "percent of buying power",
- "contracts"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "amount"
- ],
- "type": "object"
- },
- "builder": {
- "additionalProperties": true,
- "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
- "properties": {
- "dynamicUnderlying": {
- "additionalProperties": true,
- "properties": {
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "pipeline": {
- "items": {
- "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
- "oneOf": [
- {
- "additionalProperties": true,
- "properties": {
- "condition": {
- "$ref": "#/$defs/condition"
- },
- "type": {
- "const": "Filter",
- "type": "string"
- }
- },
- "required": [
- "type",
- "condition"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "type": {
- "const": "SelectTop",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "limit",
- "direction"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "percentile": {
- "maximum": 100,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "SelectPercentile",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "percentile",
- "direction"
- ],
- "type": "object"
- }
- ],
- "type": "object"
- },
- "type": "array"
- },
- "universe": {
- "additionalProperties": true,
- "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
- "properties": {
- "assets": {
- "items": {
- "additionalProperties": true,
- "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
- "properties": {
- "name": {
- "type": "string"
- },
- "symbol": {
- "type": "string"
- },
- "type": {
- "enum": [
- "Stock",
- "Cryptocurrency",
- "Option",
- "Other"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "symbol"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "source": {
- "enum": [
- "ALL_US_STOCKS",
- "SP500",
- "NASDAQ100",
- "DJIA",
- "CRYPTO",
- "SPECIFIC_ASSETS"
- ],
- "type": "string"
- }
- },
- "required": [
- "source"
- ],
- "type": "object"
- }
- },
- "required": [
- "universe"
- ],
- "type": "object"
- },
- "legs": {
- "items": {
- "additionalProperties": true,
- "description": "Single leg of an option builder.",
- "properties": {
- "direction": {
- "enum": [
- "long",
- "short"
- ],
- "type": "string"
- },
- "expirationRange": {
- "additionalProperties": true,
- "type": "object"
- },
- "expirationSelector": {
- "properties": {
- "maxDaysToExpiration": {
- "minimum": 0,
- "type": "number"
- },
- "minDaysToExpiration": {
- "minimum": 0,
- "type": "number"
- },
- "preference": {
- "enum": [
- "nearest",
- "middle",
- "furthest"
- ],
- "type": "string"
- }
- },
- "required": [
- "minDaysToExpiration",
- "maxDaysToExpiration",
- "preference"
- ],
- "type": "object"
- },
- "fallbackStrikeSelector": {
- "additionalProperties": false,
- "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
- "properties": {
- "distance": {
- "type": "number"
- },
- "distanceType": {
- "enum": [
- "percent",
- "dollars"
- ],
- "type": "string"
- }
- },
- "required": [
- "distanceType",
- "distance"
- ],
- "type": "object"
- },
- "greekFilter": {
- "additionalProperties": true,
- "description": "Optional min/max constraints on Greeks during resolution.",
- "type": "object"
- },
- "liquidityFilter": {
- "additionalProperties": false,
- "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
- "properties": {
- "maxSpreadAbsolute": {
- "type": "number"
- },
- "maxSpreadPct": {
- "type": "number"
- },
- "minBid": {
- "type": "number"
- }
- },
- "type": "object"
- },
- "optionType": {
- "enum": [
- "call",
- "put"
- ],
- "type": "string"
- },
- "ratio": {
- "type": "number"
- },
- "strikeRange": {
- "additionalProperties": true,
- "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
- "type": "object"
- },
- "strikeSelector": {
- "properties": {
- "distance": {
- "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
- "type": "number"
- },
- "distanceType": {
- "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
- "type": "string"
- }
- },
- "required": [
- "distanceType",
- "distance"
- ],
- "type": "object"
- }
- },
- "required": [
- "optionType",
- "direction",
- "expirationSelector",
- "strikeSelector"
- ],
- "type": "object"
- },
- "minItems": 1,
- "type": "array"
- },
- "spreadType": {
- "enum": [
- "vertical",
- "calendar",
- "diagonal",
- "ironCondor",
- "straddle",
- "strangle",
- "custom"
- ],
- "type": "string"
- },
- "underlyingSymbol": {
- "type": "string"
- },
- "widthConstraint": {
- "additionalProperties": false,
- "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
- "properties": {
- "minWidthDollars": {
- "exclusiveMinimum": 0,
- "type": "number"
- },
- "minWidthPercent": {
- "exclusiveMinimum": 0,
- "type": "number"
- }
- },
- "type": "object"
- }
- },
- "required": [
- "legs"
- ],
- "type": "object"
- },
- "type": {
- "const": "OpenOption",
- "type": "string"
- }
- },
- "required": [
- "type",
- "builder"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
- "properties": {
- "allocationPolicy": {
- "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
- "oneOf": [
- {
- "additionalProperties": false,
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "expectedReturnShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "riskAversion": {
- "maximum": 1000,
- "minimum": 0,
- "type": "number"
- },
- "turnoverPenalty": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "MeanVariance",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "riskAversion",
- "expectedReturnShrinkage",
- "covarianceShrinkage",
- "turnoverPenalty",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "turnoverPenalty": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "RiskParity",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "covarianceShrinkage",
- "turnoverPenalty",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "turnoverPenalty": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "MaximumDiversification",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "covarianceShrinkage",
- "turnoverPenalty",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- }
- ]
- },
- "exposurePolicy": {
- "additionalProperties": false,
- "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
- "properties": {
- "covarianceShrinkage": {
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "estimatedTransactionCostBps": {
- "maximum": 10000,
- "minimum": 0,
- "type": "number"
- },
- "lookbackPeriods": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "minimumObservations": {
- "maximum": 5000,
- "minimum": 2,
- "type": "integer"
- },
- "targetAnnualizedVolatilityPercent": {
- "maximum": 1000,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "VolatilityTarget",
- "type": "string"
- }
- },
- "required": [
- "type",
- "lookbackPeriods",
- "minimumObservations",
- "covarianceShrinkage",
- "targetAnnualizedVolatilityPercent",
- "estimatedTransactionCostBps"
- ],
- "type": "object"
- },
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "perNameAllocation": {
- "additionalProperties": true,
- "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
- "properties": {
- "amount": {
- "type": "number"
- },
- "type": {
- "enum": [
- "dollars",
- "percent of portfolio",
- "percent of buying power",
- "contracts"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "amount"
- ],
- "type": "object"
- },
- "pipeline": {
- "items": {
- "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
- "oneOf": [
- {
- "additionalProperties": true,
- "properties": {
- "condition": {
- "$ref": "#/$defs/condition"
- },
- "type": {
- "const": "Filter",
- "type": "string"
- }
- },
- "required": [
- "type",
- "condition"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "type": {
- "const": "SelectTop",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "limit",
- "direction"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "percentile": {
- "maximum": 100,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "SelectPercentile",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "percentile",
- "direction"
- ],
- "type": "object"
- }
- ],
- "type": "object"
- },
- "type": "array"
- },
- "positionScope": {
- "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
- "enum": [
- "portfolio",
- "strategy"
- ],
- "type": "string"
- },
- "sleeves": {
- "items": {
- "additionalProperties": true,
- "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
- "properties": {
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "name": {
- "type": "string"
- },
- "perNameAllocation": {
- "additionalProperties": true,
- "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
- "properties": {
- "amount": {
- "type": "number"
- },
- "type": {
- "enum": [
- "dollars",
- "percent of portfolio",
- "percent of buying power",
- "contracts"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "amount"
- ],
- "type": "object"
- },
- "pipeline": {
- "items": {
- "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
- "oneOf": [
- {
- "additionalProperties": true,
- "properties": {
- "condition": {
- "$ref": "#/$defs/condition"
- },
- "type": {
- "const": "Filter",
- "type": "string"
- }
- },
- "required": [
- "type",
- "condition"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "limit": {
- "minimum": 1,
- "type": "number"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "type": {
- "const": "SelectTop",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "limit",
- "direction"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "direction": {
- "enum": [
- "Highest",
- "Lowest"
- ],
- "type": "string"
- },
- "metric": {
- "$ref": "#/$defs/indicator"
- },
- "percentile": {
- "maximum": 100,
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "const": "SelectPercentile",
- "type": "string"
- }
- },
- "required": [
- "type",
- "metric",
- "percentile",
- "direction"
- ],
- "type": "object"
- }
- ],
- "type": "object"
- },
- "type": "array"
- },
- "structureTemplates": {
- "items": {
- "additionalProperties": true,
- "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
- "properties": {
- "eligibility": {
- "$ref": "#/$defs/condition"
- },
- "legs": {
- "items": {
- "additionalProperties": true,
- "description": "Single leg of an option builder.",
- "properties": {
- "direction": {
- "enum": [
- "long",
- "short"
- ],
- "type": "string"
- },
- "expirationRange": {
- "additionalProperties": true,
- "type": "object"
- },
- "expirationSelector": {
- "properties": {
- "maxDaysToExpiration": {
- "minimum": 0,
- "type": "number"
- },
- "minDaysToExpiration": {
- "minimum": 0,
- "type": "number"
- },
- "preference": {
- "enum": [
- "nearest",
- "middle",
- "furthest"
- ],
- "type": "string"
- }
- },
- "required": [
- "minDaysToExpiration",
- "maxDaysToExpiration",
- "preference"
- ],
- "type": "object"
- },
- "fallbackStrikeSelector": {
- "additionalProperties": false,
- "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
- "properties": {
- "distance": {
- "type": "number"
- },
- "distanceType": {
- "enum": [
- "percent",
- "dollars"
- ],
- "type": "string"
- }
- },
- "required": [
- "distanceType",
- "distance"
- ],
- "type": "object"
- },
- "greekFilter": {
- "additionalProperties": true,
- "description": "Optional min/max constraints on Greeks during resolution.",
- "type": "object"
- },
- "liquidityFilter": {
- "additionalProperties": false,
- "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
- "properties": {
- "maxSpreadAbsolute": {
- "type": "number"
- },
- "maxSpreadPct": {
- "type": "number"
- },
- "minBid": {
- "type": "number"
- }
- },
- "type": "object"
- },
- "optionType": {
- "enum": [
- "call",
- "put"
- ],
- "type": "string"
- },
- "ratio": {
- "type": "number"
- },
- "strikeRange": {
- "additionalProperties": true,
- "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
- "type": "object"
- },
- "strikeSelector": {
- "properties": {
- "distance": {
- "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
- "type": "number"
- },
- "distanceType": {
- "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
- "type": "string"
- }
- },
- "required": [
- "distanceType",
- "distance"
- ],
- "type": "object"
- }
- },
- "required": [
- "optionType",
- "direction",
- "expirationSelector",
- "strikeSelector"
- ],
- "type": "object"
- },
- "minItems": 1,
- "type": "array"
- },
- "name": {
- "type": "string"
- },
- "spreadType": {
- "enum": [
- "vertical",
- "calendar",
- "diagonal",
- "ironCondor",
- "straddle",
- "strangle",
- "custom"
- ],
- "type": "string"
- },
- "widthConstraint": {
- "additionalProperties": false,
- "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
- "properties": {
- "minWidthDollars": {
- "exclusiveMinimum": 0,
- "type": "number"
- },
- "minWidthPercent": {
- "exclusiveMinimum": 0,
- "type": "number"
- }
- },
- "type": "object"
- }
- },
- "required": [
- "legs"
- ],
- "type": "object"
- },
- "minItems": 1,
- "type": "array"
- },
- "universe": {
- "additionalProperties": true,
- "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
- "properties": {
- "assets": {
- "items": {
- "additionalProperties": true,
- "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
- "properties": {
- "name": {
- "type": "string"
- },
- "symbol": {
- "type": "string"
- },
- "type": {
- "enum": [
- "Stock",
- "Cryptocurrency",
- "Option",
- "Other"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "symbol"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "source": {
- "enum": [
- "ALL_US_STOCKS",
- "SP500",
- "NASDAQ100",
- "DJIA",
- "CRYPTO",
- "SPECIFIC_ASSETS"
- ],
- "type": "string"
- }
- },
- "required": [
- "source"
- ],
- "type": "object"
- },
- "weightIndicator": {
- "$ref": "#/$defs/indicator"
- }
- },
- "required": [
- "name"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "structureTemplates": {
- "items": {
- "additionalProperties": true,
- "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
- "properties": {
- "eligibility": {
- "$ref": "#/$defs/condition"
- },
- "legs": {
- "items": {
- "additionalProperties": true,
- "description": "Single leg of an option builder.",
- "properties": {
- "direction": {
- "enum": [
- "long",
- "short"
- ],
- "type": "string"
- },
- "expirationRange": {
- "additionalProperties": true,
- "type": "object"
- },
- "expirationSelector": {
- "properties": {
- "maxDaysToExpiration": {
- "minimum": 0,
- "type": "number"
- },
- "minDaysToExpiration": {
- "minimum": 0,
- "type": "number"
- },
- "preference": {
- "enum": [
- "nearest",
- "middle",
- "furthest"
- ],
- "type": "string"
- }
- },
- "required": [
- "minDaysToExpiration",
- "maxDaysToExpiration",
- "preference"
- ],
- "type": "object"
- },
- "fallbackStrikeSelector": {
- "additionalProperties": false,
- "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
- "properties": {
- "distance": {
- "type": "number"
- },
- "distanceType": {
- "enum": [
- "percent",
- "dollars"
- ],
- "type": "string"
- }
- },
- "required": [
- "distanceType",
- "distance"
- ],
- "type": "object"
- },
- "greekFilter": {
- "additionalProperties": true,
- "description": "Optional min/max constraints on Greeks during resolution.",
- "type": "object"
- },
- "liquidityFilter": {
- "additionalProperties": false,
- "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
- "properties": {
- "maxSpreadAbsolute": {
- "type": "number"
- },
- "maxSpreadPct": {
- "type": "number"
- },
- "minBid": {
- "type": "number"
- }
- },
- "type": "object"
- },
- "optionType": {
- "enum": [
- "call",
- "put"
- ],
- "type": "string"
- },
- "ratio": {
- "type": "number"
- },
- "strikeRange": {
- "additionalProperties": true,
- "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
- "type": "object"
- },
- "strikeSelector": {
- "properties": {
- "distance": {
- "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
- "type": "number"
- },
- "distanceType": {
- "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
- "type": "string"
- }
- },
- "required": [
- "distanceType",
- "distance"
- ],
- "type": "object"
- }
- },
- "required": [
- "optionType",
- "direction",
- "expirationSelector",
- "strikeSelector"
- ],
- "type": "object"
- },
- "minItems": 1,
- "type": "array"
- },
- "name": {
- "type": "string"
- },
- "spreadType": {
- "enum": [
- "vertical",
- "calendar",
- "diagonal",
- "ironCondor",
- "straddle",
- "strangle",
- "custom"
- ],
- "type": "string"
- },
- "widthConstraint": {
- "additionalProperties": false,
- "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
- "properties": {
- "minWidthDollars": {
- "exclusiveMinimum": 0,
- "type": "number"
- },
- "minWidthPercent": {
- "exclusiveMinimum": 0,
- "type": "number"
- }
- },
- "type": "object"
- }
- },
- "required": [
- "legs"
- ],
- "type": "object"
- },
- "minItems": 1,
- "type": "array"
- },
- "totalBudget": {
- "additionalProperties": true,
- "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
- "properties": {
- "amount": {
- "minimum": 0,
- "type": "number"
- },
- "type": {
- "enum": [
- "dollars",
- "percent of portfolio"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "amount"
- ],
- "type": "object"
- },
- "type": {
- "const": "RebalanceOption",
- "type": "string"
- },
- "universe": {
- "additionalProperties": true,
- "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
- "properties": {
- "assets": {
- "items": {
- "additionalProperties": true,
- "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
- "properties": {
- "name": {
- "type": "string"
- },
- "symbol": {
- "type": "string"
- },
- "type": {
- "enum": [
- "Stock",
- "Cryptocurrency",
- "Option",
- "Other"
- ],
- "type": "string"
- }
- },
- "required": [
- "type",
- "symbol"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "source": {
- "enum": [
- "ALL_US_STOCKS",
- "SP500",
- "NASDAQ100",
- "DJIA",
- "CRYPTO",
- "SPECIFIC_ASSETS"
- ],
- "type": "string"
- }
- },
- "required": [
- "source"
- ],
- "type": "object"
- },
- "weightIndicator": {
- "$ref": "#/$defs/indicator"
- }
- },
- "required": [
- "type",
- "universe",
- "pipeline",
- "weightIndicator",
- "structureTemplates"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
- "properties": {
- "closeScope": {
- "enum": [
- "spread",
- "leg"
- ],
- "type": "string"
- },
- "direction": {
- "enum": [
- "long",
- "short"
- ],
- "type": "string"
- },
- "optionType": {
- "enum": [
- "call",
- "put"
- ],
- "type": "string"
- },
- "quantity": {
- "additionalProperties": true,
- "description": "How many contracts to close. Defaults to all matching when omitted.",
- "type": "object"
- },
- "spreadType": {
- "enum": [
- "vertical",
- "calendar",
- "diagonal",
- "ironCondor",
- "straddle",
- "strangle",
- "custom"
- ],
- "type": "string"
- },
- "triggers": {
- "items": {
- "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
- "oneOf": [
- {
- "additionalProperties": true,
- "properties": {
- "maxPnlPercent": {
- "type": "number"
- },
- "minPnlPercent": {
- "type": "number"
- },
- "type": {
- "const": "pnl",
- "type": "string"
- }
- },
- "required": [
- "type"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "maxDte": {
- "type": "number"
- },
- "minDte": {
- "type": "number"
- },
- "type": {
- "const": "dte",
- "type": "string"
- }
- },
- "required": [
- "type"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "maxDaysHeld": {
- "type": "number"
- },
- "minDaysHeld": {
- "type": "number"
- },
- "type": {
- "const": "daysHeld",
- "type": "string"
- }
- },
- "required": [
- "type"
- ],
- "type": "object"
- },
- {
- "additionalProperties": true,
- "properties": {
- "maxIv": {
- "type": "number"
- },
- "maxSpreadDelta": {
- "type": "number"
- },
- "maxSpreadTheta": {
- "type": "number"
- },
- "minIv": {
- "type": "number"
- },
- "minSpreadDelta": {
- "type": "number"
- },
- "minSpreadTheta": {
- "type": "number"
- },
- "type": {
- "const": "greeks",
- "type": "string"
- }
- },
- "required": [
- "type"
- ],
- "type": "object"
- }
- ],
- "type": "object"
- },
- "type": "array"
- },
- "type": {
- "const": "CloseOption",
- "type": "string"
- },
- "underlyings": {
- "items": {
- "type": "string"
- },
- "type": "array"
- }
- },
- "required": [
- "type"
- ],
- "type": "object"
- }
-]New value: +[
+ {
+ "additionalProperties": true,
+ "description": "Buy or Sell a stock/crypto position.",
+ "properties": {
+ "amount": {
+ "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
+ "properties": {
+ "amount": {
+ "type": "number"
+ },
+ "type": {
+ "enum": [
+ "percent of portfolio",
+ "percent of buying power",
+ "percent of current positions",
+ "dollars",
+ "number of assets"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "amount"
+ ],
+ "type": "object"
+ },
+ "targetAsset": {
+ "additionalProperties": true,
+ "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "symbol": {
+ "type": "string"
+ },
+ "type": {
+ "enum": [
+ "Stock",
+ "Cryptocurrency",
+ "Option",
+ "Other"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "symbol"
+ ],
+ "type": "object"
+ },
+ "type": {
+ "enum": [
+ "Buy",
+ "Sell"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "targetAsset",
+ "amount"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "description": "Send an alert message (no order).",
+ "properties": {
+ "message": {
+ "type": "string"
+ },
+ "type": {
+ "const": "Alert",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "message"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
+ "properties": {
+ "allocationPolicy": {
+ "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
+ "oneOf": [
+ {
+ "additionalProperties": false,
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "expectedReturnShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "riskAversion": {
+ "maximum": 1000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "turnoverPenalty": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "MeanVariance",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "riskAversion",
+ "expectedReturnShrinkage",
+ "covarianceShrinkage",
+ "turnoverPenalty",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "turnoverPenalty": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "RiskParity",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "covarianceShrinkage",
+ "turnoverPenalty",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "turnoverPenalty": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "MaximumDiversification",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "covarianceShrinkage",
+ "turnoverPenalty",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ }
+ ]
+ },
+ "canSell": {
+ "$ref": "#/$defs/condition",
+ "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
+ },
+ "deploymentPercent": {
+ "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
+ "maximum": 100,
+ "minimum": 0,
+ "type": "number"
+ },
+ "exposurePolicy": {
+ "additionalProperties": false,
+ "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "targetAnnualizedVolatilityPercent": {
+ "maximum": 1000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "VolatilityTarget",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "covarianceShrinkage",
+ "targetAnnualizedVolatilityPercent",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ },
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "perNameAllocation": {
+ "additionalProperties": true,
+ "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.",
+ "properties": {
+ "amount": {
+ "exclusiveMinimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "enum": [
+ "percent of portfolio",
+ "dollars"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "amount"
+ ],
+ "type": "object"
+ },
+ "pipeline": {
+ "items": {
+ "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
+ "oneOf": [
+ {
+ "additionalProperties": true,
+ "properties": {
+ "condition": {
+ "$ref": "#/$defs/condition"
+ },
+ "type": {
+ "const": "Filter",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "condition"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "type": {
+ "const": "SelectTop",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "limit",
+ "direction"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "percentile": {
+ "maximum": 100,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "SelectPercentile",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "percentile",
+ "direction"
+ ],
+ "type": "object"
+ }
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "type": {
+ "const": "DynamicRebalance",
+ "type": "string"
+ },
+ "universe": {
+ "additionalProperties": true,
+ "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
+ "properties": {
+ "assets": {
+ "items": {
+ "additionalProperties": true,
+ "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "symbol": {
+ "type": "string"
+ },
+ "type": {
+ "enum": [
+ "Stock",
+ "Cryptocurrency",
+ "Option",
+ "Other"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "symbol"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "source": {
+ "enum": [
+ "ALL_US_STOCKS",
+ "SP500",
+ "NASDAQ100",
+ "DJIA",
+ "CRYPTO",
+ "SPECIFIC_ASSETS"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "source"
+ ],
+ "type": "object"
+ },
+ "weightIndicator": {
+ "$ref": "#/$defs/indicator"
+ }
+ },
+ "required": [
+ "type",
+ "universe",
+ "pipeline",
+ "weightIndicator"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
+ "properties": {
+ "continueExisting": {
+ "type": "boolean"
+ },
+ "cooldownMinutes": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "executionModel": {
+ "type": "string"
+ },
+ "includeMarketData": {
+ "type": "boolean"
+ },
+ "initialMessage": {
+ "type": "string"
+ },
+ "maxIterations": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "planningModel": {
+ "type": "string"
+ },
+ "skipPlanning": {
+ "type": "boolean"
+ },
+ "type": {
+ "const": "LaunchAgent",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "planningModel",
+ "executionModel",
+ "initialMessage",
+ "maxIterations",
+ "includeMarketData",
+ "continueExisting",
+ "skipPlanning"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
+ "properties": {
+ "against": {
+ "additionalProperties": true,
+ "description": "Optional parent-position selector (e.g. for covered calls).",
+ "type": "object"
+ },
+ "allocation": {
+ "additionalProperties": true,
+ "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
+ "properties": {
+ "amount": {
+ "type": "number"
+ },
+ "type": {
+ "enum": [
+ "dollars",
+ "percent of portfolio",
+ "percent of buying power",
+ "contracts",
+ "percent of realized premium"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "amount"
+ ],
+ "type": "object"
+ },
+ "builder": {
+ "additionalProperties": true,
+ "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
+ "properties": {
+ "dynamicUnderlying": {
+ "additionalProperties": true,
+ "properties": {
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "pipeline": {
+ "items": {
+ "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
+ "oneOf": [
+ {
+ "additionalProperties": true,
+ "properties": {
+ "condition": {
+ "$ref": "#/$defs/condition"
+ },
+ "type": {
+ "const": "Filter",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "condition"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "type": {
+ "const": "SelectTop",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "limit",
+ "direction"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "percentile": {
+ "maximum": 100,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "SelectPercentile",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "percentile",
+ "direction"
+ ],
+ "type": "object"
+ }
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "universe": {
+ "additionalProperties": true,
+ "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
+ "properties": {
+ "assets": {
+ "items": {
+ "additionalProperties": true,
+ "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "symbol": {
+ "type": "string"
+ },
+ "type": {
+ "enum": [
+ "Stock",
+ "Cryptocurrency",
+ "Option",
+ "Other"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "symbol"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "source": {
+ "enum": [
+ "ALL_US_STOCKS",
+ "SP500",
+ "NASDAQ100",
+ "DJIA",
+ "CRYPTO",
+ "SPECIFIC_ASSETS"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "source"
+ ],
+ "type": "object"
+ }
+ },
+ "required": [
+ "universe"
+ ],
+ "type": "object"
+ },
+ "legs": {
+ "items": {
+ "additionalProperties": true,
+ "description": "Single leg of an option builder.",
+ "properties": {
+ "direction": {
+ "enum": [
+ "long",
+ "short"
+ ],
+ "type": "string"
+ },
+ "expirationRange": {
+ "additionalProperties": true,
+ "type": "object"
+ },
+ "expirationSelector": {
+ "properties": {
+ "maxDaysToExpiration": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "minDaysToExpiration": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "preference": {
+ "enum": [
+ "nearest",
+ "middle",
+ "furthest"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "minDaysToExpiration",
+ "maxDaysToExpiration",
+ "preference"
+ ],
+ "type": "object"
+ },
+ "fallbackStrikeSelector": {
+ "additionalProperties": false,
+ "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
+ "properties": {
+ "distance": {
+ "type": "number"
+ },
+ "distanceType": {
+ "enum": [
+ "percent",
+ "dollars"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "distanceType",
+ "distance"
+ ],
+ "type": "object"
+ },
+ "greekFilter": {
+ "additionalProperties": true,
+ "description": "Optional min/max constraints on Greeks during resolution.",
+ "type": "object"
+ },
+ "liquidityFilter": {
+ "additionalProperties": false,
+ "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
+ "properties": {
+ "maxSpreadAbsolute": {
+ "type": "number"
+ },
+ "maxSpreadPct": {
+ "type": "number"
+ },
+ "minBid": {
+ "type": "number"
+ }
+ },
+ "type": "object"
+ },
+ "optionType": {
+ "enum": [
+ "call",
+ "put"
+ ],
+ "type": "string"
+ },
+ "ratio": {
+ "type": "number"
+ },
+ "strikeRange": {
+ "additionalProperties": true,
+ "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
+ "type": "object"
+ },
+ "strikeSelector": {
+ "properties": {
+ "distance": {
+ "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
+ "type": "number"
+ },
+ "distanceType": {
+ "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "distanceType",
+ "distance"
+ ],
+ "type": "object"
+ }
+ },
+ "required": [
+ "optionType",
+ "direction",
+ "expirationSelector",
+ "strikeSelector"
+ ],
+ "type": "object"
+ },
+ "minItems": 1,
+ "type": "array"
+ },
+ "spreadType": {
+ "enum": [
+ "vertical",
+ "calendar",
+ "diagonal",
+ "ironCondor",
+ "straddle",
+ "strangle",
+ "custom"
+ ],
+ "type": "string"
+ },
+ "underlyingSymbol": {
+ "type": "string"
+ },
+ "widthConstraint": {
+ "additionalProperties": false,
+ "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
+ "properties": {
+ "minWidthDollars": {
+ "exclusiveMinimum": 0,
+ "type": "number"
+ },
+ "minWidthPercent": {
+ "exclusiveMinimum": 0,
+ "type": "number"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "required": [
+ "legs"
+ ],
+ "type": "object"
+ },
+ "type": {
+ "const": "OpenOption",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "builder"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
+ "properties": {
+ "allocationPolicy": {
+ "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
+ "oneOf": [
+ {
+ "additionalProperties": false,
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "expectedReturnShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "riskAversion": {
+ "maximum": 1000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "turnoverPenalty": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "MeanVariance",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "riskAversion",
+ "expectedReturnShrinkage",
+ "covarianceShrinkage",
+ "turnoverPenalty",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "turnoverPenalty": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "RiskParity",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "covarianceShrinkage",
+ "turnoverPenalty",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "turnoverPenalty": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "MaximumDiversification",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "covarianceShrinkage",
+ "turnoverPenalty",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ }
+ ]
+ },
+ "exposurePolicy": {
+ "additionalProperties": false,
+ "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
+ "properties": {
+ "covarianceShrinkage": {
+ "maximum": 1,
+ "minimum": 0,
+ "type": "number"
+ },
+ "estimatedTransactionCostBps": {
+ "maximum": 10000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "lookbackPeriods": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "minimumObservations": {
+ "maximum": 5000,
+ "minimum": 2,
+ "type": "integer"
+ },
+ "targetAnnualizedVolatilityPercent": {
+ "maximum": 1000,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "VolatilityTarget",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "lookbackPeriods",
+ "minimumObservations",
+ "covarianceShrinkage",
+ "targetAnnualizedVolatilityPercent",
+ "estimatedTransactionCostBps"
+ ],
+ "type": "object"
+ },
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "perNameAllocation": {
+ "additionalProperties": true,
+ "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
+ "properties": {
+ "amount": {
+ "type": "number"
+ },
+ "type": {
+ "enum": [
+ "dollars",
+ "percent of portfolio",
+ "percent of buying power",
+ "contracts",
+ "percent of realized premium"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "amount"
+ ],
+ "type": "object"
+ },
+ "pipeline": {
+ "items": {
+ "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
+ "oneOf": [
+ {
+ "additionalProperties": true,
+ "properties": {
+ "condition": {
+ "$ref": "#/$defs/condition"
+ },
+ "type": {
+ "const": "Filter",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "condition"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "type": {
+ "const": "SelectTop",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "limit",
+ "direction"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "percentile": {
+ "maximum": 100,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "SelectPercentile",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "percentile",
+ "direction"
+ ],
+ "type": "object"
+ }
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "positionScope": {
+ "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
+ "enum": [
+ "portfolio",
+ "strategy"
+ ],
+ "type": "string"
+ },
+ "sleeves": {
+ "items": {
+ "additionalProperties": true,
+ "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
+ "properties": {
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "name": {
+ "type": "string"
+ },
+ "perNameAllocation": {
+ "additionalProperties": true,
+ "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
+ "properties": {
+ "amount": {
+ "type": "number"
+ },
+ "type": {
+ "enum": [
+ "dollars",
+ "percent of portfolio",
+ "percent of buying power",
+ "contracts",
+ "percent of realized premium"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "amount"
+ ],
+ "type": "object"
+ },
+ "pipeline": {
+ "items": {
+ "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
+ "oneOf": [
+ {
+ "additionalProperties": true,
+ "properties": {
+ "condition": {
+ "$ref": "#/$defs/condition"
+ },
+ "type": {
+ "const": "Filter",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "condition"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "limit": {
+ "minimum": 1,
+ "type": "number"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "type": {
+ "const": "SelectTop",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "limit",
+ "direction"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "direction": {
+ "enum": [
+ "Highest",
+ "Lowest"
+ ],
+ "type": "string"
+ },
+ "metric": {
+ "$ref": "#/$defs/indicator"
+ },
+ "percentile": {
+ "maximum": 100,
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "const": "SelectPercentile",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "metric",
+ "percentile",
+ "direction"
+ ],
+ "type": "object"
+ }
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "structureTemplates": {
+ "items": {
+ "additionalProperties": true,
+ "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
+ "properties": {
+ "eligibility": {
+ "$ref": "#/$defs/condition"
+ },
+ "legs": {
+ "items": {
+ "additionalProperties": true,
+ "description": "Single leg of an option builder.",
+ "properties": {
+ "direction": {
+ "enum": [
+ "long",
+ "short"
+ ],
+ "type": "string"
+ },
+ "expirationRange": {
+ "additionalProperties": true,
+ "type": "object"
+ },
+ "expirationSelector": {
+ "properties": {
+ "maxDaysToExpiration": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "minDaysToExpiration": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "preference": {
+ "enum": [
+ "nearest",
+ "middle",
+ "furthest"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "minDaysToExpiration",
+ "maxDaysToExpiration",
+ "preference"
+ ],
+ "type": "object"
+ },
+ "fallbackStrikeSelector": {
+ "additionalProperties": false,
+ "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
+ "properties": {
+ "distance": {
+ "type": "number"
+ },
+ "distanceType": {
+ "enum": [
+ "percent",
+ "dollars"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "distanceType",
+ "distance"
+ ],
+ "type": "object"
+ },
+ "greekFilter": {
+ "additionalProperties": true,
+ "description": "Optional min/max constraints on Greeks during resolution.",
+ "type": "object"
+ },
+ "liquidityFilter": {
+ "additionalProperties": false,
+ "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
+ "properties": {
+ "maxSpreadAbsolute": {
+ "type": "number"
+ },
+ "maxSpreadPct": {
+ "type": "number"
+ },
+ "minBid": {
+ "type": "number"
+ }
+ },
+ "type": "object"
+ },
+ "optionType": {
+ "enum": [
+ "call",
+ "put"
+ ],
+ "type": "string"
+ },
+ "ratio": {
+ "type": "number"
+ },
+ "strikeRange": {
+ "additionalProperties": true,
+ "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
+ "type": "object"
+ },
+ "strikeSelector": {
+ "properties": {
+ "distance": {
+ "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
+ "type": "number"
+ },
+ "distanceType": {
+ "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "distanceType",
+ "distance"
+ ],
+ "type": "object"
+ }
+ },
+ "required": [
+ "optionType",
+ "direction",
+ "expirationSelector",
+ "strikeSelector"
+ ],
+ "type": "object"
+ },
+ "minItems": 1,
+ "type": "array"
+ },
+ "name": {
+ "type": "string"
+ },
+ "spreadType": {
+ "enum": [
+ "vertical",
+ "calendar",
+ "diagonal",
+ "ironCondor",
+ "straddle",
+ "strangle",
+ "custom"
+ ],
+ "type": "string"
+ },
+ "widthConstraint": {
+ "additionalProperties": false,
+ "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
+ "properties": {
+ "minWidthDollars": {
+ "exclusiveMinimum": 0,
+ "type": "number"
+ },
+ "minWidthPercent": {
+ "exclusiveMinimum": 0,
+ "type": "number"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "required": [
+ "legs"
+ ],
+ "type": "object"
+ },
+ "minItems": 1,
+ "type": "array"
+ },
+ "universe": {
+ "additionalProperties": true,
+ "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
+ "properties": {
+ "assets": {
+ "items": {
+ "additionalProperties": true,
+ "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "symbol": {
+ "type": "string"
+ },
+ "type": {
+ "enum": [
+ "Stock",
+ "Cryptocurrency",
+ "Option",
+ "Other"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "symbol"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "source": {
+ "enum": [
+ "ALL_US_STOCKS",
+ "SP500",
+ "NASDAQ100",
+ "DJIA",
+ "CRYPTO",
+ "SPECIFIC_ASSETS"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "source"
+ ],
+ "type": "object"
+ },
+ "weightIndicator": {
+ "$ref": "#/$defs/indicator"
+ }
+ },
+ "required": [
+ "name"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "structureTemplates": {
+ "items": {
+ "additionalProperties": true,
+ "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
+ "properties": {
+ "eligibility": {
+ "$ref": "#/$defs/condition"
+ },
+ "legs": {
+ "items": {
+ "additionalProperties": true,
+ "description": "Single leg of an option builder.",
+ "properties": {
+ "direction": {
+ "enum": [
+ "long",
+ "short"
+ ],
+ "type": "string"
+ },
+ "expirationRange": {
+ "additionalProperties": true,
+ "type": "object"
+ },
+ "expirationSelector": {
+ "properties": {
+ "maxDaysToExpiration": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "minDaysToExpiration": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "preference": {
+ "enum": [
+ "nearest",
+ "middle",
+ "furthest"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "minDaysToExpiration",
+ "maxDaysToExpiration",
+ "preference"
+ ],
+ "type": "object"
+ },
+ "fallbackStrikeSelector": {
+ "additionalProperties": false,
+ "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
+ "properties": {
+ "distance": {
+ "type": "number"
+ },
+ "distanceType": {
+ "enum": [
+ "percent",
+ "dollars"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "distanceType",
+ "distance"
+ ],
+ "type": "object"
+ },
+ "greekFilter": {
+ "additionalProperties": true,
+ "description": "Optional min/max constraints on Greeks during resolution.",
+ "type": "object"
+ },
+ "liquidityFilter": {
+ "additionalProperties": false,
+ "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
+ "properties": {
+ "maxSpreadAbsolute": {
+ "type": "number"
+ },
+ "maxSpreadPct": {
+ "type": "number"
+ },
+ "minBid": {
+ "type": "number"
+ }
+ },
+ "type": "object"
+ },
+ "optionType": {
+ "enum": [
+ "call",
+ "put"
+ ],
+ "type": "string"
+ },
+ "ratio": {
+ "type": "number"
+ },
+ "strikeRange": {
+ "additionalProperties": true,
+ "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
+ "type": "object"
+ },
+ "strikeSelector": {
+ "properties": {
+ "distance": {
+ "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
+ "type": "number"
+ },
+ "distanceType": {
+ "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "distanceType",
+ "distance"
+ ],
+ "type": "object"
+ }
+ },
+ "required": [
+ "optionType",
+ "direction",
+ "expirationSelector",
+ "strikeSelector"
+ ],
+ "type": "object"
+ },
+ "minItems": 1,
+ "type": "array"
+ },
+ "name": {
+ "type": "string"
+ },
+ "spreadType": {
+ "enum": [
+ "vertical",
+ "calendar",
+ "diagonal",
+ "ironCondor",
+ "straddle",
+ "strangle",
+ "custom"
+ ],
+ "type": "string"
+ },
+ "widthConstraint": {
+ "additionalProperties": false,
+ "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
+ "properties": {
+ "minWidthDollars": {
+ "exclusiveMinimum": 0,
+ "type": "number"
+ },
+ "minWidthPercent": {
+ "exclusiveMinimum": 0,
+ "type": "number"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "required": [
+ "legs"
+ ],
+ "type": "object"
+ },
+ "minItems": 1,
+ "type": "array"
+ },
+ "totalBudget": {
+ "additionalProperties": true,
+ "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
+ "properties": {
+ "amount": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "type": {
+ "enum": [
+ "dollars",
+ "percent of portfolio"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "amount"
+ ],
+ "type": "object"
+ },
+ "type": {
+ "const": "RebalanceOption",
+ "type": "string"
+ },
+ "universe": {
+ "additionalProperties": true,
+ "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
+ "properties": {
+ "assets": {
+ "items": {
+ "additionalProperties": true,
+ "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "symbol": {
+ "type": "string"
+ },
+ "type": {
+ "enum": [
+ "Stock",
+ "Cryptocurrency",
+ "Option",
+ "Other"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "symbol"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "source": {
+ "enum": [
+ "ALL_US_STOCKS",
+ "SP500",
+ "NASDAQ100",
+ "DJIA",
+ "CRYPTO",
+ "SPECIFIC_ASSETS"
+ ],
+ "type": "string"
+ }
+ },
+ "required": [
+ "source"
+ ],
+ "type": "object"
+ },
+ "weightIndicator": {
+ "$ref": "#/$defs/indicator"
+ }
+ },
+ "required": [
+ "type",
+ "universe",
+ "pipeline",
+ "weightIndicator",
+ "structureTemplates"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
+ "properties": {
+ "closeScope": {
+ "enum": [
+ "spread",
+ "leg"
+ ],
+ "type": "string"
+ },
+ "direction": {
+ "enum": [
+ "long",
+ "short"
+ ],
+ "type": "string"
+ },
+ "optionType": {
+ "enum": [
+ "call",
+ "put"
+ ],
+ "type": "string"
+ },
+ "quantity": {
+ "additionalProperties": true,
+ "description": "How many contracts to close. Defaults to all matching when omitted.",
+ "type": "object"
+ },
+ "spreadType": {
+ "enum": [
+ "vertical",
+ "calendar",
+ "diagonal",
+ "ironCondor",
+ "straddle",
+ "strangle",
+ "custom"
+ ],
+ "type": "string"
+ },
+ "triggers": {
+ "items": {
+ "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
+ "oneOf": [
+ {
+ "additionalProperties": true,
+ "properties": {
+ "maxPnlPercent": {
+ "type": "number"
+ },
+ "minPnlPercent": {
+ "type": "number"
+ },
+ "type": {
+ "const": "pnl",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "maxDte": {
+ "type": "number"
+ },
+ "minDte": {
+ "type": "number"
+ },
+ "type": {
+ "const": "dte",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "maxDaysHeld": {
+ "type": "number"
+ },
+ "minDaysHeld": {
+ "type": "number"
+ },
+ "type": {
+ "const": "daysHeld",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": true,
+ "properties": {
+ "maxIv": {
+ "type": "number"
+ },
+ "maxSpreadDelta": {
+ "type": "number"
+ },
+ "maxSpreadTheta": {
+ "type": "number"
+ },
+ "minIv": {
+ "type": "number"
+ },
+ "minSpreadDelta": {
+ "type": "number"
+ },
+ "minSpreadTheta": {
+ "type": "number"
+ },
+ "type": {
+ "const": "greeks",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "type": "object"
+ }
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "type": {
+ "const": "CloseOption",
+ "type": "string"
+ },
+ "underlyings": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "type": "object"
+ }
+]