Endpoints: 28,729MCP servers: 18,414Payout addresses: 2,071Paid calls: 1,562Letters: 14Defects: 1,336counted 3 min ago
teppi

Server definition

Hash
sha256:fb533b9a8dd97eb1eda28dbe9ac717b30e741b93beec558b90c9a4c534f57d0e
What it is
What a remote MCP server returned when asked what it offers: 25 tools

The blob, as servednamed by its sha256

{ "instructions": "NexusTrade MCP — portfolio authoring\n\nPrefer structured create_portfolio / build_portfolio (zero LLM cost). Validate drafts with build_portfolio before create_portfolio.\n\nCustom data sources: none yet.\nCreate one with run_compute (pass name and point_kind to promote its signal output directly), or use dataset_to_indicator with a saved dataset; then reference customIndicatorId in create_portfolio.", "tools": [ { "description": "⚠ INDIRECTLY COSTS LLM CREDITS — approving the plan unfreezes the agent which then runs more planning + execution LLM calls. Manual approval required; do NOT call unless the user explicitly told you to advance their Aurora agent. Approve a semi-automated agent that is waiting in pending_plan_approval or pending_action_approval. Auto-detects which approval the agent needs and emits the matching state-machine event so the agent resumes execution. Returns 400 if the agent is not in a pending-approval state.", "inputSchema": { "properties": { "agentId": { "description": "MongoDB agent _id to approve", "type": "string" } }, "required": [ "agentId" ], "type": "object" }, "name": "approve_agent_plan", "outputSchema": null }, { "description": "Aurora agent surface (no LLM cost — pure DB write). Only relevant when managing Aurora agents. Archive an agent (soft-delete). The agent remains in the database but is hidden from default listings. Address by agentId OR exact title (XOR).", "inputSchema": { "properties": { "agentId": { "description": "MongoDB agent _id to archive (XOR with title)", "type": "string" }, "title": { "description": "Exact case-insensitive user-assigned title (XOR with agentId)", "type": "string" } }, "required": [], "type": "object" }, "name": "archive_agent", "outputSchema": null }, { "description": "Submit an asynchronous historical backtest for a portfolio over a date range. Minute interval: first-look default is the last 90 inclusive calendar days; the selected range plus minute-indicator warmup cannot exceed 730 days of minute data, so a multi-year Minute window up to that span is allowed — do not emit 2010, and never split a longer span into yearly Minute jobs. Daily equity may use a long window. Set baseline_symbol to match the book — underlying ticker for single-name options (AAPL→AAPL), per-underlying baselines or equal-weight universe B&H for multi-name options; SPY only for broad equity. Returns a backtest ID immediately; poll query_backtest_status, then query_backtest_history (zero-LLM). Aurora may also use Read Backtest for an LLM narrative once complete.", "inputSchema": { "properties": { "baseline_symbol": { "description": "Benchmark for comparisonValue (buy-and-hold of this ticker). Defaults to SPY if omitted — use SPY only for broad equity/market strategies. For single-name options, set to that underlying (AAPL options → AAPL). For multi-name options books, run separate backtests with each material underlying as baseline (AAPL for AAPL sleeve, MSFT for MSFT), or equal-weight B&H of the traded universe — do not default to SPY.", "pattern": "^[A-Za-z]{1,5}$", "type": "string" }, "end_date": { "description": "Backtest end date (ISO format, e.g. 2024-12-31). Minute allows up to 730 days of minute data from start_date, counting minute-indicator warmup; never split a longer span into yearly Minute jobs.", "pattern": "^\\d{4}-\\d{2}-\\d{2}", "type": "string" }, "fee_config": { "additionalProperties": true, "description": "Optional fee contract keyed by AssetTypeEnum (Stock/Cryptocurrency/Option) with {amount, type: percent|dollars}. Omit for shared defaults (Option $0.65/contract). For replay of an optimizer/walk-forward study, pass that study's persisted feeConfig. Option fill slippage (OptionSlippageFraction) is not set here — engine default 0.5 applies.", "type": "object" }, "generate_events": { "description": "Generate detailed event data (signals, orders, audits) during backtest. Costs 5x research tokens. Events are Mongo hot-store traces retained for 3 days. Use query_backtest_events to explore them while retained.", "type": "boolean" }, "initial_value": { "description": "Starting portfolio value (default 10000)", "minimum": 1, "type": "number" }, "interval": { "description": "Time interval: Day or Minute (default Day). Minute is a daytrade tape. 730 days of minute data (selected range plus warmup) is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year or two is a normal second backtest, not an escalation.", "enum": [ "Day", "Minute" ], "type": "string" }, "portfolio_id": { "description": "Portfolio ID (live, paper, or chat — from fetch_portfolios or create_portfolio). Server resolves the collection automatically.", "type": "string" }, "start_date": { "description": "Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range plus minute-indicator warmup cannot exceed 730 days of minute data. Do not use 2010-01-01 on Minute.", "pattern": "^\\d{4}-\\d{2}-\\d{2}", "type": "string" } }, "required": [ "start_date", "end_date" ], "type": "object" }, "name": "backtest_portfolio", "outputSchema": null }, { "description": "Preview/builder twin of create_portfolio. Runs the SAME construction + per-strategy validation (Portfolio/Strategy/Condition/Indicator) as create_portfolio but PERSISTS NOTHING. Accepts the same IPortfolio JSON (all fields optional so partial drafts can be checked). Returns the canonicalized portfolio plus a per-component issue list (path + component + message) so you can see exactly which strategy/condition/indicator is wrong before committing. A draft that previews clean cannot fail on create_portfolio. Zero research token cost.\n\nCustom data sources: none yet.\nCreate one with run_compute (pass name and point_kind to promote its signal output directly), or use dataset_to_indicator with a saved dataset; then reference customIndicatorId in create_portfolio.", "inputSchema": { "$defs": { "action": { "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).", "oneOf": [ { "additionalProperties": true, "description": "Buy or Sell a stock/crypto position.", "properties": { "amount": { "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "percent of portfolio", "percent of buying power", "percent of current positions", "dollars", "number of assets" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "targetAsset": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": { "enum": [ "Buy", "Sell" ], "type": "string" } }, "required": [ "type", "targetAsset", "amount" ], "type": "object" }, { "additionalProperties": true, "description": "Send an alert message (no order).", "properties": { "message": { "type": "string" }, "type": { "const": "Alert", "type": "string" } }, "required": [ "type", "message" ], "type": "object" }, { "additionalProperties": true, "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is the deploymentPercent indicator (0–100; use Value for a constant). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.", "properties": { "allocationPolicy": { "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", "oneOf": [ { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "expectedReturnShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "riskAversion": { "maximum": 1000, "minimum": 0, "type": "number" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MeanVariance", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "riskAversion", "expectedReturnShrinkage", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "RiskParity", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MaximumDiversification", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" } ] }, "canSell": { "$ref": "#/$defs/condition", "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out." }, "deploymentPercent": { "$ref": "#/$defs/indicator", "description": "Indicator returning percent of portfolio NAV to deploy, 0–100 (remainder cash). Use Value for a constant, or PoliticalPurchaseShare with memberId and instrument Equity. Do not use totalBudget here." }, "exposurePolicy": { "additionalProperties": false, "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "targetAnnualizedVolatilityPercent": { "maximum": 1000, "minimum": 0, "type": "number" }, "type": { "const": "VolatilityTarget", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "targetAnnualizedVolatilityPercent", "estimatedTransactionCostBps" ], "type": "object" }, "limit": { "minimum": 1, "type": "number" }, "perNameAllocation": { "additionalProperties": true, "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.", "properties": { "amount": { "exclusiveMinimum": 0, "type": "number" }, "type": { "enum": [ "percent of portfolio", "dollars" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "type": { "const": "DynamicRebalance", "type": "string" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "type", "universe", "pipeline", "weightIndicator" ], "type": "object" }, { "additionalProperties": true, "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).", "properties": { "continueExisting": { "type": "boolean" }, "cooldownMinutes": { "minimum": 0, "type": "number" }, "executionModel": { "type": "string" }, "includeMarketData": { "type": "boolean" }, "initialMessage": { "type": "string" }, "maxIterations": { "minimum": 1, "type": "number" }, "planningModel": { "type": "string" }, "skipPlanning": { "type": "boolean" }, "type": { "const": "LaunchAgent", "type": "string" } }, "required": [ "type", "planningModel", "executionModel", "initialMessage", "maxIterations", "includeMarketData", "continueExisting", "skipPlanning" ], "type": "object" }, { "additionalProperties": true, "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.", "properties": { "against": { "additionalProperties": true, "description": "Optional parent-position selector (e.g. for covered calls).", "type": "object" }, "allocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "builder": { "additionalProperties": true, "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.", "properties": { "dynamicUnderlying": { "additionalProperties": true, "properties": { "limit": { "minimum": 1, "type": "number" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" } }, "required": [ "universe" ], "type": "object" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "underlyingSymbol": { "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "type": { "const": "OpenOption", "type": "string" } }, "required": [ "type", "builder" ], "type": "object" }, { "additionalProperties": true, "description": "RebalanceOption: filter/rank a universe, then allocate option premium under totalBudget. sizingMode fixedPerName (default) uses weightIndicator only to rank names and perNameAllocation to size each. sizingMode proportionalToWeight splits totalBudget among selected names in proportion to positive weightIndicator values; perNameAllocation is ignored, and sleeves/allocationPolicy/exposurePolicy cannot be combined with it. allocationPolicy may jointly size selected names in fixedPerName mode; exposurePolicy may scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder for shared cadence. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies.", "properties": { "allocationPolicy": { "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", "oneOf": [ { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "expectedReturnShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "riskAversion": { "maximum": 1000, "minimum": 0, "type": "number" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MeanVariance", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "riskAversion", "expectedReturnShrinkage", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "RiskParity", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MaximumDiversification", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" } ] }, "exposurePolicy": { "additionalProperties": false, "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "targetAnnualizedVolatilityPercent": { "maximum": 1000, "minimum": 0, "type": "number" }, "type": { "const": "VolatilityTarget", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "targetAnnualizedVolatilityPercent", "estimatedTransactionCostBps" ], "type": "object" }, "limit": { "minimum": 1, "type": "number" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "positionScope": { "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.", "enum": [ "portfolio", "strategy" ], "type": "string" }, "sizingMode": { "enum": [ "fixedPerName", "proportionalToWeight" ], "type": "string" }, "sleeves": { "items": { "additionalProperties": true, "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).", "properties": { "limit": { "minimum": 1, "type": "number" }, "name": { "type": "string" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "structureTemplates": { "items": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "minItems": 1, "type": "array" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "name" ], "type": "object" }, "type": "array" }, "structureTemplates": { "items": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "minItems": 1, "type": "array" }, "totalBudget": { "additionalProperties": true, "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", "properties": { "amount": { "$ref": "#/$defs/indicator", "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." }, "type": { "enum": [ "dollars", "percent of portfolio" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "type": { "const": "RebalanceOption", "type": "string" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "type", "universe", "pipeline", "weightIndicator", "structureTemplates" ], "type": "object" }, { "additionalProperties": true, "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.", "properties": { "closeScope": { "enum": [ "spread", "leg" ], "type": "string" }, "direction": { "enum": [ "long", "short" ], "type": "string" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "quantity": { "additionalProperties": true, "description": "How many contracts to close. Defaults to all matching when omitted.", "type": "object" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "triggers": { "items": { "description": "Close trigger for an options exit. Triggers within an array are OR-gated.", "oneOf": [ { "additionalProperties": true, "properties": { "maxPnlPercent": { "type": "number" }, "minPnlPercent": { "type": "number" }, "type": { "const": "pnl", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxDte": { "type": "number" }, "minDte": { "type": "number" }, "type": { "const": "dte", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxDaysHeld": { "type": "number" }, "minDaysHeld": { "type": "number" }, "type": { "const": "daysHeld", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxIv": { "type": "number" }, "maxSpreadDelta": { "type": "number" }, "maxSpreadTheta": { "type": "number" }, "minIv": { "type": "number" }, "minSpreadDelta": { "type": "number" }, "minSpreadTheta": { "type": "number" }, "type": { "const": "greeks", "type": "string" } }, "required": [ "type" ], "type": "object" } ], "type": "object" }, "type": "array" }, "type": { "const": "CloseOption", "type": "string" }, "underlyings": { "items": { "type": "string" }, "type": "array" } }, "required": [ "type" ], "type": "object" } ], "type": "object" }, "asset": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "condition": { "additionalProperties": true, "description": "A condition tree (Bridge pattern). type='Base' compares lhs vs rhs with a comparator; type='And'/'Or' combine an array of nested conditions; type='Multi' fires when N nested conditions are true (count vs threshold); type='Then' is sequential — it fires when the last nested condition is true now and each earlier one was true at a strictly earlier tick within 'window' of the next, so it needs at least 2 conditions and a window with length > 0.", "properties": { "comparison": { "description": "Base / Multi only: how to compare.", "enum": [ "lessThan", "greaterThan", "lessThanOrEqual", "greaterThanOrEqual", "equal", "notEqual" ], "type": "string" }, "conditions": { "description": "And / Or / Multi / Then only: nested conditions. Then reads them in order (at least 2).", "items": { "$ref": "#/$defs/condition" }, "type": "array" }, "lhs": { "$ref": "#/$defs/indicator", "description": "Base only: left-hand indicator." }, "name": { "description": "Optional name; auto-derived if omitted.", "type": "string" }, "rhs": { "$ref": "#/$defs/indicator", "description": "Base only: right-hand indicator." }, "type": { "enum": [ "And", "Or", "Base", "Multi", "Then" ], "type": "string" }, "value": { "description": "Multi only: threshold count (>=1).", "type": "number" }, "window": { "description": "Then only: how long each step has to be followed by the next one, e.g. {length: 30, interval: 'Minute'}. length must be > 0.", "properties": { "interval": { "enum": [ "Day", "Hour", "Minute" ], "type": "string" }, "length": { "type": "number" } }, "required": [ "length", "interval" ], "type": "object" } }, "required": [ "type" ], "type": "object" }, "deploymentBudget": { "additionalProperties": true, "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", "properties": { "amount": { "$ref": "#/$defs/indicator", "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." }, "type": { "enum": [ "dollars", "percent of portfolio" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "indicator": { "additionalProperties": true, "description": "An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; InstitutionalHoldings (SEC Form 13F positions) needs targetAsset, metric, windowDays and optional manager, reads the latest quarter public on or before the evaluation date, never sums across quarters, and measures accumulation and crowding rather than entry timing since a 13F is long-only and up to 45 days stale; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), MovingAverageConvergenceDivergence (MACD; needs targetAsset; optional fastLength/slowLength/signalLength defaulting to 12/26/9 with slowLength > fastLength, interval Day|Hour|Minute default Day, and line macd|signal|histogram selecting which of the three MACD outputs to emit), AverageDirectionalIndex (Wilder ADX trend-strength system 0-100; needs targetAsset+window; optional line adx|plusDi|minusDi — ADX measures strength, +DI/-DI direction), RelativeVolume (RVOL; needs targetAsset+window; current bar volume divided by the mean volume of the trailing N completed bars, ~1.0 is its recent pace), Stochastic (needs targetAsset+window; optional smoothK/smoothD defaulting to 3/3 and line k|d), CommodityChannelIndex (CCI; needs targetAsset+window; optional constant defaulting to 0.015), WilliamsR (needs targetAsset+window; −100 to 0 scale), MoneyFlowIndex (MFI; needs targetAsset+window; volume-weighted 0-100), OnBalanceVolume (OBV; needs targetAsset; optional interval default Day), AccumulationDistribution (ADL; needs targetAsset; optional interval default Day), ChaikinMoneyFlow (CMF; needs targetAsset+window; −1 to +1 scale), DonchianChannel (needs targetAsset+window; optional line upper|lower|middle default upper), KeltnerChannel (needs targetAsset+window; optional multiplier default 2 and line upper|middle|lower default middle), Supertrend (needs targetAsset+window; optional multiplier default 3 and line value|direction default value, direction reads +1 up / −1 down), IchimokuCloud (needs targetAsset+window; optional spanLength default 52 and line tenkan|kijun|senkouA|senkouB|chikou default tenkan; lines unshifted), ParabolicSar (needs targetAsset; optional interval default Day, step default 0.02, maximum default 0.2), HeikinAshi (needs targetAsset + line open|high|low|close|streak; candles from completed one-minute regular-session bars, identical in backtests and live; streak is the signed length of the current same-color run since the last color change, 0 on a doji or once the run shows an opposite-direction wick, so three clean same-color candles are streak >= 3 or <= -3), TrueRange/AverageTrueRange (need targetAsset; ATR also window), VWAP (needs targetAsset; resets each trading day), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), Correlation (rolling Pearson of two sub-indicators' returns; needs 2 sub-indicators + window with length >= 2), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown.", "properties": { "amountBasis": { "description": "Disclosed transaction range endpoint. PoliticalPurchaseShare defaults to Midpoint; PoliticalTrades amount metrics default to LowerBound.", "enum": [ "LowerBound", "Midpoint", "UpperBound" ], "type": "string" }, "assetType": { "description": "IsAssetType: e.g. 'Stock', 'Cryptocurrency'.", "type": "string" }, "base": { "description": "Log: logarithm base (>0, ≠1).", "type": "number" }, "chamber": { "description": "PoliticalTrades optional cohort filter. All combines House and Senate.", "enum": [ "All", "House", "Senate" ], "type": "string" }, "compound": { "type": "boolean" }, "condition": { "$ref": "#/$defs/condition", "description": "ConsecutiveTrue / CountTrue: the condition to evaluate over the window." }, "customIndicatorId": { "description": "REQUIRED when type is CustomIndicator. Mongo ObjectId hex string for the owned custom data source (see list_custom_indicators or MCP session instructions). Never omit — display name alone is rejected.", "type": "string" }, "customIndicatorName": { "description": "Optional display label for CustomIndicator. Ignored for lookup; customIndicatorId is authoritative.", "type": "string" }, "direction": { "description": "Option* indicators: long or short.", "enum": [ "long", "short" ], "type": "string" }, "exponent": { "description": "Exponentiation: power exponent.", "type": "number" }, "filer": { "description": "PoliticalTrades member full or last name; empty means all members.", "type": "string" }, "form": { "additionalProperties": true, "description": "Optional auto-generated form metadata. Usually omit; the server fills this.", "type": "object" }, "index": { "description": "IsIndexMember: point-in-time index id ('SP500', 'NASDAQ100', or 'DJIA').", "enum": [ "SP500", "NASDAQ100", "DJIA" ], "type": "string" }, "indicators": { "description": "Sub-indicators for compound types (Plus, CrossAbove, etc.).", "items": { "$ref": "#/$defs/indicator" }, "type": "array" }, "industry": { "description": "IsIndustry: industry tag.", "type": "string" }, "instrument": { "description": "PoliticalTrades instrument class (Equity, Option, All). PoliticalPurchaseShare requires Equity or Option and returns that side's percent of member-wide public purchases.", "enum": [ "Equity", "Option", "All" ], "type": "string" }, "length": { "description": "TrailingSum and similar — window length in days.", "type": "number" }, "lookbackDays": { "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" }, "manager": { "description": "InstitutionalHoldings filing manager: a CIK such as 1067983 matches exactly, any other text matches a filed name containing it, and empty reads every manager. Prefer the CIK — one CIK files under as many as six spellings of its own name, and a name like 'berkshire' spans Buffett's firm, two of its insurance subsidiaries and an unrelated asset manager.", "type": "string" }, "matchAsset": { "additionalProperties": true, "description": "IsAsset / IsNotAsset: the asset to match against.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "maxDte": { "description": "Option* indicators: max days to expiration.", "type": "number" }, "memberId": { "description": "Bioguide member id (e.g. P000197). Required for PoliticalPurchaseShare, whose member-wide public purchase amounts include symbols outside the trading universe; also selects an exact PoliticalTrades member and overrides filer.", "type": "string" }, "message": { "description": "DaysSinceAlert / MinutesSinceAlert: alert message to match.", "type": "string" }, "metric": { "description": "PoliticalTrades: NetAmount, BuyAmount, SellAmount, BuyCount, SellCount, DistinctBuyers, Held. InstitutionalHoldings: HolderCount, TotalShares, TotalValue, BookSharePercent, ConcentrationTop5, NetShareChange, NetHolderChange, NewHolders, ClosedHolders. Fundamental/CompoundAnnualGrowthRate: financial metric (e.g. 'peRatio'). Economic: economic indicator (e.g. 'UNRATE'). Index: index symbol (e.g. 'VIX', 'SPX'). RebalanceDecisionMetric: allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit.", "type": "string" }, "minDte": { "description": "Option* indicators: min days to expiration.", "type": "number" }, "minOrMax": { "description": "OptionDaysToExpiration / OptionDaysHeld: aggregate selector.", "enum": [ "min", "max" ], "type": "string" }, "minutesAfterOpen": { "description": "IndicatorAtMinutesAfterOpen: 0–390.", "maximum": 390, "minimum": 0, "type": "number" }, "name": { "description": "Optional human-readable name. Auto-derived if omitted.", "type": "string" }, "numStandardDeviations": { "description": "BollingerBand: e.g. 2.", "type": "number" }, "optionType": { "description": "Option* indicators: call or put.", "enum": [ "call", "put" ], "type": "string" }, "orderStatus": { "description": "Order-side indicators: filter by status.", "enum": [ "Pending", "Accepted", "Pending User Approval", "Canceled", "Filled", "Partially Filled" ], "type": "string" }, "positionEffect": { "description": "Option* indicators: open or close.", "type": "string" }, "side": { "description": "Order-side indicators: Buy or Sell.", "enum": [ "Buy", "Sell" ], "type": "string" }, "spreadType": { "description": "Option* indicators: vertical, ironCondor, etc.", "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "targetAsset": { "additionalProperties": true, "description": "The asset this indicator measures (most price/option indicators).", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "targetAssets": { "description": "Multi-asset variant (position / order indicators).", "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "transactionStatus": { "description": "DaysSinceTransaction: transaction status.", "enum": [ "Pending", "Canceled", "Completed" ], "type": "string" }, "transactionType": { "description": "DaysSinceTransaction: Deposit or Withdraw.", "enum": [ "Deposit", "Withdraw" ], "type": "string" }, "type": { "enum": [ "DaysSinceAgent", "MinutesSinceAgent", "DaysSinceAlert", "MinutesSinceAlert", "StockReport", "DaysUntilEarnings", "DaysSinceEarnings", "ImpliedVolatility", "IVRank", "IVPercentile", "IVHVRatio", "LastOrderPrice", "Fundamental", "Economic", "CustomIndicator", "Index", "BollingerBand", "RelativeStrengthIndex", "MovingAverageConvergenceDivergence", "AverageDirectionalIndex", "RelativeVolume", "Stochastic", "CommodityChannelIndex", "WilliamsR", "MoneyFlowIndex", "OnBalanceVolume", "AccumulationDistribution", "ChaikinMoneyFlow", "DonchianChannel", "KeltnerChannel", "Supertrend", "IchimokuCloud", "ParabolicSar", "PriceMeanAbsoluteDeviation", "ExponentialMovingAverage", "SimpleMovingAverage", "PriceStandardDeviation", "PriceRateOfChange", "MaxDrawdown", "MaxDrawup", "MinimumPrice", "MaximumPrice", "IndicatorMeanAbsoluteDeviation", "IndicatorExponentialMovingAverage", "IndicatorSimpleMovingAverage", "IndicatorStandardDeviation", "IndicatorRateOfChange", "DaysSinceOrder", "DaysSinceOptionOrder", "DaysSinceStrategyFired", "DaysSinceLastRebalanceOptionOrder", "MinutesSinceOptionOrder", "MinutesSinceOrder", "DaysSinceTransaction", "InitialValue", "BuyingPower", "PositionValue", "PositionPercentChange", "PortfolioValue", "RebalanceDecisionMetric", "Value", "Price", "Plus", "Minus", "Multiply", "Divide", "Negative", "AbsoluteValue", "SquareRoot", "Max", "Min", "Day", "Month", "Date", "Year", "CurrentTimeSeconds", "CurrentTimeMinutes", "CurrentTimeHours", "TrailingSum", "CompoundAnnualGrowthRate", "Log", "Exponentiation", "SumOrderQuantity", "SumOrderAmount", "MinutesAfterOpen", "OpeningPrice", "MinuteBarHigh", "HeikinAshi", "MinuteBarLow", "PreviousClosingPrice", "HighOfDay", "LowOfDay", "MinutesUntilClose", "PriceChangeSinceOpen", "GapSize", "GapPercentage", "TrueRange", "AverageTrueRange", "Volume", "VWAP", "BullishFairValueGap", "BearishFairValueGap", "IndicatorAtMinutesAfterOpen", "IndicatorWindowAgo", "IndicatorAtEntry", "IsIndexMember", "PoliticalTrades", "PoliticalPurchaseShare", "InsiderTrades", "InstitutionalHoldings", "IsIndustry", "IsAssetType", "IsAsset", "IsNotAsset", "CrossAbove", "CrossBelow", "Correlation", "PositionMaxDrawdown", "PositionMaxDrawup", "UnderlyingMaxDrawdown", "ConsecutiveTrue", "CountTrue", "OptionPositionValue", "OptionPositionCount", "OptionPositionPercentChange", "OptionPositionMaxDrawdown", "OptionDaysToExpiration", "OptionDaysHeld", "OptionCollateral", "OptionSpreadCount", "OptionSpreadEntryPrice", "OptionUnrealizedPnL", "OptionRealizedPnL", "OptionRealizedPremium", "OptionGrossExposurePercent" ], "type": "string" }, "underlying": { "description": "Option* indicators: underlying ticker (e.g. 'SPY').", "type": "string" }, "value": { "description": "Required for Value indicators (numeric constant).", "type": "number" }, "window": { "description": "Rolling time window. e.g. {length:14, interval:'Day'} = trailing 14 trading days.", "properties": { "interval": { "enum": [ "Day", "Hour", "Minute" ], "type": "string" }, "length": { "minimum": 1, "type": "number" } }, "required": [ "length", "interval" ], "type": "object" }, "windowDays": { "description": "PoliticalTrades / InsiderTrades trailing calendar days. InstitutionalHoldings reads a disclosed quarter only if its filing became public within this many days, so it defaults to 180 rather than 90: a 13F is quarterly plus a filing lag of up to 45 days, and 91 days can separate two filings.", "maximum": 3650, "minimum": 1, "type": "integer" }, "years": { "description": "CompoundAnnualGrowthRate: years over which to compute CAGR.", "type": "number" } }, "required": [ "type" ], "type": "object" }, "optionStructureTemplate": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "orderExecution": { "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", "oneOf": [ { "additionalProperties": false, "properties": { "type": { "const": "Market", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": false, "properties": { "price": { "oneOf": [ { "additionalProperties": false, "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.", "properties": { "amount": { "minimum": 1e-8, "type": "number" }, "type": { "const": "UnitPrice", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.", "properties": { "amount": { "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).", "oneOf": [ { "minimum": 1e-8, "type": "number" }, { "$ref": "#/$defs/indicator" } ] }, "type": { "const": "MinimumNetCredit", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.", "properties": { "amount": { "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).", "oneOf": [ { "minimum": 1e-8, "type": "number" }, { "$ref": "#/$defs/indicator" } ] }, "type": { "const": "MaximumNetDebit", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.", "properties": { "reference": { "const": "Current", "type": "string" }, "type": { "const": "QuoteRelative", "type": "string" } }, "required": [ "type", "reference" ], "type": "object" } ] }, "type": { "const": "Limit", "type": "string" }, "workingTime": { "oneOf": [ { "additionalProperties": false, "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.", "properties": { "type": { "const": "Day", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": false, "properties": { "minutes": { "minimum": 1, "type": "number" }, "type": { "const": "Minutes", "type": "string" } }, "required": [ "type", "minutes" ], "type": "object" } ] } }, "required": [ "type", "price" ], "type": "object" } ], "type": "object" }, "rebalanceOptionSleeve": { "additionalProperties": true, "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).", "properties": { "limit": { "minimum": 1, "type": "number" }, "name": { "type": "string" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). 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" }, "strategy": { "additionalProperties": true, "description": "A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", "properties": { "action": { "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).", "oneOf": [ { "additionalProperties": true, "description": "Buy or Sell a stock/crypto position.", "properties": { "amount": { "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "percent of portfolio", "percent of buying power", "percent of current positions", "dollars", "number of assets" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "targetAsset": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": { "enum": [ "Buy", "Sell" ], "type": "string" } }, "required": [ "type", "targetAsset", "amount" ], "type": "object" }, { "additionalProperties": true, "description": "Send an alert message (no order).", "properties": { "message": { "type": "string" }, "type": { "const": "Alert", "type": "string" } }, "required": [ "type", "message" ], "type": "object" }, { "additionalProperties": true, "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is the deploymentPercent indicator (0–100; use Value for a constant). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.", "properties": { "allocationPolicy": { "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", "oneOf": [ { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "expectedReturnShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "riskAversion": { "maximum": 1000, "minimum": 0, "type": "number" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MeanVariance", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "riskAversion", "expectedReturnShrinkage", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "RiskParity", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MaximumDiversification", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" } ] }, "canSell": { "$ref": "#/$defs/condition", "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out." }, "deploymentPercent": { "$ref": "#/$defs/indicator", "description": "Indicator returning percent of portfolio NAV to deploy, 0–100 (remainder cash). Use Value for a constant, or PoliticalPurchaseShare with memberId and instrument Equity. Do not use totalBudget here." }, "exposurePolicy": { "additionalProperties": false, "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "targetAnnualizedVolatilityPercent": { "maximum": 1000, "minimum": 0, "type": "number" }, "type": { "const": "VolatilityTarget", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "targetAnnualizedVolatilityPercent", "estimatedTransactionCostBps" ], "type": "object" }, "limit": { "minimum": 1, "type": "number" }, "perNameAllocation": { "additionalProperties": true, "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.", "properties": { "amount": { "exclusiveMinimum": 0, "type": "number" }, "type": { "enum": [ "percent of portfolio", "dollars" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "type": { "const": "DynamicRebalance", "type": "string" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "type", "universe", "pipeline", "weightIndicator" ], "type": "object" }, { "additionalProperties": true, "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).", "properties": { "continueExisting": { "type": "boolean" }, "cooldownMinutes": { "minimum": 0, "type": "number" }, "executionModel": { "type": "string" }, "includeMarketData": { "type": "boolean" }, "initialMessage": { "type": "string" }, "maxIterations": { "minimum": 1, "type": "number" }, "planningModel": { "type": "string" }, "skipPlanning": { "type": "boolean" }, "type": { "const": "LaunchAgent", "type": "string" } }, "required": [ "type", "planningModel", "executionModel", "initialMessage", "maxIterations", "includeMarketData", "continueExisting", "skipPlanning" ], "type": "object" }, { "additionalProperties": true, "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.", "properties": { "against": { "additionalProperties": true, "description": "Optional parent-position selector (e.g. for covered calls).", "type": "object" }, "allocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "builder": { "additionalProperties": true, "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.", "properties": { "dynamicUnderlying": { "additionalProperties": true, "properties": { "limit": { "minimum": 1, "type": "number" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" } }, "required": [ "universe" ], "type": "object" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "underlyingSymbol": { "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "type": { "const": "OpenOption", "type": "string" } }, "required": [ "type", "builder" ], "type": "object" }, { "additionalProperties": true, "description": "RebalanceOption: filter/rank a universe, then allocate option premium under totalBudget. sizingMode fixedPerName (default) uses weightIndicator only to rank names and perNameAllocation to size each. sizingMode proportionalToWeight splits totalBudget among selected names in proportion to positive weightIndicator values; perNameAllocation is ignored, and sleeves/allocationPolicy/exposurePolicy cannot be combined with it. allocationPolicy may jointly size selected names in fixedPerName mode; exposurePolicy may scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder for shared cadence. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies.", "properties": { "allocationPolicy": { "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", "oneOf": [ { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "expectedReturnShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "riskAversion": { "maximum": 1000, "minimum": 0, "type": "number" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MeanVariance", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "riskAversion", "expectedReturnShrinkage", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "RiskParity", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MaximumDiversification", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" } ] }, "exposurePolicy": { "additionalProperties": false, "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "targetAnnualizedVolatilityPercent": { "maximum": 1000, "minimum": 0, "type": "number" }, "type": { "const": "VolatilityTarget", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "targetAnnualizedVolatilityPercent", "estimatedTransactionCostBps" ], "type": "object" }, "limit": { "minimum": 1, "type": "number" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "positionScope": { "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.", "enum": [ "portfolio", "strategy" ], "type": "string" }, "sizingMode": { "enum": [ "fixedPerName", "proportionalToWeight" ], "type": "string" }, "sleeves": { "items": { "additionalProperties": true, "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).", "properties": { "limit": { "minimum": 1, "type": "number" }, "name": { "type": "string" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "structureTemplates": { "items": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "minItems": 1, "type": "array" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "name" ], "type": "object" }, "type": "array" }, "structureTemplates": { "items": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "minItems": 1, "type": "array" }, "totalBudget": { "additionalProperties": true, "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", "properties": { "amount": { "$ref": "#/$defs/indicator", "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." }, "type": { "enum": [ "dollars", "percent of portfolio" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "type": { "const": "RebalanceOption", "type": "string" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "type", "universe", "pipeline", "weightIndicator", "structureTemplates" ], "type": "object" }, { "additionalProperties": true, "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.", "properties": { "closeScope": { "enum": [ "spread", "leg" ], "type": "string" }, "direction": { "enum": [ "long", "short" ], "type": "string" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "quantity": { "additionalProperties": true, "description": "How many contracts to close. Defaults to all matching when omitted.", "type": "object" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "triggers": { "items": { "description": "Close trigger for an options exit. Triggers within an array are OR-gated.", "oneOf": [ { "additionalProperties": true, "properties": { "maxPnlPercent": { "type": "number" }, "minPnlPercent": { "type": "number" }, "type": { "const": "pnl", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxDte": { "type": "number" }, "minDte": { "type": "number" }, "type": { "const": "dte", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxDaysHeld": { "type": "number" }, "minDaysHeld": { "type": "number" }, "type": { "const": "daysHeld", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxIv": { "type": "number" }, "maxSpreadDelta": { "type": "number" }, "maxSpreadTheta": { "type": "number" }, "minIv": { "type": "number" }, "minSpreadDelta": { "type": "number" }, "minSpreadTheta": { "type": "number" }, "type": { "const": "greeks", "type": "string" } }, "required": [ "type" ], "type": "object" } ], "type": "object" }, "type": "array" }, "type": { "const": "CloseOption", "type": "string" }, "underlyings": { "items": { "type": "string" }, "type": "array" } }, "required": [ "type" ], "type": "object" } ], "type": "object" }, "active": { "description": "Whether the strategy is active (default true).", "type": "boolean" }, "condition": { "$ref": "#/$defs/condition" }, "name": { "description": "Human-readable strategy name.", "type": "string" }, "orderExecution": { "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", "oneOf": [ { "additionalProperties": false, "properties": { "type": { "const": "Market", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": false, "properties": { "price": { "oneOf": [ { "additionalProperties": false, "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.", "properties": { "amount": { "minimum": 1e-8, "type": "number" }, "type": { "const": "UnitPrice", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.", "properties": { "amount": { "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).", "oneOf": [ { "minimum": 1e-8, "type": "number" }, { "$ref": "#/$defs/indicator" } ] }, "type": { "const": "MinimumNetCredit", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.", "properties": { "amount": { "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).", "oneOf": [ { "minimum": 1e-8, "type": "number" }, { "$ref": "#/$defs/indicator" } ] }, "type": { "const": "MaximumNetDebit", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.", "properties": { "reference": { "const": "Current", "type": "string" }, "type": { "const": "QuoteRelative", "type": "string" } }, "required": [ "type", "reference" ], "type": "object" } ] }, "type": { "const": "Limit", "type": "string" }, "workingTime": { "oneOf": [ { "additionalProperties": false, "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.", "properties": { "type": { "const": "Day", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": false, "properties": { "minutes": { "minimum": 1, "type": "number" }, "type": { "const": "Minutes", "type": "string" } }, "required": [ "type", "minutes" ], "type": "object" } ] } }, "required": [ "type", "price" ], "type": "object" } ], "type": "object" } }, "required": [ "name", "condition", "action" ], "type": "object" }, "window": { "description": "Rolling time window. e.g. {length:14, interval:'Day'} = trailing 14 trading days.", "properties": { "interval": { "enum": [ "Day", "Hour", "Minute" ], "type": "string" }, "length": { "minimum": 1, "type": "number" } }, "required": [ "length", "interval" ], "type": "object" } }, "additionalProperties": true, "properties": { "alertsEnabled": { "type": "boolean" }, "initialValue": { "description": "Starting cash (default 10000). Use 0 for agent-only / LaunchAgent portfolios that never trade capital.", "minimum": 0, "type": "number" }, "main": { "description": "Mark as main portfolio (optional).", "type": "boolean" }, "message": { "description": "OPTIONAL natural-language fallback. If provided WITHOUT name/strategies, the server runs a paid LLM to translate NL→portfolio. Prefer the structured fields (no LLM cost).", "type": "string" }, "name": { "description": "Portfolio name (required).", "type": "string" }, "policy": { "additionalProperties": false, "description": "OPTIONAL. Which stocks the portfolio's dynamic universes may select. Only stockEligibility is accepted; omitted fields take the defaults. Automated trading can never be set here: it starts off and only the owner enables it in the NexusTrade UI.", "properties": { "stockEligibility": { "additionalProperties": false, "properties": { "industryFilter": { "additionalProperties": false, "properties": { "industries": { "items": { "type": "string" }, "type": "array" }, "match": { "enum": [ "ANY", "ALL" ], "type": "string" }, "mode": { "enum": [ "ALL", "INCLUDE_ONLY" ], "type": "string" } }, "required": [ "mode", "match", "industries" ], "type": "object" }, "maximumMarketCapUsd": { "description": "Largest market cap allowed, or null for no ceiling (default).", "oneOf": [ { "minimum": 0, "type": "integer" }, { "type": "null" } ] }, "minimumMarketCapUsd": { "description": "Smallest market cap a dynamic-universe candidate may have. Default 1000000000 ($1B); lower it for a small-cap strategy.", "minimum": 0, "type": "integer" }, "missingMarketCapBehavior": { "description": "EXCLUDE (default) drops a dynamic-universe candidate with no known market cap (most ETFs, some filers). INCLUDE keeps it; the cap bounds then apply only to names whose cap is known. Omit to keep the portfolio's current setting.", "enum": [ "EXCLUDE", "INCLUDE" ], "type": "string" }, "shareClassBehavior": { "description": "ONE_PER_COMPANY (default) keeps one share class per company in a dynamic-universe selection, so a top-5 holds five companies (GOOGL over GOOG on a tie). ALL_CLASSES lets every class through, for a book that trades share classes against each other (a GOOG/GOOGL pair). Omit to keep the portfolio's current setting.", "enum": [ "ONE_PER_COMPANY", "ALL_CLASSES" ], "type": "string" } }, "type": "object" } }, "required": [ "stockEligibility" ], "type": "object" }, "strategies": { "description": "Array of strategies. Each strategy is { name, condition, action, orderExecution? }. RebalanceOption actions may include action.positionScope (portfolio | strategy). Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. See $defs.strategy / $defs.condition / $defs/indicator.", "items": { "additionalProperties": true, "description": "A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", "properties": { "action": { "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).", "oneOf": [ { "additionalProperties": true, "description": "Buy or Sell a stock/crypto position.", "properties": { "amount": { "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "percent of portfolio", "percent of buying power", "percent of current positions", "dollars", "number of assets" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "targetAsset": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": { "enum": [ "Buy", "Sell" ], "type": "string" } }, "required": [ "type", "targetAsset", "amount" ], "type": "object" }, { "additionalProperties": true, "description": "Send an alert message (no order).", "properties": { "message": { "type": "string" }, "type": { "const": "Alert", "type": "string" } }, "required": [ "type", "message" ], "type": "object" }, { "additionalProperties": true, "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is the deploymentPercent indicator (0–100; use Value for a constant). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.", "properties": { "allocationPolicy": { "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", "oneOf": [ { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "expectedReturnShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "riskAversion": { "maximum": 1000, "minimum": 0, "type": "number" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MeanVariance", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "riskAversion", "expectedReturnShrinkage", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "RiskParity", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MaximumDiversification", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" } ] }, "canSell": { "$ref": "#/$defs/condition", "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out." }, "deploymentPercent": { "$ref": "#/$defs/indicator", "description": "Indicator returning percent of portfolio NAV to deploy, 0–100 (remainder cash). Use Value for a constant, or PoliticalPurchaseShare with memberId and instrument Equity. Do not use totalBudget here." }, "exposurePolicy": { "additionalProperties": false, "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "targetAnnualizedVolatilityPercent": { "maximum": 1000, "minimum": 0, "type": "number" }, "type": { "const": "VolatilityTarget", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "targetAnnualizedVolatilityPercent", "estimatedTransactionCostBps" ], "type": "object" }, "limit": { "minimum": 1, "type": "number" }, "perNameAllocation": { "additionalProperties": true, "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.", "properties": { "amount": { "exclusiveMinimum": 0, "type": "number" }, "type": { "enum": [ "percent of portfolio", "dollars" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "type": { "const": "DynamicRebalance", "type": "string" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "type", "universe", "pipeline", "weightIndicator" ], "type": "object" }, { "additionalProperties": true, "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).", "properties": { "continueExisting": { "type": "boolean" }, "cooldownMinutes": { "minimum": 0, "type": "number" }, "executionModel": { "type": "string" }, "includeMarketData": { "type": "boolean" }, "initialMessage": { "type": "string" }, "maxIterations": { "minimum": 1, "type": "number" }, "planningModel": { "type": "string" }, "skipPlanning": { "type": "boolean" }, "type": { "const": "LaunchAgent", "type": "string" } }, "required": [ "type", "planningModel", "executionModel", "initialMessage", "maxIterations", "includeMarketData", "continueExisting", "skipPlanning" ], "type": "object" }, { "additionalProperties": true, "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.", "properties": { "against": { "additionalProperties": true, "description": "Optional parent-position selector (e.g. for covered calls).", "type": "object" }, "allocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "builder": { "additionalProperties": true, "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.", "properties": { "dynamicUnderlying": { "additionalProperties": true, "properties": { "limit": { "minimum": 1, "type": "number" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" } }, "required": [ "universe" ], "type": "object" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "underlyingSymbol": { "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "type": { "const": "OpenOption", "type": "string" } }, "required": [ "type", "builder" ], "type": "object" }, { "additionalProperties": true, "description": "RebalanceOption: filter/rank a universe, then allocate option premium under totalBudget. sizingMode fixedPerName (default) uses weightIndicator only to rank names and perNameAllocation to size each. sizingMode proportionalToWeight splits totalBudget among selected names in proportion to positive weightIndicator values; perNameAllocation is ignored, and sleeves/allocationPolicy/exposurePolicy cannot be combined with it. allocationPolicy may jointly size selected names in fixedPerName mode; exposurePolicy may scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder for shared cadence. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies.", "properties": { "allocationPolicy": { "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", "oneOf": [ { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "expectedReturnShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "riskAversion": { "maximum": 1000, "minimum": 0, "type": "number" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MeanVariance", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "riskAversion", "expectedReturnShrinkage", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "RiskParity", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MaximumDiversification", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" } ] }, "exposurePolicy": { "additionalProperties": false, "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "targetAnnualizedVolatilityPercent": { "maximum": 1000, "minimum": 0, "type": "number" }, "type": { "const": "VolatilityTarget", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "targetAnnualizedVolatilityPercent", "estimatedTransactionCostBps" ], "type": "object" }, "limit": { "minimum": 1, "type": "number" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "positionScope": { "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.", "enum": [ "portfolio", "strategy" ], "type": "string" }, "sizingMode": { "enum": [ "fixedPerName", "proportionalToWeight" ], "type": "string" }, "sleeves": { "items": { "additionalProperties": true, "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).", "properties": { "limit": { "minimum": 1, "type": "number" }, "name": { "type": "string" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "structureTemplates": { "items": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "minItems": 1, "type": "array" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "name" ], "type": "object" }, "type": "array" }, "structureTemplates": { "items": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "minItems": 1, "type": "array" }, "totalBudget": { "additionalProperties": true, "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", "properties": { "amount": { "$ref": "#/$defs/indicator", "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." }, "type": { "enum": [ "dollars", "percent of portfolio" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "type": { "const": "RebalanceOption", "type": "string" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "type", "universe", "pipeline", "weightIndicator", "structureTemplates" ], "type": "object" }, { "additionalProperties": true, "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.", "properties": { "closeScope": { "enum": [ "spread", "leg" ], "type": "string" }, "direction": { "enum": [ "long", "short" ], "type": "string" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "quantity": { "additionalProperties": true, "description": "How many contracts to close. Defaults to all matching when omitted.", "type": "object" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "triggers": { "items": { "description": "Close trigger for an options exit. Triggers within an array are OR-gated.", "oneOf": [ { "additionalProperties": true, "properties": { "maxPnlPercent": { "type": "number" }, "minPnlPercent": { "type": "number" }, "type": { "const": "pnl", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxDte": { "type": "number" }, "minDte": { "type": "number" }, "type": { "const": "dte", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxDaysHeld": { "type": "number" }, "minDaysHeld": { "type": "number" }, "type": { "const": "daysHeld", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxIv": { "type": "number" }, "maxSpreadDelta": { "type": "number" }, "maxSpreadTheta": { "type": "number" }, "minIv": { "type": "number" }, "minSpreadDelta": { "type": "number" }, "minSpreadTheta": { "type": "number" }, "type": { "const": "greeks", "type": "string" } }, "required": [ "type" ], "type": "object" } ], "type": "object" }, "type": "array" }, "type": { "const": "CloseOption", "type": "string" }, "underlyings": { "items": { "type": "string" }, "type": "array" } }, "required": [ "type" ], "type": "object" } ], "type": "object" }, "active": { "description": "Whether the strategy is active (default true).", "type": "boolean" }, "condition": { "$ref": "#/$defs/condition" }, "name": { "description": "Human-readable strategy name.", "type": "string" }, "orderExecution": { "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", "oneOf": [ { "additionalProperties": false, "properties": { "type": { "const": "Market", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": false, "properties": { "price": { "oneOf": [ { "additionalProperties": false, "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.", "properties": { "amount": { "minimum": 1e-8, "type": "number" }, "type": { "const": "UnitPrice", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.", "properties": { "amount": { "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).", "oneOf": [ { "minimum": 1e-8, "type": "number" }, { "$ref": "#/$defs/indicator" } ] }, "type": { "const": "MinimumNetCredit", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.", "properties": { "amount": { "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).", "oneOf": [ { "minimum": 1e-8, "type": "number" }, { "$ref": "#/$defs/indicator" } ] }, "type": { "const": "MaximumNetDebit", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.", "properties": { "reference": { "const": "Current", "type": "string" }, "type": { "const": "QuoteRelative", "type": "string" } }, "required": [ "type", "reference" ], "type": "object" } ] }, "type": { "const": "Limit", "type": "string" }, "workingTime": { "oneOf": [ { "additionalProperties": false, "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.", "properties": { "type": { "const": "Day", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": false, "properties": { "minutes": { "minimum": 1, "type": "number" }, "type": { "const": "Minutes", "type": "string" } }, "required": [ "type", "minutes" ], "type": "object" } ] } }, "required": [ "type", "price" ], "type": "object" } ], "type": "object" } }, "required": [ "name", "condition", "action" ], "type": "object" }, "minItems": 1, "type": "array" }, "supportsCrypto": { "type": "boolean" }, "supportsFractionalShares": { "type": "boolean" } }, "required": [], "type": "object" }, "name": "build_portfolio", "outputSchema": null }, { "description": "Replace a deployed (paper/live) portfolio's entire strategy set with deep copies of a source portfolio's strategy objects (by reference, not YAML). Source is a chat or deployed portfolio; the target MUST be a real deployed portfolio (chat portfolios are immutable and cannot be a target). Use this to deploy a chat portfolio's strategies onto a live/paper portfolio without re-describing them. Do NOT automatically backtest after clone — only backtest when the user asked for research validation. The source's prior backtest does not validate the target (different objects), but deploy-only asks should stop at clone/deploy.", "inputSchema": { "properties": { "preserve_existing": { "description": "When true, APPEND the source strategies to the target's existing strategy set instead of replacing it. Existing strategies (and their open system orders) are kept untouched — useful when the target has position-specific exit rules tied to current open positions. Defaults to false (legacy REPLACE semantics: all prior strategies are archived and their open system orders cancelled).", "type": "boolean" }, "source_portfolio_id": { "description": "Source portfolio ID (live, paper, or chat) to copy strategies FROM.", "type": "string" }, "target_portfolio_id": { "description": "Deployed portfolio ID (from fetch_portfolios — paper or live) whose strategy set will be REPLACED by default. Keeps its identity, brokerage, deployment, and history. Must be a real portfolio; chat portfolios are immutable and cannot be a target.", "type": "string" } }, "required": [ "target_portfolio_id" ], "type": "object" }, "name": "clone_strategies_to_portfolio", "outputSchema": null }, { "description": "⚠ COSTS LLM CREDITS on the NexusTrade account — spins up an Aurora agent via Router V5 classification + ReAct execution loops, billed per token. **Manual approval required**: do NOT call unless the user explicitly asked to launch an Aurora agent. For strategy creation/backtesting/analysis prefer no-LLM tools: structured create_portfolio (pass full IPortfolio JSON), backtest_portfolio, query_backtest_history, query_*, fetch_portfolios. Create a new autonomous Aurora agent using the same body shape as POST /api/agent. When maxIterations or automationMode are omitted, applies the user's saved ChatSettings. Agent models are product-locked (openai/gpt-5.6-luna planner, openai/gpt-6-luna executor, and the platform tool-role defaults) and cannot be overridden. Pass attachment_ids from upload_chat_attachment (READY) to bind files onto the last user message — same as the web FILES tab. Use this for a method-brief PDF plus a short analyze/report request.", "inputSchema": { "properties": { "attachment_ids": { "description": "READY chat-attachment ids from upload_chat_attachment. Bound onto the last user message as fileAttachments (same refs as the web FILES tab).", "items": { "type": "string" }, "type": "array" }, "automationMode": { "description": "automated | semi-automated. When omitted, uses ChatSettings.agentAutomationMode.", "enum": [ "automated", "semi-automated" ], "type": "string" }, "conversationId": { "description": "Optional NexusGenAI conversation id", "type": "string" }, "idempotencyKey": { "description": "Caller-chosen token that makes this create retry-safe. Creation runs the router and the planner and regularly takes longer than the transport will wait, so a call that times out has usually SUCCEEDED. Pass a unique key, and if the call appears to fail, retry with the SAME key: you get the agent the first call created, never a second billed run. A key reused for a different prompt is rejected rather than silently replayed.", "type": "string" }, "maxIterations": { "description": "Max agent iterations. When omitted, uses the user's saved ChatSettings.agentIterations (same as the web UI).", "type": "number" }, "messages": { "description": "ChatMessage array, e.g. [{\"sender\":\"User\",\"content\":\"...\"}]", "items": { "properties": { "content": { "description": "Message content", "type": "string" }, "data": { "description": "Optional message metadata", "type": "object" }, "sender": { "description": "Message sender, usually User", "type": "string" }, "timestamp": { "description": "Optional ISO timestamp", "type": "string" } }, "required": [ "sender", "content" ], "type": "object" }, "type": "array" }, "session_depth": { "description": "Deprecated compatibility field. Both values use Aurora's adaptive routing policy.", "enum": [ "smart", "deep" ], "type": "string" }, "title": { "description": "Optional user-assigned display name for the new agent (max 100 chars). Enables later lookup via title on get_agent / send_agent_message / etc.", "type": "string" } }, "required": [], "type": "object" }, "name": "create_agent", "outputSchema": null }, { "description": "Create an algorithmic trading portfolio. **PREFERRED PATH (no LLM cost): pass a fully-structured IPortfolio JSON payload** — see inputSchema for name + strategies[] with nested condition/action/indicator objects and optional strategy-owned orderExecution. DynamicRebalance.deploymentPercent and RebalanceOption.totalBudget.amount are indicator objects: use Value for a constant or PoliticalPurchaseShare with a Bioguide memberId, instrument Equity/Option, and amountBasis Midpoint for a dynamic purchase mix. RebalanceOption.sizingMode proportionalToWeight sizes names by positive weightIndicator values. Omit orderExecution for the explicit Market default; true waiting Limits use UnitPrice for shares/crypto or MinimumNetCredit/MaximumNetDebit for options, whose amount may be an indicator (such as OptionSpreadEntryPrice plus a Value) evaluated when the strategy fires. CustomIndicator nodes MUST include customIndicatorId from list_custom_indicators. Validate without saving by calling build_portfolio with the same JSON first. Fallback NL path `{ message: \"...\" }` costs LLM credits and should only be used when structured JSON is impractical.\n\nCustom data sources: none yet.\nCreate one with run_compute (pass name and point_kind to promote its signal output directly), or use dataset_to_indicator with a saved dataset; then reference customIndicatorId in create_portfolio.", "inputSchema": { "$defs": { "action": { "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).", "oneOf": [ { "additionalProperties": true, "description": "Buy or Sell a stock/crypto position.", "properties": { "amount": { "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "percent of portfolio", "percent of buying power", "percent of current positions", "dollars", "number of assets" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "targetAsset": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": { "enum": [ "Buy", "Sell" ], "type": "string" } }, "required": [ "type", "targetAsset", "amount" ], "type": "object" }, { "additionalProperties": true, "description": "Send an alert message (no order).", "properties": { "message": { "type": "string" }, "type": { "const": "Alert", "type": "string" } }, "required": [ "type", "message" ], "type": "object" }, { "additionalProperties": true, "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is the deploymentPercent indicator (0–100; use Value for a constant). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.", "properties": { "allocationPolicy": { "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", "oneOf": [ { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "expectedReturnShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "riskAversion": { "maximum": 1000, "minimum": 0, "type": "number" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MeanVariance", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "riskAversion", "expectedReturnShrinkage", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "RiskParity", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MaximumDiversification", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" } ] }, "canSell": { "$ref": "#/$defs/condition", "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out." }, "deploymentPercent": { "$ref": "#/$defs/indicator", "description": "Indicator returning percent of portfolio NAV to deploy, 0–100 (remainder cash). Use Value for a constant, or PoliticalPurchaseShare with memberId and instrument Equity. Do not use totalBudget here." }, "exposurePolicy": { "additionalProperties": false, "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "targetAnnualizedVolatilityPercent": { "maximum": 1000, "minimum": 0, "type": "number" }, "type": { "const": "VolatilityTarget", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "targetAnnualizedVolatilityPercent", "estimatedTransactionCostBps" ], "type": "object" }, "limit": { "minimum": 1, "type": "number" }, "perNameAllocation": { "additionalProperties": true, "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.", "properties": { "amount": { "exclusiveMinimum": 0, "type": "number" }, "type": { "enum": [ "percent of portfolio", "dollars" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "type": { "const": "DynamicRebalance", "type": "string" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "type", "universe", "pipeline", "weightIndicator" ], "type": "object" }, { "additionalProperties": true, "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).", "properties": { "continueExisting": { "type": "boolean" }, "cooldownMinutes": { "minimum": 0, "type": "number" }, "executionModel": { "type": "string" }, "includeMarketData": { "type": "boolean" }, "initialMessage": { "type": "string" }, "maxIterations": { "minimum": 1, "type": "number" }, "planningModel": { "type": "string" }, "skipPlanning": { "type": "boolean" }, "type": { "const": "LaunchAgent", "type": "string" } }, "required": [ "type", "planningModel", "executionModel", "initialMessage", "maxIterations", "includeMarketData", "continueExisting", "skipPlanning" ], "type": "object" }, { "additionalProperties": true, "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.", "properties": { "against": { "additionalProperties": true, "description": "Optional parent-position selector (e.g. for covered calls).", "type": "object" }, "allocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "builder": { "additionalProperties": true, "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.", "properties": { "dynamicUnderlying": { "additionalProperties": true, "properties": { "limit": { "minimum": 1, "type": "number" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" } }, "required": [ "universe" ], "type": "object" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "underlyingSymbol": { "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "type": { "const": "OpenOption", "type": "string" } }, "required": [ "type", "builder" ], "type": "object" }, { "additionalProperties": true, "description": "RebalanceOption: filter/rank a universe, then allocate option premium under totalBudget. sizingMode fixedPerName (default) uses weightIndicator only to rank names and perNameAllocation to size each. sizingMode proportionalToWeight splits totalBudget among selected names in proportion to positive weightIndicator values; perNameAllocation is ignored, and sleeves/allocationPolicy/exposurePolicy cannot be combined with it. allocationPolicy may jointly size selected names in fixedPerName mode; exposurePolicy may scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder for shared cadence. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies.", "properties": { "allocationPolicy": { "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", "oneOf": [ { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "expectedReturnShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "riskAversion": { "maximum": 1000, "minimum": 0, "type": "number" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MeanVariance", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "riskAversion", "expectedReturnShrinkage", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "RiskParity", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MaximumDiversification", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" } ] }, "exposurePolicy": { "additionalProperties": false, "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "targetAnnualizedVolatilityPercent": { "maximum": 1000, "minimum": 0, "type": "number" }, "type": { "const": "VolatilityTarget", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "targetAnnualizedVolatilityPercent", "estimatedTransactionCostBps" ], "type": "object" }, "limit": { "minimum": 1, "type": "number" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "positionScope": { "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.", "enum": [ "portfolio", "strategy" ], "type": "string" }, "sizingMode": { "enum": [ "fixedPerName", "proportionalToWeight" ], "type": "string" }, "sleeves": { "items": { "additionalProperties": true, "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).", "properties": { "limit": { "minimum": 1, "type": "number" }, "name": { "type": "string" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "structureTemplates": { "items": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "minItems": 1, "type": "array" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "name" ], "type": "object" }, "type": "array" }, "structureTemplates": { "items": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "minItems": 1, "type": "array" }, "totalBudget": { "additionalProperties": true, "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", "properties": { "amount": { "$ref": "#/$defs/indicator", "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." }, "type": { "enum": [ "dollars", "percent of portfolio" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "type": { "const": "RebalanceOption", "type": "string" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "type", "universe", "pipeline", "weightIndicator", "structureTemplates" ], "type": "object" }, { "additionalProperties": true, "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.", "properties": { "closeScope": { "enum": [ "spread", "leg" ], "type": "string" }, "direction": { "enum": [ "long", "short" ], "type": "string" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "quantity": { "additionalProperties": true, "description": "How many contracts to close. Defaults to all matching when omitted.", "type": "object" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "triggers": { "items": { "description": "Close trigger for an options exit. Triggers within an array are OR-gated.", "oneOf": [ { "additionalProperties": true, "properties": { "maxPnlPercent": { "type": "number" }, "minPnlPercent": { "type": "number" }, "type": { "const": "pnl", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxDte": { "type": "number" }, "minDte": { "type": "number" }, "type": { "const": "dte", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxDaysHeld": { "type": "number" }, "minDaysHeld": { "type": "number" }, "type": { "const": "daysHeld", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxIv": { "type": "number" }, "maxSpreadDelta": { "type": "number" }, "maxSpreadTheta": { "type": "number" }, "minIv": { "type": "number" }, "minSpreadDelta": { "type": "number" }, "minSpreadTheta": { "type": "number" }, "type": { "const": "greeks", "type": "string" } }, "required": [ "type" ], "type": "object" } ], "type": "object" }, "type": "array" }, "type": { "const": "CloseOption", "type": "string" }, "underlyings": { "items": { "type": "string" }, "type": "array" } }, "required": [ "type" ], "type": "object" } ], "type": "object" }, "asset": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "condition": { "additionalProperties": true, "description": "A condition tree (Bridge pattern). type='Base' compares lhs vs rhs with a comparator; type='And'/'Or' combine an array of nested conditions; type='Multi' fires when N nested conditions are true (count vs threshold); type='Then' is sequential — it fires when the last nested condition is true now and each earlier one was true at a strictly earlier tick within 'window' of the next, so it needs at least 2 conditions and a window with length > 0.", "properties": { "comparison": { "description": "Base / Multi only: how to compare.", "enum": [ "lessThan", "greaterThan", "lessThanOrEqual", "greaterThanOrEqual", "equal", "notEqual" ], "type": "string" }, "conditions": { "description": "And / Or / Multi / Then only: nested conditions. Then reads them in order (at least 2).", "items": { "$ref": "#/$defs/condition" }, "type": "array" }, "lhs": { "$ref": "#/$defs/indicator", "description": "Base only: left-hand indicator." }, "name": { "description": "Optional name; auto-derived if omitted.", "type": "string" }, "rhs": { "$ref": "#/$defs/indicator", "description": "Base only: right-hand indicator." }, "type": { "enum": [ "And", "Or", "Base", "Multi", "Then" ], "type": "string" }, "value": { "description": "Multi only: threshold count (>=1).", "type": "number" }, "window": { "description": "Then only: how long each step has to be followed by the next one, e.g. {length: 30, interval: 'Minute'}. length must be > 0.", "properties": { "interval": { "enum": [ "Day", "Hour", "Minute" ], "type": "string" }, "length": { "type": "number" } }, "required": [ "length", "interval" ], "type": "object" } }, "required": [ "type" ], "type": "object" }, "deploymentBudget": { "additionalProperties": true, "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", "properties": { "amount": { "$ref": "#/$defs/indicator", "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." }, "type": { "enum": [ "dollars", "percent of portfolio" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "indicator": { "additionalProperties": true, "description": "An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; InstitutionalHoldings (SEC Form 13F positions) needs targetAsset, metric, windowDays and optional manager, reads the latest quarter public on or before the evaluation date, never sums across quarters, and measures accumulation and crowding rather than entry timing since a 13F is long-only and up to 45 days stale; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), MovingAverageConvergenceDivergence (MACD; needs targetAsset; optional fastLength/slowLength/signalLength defaulting to 12/26/9 with slowLength > fastLength, interval Day|Hour|Minute default Day, and line macd|signal|histogram selecting which of the three MACD outputs to emit), AverageDirectionalIndex (Wilder ADX trend-strength system 0-100; needs targetAsset+window; optional line adx|plusDi|minusDi — ADX measures strength, +DI/-DI direction), RelativeVolume (RVOL; needs targetAsset+window; current bar volume divided by the mean volume of the trailing N completed bars, ~1.0 is its recent pace), Stochastic (needs targetAsset+window; optional smoothK/smoothD defaulting to 3/3 and line k|d), CommodityChannelIndex (CCI; needs targetAsset+window; optional constant defaulting to 0.015), WilliamsR (needs targetAsset+window; −100 to 0 scale), MoneyFlowIndex (MFI; needs targetAsset+window; volume-weighted 0-100), OnBalanceVolume (OBV; needs targetAsset; optional interval default Day), AccumulationDistribution (ADL; needs targetAsset; optional interval default Day), ChaikinMoneyFlow (CMF; needs targetAsset+window; −1 to +1 scale), DonchianChannel (needs targetAsset+window; optional line upper|lower|middle default upper), KeltnerChannel (needs targetAsset+window; optional multiplier default 2 and line upper|middle|lower default middle), Supertrend (needs targetAsset+window; optional multiplier default 3 and line value|direction default value, direction reads +1 up / −1 down), IchimokuCloud (needs targetAsset+window; optional spanLength default 52 and line tenkan|kijun|senkouA|senkouB|chikou default tenkan; lines unshifted), ParabolicSar (needs targetAsset; optional interval default Day, step default 0.02, maximum default 0.2), HeikinAshi (needs targetAsset + line open|high|low|close|streak; candles from completed one-minute regular-session bars, identical in backtests and live; streak is the signed length of the current same-color run since the last color change, 0 on a doji or once the run shows an opposite-direction wick, so three clean same-color candles are streak >= 3 or <= -3), TrueRange/AverageTrueRange (need targetAsset; ATR also window), VWAP (needs targetAsset; resets each trading day), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), Correlation (rolling Pearson of two sub-indicators' returns; needs 2 sub-indicators + window with length >= 2), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown.", "properties": { "amountBasis": { "description": "Disclosed transaction range endpoint. PoliticalPurchaseShare defaults to Midpoint; PoliticalTrades amount metrics default to LowerBound.", "enum": [ "LowerBound", "Midpoint", "UpperBound" ], "type": "string" }, "assetType": { "description": "IsAssetType: e.g. 'Stock', 'Cryptocurrency'.", "type": "string" }, "base": { "description": "Log: logarithm base (>0, ≠1).", "type": "number" }, "chamber": { "description": "PoliticalTrades optional cohort filter. All combines House and Senate.", "enum": [ "All", "House", "Senate" ], "type": "string" }, "compound": { "type": "boolean" }, "condition": { "$ref": "#/$defs/condition", "description": "ConsecutiveTrue / CountTrue: the condition to evaluate over the window." }, "customIndicatorId": { "description": "REQUIRED when type is CustomIndicator. Mongo ObjectId hex string for the owned custom data source (see list_custom_indicators or MCP session instructions). Never omit — display name alone is rejected.", "type": "string" }, "customIndicatorName": { "description": "Optional display label for CustomIndicator. Ignored for lookup; customIndicatorId is authoritative.", "type": "string" }, "direction": { "description": "Option* indicators: long or short.", "enum": [ "long", "short" ], "type": "string" }, "exponent": { "description": "Exponentiation: power exponent.", "type": "number" }, "filer": { "description": "PoliticalTrades member full or last name; empty means all members.", "type": "string" }, "form": { "additionalProperties": true, "description": "Optional auto-generated form metadata. Usually omit; the server fills this.", "type": "object" }, "index": { "description": "IsIndexMember: point-in-time index id ('SP500', 'NASDAQ100', or 'DJIA').", "enum": [ "SP500", "NASDAQ100", "DJIA" ], "type": "string" }, "indicators": { "description": "Sub-indicators for compound types (Plus, CrossAbove, etc.).", "items": { "$ref": "#/$defs/indicator" }, "type": "array" }, "industry": { "description": "IsIndustry: industry tag.", "type": "string" }, "instrument": { "description": "PoliticalTrades instrument class (Equity, Option, All). PoliticalPurchaseShare requires Equity or Option and returns that side's percent of member-wide public purchases.", "enum": [ "Equity", "Option", "All" ], "type": "string" }, "length": { "description": "TrailingSum and similar — window length in days.", "type": "number" }, "lookbackDays": { "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" }, "manager": { "description": "InstitutionalHoldings filing manager: a CIK such as 1067983 matches exactly, any other text matches a filed name containing it, and empty reads every manager. Prefer the CIK — one CIK files under as many as six spellings of its own name, and a name like 'berkshire' spans Buffett's firm, two of its insurance subsidiaries and an unrelated asset manager.", "type": "string" }, "matchAsset": { "additionalProperties": true, "description": "IsAsset / IsNotAsset: the asset to match against.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "maxDte": { "description": "Option* indicators: max days to expiration.", "type": "number" }, "memberId": { "description": "Bioguide member id (e.g. P000197). Required for PoliticalPurchaseShare, whose member-wide public purchase amounts include symbols outside the trading universe; also selects an exact PoliticalTrades member and overrides filer.", "type": "string" }, "message": { "description": "DaysSinceAlert / MinutesSinceAlert: alert message to match.", "type": "string" }, "metric": { "description": "PoliticalTrades: NetAmount, BuyAmount, SellAmount, BuyCount, SellCount, DistinctBuyers, Held. InstitutionalHoldings: HolderCount, TotalShares, TotalValue, BookSharePercent, ConcentrationTop5, NetShareChange, NetHolderChange, NewHolders, ClosedHolders. Fundamental/CompoundAnnualGrowthRate: financial metric (e.g. 'peRatio'). Economic: economic indicator (e.g. 'UNRATE'). Index: index symbol (e.g. 'VIX', 'SPX'). RebalanceDecisionMetric: allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit.", "type": "string" }, "minDte": { "description": "Option* indicators: min days to expiration.", "type": "number" }, "minOrMax": { "description": "OptionDaysToExpiration / OptionDaysHeld: aggregate selector.", "enum": [ "min", "max" ], "type": "string" }, "minutesAfterOpen": { "description": "IndicatorAtMinutesAfterOpen: 0–390.", "maximum": 390, "minimum": 0, "type": "number" }, "name": { "description": "Optional human-readable name. Auto-derived if omitted.", "type": "string" }, "numStandardDeviations": { "description": "BollingerBand: e.g. 2.", "type": "number" }, "optionType": { "description": "Option* indicators: call or put.", "enum": [ "call", "put" ], "type": "string" }, "orderStatus": { "description": "Order-side indicators: filter by status.", "enum": [ "Pending", "Accepted", "Pending User Approval", "Canceled", "Filled", "Partially Filled" ], "type": "string" }, "positionEffect": { "description": "Option* indicators: open or close.", "type": "string" }, "side": { "description": "Order-side indicators: Buy or Sell.", "enum": [ "Buy", "Sell" ], "type": "string" }, "spreadType": { "description": "Option* indicators: vertical, ironCondor, etc.", "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "targetAsset": { "additionalProperties": true, "description": "The asset this indicator measures (most price/option indicators).", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "targetAssets": { "description": "Multi-asset variant (position / order indicators).", "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "transactionStatus": { "description": "DaysSinceTransaction: transaction status.", "enum": [ "Pending", "Canceled", "Completed" ], "type": "string" }, "transactionType": { "description": "DaysSinceTransaction: Deposit or Withdraw.", "enum": [ "Deposit", "Withdraw" ], "type": "string" }, "type": { "enum": [ "DaysSinceAgent", "MinutesSinceAgent", "DaysSinceAlert", "MinutesSinceAlert", "StockReport", "DaysUntilEarnings", "DaysSinceEarnings", "ImpliedVolatility", "IVRank", "IVPercentile", "IVHVRatio", "LastOrderPrice", "Fundamental", "Economic", "CustomIndicator", "Index", "BollingerBand", "RelativeStrengthIndex", "MovingAverageConvergenceDivergence", "AverageDirectionalIndex", "RelativeVolume", "Stochastic", "CommodityChannelIndex", "WilliamsR", "MoneyFlowIndex", "OnBalanceVolume", "AccumulationDistribution", "ChaikinMoneyFlow", "DonchianChannel", "KeltnerChannel", "Supertrend", "IchimokuCloud", "ParabolicSar", "PriceMeanAbsoluteDeviation", "ExponentialMovingAverage", "SimpleMovingAverage", "PriceStandardDeviation", "PriceRateOfChange", "MaxDrawdown", "MaxDrawup", "MinimumPrice", "MaximumPrice", "IndicatorMeanAbsoluteDeviation", "IndicatorExponentialMovingAverage", "IndicatorSimpleMovingAverage", "IndicatorStandardDeviation", "IndicatorRateOfChange", "DaysSinceOrder", "DaysSinceOptionOrder", "DaysSinceStrategyFired", "DaysSinceLastRebalanceOptionOrder", "MinutesSinceOptionOrder", "MinutesSinceOrder", "DaysSinceTransaction", "InitialValue", "BuyingPower", "PositionValue", "PositionPercentChange", "PortfolioValue", "RebalanceDecisionMetric", "Value", "Price", "Plus", "Minus", "Multiply", "Divide", "Negative", "AbsoluteValue", "SquareRoot", "Max", "Min", "Day", "Month", "Date", "Year", "CurrentTimeSeconds", "CurrentTimeMinutes", "CurrentTimeHours", "TrailingSum", "CompoundAnnualGrowthRate", "Log", "Exponentiation", "SumOrderQuantity", "SumOrderAmount", "MinutesAfterOpen", "OpeningPrice", "MinuteBarHigh", "HeikinAshi", "MinuteBarLow", "PreviousClosingPrice", "HighOfDay", "LowOfDay", "MinutesUntilClose", "PriceChangeSinceOpen", "GapSize", "GapPercentage", "TrueRange", "AverageTrueRange", "Volume", "VWAP", "BullishFairValueGap", "BearishFairValueGap", "IndicatorAtMinutesAfterOpen", "IndicatorWindowAgo", "IndicatorAtEntry", "IsIndexMember", "PoliticalTrades", "PoliticalPurchaseShare", "InsiderTrades", "InstitutionalHoldings", "IsIndustry", "IsAssetType", "IsAsset", "IsNotAsset", "CrossAbove", "CrossBelow", "Correlation", "PositionMaxDrawdown", "PositionMaxDrawup", "UnderlyingMaxDrawdown", "ConsecutiveTrue", "CountTrue", "OptionPositionValue", "OptionPositionCount", "OptionPositionPercentChange", "OptionPositionMaxDrawdown", "OptionDaysToExpiration", "OptionDaysHeld", "OptionCollateral", "OptionSpreadCount", "OptionSpreadEntryPrice", "OptionUnrealizedPnL", "OptionRealizedPnL", "OptionRealizedPremium", "OptionGrossExposurePercent" ], "type": "string" }, "underlying": { "description": "Option* indicators: underlying ticker (e.g. 'SPY').", "type": "string" }, "value": { "description": "Required for Value indicators (numeric constant).", "type": "number" }, "window": { "description": "Rolling time window. e.g. {length:14, interval:'Day'} = trailing 14 trading days.", "properties": { "interval": { "enum": [ "Day", "Hour", "Minute" ], "type": "string" }, "length": { "minimum": 1, "type": "number" } }, "required": [ "length", "interval" ], "type": "object" }, "windowDays": { "description": "PoliticalTrades / InsiderTrades trailing calendar days. InstitutionalHoldings reads a disclosed quarter only if its filing became public within this many days, so it defaults to 180 rather than 90: a 13F is quarterly plus a filing lag of up to 45 days, and 91 days can separate two filings.", "maximum": 3650, "minimum": 1, "type": "integer" }, "years": { "description": "CompoundAnnualGrowthRate: years over which to compute CAGR.", "type": "number" } }, "required": [ "type" ], "type": "object" }, "optionStructureTemplate": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "orderExecution": { "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", "oneOf": [ { "additionalProperties": false, "properties": { "type": { "const": "Market", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": false, "properties": { "price": { "oneOf": [ { "additionalProperties": false, "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.", "properties": { "amount": { "minimum": 1e-8, "type": "number" }, "type": { "const": "UnitPrice", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.", "properties": { "amount": { "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).", "oneOf": [ { "minimum": 1e-8, "type": "number" }, { "$ref": "#/$defs/indicator" } ] }, "type": { "const": "MinimumNetCredit", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.", "properties": { "amount": { "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).", "oneOf": [ { "minimum": 1e-8, "type": "number" }, { "$ref": "#/$defs/indicator" } ] }, "type": { "const": "MaximumNetDebit", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.", "properties": { "reference": { "const": "Current", "type": "string" }, "type": { "const": "QuoteRelative", "type": "string" } }, "required": [ "type", "reference" ], "type": "object" } ] }, "type": { "const": "Limit", "type": "string" }, "workingTime": { "oneOf": [ { "additionalProperties": false, "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.", "properties": { "type": { "const": "Day", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": false, "properties": { "minutes": { "minimum": 1, "type": "number" }, "type": { "const": "Minutes", "type": "string" } }, "required": [ "type", "minutes" ], "type": "object" } ] } }, "required": [ "type", "price" ], "type": "object" } ], "type": "object" }, "rebalanceOptionSleeve": { "additionalProperties": true, "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).", "properties": { "limit": { "minimum": 1, "type": "number" }, "name": { "type": "string" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). 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" }, "strategy": { "additionalProperties": true, "description": "A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", "properties": { "action": { "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).", "oneOf": [ { "additionalProperties": true, "description": "Buy or Sell a stock/crypto position.", "properties": { "amount": { "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "percent of portfolio", "percent of buying power", "percent of current positions", "dollars", "number of assets" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "targetAsset": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": { "enum": [ "Buy", "Sell" ], "type": "string" } }, "required": [ "type", "targetAsset", "amount" ], "type": "object" }, { "additionalProperties": true, "description": "Send an alert message (no order).", "properties": { "message": { "type": "string" }, "type": { "const": "Alert", "type": "string" } }, "required": [ "type", "message" ], "type": "object" }, { "additionalProperties": true, "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is the deploymentPercent indicator (0–100; use Value for a constant). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.", "properties": { "allocationPolicy": { "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", "oneOf": [ { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "expectedReturnShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "riskAversion": { "maximum": 1000, "minimum": 0, "type": "number" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MeanVariance", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "riskAversion", "expectedReturnShrinkage", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "RiskParity", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MaximumDiversification", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" } ] }, "canSell": { "$ref": "#/$defs/condition", "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out." }, "deploymentPercent": { "$ref": "#/$defs/indicator", "description": "Indicator returning percent of portfolio NAV to deploy, 0–100 (remainder cash). Use Value for a constant, or PoliticalPurchaseShare with memberId and instrument Equity. Do not use totalBudget here." }, "exposurePolicy": { "additionalProperties": false, "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "targetAnnualizedVolatilityPercent": { "maximum": 1000, "minimum": 0, "type": "number" }, "type": { "const": "VolatilityTarget", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "targetAnnualizedVolatilityPercent", "estimatedTransactionCostBps" ], "type": "object" }, "limit": { "minimum": 1, "type": "number" }, "perNameAllocation": { "additionalProperties": true, "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.", "properties": { "amount": { "exclusiveMinimum": 0, "type": "number" }, "type": { "enum": [ "percent of portfolio", "dollars" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "type": { "const": "DynamicRebalance", "type": "string" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "type", "universe", "pipeline", "weightIndicator" ], "type": "object" }, { "additionalProperties": true, "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).", "properties": { "continueExisting": { "type": "boolean" }, "cooldownMinutes": { "minimum": 0, "type": "number" }, "executionModel": { "type": "string" }, "includeMarketData": { "type": "boolean" }, "initialMessage": { "type": "string" }, "maxIterations": { "minimum": 1, "type": "number" }, "planningModel": { "type": "string" }, "skipPlanning": { "type": "boolean" }, "type": { "const": "LaunchAgent", "type": "string" } }, "required": [ "type", "planningModel", "executionModel", "initialMessage", "maxIterations", "includeMarketData", "continueExisting", "skipPlanning" ], "type": "object" }, { "additionalProperties": true, "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.", "properties": { "against": { "additionalProperties": true, "description": "Optional parent-position selector (e.g. for covered calls).", "type": "object" }, "allocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "builder": { "additionalProperties": true, "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.", "properties": { "dynamicUnderlying": { "additionalProperties": true, "properties": { "limit": { "minimum": 1, "type": "number" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" } }, "required": [ "universe" ], "type": "object" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "underlyingSymbol": { "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "type": { "const": "OpenOption", "type": "string" } }, "required": [ "type", "builder" ], "type": "object" }, { "additionalProperties": true, "description": "RebalanceOption: filter/rank a universe, then allocate option premium under totalBudget. sizingMode fixedPerName (default) uses weightIndicator only to rank names and perNameAllocation to size each. sizingMode proportionalToWeight splits totalBudget among selected names in proportion to positive weightIndicator values; perNameAllocation is ignored, and sleeves/allocationPolicy/exposurePolicy cannot be combined with it. allocationPolicy may jointly size selected names in fixedPerName mode; exposurePolicy may scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder for shared cadence. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies.", "properties": { "allocationPolicy": { "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", "oneOf": [ { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "expectedReturnShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "riskAversion": { "maximum": 1000, "minimum": 0, "type": "number" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MeanVariance", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "riskAversion", "expectedReturnShrinkage", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "RiskParity", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MaximumDiversification", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" } ] }, "exposurePolicy": { "additionalProperties": false, "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "targetAnnualizedVolatilityPercent": { "maximum": 1000, "minimum": 0, "type": "number" }, "type": { "const": "VolatilityTarget", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "targetAnnualizedVolatilityPercent", "estimatedTransactionCostBps" ], "type": "object" }, "limit": { "minimum": 1, "type": "number" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "positionScope": { "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.", "enum": [ "portfolio", "strategy" ], "type": "string" }, "sizingMode": { "enum": [ "fixedPerName", "proportionalToWeight" ], "type": "string" }, "sleeves": { "items": { "additionalProperties": true, "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).", "properties": { "limit": { "minimum": 1, "type": "number" }, "name": { "type": "string" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "structureTemplates": { "items": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "minItems": 1, "type": "array" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "name" ], "type": "object" }, "type": "array" }, "structureTemplates": { "items": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "minItems": 1, "type": "array" }, "totalBudget": { "additionalProperties": true, "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", "properties": { "amount": { "$ref": "#/$defs/indicator", "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." }, "type": { "enum": [ "dollars", "percent of portfolio" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "type": { "const": "RebalanceOption", "type": "string" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "type", "universe", "pipeline", "weightIndicator", "structureTemplates" ], "type": "object" }, { "additionalProperties": true, "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.", "properties": { "closeScope": { "enum": [ "spread", "leg" ], "type": "string" }, "direction": { "enum": [ "long", "short" ], "type": "string" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "quantity": { "additionalProperties": true, "description": "How many contracts to close. Defaults to all matching when omitted.", "type": "object" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "triggers": { "items": { "description": "Close trigger for an options exit. Triggers within an array are OR-gated.", "oneOf": [ { "additionalProperties": true, "properties": { "maxPnlPercent": { "type": "number" }, "minPnlPercent": { "type": "number" }, "type": { "const": "pnl", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxDte": { "type": "number" }, "minDte": { "type": "number" }, "type": { "const": "dte", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxDaysHeld": { "type": "number" }, "minDaysHeld": { "type": "number" }, "type": { "const": "daysHeld", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxIv": { "type": "number" }, "maxSpreadDelta": { "type": "number" }, "maxSpreadTheta": { "type": "number" }, "minIv": { "type": "number" }, "minSpreadDelta": { "type": "number" }, "minSpreadTheta": { "type": "number" }, "type": { "const": "greeks", "type": "string" } }, "required": [ "type" ], "type": "object" } ], "type": "object" }, "type": "array" }, "type": { "const": "CloseOption", "type": "string" }, "underlyings": { "items": { "type": "string" }, "type": "array" } }, "required": [ "type" ], "type": "object" } ], "type": "object" }, "active": { "description": "Whether the strategy is active (default true).", "type": "boolean" }, "condition": { "$ref": "#/$defs/condition" }, "name": { "description": "Human-readable strategy name.", "type": "string" }, "orderExecution": { "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", "oneOf": [ { "additionalProperties": false, "properties": { "type": { "const": "Market", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": false, "properties": { "price": { "oneOf": [ { "additionalProperties": false, "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.", "properties": { "amount": { "minimum": 1e-8, "type": "number" }, "type": { "const": "UnitPrice", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.", "properties": { "amount": { "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).", "oneOf": [ { "minimum": 1e-8, "type": "number" }, { "$ref": "#/$defs/indicator" } ] }, "type": { "const": "MinimumNetCredit", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.", "properties": { "amount": { "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).", "oneOf": [ { "minimum": 1e-8, "type": "number" }, { "$ref": "#/$defs/indicator" } ] }, "type": { "const": "MaximumNetDebit", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.", "properties": { "reference": { "const": "Current", "type": "string" }, "type": { "const": "QuoteRelative", "type": "string" } }, "required": [ "type", "reference" ], "type": "object" } ] }, "type": { "const": "Limit", "type": "string" }, "workingTime": { "oneOf": [ { "additionalProperties": false, "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.", "properties": { "type": { "const": "Day", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": false, "properties": { "minutes": { "minimum": 1, "type": "number" }, "type": { "const": "Minutes", "type": "string" } }, "required": [ "type", "minutes" ], "type": "object" } ] } }, "required": [ "type", "price" ], "type": "object" } ], "type": "object" } }, "required": [ "name", "condition", "action" ], "type": "object" }, "window": { "description": "Rolling time window. e.g. {length:14, interval:'Day'} = trailing 14 trading days.", "properties": { "interval": { "enum": [ "Day", "Hour", "Minute" ], "type": "string" }, "length": { "minimum": 1, "type": "number" } }, "required": [ "length", "interval" ], "type": "object" } }, "additionalProperties": true, "properties": { "alertsEnabled": { "type": "boolean" }, "initialValue": { "description": "Starting cash (default 10000). Use 0 for agent-only / LaunchAgent portfolios that never trade capital.", "minimum": 0, "type": "number" }, "main": { "description": "Mark as main portfolio (optional).", "type": "boolean" }, "message": { "description": "OPTIONAL natural-language fallback. If provided WITHOUT name/strategies, the server runs a paid LLM to translate NL→portfolio. Prefer the structured fields (no LLM cost).", "type": "string" }, "name": { "description": "Portfolio name (required).", "type": "string" }, "policy": { "additionalProperties": false, "description": "OPTIONAL. Which stocks the portfolio's dynamic universes may select. Only stockEligibility is accepted; omitted fields take the defaults. Automated trading can never be set here: it starts off and only the owner enables it in the NexusTrade UI.", "properties": { "stockEligibility": { "additionalProperties": false, "properties": { "industryFilter": { "additionalProperties": false, "properties": { "industries": { "items": { "type": "string" }, "type": "array" }, "match": { "enum": [ "ANY", "ALL" ], "type": "string" }, "mode": { "enum": [ "ALL", "INCLUDE_ONLY" ], "type": "string" } }, "required": [ "mode", "match", "industries" ], "type": "object" }, "maximumMarketCapUsd": { "description": "Largest market cap allowed, or null for no ceiling (default).", "oneOf": [ { "minimum": 0, "type": "integer" }, { "type": "null" } ] }, "minimumMarketCapUsd": { "description": "Smallest market cap a dynamic-universe candidate may have. Default 1000000000 ($1B); lower it for a small-cap strategy.", "minimum": 0, "type": "integer" }, "missingMarketCapBehavior": { "description": "EXCLUDE (default) drops a dynamic-universe candidate with no known market cap (most ETFs, some filers). INCLUDE keeps it; the cap bounds then apply only to names whose cap is known. Omit to keep the portfolio's current setting.", "enum": [ "EXCLUDE", "INCLUDE" ], "type": "string" }, "shareClassBehavior": { "description": "ONE_PER_COMPANY (default) keeps one share class per company in a dynamic-universe selection, so a top-5 holds five companies (GOOGL over GOOG on a tie). ALL_CLASSES lets every class through, for a book that trades share classes against each other (a GOOG/GOOGL pair). Omit to keep the portfolio's current setting.", "enum": [ "ONE_PER_COMPANY", "ALL_CLASSES" ], "type": "string" } }, "type": "object" } }, "required": [ "stockEligibility" ], "type": "object" }, "strategies": { "description": "Array of strategies. Each strategy is { name, condition, action, orderExecution? }. RebalanceOption actions may include action.positionScope (portfolio | strategy). Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. See $defs.strategy / $defs.condition / $defs/indicator.", "items": { "additionalProperties": true, "description": "A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", "properties": { "action": { "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).", "oneOf": [ { "additionalProperties": true, "description": "Buy or Sell a stock/crypto position.", "properties": { "amount": { "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "percent of portfolio", "percent of buying power", "percent of current positions", "dollars", "number of assets" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "targetAsset": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": { "enum": [ "Buy", "Sell" ], "type": "string" } }, "required": [ "type", "targetAsset", "amount" ], "type": "object" }, { "additionalProperties": true, "description": "Send an alert message (no order).", "properties": { "message": { "type": "string" }, "type": { "const": "Alert", "type": "string" } }, "required": [ "type", "message" ], "type": "object" }, { "additionalProperties": true, "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is the deploymentPercent indicator (0–100; use Value for a constant). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.", "properties": { "allocationPolicy": { "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", "oneOf": [ { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "expectedReturnShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "riskAversion": { "maximum": 1000, "minimum": 0, "type": "number" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MeanVariance", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "riskAversion", "expectedReturnShrinkage", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "RiskParity", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MaximumDiversification", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" } ] }, "canSell": { "$ref": "#/$defs/condition", "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out." }, "deploymentPercent": { "$ref": "#/$defs/indicator", "description": "Indicator returning percent of portfolio NAV to deploy, 0–100 (remainder cash). Use Value for a constant, or PoliticalPurchaseShare with memberId and instrument Equity. Do not use totalBudget here." }, "exposurePolicy": { "additionalProperties": false, "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "targetAnnualizedVolatilityPercent": { "maximum": 1000, "minimum": 0, "type": "number" }, "type": { "const": "VolatilityTarget", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "targetAnnualizedVolatilityPercent", "estimatedTransactionCostBps" ], "type": "object" }, "limit": { "minimum": 1, "type": "number" }, "perNameAllocation": { "additionalProperties": true, "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.", "properties": { "amount": { "exclusiveMinimum": 0, "type": "number" }, "type": { "enum": [ "percent of portfolio", "dollars" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "type": { "const": "DynamicRebalance", "type": "string" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "type", "universe", "pipeline", "weightIndicator" ], "type": "object" }, { "additionalProperties": true, "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).", "properties": { "continueExisting": { "type": "boolean" }, "cooldownMinutes": { "minimum": 0, "type": "number" }, "executionModel": { "type": "string" }, "includeMarketData": { "type": "boolean" }, "initialMessage": { "type": "string" }, "maxIterations": { "minimum": 1, "type": "number" }, "planningModel": { "type": "string" }, "skipPlanning": { "type": "boolean" }, "type": { "const": "LaunchAgent", "type": "string" } }, "required": [ "type", "planningModel", "executionModel", "initialMessage", "maxIterations", "includeMarketData", "continueExisting", "skipPlanning" ], "type": "object" }, { "additionalProperties": true, "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.", "properties": { "against": { "additionalProperties": true, "description": "Optional parent-position selector (e.g. for covered calls).", "type": "object" }, "allocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "builder": { "additionalProperties": true, "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.", "properties": { "dynamicUnderlying": { "additionalProperties": true, "properties": { "limit": { "minimum": 1, "type": "number" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" } }, "required": [ "universe" ], "type": "object" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "underlyingSymbol": { "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "type": { "const": "OpenOption", "type": "string" } }, "required": [ "type", "builder" ], "type": "object" }, { "additionalProperties": true, "description": "RebalanceOption: filter/rank a universe, then allocate option premium under totalBudget. sizingMode fixedPerName (default) uses weightIndicator only to rank names and perNameAllocation to size each. sizingMode proportionalToWeight splits totalBudget among selected names in proportion to positive weightIndicator values; perNameAllocation is ignored, and sleeves/allocationPolicy/exposurePolicy cannot be combined with it. allocationPolicy may jointly size selected names in fixedPerName mode; exposurePolicy may scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder for shared cadence. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies.", "properties": { "allocationPolicy": { "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", "oneOf": [ { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "expectedReturnShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "riskAversion": { "maximum": 1000, "minimum": 0, "type": "number" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MeanVariance", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "riskAversion", "expectedReturnShrinkage", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "RiskParity", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MaximumDiversification", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" } ] }, "exposurePolicy": { "additionalProperties": false, "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "targetAnnualizedVolatilityPercent": { "maximum": 1000, "minimum": 0, "type": "number" }, "type": { "const": "VolatilityTarget", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "targetAnnualizedVolatilityPercent", "estimatedTransactionCostBps" ], "type": "object" }, "limit": { "minimum": 1, "type": "number" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "positionScope": { "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.", "enum": [ "portfolio", "strategy" ], "type": "string" }, "sizingMode": { "enum": [ "fixedPerName", "proportionalToWeight" ], "type": "string" }, "sleeves": { "items": { "additionalProperties": true, "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).", "properties": { "limit": { "minimum": 1, "type": "number" }, "name": { "type": "string" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "structureTemplates": { "items": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "minItems": 1, "type": "array" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "name" ], "type": "object" }, "type": "array" }, "structureTemplates": { "items": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "minItems": 1, "type": "array" }, "totalBudget": { "additionalProperties": true, "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", "properties": { "amount": { "$ref": "#/$defs/indicator", "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." }, "type": { "enum": [ "dollars", "percent of portfolio" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "type": { "const": "RebalanceOption", "type": "string" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "type", "universe", "pipeline", "weightIndicator", "structureTemplates" ], "type": "object" }, { "additionalProperties": true, "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.", "properties": { "closeScope": { "enum": [ "spread", "leg" ], "type": "string" }, "direction": { "enum": [ "long", "short" ], "type": "string" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "quantity": { "additionalProperties": true, "description": "How many contracts to close. Defaults to all matching when omitted.", "type": "object" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "triggers": { "items": { "description": "Close trigger for an options exit. Triggers within an array are OR-gated.", "oneOf": [ { "additionalProperties": true, "properties": { "maxPnlPercent": { "type": "number" }, "minPnlPercent": { "type": "number" }, "type": { "const": "pnl", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxDte": { "type": "number" }, "minDte": { "type": "number" }, "type": { "const": "dte", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxDaysHeld": { "type": "number" }, "minDaysHeld": { "type": "number" }, "type": { "const": "daysHeld", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxIv": { "type": "number" }, "maxSpreadDelta": { "type": "number" }, "maxSpreadTheta": { "type": "number" }, "minIv": { "type": "number" }, "minSpreadDelta": { "type": "number" }, "minSpreadTheta": { "type": "number" }, "type": { "const": "greeks", "type": "string" } }, "required": [ "type" ], "type": "object" } ], "type": "object" }, "type": "array" }, "type": { "const": "CloseOption", "type": "string" }, "underlyings": { "items": { "type": "string" }, "type": "array" } }, "required": [ "type" ], "type": "object" } ], "type": "object" }, "active": { "description": "Whether the strategy is active (default true).", "type": "boolean" }, "condition": { "$ref": "#/$defs/condition" }, "name": { "description": "Human-readable strategy name.", "type": "string" }, "orderExecution": { "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", "oneOf": [ { "additionalProperties": false, "properties": { "type": { "const": "Market", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": false, "properties": { "price": { "oneOf": [ { "additionalProperties": false, "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.", "properties": { "amount": { "minimum": 1e-8, "type": "number" }, "type": { "const": "UnitPrice", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.", "properties": { "amount": { "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).", "oneOf": [ { "minimum": 1e-8, "type": "number" }, { "$ref": "#/$defs/indicator" } ] }, "type": { "const": "MinimumNetCredit", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.", "properties": { "amount": { "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).", "oneOf": [ { "minimum": 1e-8, "type": "number" }, { "$ref": "#/$defs/indicator" } ] }, "type": { "const": "MaximumNetDebit", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.", "properties": { "reference": { "const": "Current", "type": "string" }, "type": { "const": "QuoteRelative", "type": "string" } }, "required": [ "type", "reference" ], "type": "object" } ] }, "type": { "const": "Limit", "type": "string" }, "workingTime": { "oneOf": [ { "additionalProperties": false, "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.", "properties": { "type": { "const": "Day", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": false, "properties": { "minutes": { "minimum": 1, "type": "number" }, "type": { "const": "Minutes", "type": "string" } }, "required": [ "type", "minutes" ], "type": "object" } ] } }, "required": [ "type", "price" ], "type": "object" } ], "type": "object" } }, "required": [ "name", "condition", "action" ], "type": "object" }, "minItems": 1, "type": "array" }, "supportsCrypto": { "type": "boolean" }, "supportsFractionalShares": { "type": "boolean" } }, "required": [ "name", "strategies" ], "type": "object" }, "name": "create_portfolio", "outputSchema": null }, { "description": "Deep-copy a source chat or deployed portfolio into a new ChatPortfolio with fresh strategy IDs. Omit patches for a clone-only draft, or apply JSON-Pointer patches (replace/add/remove) for surgical edits. Atomic: unresolved patch paths are hard errors. dry_run validates without persisting. Zero research token cost.", "inputSchema": { "properties": { "dry_run": { "description": "true → resolve + diff + validate, persist nothing.", "type": "boolean" }, "name": { "description": "Required new portfolio name.", "type": "string" }, "patches": { "description": "Optional RFC6902-style ops against canonical IPortfolio JSON. Omit or pass [] for an exact semantic clone. Sizing fields are action-type-specific: DynamicRebalance uses /strategies/N/action/deploymentPercent (indicator returning 0–100); RebalanceOption uses /strategies/N/action/totalBudget/amount (indicator). Use Value for a constant or PoliticalPurchaseShare with a Bioguide memberId for a dynamic equity/option purchase mix. Do not patch totalBudget onto DynamicRebalance or deploymentPercent onto RebalanceOption.", "items": { "properties": { "op": { "enum": [ "replace", "add", "remove" ], "type": "string" }, "path": { "type": "string" }, "value": {} }, "required": [ "op", "path" ], "type": "object" }, "type": "array" }, "source_portfolio_id": { "description": "Source portfolio ID (live, paper, or chat) to deep-copy.", "type": "string" } }, "required": [ "source_portfolio_id", "name" ], "type": "object" }, "name": "create_portfolio_variant", "outputSchema": null }, { "description": "Deep-copy a source portfolio (chat OR deployed) into a NEW chat portfolio with fresh strategy IDs and no YAML/NL re-authoring. Use this when an existing portfolio must remain the exact semantic baseline. Omit patches (or pass []) for a clone-only control; supply RFC-6902 JSON-Pointer patches (op/path/value) only for deliberate surgical changes. Patch paths target the IPortfolio shape and are action-type-specific: DynamicRebalance cash/deploy → `/strategies/0/action/deploymentPercent` (indicator returning 0–100; use Value for a constant); RebalanceOption book budget → `/strategies/0/action/totalBudget/amount` (indicator). PoliticalPurchaseShare with memberId and instrument Equity or Option gives the dynamic disclosed purchase mix; RebalanceOption sizingMode proportionalToWeight divides its budget by positive weightIndicator values. Never put totalBudget on DynamicRebalance or deploymentPercent on RebalanceOption. Requires source_portfolio_id and name. Pass dry_run:true to validate without persisting. Result is an independent chat portfolio; backtest it to evaluate.", "inputSchema": { "additionalProperties": false, "properties": { "dry_run": { "description": "Resolve, diff and validate without persisting.", "type": "boolean" }, "name": { "description": "Required new portfolio name.", "type": "string" }, "patches": { "description": "RFC6902-style ops against canonical IPortfolio JSON. Omit or pass [] for an exact semantic clone.", "type": "array" }, "source_portfolio_id": { "description": "Source portfolio ID (live, paper, or chat) to deep-copy.", "type": "string" } }, "required": [ "source_portfolio_id", "name" ], "type": "object" }, "name": "create_portfolio_variant", "outputSchema": null }, { "description": "List or search your portfolios with lightweight metadata (strategy id + name). Matches portfolio name, strategy names, and tickers — same workspace search as the dashboard / GET /api/chat-portfolio. include_chat_portfolios returns workspace DRAFTS only (excludes deployedMirror rows). Recover a past chat draft: include_paper=false, include_live=false, include_chat_portfolios=true, search=\"Delta 0.07\" (then get_portfolio for full strategy JSON). Returns an object: { portfolios, page, limit, total, totalPages, scopes }. Deployed and draft rows page as one list (all deployed, then all drafts), so every row is reachable by walking pages. When search is set, include_positions defaults to false. Use analyze_portfolios only when you need LLM-written analysis.", "inputSchema": { "properties": { "include_chat_portfolios": { "description": "Include workspace draft chat portfolios (default false). Excludes deployedMirror. Set true with include_paper=false and include_live=false for draft-only search.", "type": "boolean" }, "include_inactive": { "description": "Include inactive portfolios (default true)", "type": "boolean" }, "include_live": { "description": "Include live trading portfolios (default true)", "type": "boolean" }, "include_paper": { "description": "Include paper portfolios (default true)", "type": "boolean" }, "include_positions": { "description": "Include positions + spread-grouped holdings (default true when not searching; default false when search is set). cash and buyingPower are always returned for deployed portfolios regardless of this flag.", "type": "boolean" }, "limit": { "description": "Max portfolios to return (default 20, max 50)", "type": "number" }, "page": { "description": "Page number (default 1)", "type": "number" }, "portfolio_ids": { "description": "Specific portfolio IDs to fetch (omit for all)", "items": { "type": "string" }, "type": "array" }, "search": { "description": "Free-text search (max 100 chars) over portfolio name, strategy names, and tickers, ranked by relevance. Matches stemmed whole words (Postgres full-text) and case-insensitive substrings of 3+ characters (so prefixes like \"neckb\" find \"Neckbeard\"). Omit for list/paginate mode. Matches the dashboard workspace search — not condition-field values.", "type": "string" } }, "required": [], "type": "object" }, "name": "fetch_portfolios", "outputSchema": null }, { "description": "⚠ MUTATING — creates or modifies a portfolio. Fork strategies from a shared portfolio into the user's account. target: 'new' creates a chat portfolio; 'existing' patches a deployed portfolio. mode: 'replace' (default) removes old strategies, 'append' keeps them. For monetized portfolios, subscribe first. Returns { forkSharedPortfolioResult: { portfolioId, name, addedCount, removedCount, ... } }. Prefer fork when the user wants to edit/customize strategies.", "inputSchema": { "additionalProperties": false, "properties": { "mode": { "description": "Replace existing strategies or append to them.", "enum": [ "replace", "append" ], "type": "string" }, "name": { "description": "Name for a new portfolio.", "type": "string" }, "shared_portfolio_id": { "description": "ID of the accessible marketplace portfolio to fork into a one-time editable copy. This does not keep strategies synchronized; use copy_trade_shared for continuous mirroring.", "type": "string" }, "target": { "description": "Create a new chat portfolio or update an existing portfolio.", "enum": [ "new", "existing" ], "type": "string" }, "target_portfolio_id": { "description": "Required when target is existing.", "type": "string" } }, "required": [ "shared_portfolio_id", "target" ], "type": "object" }, "name": "fork_shared_portfolio", "outputSchema": null }, { "description": "Aurora agent surface (no LLM cost on this call — pure DB read). Only relevant when the user is actively working with an Aurora agent. Returns status, plan, messages, config. Address by agentId OR by exact title (case-insensitive); provide exactly one. Duplicate titles fail closed with candidate ids. Polling/liveness: use agent.lastProgressAt (advances during sandbox steps, tool cards, LLM rounds, and — while waiting_for_subagents — when children progress) — NOT agent.updatedAt (state transitions only; stays frozen by design while parked on subagents so the waiting-no-wake detector can prefilter). For waiting_for_subagents, a frozen lastProgressAt means children stopped progressing; confirm via child agent statuses. Sandbox step detail: agent.messages[*].data.steps. Poll until status is terminal (complete/stopped/error).", "inputSchema": { "properties": { "agentId": { "description": "MongoDB agent _id (XOR with title)", "type": "string" }, "title": { "description": "Exact case-insensitive user-assigned title (XOR with agentId). Fails if 0 or >1 matches.", "type": "string" } }, "required": [], "type": "object" }, "name": "get_agent", "outputSchema": null }, { "description": "Aurora agent surface (no LLM cost on this call — pure DB read). Only relevant when inspecting an Aurora agent run. Raw trace / trajectory events for an agent (for inspection or building evaluator input). Address by agentId OR exact title (XOR).", "inputSchema": { "properties": { "agentId": { "description": "MongoDB agent _id (XOR with title)", "type": "string" }, "title": { "description": "Exact case-insensitive user-assigned title (XOR with agentId)", "type": "string" } }, "required": [], "type": "object" }, "name": "get_agent_trajectory", "outputSchema": null }, { "description": "Fetch one portfolio with full strategy objects (condition, action, indicators), positions, and spread-grouped holdings. Zero LLM cost — same data path as GET /api/portfolio/:portfolioId. Resolves deployed paper/live portfolios first, then chat portfolios. Use fetch_portfolios to discover IDs. Response includes conditionFieldAudit (comparison, value, window.length per base condition) — use that for Gate-7/Gate-8 deploy verification, NOT strategy.name or condition.name (those may be stale after GA mutation).", "inputSchema": { "properties": { "portfolio_id": { "description": "Portfolio ID (deployed paper/live or chat portfolio ID from fetch_portfolios / create_portfolio).", "type": "string" } }, "required": [ "portfolio_id" ], "type": "object" }, "name": "get_portfolio", "outputSchema": null }, { "description": "Aurora agent surface (no LLM cost on this call itself — pure DB read). Useful only when the user is actively operating an Aurora agent. For strategy creation/backtesting prefer the structured no-LLM tools (create_portfolio with full JSON payload, backtest_portfolio, query_*, fetch_portfolios). List your Aurora agents with pagination using the same query shape as the agent controller.", "inputSchema": { "properties": { "includeArchived": { "description": "Include archived agents. Default false", "type": "boolean" }, "limit": { "description": "Page size (default 10, max 100)", "type": "number" }, "page": { "description": "Page number (default 1)", "type": "number" }, "portfolioId": { "description": "Optional portfolio id or alias to filter agents", "type": "string" }, "search": { "description": "Case-insensitive substring match over title and initialPrompt", "type": "string" }, "starredOnly": { "description": "Return only starred top-level agents, sorted by starredOrder asc then starredAt desc. Default false", "type": "boolean" } }, "required": [], "type": "object" }, "name": "list_agents", "outputSchema": null }, { "description": "Return a time series of {time, value, cash, positionValue, comparisonValue, reservedCollateral} per tick for a completed backtest. Reads from the backtesthistories collection (full minute-resolution; 30-day TTL). Use this to find suspicious single-tick portfolio value jumps without needing the codebase — feed the result through your own jump-detection logic. Cash is derived as value minus Σ(position.quantity × lastPrice). `reservedCollateral` is the collateral locked by open positions at that tick, as the engine computed it; it reads `null` for a run made before collateral reporting existed, which is NOT zero. Never re-derive it from cash − buyingPower. Zero research token cost.", "inputSchema": { "properties": { "backtest_id": { "description": "Backtest ID (required). Must be owned by the calling MCP user.", "type": "string" }, "end_date": { "description": "ISO date filter end (e.g. 2024-10-18). Inclusive; T23:59:59.999Z is appended if a bare date is given.", "type": "string" }, "jump_bps_threshold": { "description": "If set, the response appends a 'Suspicious jumps' section listing every single-tick Δvalue whose magnitude exceeds this many basis points of the FIRST point's value. E.g. 50 = flag any >0.5% move between consecutive ticks. Useful for mark-to-market bug hunts. Default: omitted (no jump scan).", "type": "number" }, "page": { "description": "Page number (default 1)", "type": "number" }, "page_size": { "description": "Rows per page (default 500, max 5000). Larger than events because history is plain numbers — cheap to emit.", "type": "number" }, "start_date": { "description": "ISO date filter start (e.g. 2024-10-07). Inclusive.", "type": "string" } }, "required": [ "backtest_id" ], "type": "object" }, "name": "query_backtest_history", "outputSchema": null }, { "description": "Return the parent backtest document's status, error, interval, timestamps, elapsed time, and completed statistics without reading history/events. Use immediately after backtest_portfolio or before query_backtest_history so ERROR/PENDING/RUNNING states are explicit. Statistics include peakReservedCollateral and medianReservedCollateral — how much capital the book actually had on the line, which a percentage return does not say. Both read \"not recorded\" for a run made before collateral reporting existed; that is not zero, so do not report it as such. Zero research token cost.", "inputSchema": { "properties": { "backtest_id": { "description": "Backtest ID (required). Must be owned by the calling MCP user.", "type": "string" } }, "required": [ "backtest_id" ], "type": "object" }, "name": "query_backtest_status", "outputSchema": null }, { "description": "Aurora agent surface (minimal LLM cost — state transition, no re-planning). Only relevant when actively managing an Aurora agent. Reject a semi-automated agent that is waiting in pending_plan_approval or pending_action_approval. Mirrors POST /api/agent/:agentId/reject, marks the latest assistant message as errored, transitions through the state machine, traces the rejection, and publishes a websocket update.", "inputSchema": { "properties": { "agentId": { "description": "MongoDB agent _id to reject", "type": "string" } }, "required": [ "agentId" ], "type": "object" }, "name": "reject_agent_action", "outputSchema": null }, { "description": "Search and browse publicly shared portfolios from other NexusTrade users, sorted by performance metrics. Optional profileId filters to one creator's public/monetized books (from Search Creators / /p/:profileId).", "inputSchema": { "properties": { "limit": { "description": "Results per page (default 20, max 100)", "maximum": 100, "minimum": 1, "type": "number" }, "max_drawdown": { "description": "Keep listings whose |max drawdown| is at most this percent. Idle books with max drawdown of 0 are excluded. Combine with min_sharpe.", "exclusiveMinimum": 0, "type": "number" }, "min_followers": { "description": "Minimum follower count filter (default 0)", "minimum": 0, "type": "number" }, "min_sharpe": { "description": "Minimum Sharpe ratio filter. Combine with max_drawdown.", "type": "number" }, "page": { "description": "Page number (default 1)", "minimum": 1, "type": "integer" }, "profile_id": { "description": "Optional public creator profileId (from search_creators / /p/:profileId). When set, returns only that creator's public/monetized shared portfolios.", "type": "string" }, "sort_by": { "description": "Sort field: week, month, threeMonths, sixMonths, year, ytd, allTime, followerCount, bookmarkCount, maxDrawdown, sharpeRatio. maxDrawdown ranks lowest |drawdown| first and excludes 0 (idle books). sharpeRatio ranks highest first.", "enum": [ "week", "month", "threeMonths", "sixMonths", "year", "ytd", "allTime", "followerCount", "bookmarkCount", "maxDrawdown", "sharpeRatio" ], "type": "string" }, "sort_order": { "description": "Sort order: 1 or -1 (default -1, or 1 when sort_by is maxDrawdown)", "enum": [ "1", "-1" ], "type": "string" }, "trading_type": { "description": "Trading type: paper-trading or live-trading", "enum": [ "paper-trading", "live-trading" ], "type": "string" } }, "required": [], "type": "object" }, "name": "search_public_portfolios", "outputSchema": null }, { "description": "⚠ COSTS LLM CREDITS — re-runs the Aurora planner LLM after appending the user's follow-up. Manual approval required; do NOT call unless the user explicitly asked to push a message into an active Aurora agent. Address by agentId OR exact title (XOR). Send a follow-up user message to an agent and re-run the planner, matching POST /api/agent/:agentId/message. This can charge planning tokens, rejects actively running/approved states, may recover terminal states, may transition the agent, and publishes websocket updates. It is not an append-only operation.", "inputSchema": { "properties": { "agentId": { "description": "MongoDB agent _id to send the message to (XOR with title)", "type": "string" }, "content": { "description": "The user message text to append to the conversation", "type": "string" }, "title": { "description": "Exact case-insensitive user-assigned title (XOR with agentId)", "type": "string" } }, "required": [ "content" ], "type": "object" }, "name": "send_agent_message", "outputSchema": null }, { "description": "⚠ COSTS LLM CREDITS — same path as POST /api/chat. Router V5 classifies the message: Ask Clarity (persisted), Create Agent (spawns Aurora research), or single-tool fulfill (queued prompt job). Use this for chat turns; use create_agent only when you explicitly want agent spawn without single-tool fulfill. Aurora chooses the complete route adaptively.", "inputSchema": { "properties": { "attachment_ids": { "description": "READY chat-attachment ids from upload_chat_attachment. Bound onto the last user message as fileAttachments.", "items": { "type": "string" }, "type": "array" }, "conversationId": { "description": "Optional NexusGenAI conversation id", "type": "string" }, "messages": { "description": "Full or partial ChatMessage array, e.g. [{\"sender\":\"User\",\"content\":\"...\"}]", "items": { "properties": { "content": { "type": "string" }, "data": { "type": "object" }, "sender": { "type": "string" }, "timestamp": { "type": "string" } }, "required": [ "sender", "content" ], "type": "object" }, "type": "array" }, "session_depth": { "description": "Deprecated compatibility field. Both values use Aurora's adaptive routing policy.", "enum": [ "smart", "deep" ], "type": "string" } }, "required": [ "messages" ], "type": "object" }, "name": "send_chat_message", "outputSchema": null }, { "description": "Aurora agent surface (no LLM cost — pure DB write). Star or unstar a top-level agent for quick sidebar access. Mirrors PATCH /api/agent/:agentId/star. Address by agentId OR exact title (XOR). Omit starred to toggle.", "inputSchema": { "properties": { "agentId": { "description": "MongoDB agent _id to star or unstar (XOR with title)", "type": "string" }, "starred": { "description": "Optional explicit star state. Omit to toggle the current state.", "type": "boolean" }, "title": { "description": "Exact case-insensitive user-assigned title (XOR with agentId)", "type": "string" } }, "required": [], "type": "object" }, "name": "star_agent", "outputSchema": null }, { "description": "Aurora agent surface (no LLM cost — pure state transition). Only relevant when actively managing an Aurora agent. Stop a running agent. Sends a cancellation request and cascades to all descendant subagents. The agent must be in an active state (running, initializing, pending approval, etc.).", "inputSchema": { "properties": { "agentId": { "description": "MongoDB agent _id to stop", "type": "string" } }, "required": [ "agentId" ], "type": "object" }, "name": "stop_agent", "outputSchema": null }, { "description": "Aurora agent surface (no LLM cost — pure DB write). Only relevant when managing Aurora agents. Restore an archived agent so it appears in default agent listings again. Address by agentId OR exact title (XOR).", "inputSchema": { "properties": { "agentId": { "description": "MongoDB agent _id to unarchive (XOR with title)", "type": "string" }, "title": { "description": "Exact case-insensitive user-assigned title (XOR with agentId)", "type": "string" } }, "required": [], "type": "object" }, "name": "unarchive_agent", "outputSchema": null }, { "description": "Deploy, undeploy, rename, delete, add/remove/replace strategies, or set deployment frequency on portfolios. **rename** requires a non-empty `name` on the operation. **delete** permanently removes a chat, paper, or live portfolio (archives deployed paper/live books; deleting a chat portfolio also archives linked deployments). Pass confirmLive:true only after explicit user confirmation when deleting an active live portfolio. **Structured path (zero LLM cost):** pass an `operations` array — see inputSchema. Use `replaceStrategy` / `replaceStrategies` with full `{name, condition, action, orderExecution?}` strategyObjects (same shape as create_portfolio). New rebalance budgets should be indicators (Value for constants, PoliticalPurchaseShare for dynamic member purchase mix); RebalanceOption accepts sizingMode proportionalToWeight. `orderExecution` defaults to Market; true waiting Limits use UnitPrice for shares/crypto or MinimumNetCredit/MaximumNetDebit for options, whose amount may be an indicator (such as OptionSpreadEntryPrice plus a Value) evaluated when the strategy fires. QuoteRelative normally executes immediately at the snapshotted quote. RebalanceOption: set `action.positionScope` to `portfolio` (single-book — closes/orphans all option spreads in the portfolio) or `strategy` (multi-strategy book).", "inputSchema": { "$defs": { "action": { "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).", "oneOf": [ { "additionalProperties": true, "description": "Buy or Sell a stock/crypto position.", "properties": { "amount": { "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "percent of portfolio", "percent of buying power", "percent of current positions", "dollars", "number of assets" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "targetAsset": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": { "enum": [ "Buy", "Sell" ], "type": "string" } }, "required": [ "type", "targetAsset", "amount" ], "type": "object" }, { "additionalProperties": true, "description": "Send an alert message (no order).", "properties": { "message": { "type": "string" }, "type": { "const": "Alert", "type": "string" } }, "required": [ "type", "message" ], "type": "object" }, { "additionalProperties": true, "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is the deploymentPercent indicator (0–100; use Value for a constant). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.", "properties": { "allocationPolicy": { "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", "oneOf": [ { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "expectedReturnShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "riskAversion": { "maximum": 1000, "minimum": 0, "type": "number" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MeanVariance", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "riskAversion", "expectedReturnShrinkage", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "RiskParity", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MaximumDiversification", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" } ] }, "canSell": { "$ref": "#/$defs/condition", "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out." }, "deploymentPercent": { "$ref": "#/$defs/indicator", "description": "Indicator returning percent of portfolio NAV to deploy, 0–100 (remainder cash). Use Value for a constant, or PoliticalPurchaseShare with memberId and instrument Equity. Do not use totalBudget here." }, "exposurePolicy": { "additionalProperties": false, "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "targetAnnualizedVolatilityPercent": { "maximum": 1000, "minimum": 0, "type": "number" }, "type": { "const": "VolatilityTarget", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "targetAnnualizedVolatilityPercent", "estimatedTransactionCostBps" ], "type": "object" }, "limit": { "minimum": 1, "type": "number" }, "perNameAllocation": { "additionalProperties": true, "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.", "properties": { "amount": { "exclusiveMinimum": 0, "type": "number" }, "type": { "enum": [ "percent of portfolio", "dollars" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "type": { "const": "DynamicRebalance", "type": "string" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "type", "universe", "pipeline", "weightIndicator" ], "type": "object" }, { "additionalProperties": true, "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).", "properties": { "continueExisting": { "type": "boolean" }, "cooldownMinutes": { "minimum": 0, "type": "number" }, "executionModel": { "type": "string" }, "includeMarketData": { "type": "boolean" }, "initialMessage": { "type": "string" }, "maxIterations": { "minimum": 1, "type": "number" }, "planningModel": { "type": "string" }, "skipPlanning": { "type": "boolean" }, "type": { "const": "LaunchAgent", "type": "string" } }, "required": [ "type", "planningModel", "executionModel", "initialMessage", "maxIterations", "includeMarketData", "continueExisting", "skipPlanning" ], "type": "object" }, { "additionalProperties": true, "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.", "properties": { "against": { "additionalProperties": true, "description": "Optional parent-position selector (e.g. for covered calls).", "type": "object" }, "allocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "builder": { "additionalProperties": true, "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.", "properties": { "dynamicUnderlying": { "additionalProperties": true, "properties": { "limit": { "minimum": 1, "type": "number" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" } }, "required": [ "universe" ], "type": "object" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "underlyingSymbol": { "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "type": { "const": "OpenOption", "type": "string" } }, "required": [ "type", "builder" ], "type": "object" }, { "additionalProperties": true, "description": "RebalanceOption: filter/rank a universe, then allocate option premium under totalBudget. sizingMode fixedPerName (default) uses weightIndicator only to rank names and perNameAllocation to size each. sizingMode proportionalToWeight splits totalBudget among selected names in proportion to positive weightIndicator values; perNameAllocation is ignored, and sleeves/allocationPolicy/exposurePolicy cannot be combined with it. allocationPolicy may jointly size selected names in fixedPerName mode; exposurePolicy may scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder for shared cadence. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies.", "properties": { "allocationPolicy": { "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", "oneOf": [ { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "expectedReturnShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "riskAversion": { "maximum": 1000, "minimum": 0, "type": "number" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MeanVariance", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "riskAversion", "expectedReturnShrinkage", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "RiskParity", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MaximumDiversification", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" } ] }, "exposurePolicy": { "additionalProperties": false, "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "targetAnnualizedVolatilityPercent": { "maximum": 1000, "minimum": 0, "type": "number" }, "type": { "const": "VolatilityTarget", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "targetAnnualizedVolatilityPercent", "estimatedTransactionCostBps" ], "type": "object" }, "limit": { "minimum": 1, "type": "number" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "positionScope": { "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.", "enum": [ "portfolio", "strategy" ], "type": "string" }, "sizingMode": { "enum": [ "fixedPerName", "proportionalToWeight" ], "type": "string" }, "sleeves": { "items": { "additionalProperties": true, "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).", "properties": { "limit": { "minimum": 1, "type": "number" }, "name": { "type": "string" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "structureTemplates": { "items": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "minItems": 1, "type": "array" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "name" ], "type": "object" }, "type": "array" }, "structureTemplates": { "items": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "minItems": 1, "type": "array" }, "totalBudget": { "additionalProperties": true, "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", "properties": { "amount": { "$ref": "#/$defs/indicator", "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." }, "type": { "enum": [ "dollars", "percent of portfolio" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "type": { "const": "RebalanceOption", "type": "string" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "type", "universe", "pipeline", "weightIndicator", "structureTemplates" ], "type": "object" }, { "additionalProperties": true, "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.", "properties": { "closeScope": { "enum": [ "spread", "leg" ], "type": "string" }, "direction": { "enum": [ "long", "short" ], "type": "string" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "quantity": { "additionalProperties": true, "description": "How many contracts to close. Defaults to all matching when omitted.", "type": "object" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "triggers": { "items": { "description": "Close trigger for an options exit. Triggers within an array are OR-gated.", "oneOf": [ { "additionalProperties": true, "properties": { "maxPnlPercent": { "type": "number" }, "minPnlPercent": { "type": "number" }, "type": { "const": "pnl", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxDte": { "type": "number" }, "minDte": { "type": "number" }, "type": { "const": "dte", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxDaysHeld": { "type": "number" }, "minDaysHeld": { "type": "number" }, "type": { "const": "daysHeld", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxIv": { "type": "number" }, "maxSpreadDelta": { "type": "number" }, "maxSpreadTheta": { "type": "number" }, "minIv": { "type": "number" }, "minSpreadDelta": { "type": "number" }, "minSpreadTheta": { "type": "number" }, "type": { "const": "greeks", "type": "string" } }, "required": [ "type" ], "type": "object" } ], "type": "object" }, "type": "array" }, "type": { "const": "CloseOption", "type": "string" }, "underlyings": { "items": { "type": "string" }, "type": "array" } }, "required": [ "type" ], "type": "object" } ], "type": "object" }, "asset": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "condition": { "additionalProperties": true, "description": "A condition tree (Bridge pattern). type='Base' compares lhs vs rhs with a comparator; type='And'/'Or' combine an array of nested conditions; type='Multi' fires when N nested conditions are true (count vs threshold); type='Then' is sequential — it fires when the last nested condition is true now and each earlier one was true at a strictly earlier tick within 'window' of the next, so it needs at least 2 conditions and a window with length > 0.", "properties": { "comparison": { "description": "Base / Multi only: how to compare.", "enum": [ "lessThan", "greaterThan", "lessThanOrEqual", "greaterThanOrEqual", "equal", "notEqual" ], "type": "string" }, "conditions": { "description": "And / Or / Multi / Then only: nested conditions. Then reads them in order (at least 2).", "items": { "$ref": "#/$defs/condition" }, "type": "array" }, "lhs": { "$ref": "#/$defs/indicator", "description": "Base only: left-hand indicator." }, "name": { "description": "Optional name; auto-derived if omitted.", "type": "string" }, "rhs": { "$ref": "#/$defs/indicator", "description": "Base only: right-hand indicator." }, "type": { "enum": [ "And", "Or", "Base", "Multi", "Then" ], "type": "string" }, "value": { "description": "Multi only: threshold count (>=1).", "type": "number" }, "window": { "description": "Then only: how long each step has to be followed by the next one, e.g. {length: 30, interval: 'Minute'}. length must be > 0.", "properties": { "interval": { "enum": [ "Day", "Hour", "Minute" ], "type": "string" }, "length": { "type": "number" } }, "required": [ "length", "interval" ], "type": "object" } }, "required": [ "type" ], "type": "object" }, "deploymentBudget": { "additionalProperties": true, "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", "properties": { "amount": { "$ref": "#/$defs/indicator", "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." }, "type": { "enum": [ "dollars", "percent of portfolio" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "indicator": { "additionalProperties": true, "description": "An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; InstitutionalHoldings (SEC Form 13F positions) needs targetAsset, metric, windowDays and optional manager, reads the latest quarter public on or before the evaluation date, never sums across quarters, and measures accumulation and crowding rather than entry timing since a 13F is long-only and up to 45 days stale; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), MovingAverageConvergenceDivergence (MACD; needs targetAsset; optional fastLength/slowLength/signalLength defaulting to 12/26/9 with slowLength > fastLength, interval Day|Hour|Minute default Day, and line macd|signal|histogram selecting which of the three MACD outputs to emit), AverageDirectionalIndex (Wilder ADX trend-strength system 0-100; needs targetAsset+window; optional line adx|plusDi|minusDi — ADX measures strength, +DI/-DI direction), RelativeVolume (RVOL; needs targetAsset+window; current bar volume divided by the mean volume of the trailing N completed bars, ~1.0 is its recent pace), Stochastic (needs targetAsset+window; optional smoothK/smoothD defaulting to 3/3 and line k|d), CommodityChannelIndex (CCI; needs targetAsset+window; optional constant defaulting to 0.015), WilliamsR (needs targetAsset+window; −100 to 0 scale), MoneyFlowIndex (MFI; needs targetAsset+window; volume-weighted 0-100), OnBalanceVolume (OBV; needs targetAsset; optional interval default Day), AccumulationDistribution (ADL; needs targetAsset; optional interval default Day), ChaikinMoneyFlow (CMF; needs targetAsset+window; −1 to +1 scale), DonchianChannel (needs targetAsset+window; optional line upper|lower|middle default upper), KeltnerChannel (needs targetAsset+window; optional multiplier default 2 and line upper|middle|lower default middle), Supertrend (needs targetAsset+window; optional multiplier default 3 and line value|direction default value, direction reads +1 up / −1 down), IchimokuCloud (needs targetAsset+window; optional spanLength default 52 and line tenkan|kijun|senkouA|senkouB|chikou default tenkan; lines unshifted), ParabolicSar (needs targetAsset; optional interval default Day, step default 0.02, maximum default 0.2), HeikinAshi (needs targetAsset + line open|high|low|close|streak; candles from completed one-minute regular-session bars, identical in backtests and live; streak is the signed length of the current same-color run since the last color change, 0 on a doji or once the run shows an opposite-direction wick, so three clean same-color candles are streak >= 3 or <= -3), TrueRange/AverageTrueRange (need targetAsset; ATR also window), VWAP (needs targetAsset; resets each trading day), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), Correlation (rolling Pearson of two sub-indicators' returns; needs 2 sub-indicators + window with length >= 2), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown.", "properties": { "amountBasis": { "description": "Disclosed transaction range endpoint. PoliticalPurchaseShare defaults to Midpoint; PoliticalTrades amount metrics default to LowerBound.", "enum": [ "LowerBound", "Midpoint", "UpperBound" ], "type": "string" }, "assetType": { "description": "IsAssetType: e.g. 'Stock', 'Cryptocurrency'.", "type": "string" }, "base": { "description": "Log: logarithm base (>0, ≠1).", "type": "number" }, "chamber": { "description": "PoliticalTrades optional cohort filter. All combines House and Senate.", "enum": [ "All", "House", "Senate" ], "type": "string" }, "compound": { "type": "boolean" }, "condition": { "$ref": "#/$defs/condition", "description": "ConsecutiveTrue / CountTrue: the condition to evaluate over the window." }, "customIndicatorId": { "description": "REQUIRED when type is CustomIndicator. Mongo ObjectId hex string for the owned custom data source (see list_custom_indicators or MCP session instructions). Never omit — display name alone is rejected.", "type": "string" }, "customIndicatorName": { "description": "Optional display label for CustomIndicator. Ignored for lookup; customIndicatorId is authoritative.", "type": "string" }, "direction": { "description": "Option* indicators: long or short.", "enum": [ "long", "short" ], "type": "string" }, "exponent": { "description": "Exponentiation: power exponent.", "type": "number" }, "filer": { "description": "PoliticalTrades member full or last name; empty means all members.", "type": "string" }, "form": { "additionalProperties": true, "description": "Optional auto-generated form metadata. Usually omit; the server fills this.", "type": "object" }, "index": { "description": "IsIndexMember: point-in-time index id ('SP500', 'NASDAQ100', or 'DJIA').", "enum": [ "SP500", "NASDAQ100", "DJIA" ], "type": "string" }, "indicators": { "description": "Sub-indicators for compound types (Plus, CrossAbove, etc.).", "items": { "$ref": "#/$defs/indicator" }, "type": "array" }, "industry": { "description": "IsIndustry: industry tag.", "type": "string" }, "instrument": { "description": "PoliticalTrades instrument class (Equity, Option, All). PoliticalPurchaseShare requires Equity or Option and returns that side's percent of member-wide public purchases.", "enum": [ "Equity", "Option", "All" ], "type": "string" }, "length": { "description": "TrailingSum and similar — window length in days.", "type": "number" }, "lookbackDays": { "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" }, "manager": { "description": "InstitutionalHoldings filing manager: a CIK such as 1067983 matches exactly, any other text matches a filed name containing it, and empty reads every manager. Prefer the CIK — one CIK files under as many as six spellings of its own name, and a name like 'berkshire' spans Buffett's firm, two of its insurance subsidiaries and an unrelated asset manager.", "type": "string" }, "matchAsset": { "additionalProperties": true, "description": "IsAsset / IsNotAsset: the asset to match against.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "maxDte": { "description": "Option* indicators: max days to expiration.", "type": "number" }, "memberId": { "description": "Bioguide member id (e.g. P000197). Required for PoliticalPurchaseShare, whose member-wide public purchase amounts include symbols outside the trading universe; also selects an exact PoliticalTrades member and overrides filer.", "type": "string" }, "message": { "description": "DaysSinceAlert / MinutesSinceAlert: alert message to match.", "type": "string" }, "metric": { "description": "PoliticalTrades: NetAmount, BuyAmount, SellAmount, BuyCount, SellCount, DistinctBuyers, Held. InstitutionalHoldings: HolderCount, TotalShares, TotalValue, BookSharePercent, ConcentrationTop5, NetShareChange, NetHolderChange, NewHolders, ClosedHolders. Fundamental/CompoundAnnualGrowthRate: financial metric (e.g. 'peRatio'). Economic: economic indicator (e.g. 'UNRATE'). Index: index symbol (e.g. 'VIX', 'SPX'). RebalanceDecisionMetric: allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit.", "type": "string" }, "minDte": { "description": "Option* indicators: min days to expiration.", "type": "number" }, "minOrMax": { "description": "OptionDaysToExpiration / OptionDaysHeld: aggregate selector.", "enum": [ "min", "max" ], "type": "string" }, "minutesAfterOpen": { "description": "IndicatorAtMinutesAfterOpen: 0–390.", "maximum": 390, "minimum": 0, "type": "number" }, "name": { "description": "Optional human-readable name. Auto-derived if omitted.", "type": "string" }, "numStandardDeviations": { "description": "BollingerBand: e.g. 2.", "type": "number" }, "optionType": { "description": "Option* indicators: call or put.", "enum": [ "call", "put" ], "type": "string" }, "orderStatus": { "description": "Order-side indicators: filter by status.", "enum": [ "Pending", "Accepted", "Pending User Approval", "Canceled", "Filled", "Partially Filled" ], "type": "string" }, "positionEffect": { "description": "Option* indicators: open or close.", "type": "string" }, "side": { "description": "Order-side indicators: Buy or Sell.", "enum": [ "Buy", "Sell" ], "type": "string" }, "spreadType": { "description": "Option* indicators: vertical, ironCondor, etc.", "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "targetAsset": { "additionalProperties": true, "description": "The asset this indicator measures (most price/option indicators).", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "targetAssets": { "description": "Multi-asset variant (position / order indicators).", "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "transactionStatus": { "description": "DaysSinceTransaction: transaction status.", "enum": [ "Pending", "Canceled", "Completed" ], "type": "string" }, "transactionType": { "description": "DaysSinceTransaction: Deposit or Withdraw.", "enum": [ "Deposit", "Withdraw" ], "type": "string" }, "type": { "enum": [ "DaysSinceAgent", "MinutesSinceAgent", "DaysSinceAlert", "MinutesSinceAlert", "StockReport", "DaysUntilEarnings", "DaysSinceEarnings", "ImpliedVolatility", "IVRank", "IVPercentile", "IVHVRatio", "LastOrderPrice", "Fundamental", "Economic", "CustomIndicator", "Index", "BollingerBand", "RelativeStrengthIndex", "MovingAverageConvergenceDivergence", "AverageDirectionalIndex", "RelativeVolume", "Stochastic", "CommodityChannelIndex", "WilliamsR", "MoneyFlowIndex", "OnBalanceVolume", "AccumulationDistribution", "ChaikinMoneyFlow", "DonchianChannel", "KeltnerChannel", "Supertrend", "IchimokuCloud", "ParabolicSar", "PriceMeanAbsoluteDeviation", "ExponentialMovingAverage", "SimpleMovingAverage", "PriceStandardDeviation", "PriceRateOfChange", "MaxDrawdown", "MaxDrawup", "MinimumPrice", "MaximumPrice", "IndicatorMeanAbsoluteDeviation", "IndicatorExponentialMovingAverage", "IndicatorSimpleMovingAverage", "IndicatorStandardDeviation", "IndicatorRateOfChange", "DaysSinceOrder", "DaysSinceOptionOrder", "DaysSinceStrategyFired", "DaysSinceLastRebalanceOptionOrder", "MinutesSinceOptionOrder", "MinutesSinceOrder", "DaysSinceTransaction", "InitialValue", "BuyingPower", "PositionValue", "PositionPercentChange", "PortfolioValue", "RebalanceDecisionMetric", "Value", "Price", "Plus", "Minus", "Multiply", "Divide", "Negative", "AbsoluteValue", "SquareRoot", "Max", "Min", "Day", "Month", "Date", "Year", "CurrentTimeSeconds", "CurrentTimeMinutes", "CurrentTimeHours", "TrailingSum", "CompoundAnnualGrowthRate", "Log", "Exponentiation", "SumOrderQuantity", "SumOrderAmount", "MinutesAfterOpen", "OpeningPrice", "MinuteBarHigh", "HeikinAshi", "MinuteBarLow", "PreviousClosingPrice", "HighOfDay", "LowOfDay", "MinutesUntilClose", "PriceChangeSinceOpen", "GapSize", "GapPercentage", "TrueRange", "AverageTrueRange", "Volume", "VWAP", "BullishFairValueGap", "BearishFairValueGap", "IndicatorAtMinutesAfterOpen", "IndicatorWindowAgo", "IndicatorAtEntry", "IsIndexMember", "PoliticalTrades", "PoliticalPurchaseShare", "InsiderTrades", "InstitutionalHoldings", "IsIndustry", "IsAssetType", "IsAsset", "IsNotAsset", "CrossAbove", "CrossBelow", "Correlation", "PositionMaxDrawdown", "PositionMaxDrawup", "UnderlyingMaxDrawdown", "ConsecutiveTrue", "CountTrue", "OptionPositionValue", "OptionPositionCount", "OptionPositionPercentChange", "OptionPositionMaxDrawdown", "OptionDaysToExpiration", "OptionDaysHeld", "OptionCollateral", "OptionSpreadCount", "OptionSpreadEntryPrice", "OptionUnrealizedPnL", "OptionRealizedPnL", "OptionRealizedPremium", "OptionGrossExposurePercent" ], "type": "string" }, "underlying": { "description": "Option* indicators: underlying ticker (e.g. 'SPY').", "type": "string" }, "value": { "description": "Required for Value indicators (numeric constant).", "type": "number" }, "window": { "description": "Rolling time window. e.g. {length:14, interval:'Day'} = trailing 14 trading days.", "properties": { "interval": { "enum": [ "Day", "Hour", "Minute" ], "type": "string" }, "length": { "minimum": 1, "type": "number" } }, "required": [ "length", "interval" ], "type": "object" }, "windowDays": { "description": "PoliticalTrades / InsiderTrades trailing calendar days. InstitutionalHoldings reads a disclosed quarter only if its filing became public within this many days, so it defaults to 180 rather than 90: a 13F is quarterly plus a filing lag of up to 45 days, and 91 days can separate two filings.", "maximum": 3650, "minimum": 1, "type": "integer" }, "years": { "description": "CompoundAnnualGrowthRate: years over which to compute CAGR.", "type": "number" } }, "required": [ "type" ], "type": "object" }, "optionStructureTemplate": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "orderExecution": { "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", "oneOf": [ { "additionalProperties": false, "properties": { "type": { "const": "Market", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": false, "properties": { "price": { "oneOf": [ { "additionalProperties": false, "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.", "properties": { "amount": { "minimum": 1e-8, "type": "number" }, "type": { "const": "UnitPrice", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.", "properties": { "amount": { "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).", "oneOf": [ { "minimum": 1e-8, "type": "number" }, { "$ref": "#/$defs/indicator" } ] }, "type": { "const": "MinimumNetCredit", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.", "properties": { "amount": { "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).", "oneOf": [ { "minimum": 1e-8, "type": "number" }, { "$ref": "#/$defs/indicator" } ] }, "type": { "const": "MaximumNetDebit", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.", "properties": { "reference": { "const": "Current", "type": "string" }, "type": { "const": "QuoteRelative", "type": "string" } }, "required": [ "type", "reference" ], "type": "object" } ] }, "type": { "const": "Limit", "type": "string" }, "workingTime": { "oneOf": [ { "additionalProperties": false, "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.", "properties": { "type": { "const": "Day", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": false, "properties": { "minutes": { "minimum": 1, "type": "number" }, "type": { "const": "Minutes", "type": "string" } }, "required": [ "type", "minutes" ], "type": "object" } ] } }, "required": [ "type", "price" ], "type": "object" } ], "type": "object" }, "rebalanceOptionSleeve": { "additionalProperties": true, "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).", "properties": { "limit": { "minimum": 1, "type": "number" }, "name": { "type": "string" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). 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" }, "strategy": { "additionalProperties": true, "description": "A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", "properties": { "action": { "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).", "oneOf": [ { "additionalProperties": true, "description": "Buy or Sell a stock/crypto position.", "properties": { "amount": { "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "percent of portfolio", "percent of buying power", "percent of current positions", "dollars", "number of assets" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "targetAsset": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": { "enum": [ "Buy", "Sell" ], "type": "string" } }, "required": [ "type", "targetAsset", "amount" ], "type": "object" }, { "additionalProperties": true, "description": "Send an alert message (no order).", "properties": { "message": { "type": "string" }, "type": { "const": "Alert", "type": "string" } }, "required": [ "type", "message" ], "type": "object" }, { "additionalProperties": true, "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is the deploymentPercent indicator (0–100; use Value for a constant). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.", "properties": { "allocationPolicy": { "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", "oneOf": [ { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "expectedReturnShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "riskAversion": { "maximum": 1000, "minimum": 0, "type": "number" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MeanVariance", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "riskAversion", "expectedReturnShrinkage", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "RiskParity", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MaximumDiversification", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" } ] }, "canSell": { "$ref": "#/$defs/condition", "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out." }, "deploymentPercent": { "$ref": "#/$defs/indicator", "description": "Indicator returning percent of portfolio NAV to deploy, 0–100 (remainder cash). Use Value for a constant, or PoliticalPurchaseShare with memberId and instrument Equity. Do not use totalBudget here." }, "exposurePolicy": { "additionalProperties": false, "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "targetAnnualizedVolatilityPercent": { "maximum": 1000, "minimum": 0, "type": "number" }, "type": { "const": "VolatilityTarget", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "targetAnnualizedVolatilityPercent", "estimatedTransactionCostBps" ], "type": "object" }, "limit": { "minimum": 1, "type": "number" }, "perNameAllocation": { "additionalProperties": true, "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.", "properties": { "amount": { "exclusiveMinimum": 0, "type": "number" }, "type": { "enum": [ "percent of portfolio", "dollars" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "type": { "const": "DynamicRebalance", "type": "string" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "type", "universe", "pipeline", "weightIndicator" ], "type": "object" }, { "additionalProperties": true, "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).", "properties": { "continueExisting": { "type": "boolean" }, "cooldownMinutes": { "minimum": 0, "type": "number" }, "executionModel": { "type": "string" }, "includeMarketData": { "type": "boolean" }, "initialMessage": { "type": "string" }, "maxIterations": { "minimum": 1, "type": "number" }, "planningModel": { "type": "string" }, "skipPlanning": { "type": "boolean" }, "type": { "const": "LaunchAgent", "type": "string" } }, "required": [ "type", "planningModel", "executionModel", "initialMessage", "maxIterations", "includeMarketData", "continueExisting", "skipPlanning" ], "type": "object" }, { "additionalProperties": true, "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.", "properties": { "against": { "additionalProperties": true, "description": "Optional parent-position selector (e.g. for covered calls).", "type": "object" }, "allocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "builder": { "additionalProperties": true, "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.", "properties": { "dynamicUnderlying": { "additionalProperties": true, "properties": { "limit": { "minimum": 1, "type": "number" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" } }, "required": [ "universe" ], "type": "object" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "underlyingSymbol": { "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "type": { "const": "OpenOption", "type": "string" } }, "required": [ "type", "builder" ], "type": "object" }, { "additionalProperties": true, "description": "RebalanceOption: filter/rank a universe, then allocate option premium under totalBudget. sizingMode fixedPerName (default) uses weightIndicator only to rank names and perNameAllocation to size each. sizingMode proportionalToWeight splits totalBudget among selected names in proportion to positive weightIndicator values; perNameAllocation is ignored, and sleeves/allocationPolicy/exposurePolicy cannot be combined with it. allocationPolicy may jointly size selected names in fixedPerName mode; exposurePolicy may scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder for shared cadence. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies.", "properties": { "allocationPolicy": { "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", "oneOf": [ { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "expectedReturnShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "riskAversion": { "maximum": 1000, "minimum": 0, "type": "number" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MeanVariance", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "riskAversion", "expectedReturnShrinkage", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "RiskParity", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MaximumDiversification", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" } ] }, "exposurePolicy": { "additionalProperties": false, "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "targetAnnualizedVolatilityPercent": { "maximum": 1000, "minimum": 0, "type": "number" }, "type": { "const": "VolatilityTarget", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "targetAnnualizedVolatilityPercent", "estimatedTransactionCostBps" ], "type": "object" }, "limit": { "minimum": 1, "type": "number" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "positionScope": { "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.", "enum": [ "portfolio", "strategy" ], "type": "string" }, "sizingMode": { "enum": [ "fixedPerName", "proportionalToWeight" ], "type": "string" }, "sleeves": { "items": { "additionalProperties": true, "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).", "properties": { "limit": { "minimum": 1, "type": "number" }, "name": { "type": "string" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "structureTemplates": { "items": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "minItems": 1, "type": "array" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "name" ], "type": "object" }, "type": "array" }, "structureTemplates": { "items": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "minItems": 1, "type": "array" }, "totalBudget": { "additionalProperties": true, "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", "properties": { "amount": { "$ref": "#/$defs/indicator", "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." }, "type": { "enum": [ "dollars", "percent of portfolio" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "type": { "const": "RebalanceOption", "type": "string" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "type", "universe", "pipeline", "weightIndicator", "structureTemplates" ], "type": "object" }, { "additionalProperties": true, "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.", "properties": { "closeScope": { "enum": [ "spread", "leg" ], "type": "string" }, "direction": { "enum": [ "long", "short" ], "type": "string" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "quantity": { "additionalProperties": true, "description": "How many contracts to close. Defaults to all matching when omitted.", "type": "object" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "triggers": { "items": { "description": "Close trigger for an options exit. Triggers within an array are OR-gated.", "oneOf": [ { "additionalProperties": true, "properties": { "maxPnlPercent": { "type": "number" }, "minPnlPercent": { "type": "number" }, "type": { "const": "pnl", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxDte": { "type": "number" }, "minDte": { "type": "number" }, "type": { "const": "dte", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxDaysHeld": { "type": "number" }, "minDaysHeld": { "type": "number" }, "type": { "const": "daysHeld", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxIv": { "type": "number" }, "maxSpreadDelta": { "type": "number" }, "maxSpreadTheta": { "type": "number" }, "minIv": { "type": "number" }, "minSpreadDelta": { "type": "number" }, "minSpreadTheta": { "type": "number" }, "type": { "const": "greeks", "type": "string" } }, "required": [ "type" ], "type": "object" } ], "type": "object" }, "type": "array" }, "type": { "const": "CloseOption", "type": "string" }, "underlyings": { "items": { "type": "string" }, "type": "array" } }, "required": [ "type" ], "type": "object" } ], "type": "object" }, "active": { "description": "Whether the strategy is active (default true).", "type": "boolean" }, "condition": { "$ref": "#/$defs/condition" }, "name": { "description": "Human-readable strategy name.", "type": "string" }, "orderExecution": { "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", "oneOf": [ { "additionalProperties": false, "properties": { "type": { "const": "Market", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": false, "properties": { "price": { "oneOf": [ { "additionalProperties": false, "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.", "properties": { "amount": { "minimum": 1e-8, "type": "number" }, "type": { "const": "UnitPrice", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.", "properties": { "amount": { "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).", "oneOf": [ { "minimum": 1e-8, "type": "number" }, { "$ref": "#/$defs/indicator" } ] }, "type": { "const": "MinimumNetCredit", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.", "properties": { "amount": { "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).", "oneOf": [ { "minimum": 1e-8, "type": "number" }, { "$ref": "#/$defs/indicator" } ] }, "type": { "const": "MaximumNetDebit", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.", "properties": { "reference": { "const": "Current", "type": "string" }, "type": { "const": "QuoteRelative", "type": "string" } }, "required": [ "type", "reference" ], "type": "object" } ] }, "type": { "const": "Limit", "type": "string" }, "workingTime": { "oneOf": [ { "additionalProperties": false, "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.", "properties": { "type": { "const": "Day", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": false, "properties": { "minutes": { "minimum": 1, "type": "number" }, "type": { "const": "Minutes", "type": "string" } }, "required": [ "type", "minutes" ], "type": "object" } ] } }, "required": [ "type", "price" ], "type": "object" } ], "type": "object" } }, "required": [ "name", "condition", "action" ], "type": "object" }, "window": { "description": "Rolling time window. e.g. {length:14, interval:'Day'} = trailing 14 trading days.", "properties": { "interval": { "enum": [ "Day", "Hour", "Minute" ], "type": "string" }, "length": { "minimum": 1, "type": "number" } }, "required": [ "length", "interval" ], "type": "object" } }, "properties": { "operations": { "description": "Array of edit operations. Each operation needs \"portfolioId\" (live, paper, or chat — server resolves automatically). Supported types include \"rename\" (requires non-empty \"name\"), \"delete\" (permanently remove a chat/paper/live portfolio; archives deployed books; pass confirmLive:true only after explicit user confirmation when deleting an active live portfolio). DEPLOY SAFETY: deploying a chat portfolio ID creates a NEW PAPER-TRADING portfolio (simulated money, no broker order ever placed). It cannot place real-money trades. A LIVE/real-brokerage deployment only happens when the target is an EXISTING real-brokerage portfolio (re-activating it, or addStrategies/replaceStrategies on a portfolio already connected to a live broker). You cannot create a live brokerage account from a chat portfolio through this tool. Fetch the portfolio first and use strategy IDs from the returned \"strategies\" array for removals. To add/replace strategies, pass FINISHED strategy objects ({name, condition, action, orderExecution?} — same shape as create_portfolio.strategies) via \"strategyObjects\" (or \"strategyObject\" for replaceStrategy). These are ingested deterministically with zero LLM cost; prefer them. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. RebalanceOption `action.positionScope`: `\"portfolio\"` (default for single-book portfolios — rotation-close and open-skip span all option spreads in the portfolio) or `\"strategy\"` (only spreads this strategy opened; use when multiple RebalanceOption strategies share one portfolio). Set on `create_portfolio` strategies[].action or on `update_portfolio` replaceStrategy/replaceStrategies `strategyObject.action`. Examples: [{\"type\":\"deploy\",\"portfolioId\":\"id\"}, {\"type\":\"undeploy\",\"portfolioId\":\"id\"}, {\"type\":\"delete\",\"portfolioId\":\"id\"}, {\"type\":\"addStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...},\"orderExecution\":{\"type\":\"Limit\",\"price\":{\"type\":\"UnitPrice\",\"amount\":150},\"workingTime\":{\"type\":\"Day\"}}}]}, {\"type\":\"removeStrategies\",\"portfolioId\":\"id\",\"strategyIds\":[\"strategyId\"]}, {\"type\":\"replaceStrategy\",\"portfolioId\":\"id\",\"targetStrategyId\":\"strategyId\",\"strategyObject\":{\"name\":\"...\",\"condition\":{...},\"action\":{\"type\":\"RebalanceOption\",\"positionScope\":\"portfolio\",...}}}, {\"type\":\"replaceStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...}}]}, {\"type\":\"setDeploymentFrequency\",\"portfolioId\":\"id\",\"deploymentFrequency\":\"Constant\"}, {\"type\":\"rename\",\"portfolioId\":\"id\",\"name\":\"New Portfolio Name\"}, {\"type\":\"setStockEligibility\",\"portfolioId\":\"id\",\"stockEligibility\":{\"shareClassBehavior\":\"ALL_CLASSES\"}}]. \"setStockEligibility\" changes only stock eligibility (market-cap bounds, industry filter, missingMarketCapBehavior, shareClassBehavior); automated trading can never be changed through MCP.", "items": { "additionalProperties": false, "properties": { "confirmLive": { "type": "boolean" }, "deploymentFrequency": { "enum": [ "Constant", "OpenClose" ], "type": "string" }, "name": { "type": "string" }, "portfolioId": { "type": "string" }, "stockEligibility": { "additionalProperties": false, "description": "setStockEligibility only: the stock-eligibility fields to change on the portfolio's policy. Omitted fields keep their current values. Automated trading can never be changed through MCP.", "properties": { "industryFilter": { "additionalProperties": false, "properties": { "industries": { "items": { "type": "string" }, "type": "array" }, "match": { "enum": [ "ANY", "ALL" ], "type": "string" }, "mode": { "enum": [ "ALL", "INCLUDE_ONLY" ], "type": "string" } }, "required": [ "mode", "match", "industries" ], "type": "object" }, "maximumMarketCapUsd": { "description": "Largest market cap allowed, or null for no ceiling (default).", "oneOf": [ { "minimum": 0, "type": "integer" }, { "type": "null" } ] }, "minimumMarketCapUsd": { "description": "Smallest market cap a dynamic-universe candidate may have. Default 1000000000 ($1B); lower it for a small-cap strategy.", "minimum": 0, "type": "integer" }, "missingMarketCapBehavior": { "description": "EXCLUDE (default) drops a dynamic-universe candidate with no known market cap (most ETFs, some filers). INCLUDE keeps it; the cap bounds then apply only to names whose cap is known. Omit to keep the portfolio's current setting.", "enum": [ "EXCLUDE", "INCLUDE" ], "type": "string" }, "shareClassBehavior": { "description": "ONE_PER_COMPANY (default) keeps one share class per company in a dynamic-universe selection, so a top-5 holds five companies (GOOGL over GOOG on a tie). ALL_CLASSES lets every class through, for a book that trades share classes against each other (a GOOG/GOOGL pair). Omit to keep the portfolio's current setting.", "enum": [ "ONE_PER_COMPANY", "ALL_CLASSES" ], "type": "string" } }, "type": "object" }, "strategyIds": { "items": { "type": "string" }, "type": "array" }, "strategyObject": { "additionalProperties": true, "description": "A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", "properties": { "action": { "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).", "oneOf": [ { "additionalProperties": true, "description": "Buy or Sell a stock/crypto position.", "properties": { "amount": { "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "percent of portfolio", "percent of buying power", "percent of current positions", "dollars", "number of assets" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "targetAsset": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": { "enum": [ "Buy", "Sell" ], "type": "string" } }, "required": [ "type", "targetAsset", "amount" ], "type": "object" }, { "additionalProperties": true, "description": "Send an alert message (no order).", "properties": { "message": { "type": "string" }, "type": { "const": "Alert", "type": "string" } }, "required": [ "type", "message" ], "type": "object" }, { "additionalProperties": true, "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is the deploymentPercent indicator (0–100; use Value for a constant). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.", "properties": { "allocationPolicy": { "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", "oneOf": [ { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "expectedReturnShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "riskAversion": { "maximum": 1000, "minimum": 0, "type": "number" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MeanVariance", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "riskAversion", "expectedReturnShrinkage", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "RiskParity", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MaximumDiversification", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" } ] }, "canSell": { "$ref": "#/$defs/condition", "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out." }, "deploymentPercent": { "$ref": "#/$defs/indicator", "description": "Indicator returning percent of portfolio NAV to deploy, 0–100 (remainder cash). Use Value for a constant, or PoliticalPurchaseShare with memberId and instrument Equity. Do not use totalBudget here." }, "exposurePolicy": { "additionalProperties": false, "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "targetAnnualizedVolatilityPercent": { "maximum": 1000, "minimum": 0, "type": "number" }, "type": { "const": "VolatilityTarget", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "targetAnnualizedVolatilityPercent", "estimatedTransactionCostBps" ], "type": "object" }, "limit": { "minimum": 1, "type": "number" }, "perNameAllocation": { "additionalProperties": true, "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.", "properties": { "amount": { "exclusiveMinimum": 0, "type": "number" }, "type": { "enum": [ "percent of portfolio", "dollars" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "type": { "const": "DynamicRebalance", "type": "string" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "type", "universe", "pipeline", "weightIndicator" ], "type": "object" }, { "additionalProperties": true, "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).", "properties": { "continueExisting": { "type": "boolean" }, "cooldownMinutes": { "minimum": 0, "type": "number" }, "executionModel": { "type": "string" }, "includeMarketData": { "type": "boolean" }, "initialMessage": { "type": "string" }, "maxIterations": { "minimum": 1, "type": "number" }, "planningModel": { "type": "string" }, "skipPlanning": { "type": "boolean" }, "type": { "const": "LaunchAgent", "type": "string" } }, "required": [ "type", "planningModel", "executionModel", "initialMessage", "maxIterations", "includeMarketData", "continueExisting", "skipPlanning" ], "type": "object" }, { "additionalProperties": true, "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.", "properties": { "against": { "additionalProperties": true, "description": "Optional parent-position selector (e.g. for covered calls).", "type": "object" }, "allocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "builder": { "additionalProperties": true, "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.", "properties": { "dynamicUnderlying": { "additionalProperties": true, "properties": { "limit": { "minimum": 1, "type": "number" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" } }, "required": [ "universe" ], "type": "object" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "underlyingSymbol": { "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "type": { "const": "OpenOption", "type": "string" } }, "required": [ "type", "builder" ], "type": "object" }, { "additionalProperties": true, "description": "RebalanceOption: filter/rank a universe, then allocate option premium under totalBudget. sizingMode fixedPerName (default) uses weightIndicator only to rank names and perNameAllocation to size each. sizingMode proportionalToWeight splits totalBudget among selected names in proportion to positive weightIndicator values; perNameAllocation is ignored, and sleeves/allocationPolicy/exposurePolicy cannot be combined with it. allocationPolicy may jointly size selected names in fixedPerName mode; exposurePolicy may scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder for shared cadence. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies.", "properties": { "allocationPolicy": { "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", "oneOf": [ { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "expectedReturnShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "riskAversion": { "maximum": 1000, "minimum": 0, "type": "number" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MeanVariance", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "riskAversion", "expectedReturnShrinkage", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "RiskParity", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MaximumDiversification", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" } ] }, "exposurePolicy": { "additionalProperties": false, "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "targetAnnualizedVolatilityPercent": { "maximum": 1000, "minimum": 0, "type": "number" }, "type": { "const": "VolatilityTarget", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "targetAnnualizedVolatilityPercent", "estimatedTransactionCostBps" ], "type": "object" }, "limit": { "minimum": 1, "type": "number" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "positionScope": { "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.", "enum": [ "portfolio", "strategy" ], "type": "string" }, "sizingMode": { "enum": [ "fixedPerName", "proportionalToWeight" ], "type": "string" }, "sleeves": { "items": { "additionalProperties": true, "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).", "properties": { "limit": { "minimum": 1, "type": "number" }, "name": { "type": "string" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "structureTemplates": { "items": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "minItems": 1, "type": "array" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "name" ], "type": "object" }, "type": "array" }, "structureTemplates": { "items": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "minItems": 1, "type": "array" }, "totalBudget": { "additionalProperties": true, "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", "properties": { "amount": { "$ref": "#/$defs/indicator", "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." }, "type": { "enum": [ "dollars", "percent of portfolio" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "type": { "const": "RebalanceOption", "type": "string" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "type", "universe", "pipeline", "weightIndicator", "structureTemplates" ], "type": "object" }, { "additionalProperties": true, "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.", "properties": { "closeScope": { "enum": [ "spread", "leg" ], "type": "string" }, "direction": { "enum": [ "long", "short" ], "type": "string" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "quantity": { "additionalProperties": true, "description": "How many contracts to close. Defaults to all matching when omitted.", "type": "object" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "triggers": { "items": { "description": "Close trigger for an options exit. Triggers within an array are OR-gated.", "oneOf": [ { "additionalProperties": true, "properties": { "maxPnlPercent": { "type": "number" }, "minPnlPercent": { "type": "number" }, "type": { "const": "pnl", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxDte": { "type": "number" }, "minDte": { "type": "number" }, "type": { "const": "dte", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxDaysHeld": { "type": "number" }, "minDaysHeld": { "type": "number" }, "type": { "const": "daysHeld", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxIv": { "type": "number" }, "maxSpreadDelta": { "type": "number" }, "maxSpreadTheta": { "type": "number" }, "minIv": { "type": "number" }, "minSpreadDelta": { "type": "number" }, "minSpreadTheta": { "type": "number" }, "type": { "const": "greeks", "type": "string" } }, "required": [ "type" ], "type": "object" } ], "type": "object" }, "type": "array" }, "type": { "const": "CloseOption", "type": "string" }, "underlyings": { "items": { "type": "string" }, "type": "array" } }, "required": [ "type" ], "type": "object" } ], "type": "object" }, "active": { "description": "Whether the strategy is active (default true).", "type": "boolean" }, "condition": { "$ref": "#/$defs/condition" }, "name": { "description": "Human-readable strategy name.", "type": "string" }, "orderExecution": { "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", "oneOf": [ { "additionalProperties": false, "properties": { "type": { "const": "Market", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": false, "properties": { "price": { "oneOf": [ { "additionalProperties": false, "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.", "properties": { "amount": { "minimum": 1e-8, "type": "number" }, "type": { "const": "UnitPrice", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.", "properties": { "amount": { "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).", "oneOf": [ { "minimum": 1e-8, "type": "number" }, { "$ref": "#/$defs/indicator" } ] }, "type": { "const": "MinimumNetCredit", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.", "properties": { "amount": { "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).", "oneOf": [ { "minimum": 1e-8, "type": "number" }, { "$ref": "#/$defs/indicator" } ] }, "type": { "const": "MaximumNetDebit", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.", "properties": { "reference": { "const": "Current", "type": "string" }, "type": { "const": "QuoteRelative", "type": "string" } }, "required": [ "type", "reference" ], "type": "object" } ] }, "type": { "const": "Limit", "type": "string" }, "workingTime": { "oneOf": [ { "additionalProperties": false, "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.", "properties": { "type": { "const": "Day", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": false, "properties": { "minutes": { "minimum": 1, "type": "number" }, "type": { "const": "Minutes", "type": "string" } }, "required": [ "type", "minutes" ], "type": "object" } ] } }, "required": [ "type", "price" ], "type": "object" } ], "type": "object" } }, "required": [ "name", "condition", "action" ], "type": "object" }, "strategyObjects": { "items": { "additionalProperties": true, "description": "A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", "properties": { "action": { "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).", "oneOf": [ { "additionalProperties": true, "description": "Buy or Sell a stock/crypto position.", "properties": { "amount": { "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "percent of portfolio", "percent of buying power", "percent of current positions", "dollars", "number of assets" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "targetAsset": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": { "enum": [ "Buy", "Sell" ], "type": "string" } }, "required": [ "type", "targetAsset", "amount" ], "type": "object" }, { "additionalProperties": true, "description": "Send an alert message (no order).", "properties": { "message": { "type": "string" }, "type": { "const": "Alert", "type": "string" } }, "required": [ "type", "message" ], "type": "object" }, { "additionalProperties": true, "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is the deploymentPercent indicator (0–100; use Value for a constant). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.", "properties": { "allocationPolicy": { "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", "oneOf": [ { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "expectedReturnShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "riskAversion": { "maximum": 1000, "minimum": 0, "type": "number" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MeanVariance", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "riskAversion", "expectedReturnShrinkage", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "RiskParity", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MaximumDiversification", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" } ] }, "canSell": { "$ref": "#/$defs/condition", "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out." }, "deploymentPercent": { "$ref": "#/$defs/indicator", "description": "Indicator returning percent of portfolio NAV to deploy, 0–100 (remainder cash). Use Value for a constant, or PoliticalPurchaseShare with memberId and instrument Equity. Do not use totalBudget here." }, "exposurePolicy": { "additionalProperties": false, "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "targetAnnualizedVolatilityPercent": { "maximum": 1000, "minimum": 0, "type": "number" }, "type": { "const": "VolatilityTarget", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "targetAnnualizedVolatilityPercent", "estimatedTransactionCostBps" ], "type": "object" }, "limit": { "minimum": 1, "type": "number" }, "perNameAllocation": { "additionalProperties": true, "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.", "properties": { "amount": { "exclusiveMinimum": 0, "type": "number" }, "type": { "enum": [ "percent of portfolio", "dollars" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "type": { "const": "DynamicRebalance", "type": "string" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "type", "universe", "pipeline", "weightIndicator" ], "type": "object" }, { "additionalProperties": true, "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).", "properties": { "continueExisting": { "type": "boolean" }, "cooldownMinutes": { "minimum": 0, "type": "number" }, "executionModel": { "type": "string" }, "includeMarketData": { "type": "boolean" }, "initialMessage": { "type": "string" }, "maxIterations": { "minimum": 1, "type": "number" }, "planningModel": { "type": "string" }, "skipPlanning": { "type": "boolean" }, "type": { "const": "LaunchAgent", "type": "string" } }, "required": [ "type", "planningModel", "executionModel", "initialMessage", "maxIterations", "includeMarketData", "continueExisting", "skipPlanning" ], "type": "object" }, { "additionalProperties": true, "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.", "properties": { "against": { "additionalProperties": true, "description": "Optional parent-position selector (e.g. for covered calls).", "type": "object" }, "allocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "builder": { "additionalProperties": true, "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.", "properties": { "dynamicUnderlying": { "additionalProperties": true, "properties": { "limit": { "minimum": 1, "type": "number" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" } }, "required": [ "universe" ], "type": "object" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "underlyingSymbol": { "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "type": { "const": "OpenOption", "type": "string" } }, "required": [ "type", "builder" ], "type": "object" }, { "additionalProperties": true, "description": "RebalanceOption: filter/rank a universe, then allocate option premium under totalBudget. sizingMode fixedPerName (default) uses weightIndicator only to rank names and perNameAllocation to size each. sizingMode proportionalToWeight splits totalBudget among selected names in proportion to positive weightIndicator values; perNameAllocation is ignored, and sleeves/allocationPolicy/exposurePolicy cannot be combined with it. allocationPolicy may jointly size selected names in fixedPerName mode; exposurePolicy may scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder for shared cadence. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies.", "properties": { "allocationPolicy": { "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.", "oneOf": [ { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "expectedReturnShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "riskAversion": { "maximum": 1000, "minimum": 0, "type": "number" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MeanVariance", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "riskAversion", "expectedReturnShrinkage", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "RiskParity", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" }, { "additionalProperties": false, "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "turnoverPenalty": { "maximum": 10000, "minimum": 0, "type": "number" }, "type": { "const": "MaximumDiversification", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "turnoverPenalty", "estimatedTransactionCostBps" ], "type": "object" } ] }, "exposurePolicy": { "additionalProperties": false, "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.", "properties": { "covarianceShrinkage": { "maximum": 1, "minimum": 0, "type": "number" }, "estimatedTransactionCostBps": { "maximum": 10000, "minimum": 0, "type": "number" }, "lookbackPeriods": { "maximum": 5000, "minimum": 2, "type": "integer" }, "minimumObservations": { "maximum": 5000, "minimum": 2, "type": "integer" }, "targetAnnualizedVolatilityPercent": { "maximum": 1000, "minimum": 0, "type": "number" }, "type": { "const": "VolatilityTarget", "type": "string" } }, "required": [ "type", "lookbackPeriods", "minimumObservations", "covarianceShrinkage", "targetAnnualizedVolatilityPercent", "estimatedTransactionCostBps" ], "type": "object" }, "limit": { "minimum": 1, "type": "number" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "positionScope": { "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.", "enum": [ "portfolio", "strategy" ], "type": "string" }, "sizingMode": { "enum": [ "fixedPerName", "proportionalToWeight" ], "type": "string" }, "sleeves": { "items": { "additionalProperties": true, "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).", "properties": { "limit": { "minimum": 1, "type": "number" }, "name": { "type": "string" }, "perNameAllocation": { "additionalProperties": true, "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.", "properties": { "amount": { "type": "number" }, "type": { "enum": [ "dollars", "percent of portfolio", "percent of buying power", "contracts", "percent of realized premium" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "pipeline": { "items": { "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.", "oneOf": [ { "additionalProperties": true, "properties": { "condition": { "$ref": "#/$defs/condition" }, "type": { "const": "Filter", "type": "string" } }, "required": [ "type", "condition" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "limit": { "minimum": 1, "type": "number" }, "metric": { "$ref": "#/$defs/indicator" }, "type": { "const": "SelectTop", "type": "string" } }, "required": [ "type", "metric", "limit", "direction" ], "type": "object" }, { "additionalProperties": true, "properties": { "direction": { "enum": [ "Highest", "Lowest" ], "type": "string" }, "metric": { "$ref": "#/$defs/indicator" }, "percentile": { "maximum": 100, "minimum": 0, "type": "number" }, "type": { "const": "SelectPercentile", "type": "string" } }, "required": [ "type", "metric", "percentile", "direction" ], "type": "object" } ], "type": "object" }, "type": "array" }, "structureTemplates": { "items": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "minItems": 1, "type": "array" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "name" ], "type": "object" }, "type": "array" }, "structureTemplates": { "items": { "additionalProperties": true, "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.", "properties": { "eligibility": { "$ref": "#/$defs/condition" }, "legs": { "items": { "additionalProperties": true, "description": "Single leg of an option builder.", "properties": { "direction": { "enum": [ "long", "short" ], "type": "string" }, "expirationRange": { "additionalProperties": true, "type": "object" }, "expirationSelector": { "properties": { "maxDaysToExpiration": { "minimum": 0, "type": "number" }, "minDaysToExpiration": { "minimum": 0, "type": "number" }, "preference": { "enum": [ "nearest", "middle", "furthest" ], "type": "string" } }, "required": [ "minDaysToExpiration", "maxDaysToExpiration", "preference" ], "type": "object" }, "fallbackStrikeSelector": { "additionalProperties": false, "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.", "properties": { "distance": { "type": "number" }, "distanceType": { "enum": [ "percent", "dollars" ], "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" }, "greekFilter": { "additionalProperties": true, "description": "Optional min/max constraints on Greeks during resolution.", "type": "object" }, "liquidityFilter": { "additionalProperties": false, "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.", "properties": { "maxSpreadAbsolute": { "type": "number" }, "maxSpreadPct": { "type": "number" }, "minBid": { "type": "number" } }, "type": "object" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "ratio": { "type": "number" }, "strikeRange": { "additionalProperties": true, "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.", "type": "object" }, "strikeSelector": { "properties": { "distance": { "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).", "type": "number" }, "distanceType": { "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.", "type": "string" } }, "required": [ "distanceType", "distance" ], "type": "object" } }, "required": [ "optionType", "direction", "expirationSelector", "strikeSelector" ], "type": "object" }, "minItems": 1, "type": "array" }, "name": { "type": "string" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "widthConstraint": { "additionalProperties": false, "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.", "properties": { "minWidthDollars": { "exclusiveMinimum": 0, "type": "number" }, "minWidthPercent": { "exclusiveMinimum": 0, "type": "number" } }, "type": "object" } }, "required": [ "legs" ], "type": "object" }, "minItems": 1, "type": "array" }, "totalBudget": { "additionalProperties": true, "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: percentage of NAV (0–100); dollars: fixed dollars. The amount is an indicator evaluated when the action fires.", "properties": { "amount": { "$ref": "#/$defs/indicator", "description": "Budget indicator evaluated when the action fires. Use Value for a constant or PoliticalPurchaseShare for a member's equity/option purchase mix." }, "type": { "enum": [ "dollars", "percent of portfolio" ], "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, "type": { "const": "RebalanceOption", "type": "string" }, "universe": { "additionalProperties": true, "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].", "properties": { "assets": { "items": { "additionalProperties": true, "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.", "properties": { "name": { "type": "string" }, "symbol": { "type": "string" }, "type": { "enum": [ "Stock", "Cryptocurrency", "Option", "Other" ], "type": "string" } }, "required": [ "type", "symbol" ], "type": "object" }, "type": "array" }, "source": { "enum": [ "ALL_US_STOCKS", "SP500", "NASDAQ100", "DJIA", "CRYPTO", "SPECIFIC_ASSETS" ], "type": "string" } }, "required": [ "source" ], "type": "object" }, "weightIndicator": { "$ref": "#/$defs/indicator" } }, "required": [ "type", "universe", "pipeline", "weightIndicator", "structureTemplates" ], "type": "object" }, { "additionalProperties": true, "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.", "properties": { "closeScope": { "enum": [ "spread", "leg" ], "type": "string" }, "direction": { "enum": [ "long", "short" ], "type": "string" }, "optionType": { "enum": [ "call", "put" ], "type": "string" }, "quantity": { "additionalProperties": true, "description": "How many contracts to close. Defaults to all matching when omitted.", "type": "object" }, "spreadType": { "enum": [ "vertical", "calendar", "diagonal", "ironCondor", "straddle", "strangle", "custom" ], "type": "string" }, "triggers": { "items": { "description": "Close trigger for an options exit. Triggers within an array are OR-gated.", "oneOf": [ { "additionalProperties": true, "properties": { "maxPnlPercent": { "type": "number" }, "minPnlPercent": { "type": "number" }, "type": { "const": "pnl", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxDte": { "type": "number" }, "minDte": { "type": "number" }, "type": { "const": "dte", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxDaysHeld": { "type": "number" }, "minDaysHeld": { "type": "number" }, "type": { "const": "daysHeld", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": true, "properties": { "maxIv": { "type": "number" }, "maxSpreadDelta": { "type": "number" }, "maxSpreadTheta": { "type": "number" }, "minIv": { "type": "number" }, "minSpreadDelta": { "type": "number" }, "minSpreadTheta": { "type": "number" }, "type": { "const": "greeks", "type": "string" } }, "required": [ "type" ], "type": "object" } ], "type": "object" }, "type": "array" }, "type": { "const": "CloseOption", "type": "string" }, "underlyings": { "items": { "type": "string" }, "type": "array" } }, "required": [ "type" ], "type": "object" } ], "type": "object" }, "active": { "description": "Whether the strategy is active (default true).", "type": "boolean" }, "condition": { "$ref": "#/$defs/condition" }, "name": { "description": "Human-readable strategy name.", "type": "string" }, "orderExecution": { "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.", "oneOf": [ { "additionalProperties": false, "properties": { "type": { "const": "Market", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": false, "properties": { "price": { "oneOf": [ { "additionalProperties": false, "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.", "properties": { "amount": { "minimum": 1e-8, "type": "number" }, "type": { "const": "UnitPrice", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.", "properties": { "amount": { "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).", "oneOf": [ { "minimum": 1e-8, "type": "number" }, { "$ref": "#/$defs/indicator" } ] }, "type": { "const": "MinimumNetCredit", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.", "properties": { "amount": { "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).", "oneOf": [ { "minimum": 1e-8, "type": "number" }, { "$ref": "#/$defs/indicator" } ] }, "type": { "const": "MaximumNetDebit", "type": "string" } }, "required": [ "type", "amount" ], "type": "object" }, { "additionalProperties": false, "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.", "properties": { "reference": { "const": "Current", "type": "string" }, "type": { "const": "QuoteRelative", "type": "string" } }, "required": [ "type", "reference" ], "type": "object" } ] }, "type": { "const": "Limit", "type": "string" }, "workingTime": { "oneOf": [ { "additionalProperties": false, "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.", "properties": { "type": { "const": "Day", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "additionalProperties": false, "properties": { "minutes": { "minimum": 1, "type": "number" }, "type": { "const": "Minutes", "type": "string" } }, "required": [ "type", "minutes" ], "type": "object" } ] } }, "required": [ "type", "price" ], "type": "object" } ], "type": "object" } }, "required": [ "name", "condition", "action" ], "type": "object" }, "type": "array" }, "targetStrategyId": { "type": "string" }, "targetStrategyName": { "type": "string" }, "type": { "enum": [ "deploy", "undeploy", "addStrategies", "removeStrategies", "replaceStrategy", "replaceStrategies", "setDeploymentFrequency", "rename", "delete", "setStockEligibility" ], "type": "string" } }, "required": [ "type", "portfolioId" ], "type": "object" }, "maxItems": 20, "minItems": 1, "type": "array" } }, "required": [ "operations" ], "type": "object" }, "name": "update_portfolio", "outputSchema": null } ] }
Verify it yourselfcurl -s https://api.teppi.xyz/v1/evidence/sha256:fb533b9a8dd97eb1eda28dbe9ac717b30e741b93beec558b90c9a4c534f57d0e | sha256sum