Skip to main content
Glama

NexusTrade Financial MCP

Server Details

Quant research, backtesting, marketplace subscriptions, editable forks, copy trading, and execution.

Glama couldn't complete the latest health check. If this server requires authentication, missing or expired test credentials may be the cause. A test profile lets Glama authenticate for health checks and discover tools; it is separate from your personal connections.

If you are the author, claim ownership, then add or update a test profile under Admin → Test Profile.

Status
Unhealthy
Uptime
4.0% over 38 days
OAuth
Works in Glama
Last Tested
Transport
Streamable HTTP · MCP 2025-11-25
URL
Repository
austin-starks/nexustrade-ts
GitHub Stars
6
Server Listing
NexusTrade Financial MCP

TDQS

A4/5.0

Scored across 24 tools

Disambiguation5/5

The 24 tools split cleanly into portfolio management (create/build/variant/clone/fork/get/fetch/update/search) and Aurora agent management (create/get/list/archive/unarchive/star/stop/approve/reject/send_message/trajectory) domains. Descriptions are exceptionally detailed and explicitly cross-reference siblings to prevent confusion — e.g., build_portfolio vs create_portfolio, get_portfolio vs fetch_portfolios, query_backtest_status vs query_backtest_history, send_agent_message vs send_chat_message. No two tools appear to do the same thing.

Naming Consistency4/5

The dominant pattern is verb_noun (create_portfolio, get_agent, stop_agent, query_backtest_status) and is mostly consistent. Minor deviations: fetch_portfolios vs list_agents use different verbs for the same listing operation, query_ prefix is used for backtest reads while get_/fetch_ are used elsewhere, and create_portfolio_variant, clone_strategies_to_portfolio, fork_shared_portfolio break the strict verb_noun shape. Readable and predictable overall despite these inconsistencies.

Tool Count3/5

24 tools sits at the heavy end of the acceptable range (16-25). The scope is genuinely broad — algorithmic portfolio CRUD, backtesting lifecycle, and a full autonomous-agent management surface — which justifies much of the count, but 11 of 24 tools are agent-specific and the portfolio tools overlap in function (create_portfolio_variant, clone_strategies_to_portfolio, fork_shared_portfolio, build_portfolio all produce or modify portfolios). The set would be tighter at ~18-20 tools.

Completeness3/5

Core workflows are well covered: portfolio lifecycle (create/build/variant/get/fetch/update/delete/fork/clone), backtesting (run/status/history), and agent lifecycle (create/get/list/archive/unarchive/star/stop/approve/reject/message). However, several descriptions reference tools that are NOT in the actual tool set — run_compute, dataset_to_indicator, list_custom_indicators, upload_chat_attachment, analyze_portfolios — which will cause agent failures when an agent tries to call them based on the documented workflows. This is a notable gap in the exposed surface.

Available Tools

24 tools
approve_agent_planAInspect

⚠ 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
agentIdYesMongoDB agent _id to approve

TDQS

A4.7/5.0
Behavior5/5

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

No annotations are present, so the description carries the full burden. It discloses that approval indirectly costs LLM credits, unfreezes the agent, triggers further planning/execution calls, emits the matching state-machine event, and returns 400 for invalid states. This is thorough and directly actionable.

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

Conciseness5/5

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

The description is dense but every sentence earns its place: the credit-cost warning is front-loaded, followed by usage constraints, behavior, and error semantics. It avoids fluff and repetition.

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

Completeness5/5

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

For a single-parameter tool with no output schema, the description is remarkably complete. It covers prerequisites, state requirements, behavior, side-effects, and error responses, leaving no critical unknowns for an agent deciding whether and how to invoke it.

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

Parameters3/5

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

Schema description coverage is 100% and clearly documents agentId as the MongoDB agent _id to approve. The description adds useful context that the agent must be in a pending-approval state, but it does not add significant parameter-level semantics beyond the schema.

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

Purpose5/5

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

The description clearly states the tool approves a semi-automated agent that is waiting in pending_plan_approval or pending_action_approval, and explains it auto-detects the needed approval type. It uses a specific verb and resource, and the manual-approval warning distinguishes this from passive read or messaging tools.

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

Usage Guidelines5/5

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

The description gives explicit when-to-use guidance: only for agents in pending_plan_approval or pending_action_approval, and only when the user explicitly asked to advance the agent. It also includes a strong when-not-to-use warning ('do NOT call unless the user explicitly told you'), which is unusually clear.

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

archive_agentAInspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
titleNoExact case-insensitive user-assigned title (XOR with agentId)
agentIdNoMongoDB agent _id to archive (XOR with title)

TDQS

A4.1/5.0
Behavior4/5

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

With no annotations provided, the description carries the full behavioral disclosure burden. It does well by stating 'no LLM cost — pure DB write,' clarifying the soft-delete semantics, and noting that the agent 'remains in the database but is hidden from default listings.' It does not mention reversibility explicitly, but 'soft-delete' and the sibling unarchive_agent imply it.

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

Conciseness4/5

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

The description is concise and front-loaded with the core operation: 'Archive an agent (soft-delete).' The additional sentences add useful context about cost, scope, persistence, and addressing. It could be tightened slightly by merging the introductory clauses, but every sentence earns its place.

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

Completeness4/5

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

Given the low complexity, two optional parameters, full schema coverage, and no output schema, the description is nearly complete. It explains the behavioral outcome and addressing constraint well. Minor omissions like explicit reversal path or permission requirements are not critical for correct invocation.

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

Parameters3/5

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

Schema coverage is 100%, so the schema already explains both parameters. The description repeats the XOR relationship between agentId and title, which adds emphasis but not new meaning beyond the schema's own descriptions. This is the baseline case where structured data does the heavy lifting.

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

Purpose5/5

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

The description states a specific action and resource: 'Archive an agent (soft-delete).' It elaborates on the observable effect ('hidden from default listings'), which clearly distinguishes it from siblings like unarchive_agent and other agent-management tools. An agent can immediately tell what this tool does.

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

Usage Guidelines4/5

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

The description gives clear contextual scope: 'Only relevant when managing Aurora agents.' It implies use when the goal is to soft-delete an agent, and the sibling set includes unarchive_agent as the natural inverse. It does not explicitly list exclusions or alternative tools, but the context is sufficient.

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

backtest_portfolioAInspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
end_dateYesBacktest 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.
intervalNoTime 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.
fee_configNoOptional 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.
start_dateYesBacktest 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.
portfolio_idNoPortfolio ID (live, paper, or chat — from fetch_portfolios or create_portfolio). Server resolves the collection automatically.
initial_valueNoStarting portfolio value (default 10000)
baseline_symbolNoBenchmark 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.
generate_eventsNoGenerate 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.

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations, the description carries the behavioral load and does well: it discloses async submission, that a backtest ID is returned immediately, the polling workflow, the 5x research-token cost of generate_events, and the 3-day Mongo hot-store retention. It does not state permission/auth requirements or failure behavior, so it stops short of a 5.

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

Conciseness4/5

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

Front-loaded with purpose and the critical constraint, and most sentences earn their place by covering distinct rules. However, the 90-day default and 730-day cap are repeated from the parameter schema, adding avoidable length to an already dense paragraph.

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

Completeness4/5

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

For an 8-parameter, nested-object, no-annotation, no-output-schema tool, the description covers the call path: constraints, baseline selection, cost, retention, and the ID-plus-polling return workflow. Permission requirements and error handling are absent, keeping it just short of fully complete.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds genuine decision logic beyond the schema: baseline_symbol should mirror the book (AAPL options → AAPL, per-underlying or equal-weight B&H for multi-name, SPY only for broad equity) and fee_config can be replayed from a study. It partly restates schema text (the 90/730-day rules), which caps this at 4.

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

Purpose5/5

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

States a specific verb and resource: 'Submit an asynchronous historical backtest for a portfolio over a date range.' It also names the sibling tools it hands off to (query_backtest_status, query_backtest_history, Read Backtest), so an agent can distinguish submission from polling and reporting.

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

Usage Guidelines5/5

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

Explicit when-to-use guidance for interval (Day vs Minute), date spans, and baseline_symbol selection, with clear exclusions ('do not emit 2010', 'never split a longer span into yearly Minute jobs', 'do not default to SPY'). It also names the downstream alternatives and their order, leaving little to inference.

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

build_portfolioAInspect

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

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

ParametersJSON Schema
NameRequiredDescriptionDefault
mainNoMark as main portfolio (optional).
nameNoPortfolio name (required).
messageNoOPTIONAL natural-language fallback. If provided WITHOUT name/strategies, the server runs a paid LLM to translate NL→portfolio. Prefer the structured fields (no LLM cost).
strategiesNoArray of strategies. Each strategy is { name, condition, action, orderExecution? }. RebalanceOption actions may include action.positionScope (portfolio | strategy). Optional strategy-level `orderExecution` defaults to `{type:"Market"}`. For a true waiting Limit, use `{type:"Limit",price:{type:"UnitPrice",amount:...},workingTime:{type:"Day"|"Minutes",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:"Plus",indicators:[{type:"OptionSpreadEntryPrice",underlying:"SPX",optionType:"call",direction:"long",spreadType:"vertical"},{type:"Value",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. See $defs.strategy / $defs.condition / $defs/indicator.
initialValueNoStarting cash (default 10000). Use 0 for agent-only / LaunchAgent portfolios that never trade capital.
alertsEnabledNo
supportsCryptoNo
supportsFractionalSharesNo

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden, and it delivers: it discloses that the tool persists nothing, runs the same construction and per-strategy validation, returns a canonicalized portfolio plus a per-component issue list, and costs zero research tokens. It also discloses the guarantee that a clean preview cannot fail on create_portfolio. The only minor gap is that it doesn't describe error/edge behavior for the message fallback path, but the core behavioral traits are well covered.

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

Conciseness4/5

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

The description is front-loaded with the most important facts (preview twin, persists nothing, same validation) and then adds return-value detail and custom-data-source guidance. It is longer than strictly necessary, and the custom data source paragraph is somewhat tangential to the tool's core purpose, but every sentence carries useful information and the structure is logical.

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

Completeness4/5

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

For a complex tool with 8 parameters, no output schema, and no annotations, the description covers the key things an agent needs: what the tool does, what it returns, the no-persistence guarantee, the zero-cost property, and the relationship to create_portfolio. It doesn't fully document the return shape (e.g., exact fields of the issue list), but it names the components (path + component + message) and the canonicalized portfolio, which is sufficient for an agent to interpret the result.

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

Parameters4/5

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

Schema description coverage is 63%, so the schema already documents most parameters. The description adds meaningful semantics beyond the schema: it explains that all fields are optional so partial drafts can be checked, that the message field is a paid LLM fallback to avoid, and that customIndicatorId is the authoritative reference for custom data sources. This compensates for the uncovered parameters and adds selection guidance.

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

Purpose5/5

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

The description opens with 'Preview/builder twin of create_portfolio' and states a specific verb (build/preview), resource (portfolio), and the key differentiator: it runs the same construction and validation but persists nothing. It also names the sibling it mirrors (create_portfolio), so an agent can distinguish it from create_portfolio, update_portfolio, and backtest_portfolio without opening the schema.

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

Usage Guidelines5/5

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

The description explicitly frames this as the preview twin of create_portfolio, states that it accepts the same IPortfolio JSON with all fields optional for partial drafts, and gives a concrete routing rule: 'A draft that previews clean cannot fail on create_portfolio.' It also tells the agent when to use the structured path vs the message fallback and how to create custom data sources. This is explicit when-to-use guidance with a clear alternative named.

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

clone_strategies_to_portfolioAInspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
preserve_existingNoWhen 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).
source_portfolio_idNoSource portfolio ID (live, paper, or chat) to copy strategies FROM.
target_portfolio_idYesDeployed 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.

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations, the description carries the behavioral burden, and it does disclose the destructive default ('Replace... entire strategy set'), source/target validity, and the no-implicit-backtest rule. It does not explicitly state in the main description that prior target strategies are archived and their open system orders cancelled by default—that detail lives only in the preserve_existing parameter schema—and the phrase 'deep copies... by reference, not YAML' is slightly ambiguous.

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

Conciseness4/5

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

The description is front-loaded with the core operation, followed by the main use case and guardrails; almost every sentence earns its place. It is slightly long and partially restates schema constraints such as 'the target MUST be a real deployed portfolio', which prevents a 5.

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

Completeness5/5

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

For a mutation tool with no annotations and no output schema, the description is unusually complete: it covers source types, target immutability, copy semantics, replacement behavior, and the post-clone backtest policy. Combined with the detailed input schema and sibling fetch_portfolios for ID discovery, an agent has enough context to invoke it correctly.

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

Parameters3/5

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

Schema description coverage is 100% and the parameter descriptions are already detailed, including preserve_existing behavior, source portfolio types, and the deployed-target restriction. The description reinforces the target constraint and workflow context but adds no genuinely new parameter-level semantics, so the baseline of 3 is appropriate.

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

Purpose5/5

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

The description opens with a specific verb and resource: 'Replace a deployed (paper/live) portfolio's entire strategy set with deep copies of a source portfolio's strategy objects.' It also states the concrete use case—deploying a chat portfolio's strategies onto a live/paper portfolio without re-describing them—which clearly separates this tool from broader portfolio-building siblings.

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

Usage Guidelines4/5

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

The description gives an explicit trigger: 'Use this to deploy a chat portfolio's strategies onto a live/paper portfolio without re-describing them.' It also adds important boundaries: 'Do NOT automatically backtest after clone' and 'chat portfolios are immutable and cannot be a target.' It does not explicitly name sibling alternatives such as fork_shared_portfolio or update_portfolio, so it stops short of a 5.

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

create_agentAInspect

⚠ 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, xiaomi/mimo-v2.6-flash 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleNoOptional user-assigned display name for the new agent (max 100 chars). Enables later lookup via title on get_agent / send_agent_message / etc.
messagesNoChatMessage array, e.g. [{"sender":"User","content":"..."}]
maxIterationsNoMax agent iterations. When omitted, uses the user's saved ChatSettings.agentIterations (same as the web UI).
session_depthNoDeprecated compatibility field. Both values use Aurora's adaptive routing policy.
attachment_idsNoREADY chat-attachment ids from upload_chat_attachment. Bound onto the last user message as fileAttachments (same refs as the web FILES tab).
automationModeNoautomated | semi-automated. When omitted, uses ChatSettings.agentAutomationMode.
conversationIdNoOptional NexusGenAI conversation id
idempotencyKeyNoCaller-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.

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations present, the description carries the full burden and does so thoroughly: it discloses LLM credit costs, manual-approval requirements, model locking, fallback to saved ChatSettings, and idempotent retry behavior. This goes well beyond a basic 'create' statement.

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

Conciseness5/5

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

The description front-loads the most critical information (credit cost and approval requirement) and then each subsequent sentence earns its place by covering alternatives, defaults, model constraints, attachments, and a concrete use case. Nothing feels padded or redundant.

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

Completeness5/5

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

Even without an output schema, the description gives enough context for correct invocation: cost implications, approval gate, sibling routing, defaults, model lock, attachment binding, and retry semantics. There is no critical gap that would prevent an agent from calling this tool appropriately.

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

Parameters3/5

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

Schema description coverage is 100%, so the baseline is 3. The description reinforces key semantic details already present in the schema, such as ChatSettings defaults and READY attachment IDs, but it does not need to add much because the schema is already rich.

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

Purpose5/5

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

The description states a precise verb and resource: 'Create a new autonomous Aurora agent' using the same body shape as POST /api/agent. It also differentiates from siblings by warning this is the LLM-billed agent-creation path versus the no-LLM portfolio/backtesting alternatives.

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

Usage Guidelines5/5

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

It gives explicit when-to-use and when-not-to-use guidance: 'do NOT call unless the user explicitly asked to launch an Aurora agent' and names the preferred alternatives for strategy work (create_portfolio, backtest_portfolio, query_*). It even supplies a concrete use case: a method-brief PDF plus a short analyze/report request.

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

create_portfolioAInspect

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. 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.

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

ParametersJSON Schema
NameRequiredDescriptionDefault
mainNoMark as main portfolio (optional).
nameYesPortfolio name (required).
messageNoOPTIONAL natural-language fallback. If provided WITHOUT name/strategies, the server runs a paid LLM to translate NL→portfolio. Prefer the structured fields (no LLM cost).
strategiesYesArray of strategies. Each strategy is { name, condition, action, orderExecution? }. RebalanceOption actions may include action.positionScope (portfolio | strategy). Optional strategy-level `orderExecution` defaults to `{type:"Market"}`. For a true waiting Limit, use `{type:"Limit",price:{type:"UnitPrice",amount:...},workingTime:{type:"Day"|"Minutes",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:"Plus",indicators:[{type:"OptionSpreadEntryPrice",underlying:"SPX",optionType:"call",direction:"long",spreadType:"vertical"},{type:"Value",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. See $defs.strategy / $defs.condition / $defs/indicator.
initialValueNoStarting cash (default 10000). Use 0 for agent-only / LaunchAgent portfolios that never trade capital.
alertsEnabledNo
supportsCryptoNo
supportsFractionalSharesNo

TDQS

A4.3/5.0
Behavior4/5

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

Given no annotations are provided, the description carries the full burden. It discloses that the structured path avoids LLM cost while the fallback incurs LLM credits, that CustomIndicator nodes require a customIndicatorId, and that build_portfolio can validate without saving (implying create_portfolio saves). It stops short of stating the return value or any asynchronous behavior, but it adds meaningful behavioral context beyond the schema.

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

Conciseness4/5

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

The description is compact and front-loaded: the first sentence states the core purpose and the preferred path. It includes only a brief, relevant note about custom data sources and avoids repeating schema details. Every sentence earns its place, though it could be slightly tighter by merging the custom data source paragraph.

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

Completeness4/5

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

For a tool with a massive, self-documenting schema, the description correctly points to the schema for full parameter detail while highlighting the critical structured-vs-NL decision and the validation step via build_portfolio. It would be more complete with an explicit statement of the return value (e.g., portfolio ID or created resource), but overall it provides enough for an agent to select and invoke the tool correctly.

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

Parameters3/5

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

The input schema is extraordinarily detailed with per-field descriptions (high schema_description_coverage), so the baseline is 3. The description adds high-level guidance on payload shapes, the customIndicatorId requirement, and orderExecution forms (UnitPrice, MinimumNetCredit/MaximumNetDebit). However, most of this information is already embedded in the schema's own field descriptions, so the description's incremental value is modest.

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

Purpose5/5

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

The description opens with a specific verb+resource: 'Create an algorithmic trading portfolio.' It further distinguishes the tool from sibling build_portfolio by explicitly recommending build_portfolio for validate-without-saving, and separates the preferred structured JSON path from the NL fallback path. This makes the tool's purpose unambiguous and clearly differentiated.

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

Usage Guidelines5/5

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

The description explicitly instructs when to use the structured payload (PREFERRED PATH, no LLM cost) versus the fallback NL path (only when structured JSON is impractical). It also names build_portfolio as the validation alternative and explains how to create custom data sources via run_compute or dataset_to_indicator before referencing them in create_portfolio. This is strong, explicit when-to-use guidance.

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

create_portfolio_variantAInspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesRequired new portfolio name.
dry_runNotrue → resolve + diff + validate, persist nothing.
patchesNoOptional RFC6902-style ops against canonical IPortfolio JSON. Omit or pass [] for an exact semantic clone. Sizing fields are action-type-specific: DynamicRebalance uses /strategies/N/action/deploymentPercent (0–100 number); RebalanceOption uses /strategies/N/action/totalBudget/amount. Do not patch totalBudget onto DynamicRebalance or deploymentPercent onto RebalanceOption.
source_portfolio_idYesSource portfolio ID (live, paper, or chat) to deep-copy.

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations provided, the description carries the full behavioral burden and does so thoroughly. It discloses atomic patch behavior with hard errors on unresolved paths, dry-run no-persist semantics, zero research token cost, and fresh strategy IDs in the copied portfolio, all of which go well beyond a generic 'creates a copy' statement.

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

Conciseness5/5

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

Every sentence earns its place: core action, clone-versus-edit mode, error semantics, dry-run behavior, and cost. The description is compact, front-loaded with the main purpose, and contains no fluff or redundant restatement of schema properties.

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

Completeness5/5

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

For a tool with no annotations and no output schema, the description plus the rich input schema gives an agent everything needed to select and invoke it correctly: source identification, patch constraints, action-type-specific sizing, atomicity, dry-run behavior, and cost. The lack of explicit return-shape details is not a blocker for correct invocation.

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

Parameters4/5

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

The input schema already provides 100% description coverage, so the baseline is 3; the tool description raises it by clarifying cross-parameter behavior: omitting patches yields a clone, providing patches yields surgical edits, and dry_run changes whether anything persists. It also adds the atomic hard-error behavior for unresolved patch paths, which is absent from the schema text.

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

Purpose5/5

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

The first sentence names a specific action ('deep-copy'), a source ('source chat or deployed portfolio'), and a target ('new ChatPortfolio with fresh strategy IDs'), making the tool's create-and-copy purpose unmistakable. This clearly distinguishes it from siblings like update_portfolio, which mutates an existing portfolio, and build_portfolio, which would create from scratch.

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

Usage Guidelines4/5

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

The description gives clear usage modes: omit patches for a clone-only draft, apply JSON-Pointer patches for surgical edits, and use dry_run to validate without persisting. It does not explicitly name sibling alternatives or exclusion conditions, but the source-copy semantics and mode guidance are enough for an agent to decide when this tool fits.

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

fetch_portfoliosAInspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number (default 1)
limitNoMax portfolios to return (default 20, max 50)
searchNoFree-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.
include_liveNoInclude live trading portfolios (default true)
include_paperNoInclude paper portfolios (default true)
portfolio_idsNoSpecific portfolio IDs to fetch (omit for all)
include_inactiveNoInclude inactive portfolios (default true)
include_positionsNoInclude 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.
include_chat_portfoliosNoInclude workspace draft chat portfolios (default false). Excludes deployedMirror. Set true with include_paper=false and include_live=false for draft-only search.

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations, the description carries full behavioral burden, and it delivers: it discloses pagination ordering (deployed first, then drafts), draft-only scoping and deployedMirror exclusion, search matching semantics, and default changes such as include_positions defaulting to false when searching. It also reveals the return object shape. This is exceptionally transparent for a tool with no annotations.

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

Conciseness4/5

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

The description is information-dense and front-loaded with the core purpose, but it is fairly long and includes some redundancy, such as repeating search behavior already in the schema. Every sentence carries useful information, yet a tighter structure would improve skimmability without losing key details.

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

Completeness5/5

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

Given 9 parameters, no annotations, and no output schema, the description is remarkably complete: it covers return fields, pagination behavior, search nuances, draft handling, and parameter defaults. An agent has enough context to decide when to call it and how to invoke it correctly. No critical behavior is left unexplained.

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

Parameters4/5

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

Schema coverage is 100% and the schema already documents parameters richly. The description still adds value beyond the schema by explaining that include_chat_portfolios returns only workspace DRAFTS and excludes deployedMirror, and by offering a concrete draft-recovery example. This goes beyond mere repetition, but the schema already does most of the heavy lifting.

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

Purpose5/5

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

The description opens with a specific verb and resource: 'List or search your portfolios with lightweight metadata (strategy id + name).' It clearly differentiates from siblings by noting it returns lightweight metadata and explicitly points to analyze_portfolios and get_portfolio for other needs. This is unambiguous and lets an agent know exactly what the tool is for.

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

Usage Guidelines5/5

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

The description gives explicit usage context: when to use search vs. list mode, how to recover past chat drafts with specific flag combinations, and when to prefer analyze_portfolios or get_portfolio. It also clarifies that include_chat_portfolios is for draft-only searches. This is strong, actionable guidance for selecting the right tool.

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

fork_shared_portfolioAInspect

⚠ 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
modeNoReplace existing strategies or append to them.
nameNoName for a new portfolio.
targetYesCreate a new chat portfolio or update an existing portfolio.
shared_portfolio_idYesID 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.
target_portfolio_idNoRequired when target is existing.

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations provided, the description carries the full burden and meets it: it leads with '⚠ MUTATING,' discloses that mode 'replace' removes old strategies while 'append' keeps them, states the prerequisite to 'subscribe first' for monetized portfolios, and reveals the return shape. These side effects and preconditions appear nowhere in structured annotations, making this genuinely additive.

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

Conciseness5/5

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

The description is compact and dense but every sentence earns its place: mutation warning and purpose are front-loaded, followed by target/mode semantics, the monetization prerequisite, the return shape, and routing guidance. No filler or repetition of schema content.

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

Completeness5/5

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

For a 5-parameter mutating tool with no annotations and no output schema, this description is remarkably complete: safety profile, mode semantics, the subscription prerequisite, the return value shape (forkSharedPortfolioResult fields), and usage routing are all covered. The one conditional dependency (target_portfolio_id required when target=existing) is left to the schema, which is acceptable given 100% schema coverage.

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

Parameters4/5

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

Schema description coverage is 100%, so the baseline is 3; the description adds meaning by disclosing that mode defaults to 'replace' — a fact absent from the schema, which has no default field — and spelling out the behavioral consequence of each mode choice. The remaining parameters are fully documented in the schema, so the description does not need to repeat them.

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

Purpose5/5

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

States a specific verb and resource — 'fork strategies from a shared portfolio into the user's account' — and clarifies the two target behaviors ('new' creates a chat portfolio, 'existing' patches a deployed portfolio). The closing line 'Prefer fork when the user wants to edit/customize strategies' differentiates it from siblings such as backtest_portfolio, clone_strategies_to_portfolio, and fetch_portfolios.

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

Usage Guidelines4/5

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

The description gives explicit when-to-use guidance: 'Prefer fork when the user wants to edit/customize strategies.' However, it does not name alternative tools or state when not to use it; the copy_trade_shared alternative for continuous mirroring appears only in the schema's shared_portfolio_id description, not in the tool description itself.

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

get_agentAInspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
titleNoExact case-insensitive user-assigned title (XOR with agentId). Fails if 0 or >1 matches.
agentIdNoMongoDB agent _id (XOR with title)

TDQS

A4.1/5.0
Behavior5/5

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

With zero annotations, the description carries the full disclosure burden and delivers comprehensively: cost ('no LLM cost on this call'), safety ('pure DB read'), failure semantics ('Duplicate titles fail closed with candidate ids'), case-insensitive matching behavior, the by-design frozen behavior of updatedAt, and fine-grained liveness semantics for lastProgressAt including the waiting_for_subagents corner case. No structured data covers any of this, so the description is the sole source and it is remarkably thorough.

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

Conciseness4/5

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

The description is long, but the length is earned: the lastProgressAt versus updatedAt distinction, the waiting_no_wake detector rationale, and the frozen-progress interpretation are genuinely subtle and would cause real polling bugs if omitted. It front-loads the most decision-relevant facts (cheap, pure DB read, relevance condition) before the deep polling guidance, though a single dense paragraph is harder to scan than clearly separated sections.

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

Completeness5/5

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

Given zero annotations and no output schema, the description covers everything needed for correct invocation and polling: safety and cost profile, addressing rules, duplicate-title failure behavior, liveness semantics, sandbox step location (agent.messages[*].data.steps), and terminal states. The only gap is a full status enum, but the terminal states and the one non-terminal state that matters operationally (waiting_for_subagents) are disclosed, so an agent can poll correctly.

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

Parameters3/5

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

The input schema already documents both parameters at 100% coverage, including the XOR relationship and the fail-if-not-exactly-one-match behavior, so the baseline is 3. The description adds only marginal value on top: restating 'provide exactly one' and the detail that duplicate-title failures return candidate ids. This does not meaningfully exceed what the schema provides.

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

Purpose4/5

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

The description identifies the resource ('Aurora agent surface'), the operation kind ('pure DB read'), and the returned contents ('status, plan, messages, config'), which together make the intent unambiguous and distinguish it from siblings like get_agent_trajectory and list_agents. The verb is only implied via the tool name and the word 'Returns' rather than stated as an explicit 'Gets/fetches X', which keeps it from a 5.

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

Usage Guidelines4/5

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

It gives a concrete applicability condition ('Only relevant when the user is actively working with an Aurora agent') and exceptionally detailed polling usage guidance: use lastProgressAt rather than updatedAt, treat a frozen lastProgressAt during waiting_for_subagents as stalled children, confirm via child agent statuses, and poll until a terminal state. It does not explicitly name sibling alternatives for other retrieval needs, such as list_agents or get_agent_trajectory, but the context for when and how to poll is far beyond typical.

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

get_agent_trajectoryAInspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
titleNoExact case-insensitive user-assigned title (XOR with agentId)
agentIdNoMongoDB agent _id (XOR with title)

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations present, the description carries the full burden and does well by explicitly stating 'no LLM cost on this call — pure DB read.' This discloses a key behavioral trait: the call is read-only and cheap. It also clarifies the output is raw trace/trajectory events, though it does not detail ordering, limits, or empty-result behavior.

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

Conciseness5/5

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

The description is three tightly written sentences with no filler. It front-loads the most valuable behavioral note (no LLM cost, pure DB read), then gives usage context, purpose, and addressing semantics without wasting words.

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

Completeness4/5

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

For a simple two-parameter read tool, the description covers what the tool returns, when to use it, and how to identify the target agent. There is no output schema, but 'raw trace / trajectory events' conveys the return shape reasonably. Missing minor details like behavior when both or neither XOR parameter is supplied are acceptable for a read-only inspection tool.

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

Parameters3/5

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

Schema description coverage is 100% and both parameters already include detailed descriptions including the XOR constraint. The tool description restates the XOR relationship but adds no new parameter semantics beyond what the schema already provides, so the baseline of 3 is appropriate.

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

Purpose5/5

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

The description clearly identifies the tool as retrieving raw trace/trajectory events for an Aurora agent, which is a specific resource and output type. It distinguishes itself from sibling tools like get_agent by emphasizing 'raw trace / trajectory events' rather than general agent metadata.

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

Usage Guidelines4/5

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

The description explicitly states it is 'only relevant when inspecting an Aurora agent run,' giving clear context for when this tool should be used. It does not name alternative sibling tools, but the usage boundary is clear enough that an agent can infer it is not for general agent listing or management.

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

get_portfolioAInspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
portfolio_idYesPortfolio ID (deployed paper/live or chat portfolio ID from fetch_portfolios / create_portfolio).

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations provided, the description carries the full behavioral burden. It discloses zero-LLM-cost behavior, the underlying API path, resolution priority, and a stale-data caveat about strategy.name/condition.name after GA mutation. This is substantial transparency beyond the schema.

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

Conciseness5/5

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

Five dense sentences, each adding distinct value: purpose, cost/API equivalence, resolution order, ID discovery, and verification guidance. Front-loaded with the core purpose and no filler or redundant restatement of the tool name.

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

Completeness5/5

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

For a one-parameter read tool with no output schema, the description is remarkably complete. It names what the response includes, flags stale fields to avoid, and tells the agent how to obtain the required portfolio_id. No critical calling information is missing.

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

Parameters3/5

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

Schema description coverage is 100%, so the parameter is already fully documented. The description adds context about using fetch_portfolios to discover IDs, but that mostly reinforces what the schema already states. Thus the baseline 3 is appropriate.

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

Purpose5/5

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

The description opens with a specific verb and resource: 'Fetch one portfolio' with explicit contents (full strategy objects, positions, spread-grouped holdings). It clearly differentiates from the sibling fetch_portfolios by emphasizing singular retrieval, making its unique role obvious.

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

Usage Guidelines5/5

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

It explicitly directs agents to use fetch_portfolios for ID discovery and gives a precise verification use case: use conditionFieldAudit for Gate-7/Gate-8 verification, not strategy.name or condition.name. It also explains resolution order, giving clear context on when and how the tool behaves.

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

list_agentsAInspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number (default 1)
limitNoPage size (default 10, max 100)
searchNoCase-insensitive substring match over title and initialPrompt
portfolioIdNoOptional portfolio id or alias to filter agents
starredOnlyNoReturn only starred top-level agents, sorted by starredOrder asc then starredAt desc. Default false
includeArchivedNoInclude archived agents. Default false

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations, the description carries the disclosure burden and does so by stating 'no LLM cost on this call itself — pure DB read,' which signals a safe read-only operation. It adds useful context about pagination and query shape, though it stops short of describing the return payload or default ordering.

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

Conciseness4/5

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

The description is compact and front-loads the no-cost/read-only nature before the routing guidance. The phrase 'Aurora agent surface' is slightly abstract, but the core instruction and exclusions are delivered without wasted sentences.

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

Completeness4/5

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

Given no annotations and no output schema, the description still covers cost/read-only behavior, when to use it, alternatives, and pagination. It lacks an explicit statement of what the response contains, but for a list operation with a fully documented parameter schema this is a minor gap.

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

Parameters3/5

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

Schema description coverage is 100%, so each parameter is already documented with meaning. The description adds only 'using the same query shape as the agent controller,' which is contextual but not a substitute for the schema's parameter details.

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

Purpose5/5

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

The description states 'List your Aurora agents with pagination', giving a specific verb and resource. It further distinguishes this tool from strategy-creation/backtesting siblings by directing users to create_portfolio, backtest_portfolio, query_*, and fetch_portfolios for those tasks.

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

Usage Guidelines5/5

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

It gives an explicit trigger condition: 'Useful only when the user is actively operating an Aurora agent.' It also names the alternative tools for other intents, so an agent can route correctly without inferring.

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

query_backtest_historyAInspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number (default 1)
end_dateNoISO date filter end (e.g. 2024-10-18). Inclusive; T23:59:59.999Z is appended if a bare date is given.
page_sizeNoRows per page (default 500, max 5000). Larger than events because history is plain numbers — cheap to emit.
start_dateNoISO date filter start (e.g. 2024-10-07). Inclusive.
backtest_idYesBacktest ID (required). Must be owned by the calling MCP user.
jump_bps_thresholdNoIf 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).

TDQS

A4.4/5.0
Behavior5/5

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

With no annotations provided, the description carries the full burden, and it does so thoroughly. It discloses the data source collection, 30-day TTL, minute resolution, cash derivation formula, reservedCollateral null semantics, and explicitly warns against re-deriving reservedCollateral from cash − buyingPower. It also notes zero research token cost.

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

Conciseness5/5

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

The description is front-loaded with the purpose, then adds only high-value operational details: storage, TTL, derivation, null semantics, and cost. Every sentence earns its place; caveats are compact and directly relevant to avoiding misuse.

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

Completeness4/5

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

There is no output schema, and the description compensates by enumerating the per-tick fields and explaining the tricky ones (cash derivation, reservedCollateral null behavior) and the optional 'Suspicious jumps' section. It does not define comparisonValue or positionValue in detail, and ownership is only mentioned in the input schema, but overall an agent has enough context to invoke and interpret the tool.

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

Parameters3/5

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

Schema description coverage is 100%, so the baseline is 3. The description does not add per-parameter syntax or meaning, but it enriches interpretation of the output fields relevant to parameters like jump_bps_threshold. Since the schema already fully documents the parameters, no strong compensation is needed.

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

Purpose5/5

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

States a specific verb ('Return') and resource ('a time series ... per tick for a completed backtest'), and distinguishes itself from siblings such as query_backtest_status by focusing on tick-level historical data. The description makes the tool's role immediately distinguishable from other backtest-related and portfolio tools.

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

Usage Guidelines4/5

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

Explicitly says when to use the tool: to find suspicious single-tick portfolio value jumps without needing the codebase. It does not explicitly name excluded alternatives or when-not-to-use conditions, but the intended usage context is clear and actionable.

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

query_backtest_statusAInspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
backtest_idYesBacktest ID (required). Must be owned by the calling MCP user.

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations, the description carries the full behavioral burden, and it delivers: it states this is a read of the parent document rather than history/events, notes zero research token cost, and explains the special 'not recorded' semantics for collateral fields. This is genuinely useful non-obvious behavior beyond the schema.

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

Conciseness5/5

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

The description is dense but every sentence earns its place: it front-loads what is returned, then gives usage timing, then explains a critical data interpretation nuance, then states cost. There is no filler or repetition.

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

Completeness5/5

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

Even without an output schema, the description enumerates the key returned fields, explains the special-case 'not recorded' values, states cost, and gives usage context. For a single-parameter status-query tool, an agent has everything needed to invoke it correctly and interpret its results.

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

Parameters3/5

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

Schema coverage is 100%, and the schema already documents backtest_id as required and user-owned. The description adds context about when to use the tool but does not add new parameter format details. Baseline 3 is appropriate because the schema handles parameter semantics.

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

Purpose5/5

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

The description opens with a specific verb and resource: 'Return the parent backtest document's status, error, interval, timestamps, elapsed time, and completed statistics.' It also explicitly distinguishes itself from query_backtest_history by stating it works 'without reading history/events.' This leaves no ambiguity about what the tool does or how it differs from its sibling.

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

Usage Guidelines5/5

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

It gives explicit placement guidance: 'Use immediately after backtest_portfolio or before query_backtest_history so ERROR/PENDING/RUNNING states are explicit.' This tells the agent both the trigger and the sequencing relative to related tools, which is more than enough to select the correct tool.

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

reject_agent_actionAInspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
agentIdYesMongoDB agent _id to reject

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does substantial work: it discloses that the action is a state transition, marks the latest assistant message as errored, traces the rejection, and publishes a websocket update. It does not mention whether the operation is reversible or what permissions are required, but the core behavior is well covered.

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

Conciseness5/5

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

The description is compact and information-dense. Every sentence earns its place: the first frames scope and cost, the second gives the usage precondition, and the third lists concrete behavioral effects. No filler or repetition.

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

Completeness4/5

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

For a one-parameter tool with no output schema and no annotations, the description covers the action, valid states, and side effects quite well. It does not explicitly state what the tool returns after rejection, which would be useful with no output schema, but the low complexity and rich effect description make this a minor gap.

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

Parameters3/5

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

Schema coverage is 100% and the single parameter agentId is already described as 'MongoDB agent _id to reject.' The description adds the endpoint pattern POST /api/agent/:agentId/reject, which reinforces that agentId is a path identifier, but it does not materially expand on schema semantics. Baseline 3 is appropriate.

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

Purpose5/5

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

The description states a specific verb and resource: 'Reject a semi-automated agent that is waiting in pending_plan_approval or pending_action_approval.' It also distinguishes itself from sibling tools by scoping to the Aurora agent surface and to pending-approval states, making it clear this is the rejection counterpart to approval or stopping tools.

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

Usage Guidelines4/5

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

It provides explicit when-to-use guidance: 'Only relevant when actively managing an Aurora agent' and specifies the exact pending states required. It does not explicitly name alternatives or state when not to use it, so it stops short of a 5, but the conditionality is clear enough for an agent to route correctly.

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

search_public_portfoliosAInspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number (default 1)
limitNoResults per page (default 20, max 100)
sort_byNoSort 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.
min_sharpeNoMinimum Sharpe ratio filter. Combine with max_drawdown.
profile_idNoOptional public creator profileId (from search_creators / /p/:profileId). When set, returns only that creator's public/monetized shared portfolios.
sort_orderNoSort order: 1 or -1 (default -1, or 1 when sort_by is maxDrawdown)
max_drawdownNoKeep listings whose |max drawdown| is at most this percent. Idle books with max drawdown of 0 are excluded. Combine with min_sharpe.
trading_typeNoTrading type: paper-trading or live-trading
min_followersNoMinimum follower count filter (default 0)

TDQS

A3.6/5.0
Behavior3/5

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

With no annotations provided, the description carries the transparency burden. It does add useful behavioral context, such as the public/monetized scope and the ability to filter by profileId, but it does not disclose output format, pagination details, or the read-only nature of the search operation beyond the word 'browse'.

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

Conciseness5/5

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

The description is concise and well-structured: a two-sentence opener that front-loads the core purpose and then adds the most important filter. There is no wasted text or redundancy with the schema.

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

Completeness3/5

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

For a tool with 9 parameters, no annotations, and no output schema, the description provides only a partial picture. It explains the search scope and the profileId filter, but it does not indicate what a result entry looks like or what return format the caller should expect.

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

Parameters4/5

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

Schema coverage is 100%, so the schema already documents every parameter thoroughly. The description adds meaningful extra context for profile_id by telling the agent it comes from Search Creators or /p/:profileId, which is valuable beyond the schema's description.

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

Purpose4/5

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

The description clearly states the tool's purpose: searching and browsing publicly shared portfolios from other NexusTrade users, sorted by performance metrics. It is specific about the resource and scope, though it does not explicitly differentiate itself from sibling tools like fetch_portfolios.

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

Usage Guidelines3/5

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

The description implies when to use the tool: for browsing or searching public portfolios, and optionally filtering by one creator's profileId. However, it does not explicitly state when not to use it or compare it with alternatives such as fetch_portfolios or get_portfolio.

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

send_agent_messageAInspect

⚠ 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleNoExact case-insensitive user-assigned title (XOR with agentId)
agentIdNoMongoDB agent _id to send the message to (XOR with title)
contentYesThe user message text to append to the conversation

TDQS

A4.7/5.0
Behavior5/5

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

No annotations are provided, so the description carries the full burden of disclosing behavior. It does so extensively: costs LLM credits, charges planning tokens, rejects active/approved states, may recover terminal states, may transition the agent, publishes websocket updates, and is not append-only. This is exemplary side-effect disclosure.

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

Conciseness5/5

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

The warning is front-loaded and every clause adds distinct value: cost, approval requirement, usage restriction, addressing, state effects, and websocket notifications. It is dense but appropriately sized for a high-risk mutation tool with no annotations.

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

Completeness5/5

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

Given the absence of annotations and output schema, the description fully covers prerequisites, side effects, addressing constraints, and state transitions. An agent has enough information to decide when to call this tool and what consequences to expect.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents all three parameters. The description adds the XOR relationship and exact-title matching, but these are also already present in the schema property descriptions. It therefore provides minimal additional meaning beyond the structured schema.

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

Purpose5/5

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

The description clearly states the operation: 'Send a follow-up user message to an agent and re-run the planner' and identifies the target resource via agentId or exact title. It also distinguishes itself from generic messaging by noting it is not append-only and re-runs the Aurora planner, which sets it apart from siblings like send_chat_message.

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

Usage Guidelines5/5

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

The description gives an explicit guardrail: 'do NOT call unless the user explicitly asked to push a message into an active Aurora agent.' It also specifies manual approval, XOR addressing, and the endpoint it matches, giving clear when-to-use and when-not-to-use guidance.

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

send_chat_messageAInspect

⚠ 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
messagesYesFull or partial ChatMessage array, e.g. [{"sender":"User","content":"..."}]
session_depthNoDeprecated compatibility field. Both values use Aurora's adaptive routing policy.
attachment_idsNoREADY chat-attachment ids from upload_chat_attachment. Bound onto the last user message as fileAttachments.
conversationIdNoOptional NexusGenAI conversation id

TDQS

A4.2/5.0
Behavior4/5

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

No annotations are provided, so the description carries the full burden. It discloses LLM credit costs, three routing outcomes (persisted Ask Clarity, spawned Aurora research, queued single-tool fulfill), and adaptive routing. It omits auth and response/async details, but the behavioral context is substantial.

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

Conciseness5/5

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

The cost warning is front-loaded, and the four sentences each add distinct value: cost/path, routing behavior, usage guidance, and adaptive selection. There is no filler or redundancy that hurts clarity.

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

Completeness4/5

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

For a tool with no annotations and no output schema, the description gives strong context about behavior, cost, and route selection, while the schema covers all parameters. It does not explain return values or async completion, which is a minor gap given the tool can queue jobs or spawn agents.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents all parameters. The description adds no per-parameter meaning beyond what the schema provides, but it does not need to because the schema entries are adequate.

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

Purpose4/5

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

The description clearly states the tool sends a chat message via the POST /api/chat path and orients it as the tool 'for chat turns'. It explicitly contrasts with create_agent, but it does not address send_agent_message, so sibling differentiation is partial rather than complete.

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

Usage Guidelines5/5

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

Provides explicit selection guidance: 'Use this for chat turns; use create_agent only when you explicitly want agent spawn without single-tool fulfill.' This directly tells the agent when to choose this tool versus the main ambiguous sibling.

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

star_agentAInspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleNoExact case-insensitive user-assigned title (XOR with agentId)
agentIdNoMongoDB agent _id to star or unstar (XOR with title)
starredNoOptional explicit star state. Omit to toggle the current state.

TDQS

A4.2/5.0
Behavior4/5

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

No annotations are provided, so the description carries the behavioral burden. It discloses that this is a pure DB write with no LLM cost, that it stars or unstars, and that omitting 'starred' toggles the current state. It could mention error cases or permission requirements, but the main side effects are clearly surfaced.

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

Conciseness5/5

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

Three concise sentences with no filler. The most decision-relevant trait (no LLM cost, pure DB write) is front-loaded, followed by the action and the key usage constraints.

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

Completeness4/5

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

For a simple 3-parameter toggle operation with high schema coverage, the description plus schema covers identifiers, XOR rules, toggle behavior, and cost profile. It omits explicit return-value or error details, but these are not essential for this simple tool.

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

Parameters3/5

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

The schema already documents all three parameters with 100% coverage, including XOR constraints and toggle behavior. The description reinforces these semantics but does not add significant new parameter-level meaning beyond what the schema provides.

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

Purpose5/5

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

The description clearly states the action (star/unstar), the resource (a top-level agent), and the purpose (quick sidebar access). It also references the exact API endpoint it mirrors, which helps distinguish it from sibling agent-management tools.

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

Usage Guidelines4/5

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

The description gives clear operating context: pure DB write with no LLM cost, for quick sidebar access, and how to address the agent via agentId or exact title (XOR). It does not explicitly name when-not-to-use alternatives, but the starring use case is distinct enough from siblings.

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

stop_agentAInspect

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.).

ParametersJSON Schema
NameRequiredDescriptionDefault
agentIdYesMongoDB agent _id to stop

TDQS

A3.8/5.0
Behavior4/5

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

With no annotations provided, the description carries the disclosure burden. It reveals meaningful behavioral traits: no LLM cost, pure state transition, cancellation request semantics, and cascade to descendant subagents. It does not describe result/return behavior, but the disclosed details go well beyond the tool name.

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

Conciseness3/5

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

The description is reasonably sized but not perfectly front-loaded. The actual purpose 'Stop a running agent' appears in the third sentence after the introductory 'Aurora agent surface' context. It is compact, but some early sentences are contextual rather than action-oriented.

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

Completeness4/5

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

For a simple one-parameter tool with no output schema, the description covers the purpose, preconditions (active state), and side effects (cascade). It does not mention error cases or exact response shape, but the essential context for calling it correctly is present.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already fully documents agentId as 'MongoDB agent _id to stop.' The description adds no additional parameter-level detail, which is acceptable given the complete schema coverage.

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

Purpose5/5

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

The description clearly states the verb and resource: 'Stop a running agent.' It adds specific behavioral detail—sends a cancellation request and cascades to all descendant subagents—which distinguishes it from siblings like archive_agent or reject_agent_action.

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

Usage Guidelines3/5

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

It provides clear context for when the tool is relevant: when actively managing an Aurora agent and when the agent is in an active state. However, it does not explicitly mention alternatives or when not to use this tool versus related sibling tools.

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

unarchive_agentAInspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
titleNoExact case-insensitive user-assigned title (XOR with agentId)
agentIdNoMongoDB agent _id to unarchive (XOR with title)

TDQS

A4.1/5.0
Behavior4/5

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

With no annotations provided, the description carries the behavioral burden and it does disclose a key trait: 'no LLM cost — pure DB write', and the visible effect on default listings. It does not discuss auth, idempotency, or error behavior, but this is a simple write operation and the core side effects are stated.

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

Conciseness4/5

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

The description is short and scannable, with the main action and effect stated in one sentence. The first sentence contains slightly redundant context ('Aurora agent surface', 'Only relevant when managing Aurora agents'), so it is not perfectly optimized, but there is no real waste.

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

Completeness4/5

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

For a two-parameter tool with no output schema, this is mostly complete: purpose, effect, and addressing mode are covered. The only notable ambiguity is that the schema marks both parameters as optional while the description's XOR implies exactly one is required; spelling that out explicitly would make it fully complete.

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

Parameters3/5

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

Schema description coverage is 100% and both parameters already carry their own descriptions plus XOR hints. The description restates the XOR relationship but adds no new parameter semantics beyond the schema.

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

Purpose5/5

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

The description uses a specific verb ('Restore') with a clear resource ('an archived agent') and an observable outcome ('appears in default agent listings again'). This makes it easy to distinguish from sibling tools like archive_agent and list_agents, even without naming them.

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

Usage Guidelines4/5

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

It gives clear context: use this only when managing Aurora agents and specifically when an archived agent should be made visible again. It does not list exclusions or alternative tools, but the inverse relationship to archive_agent makes the intended use case fairly obvious.

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

update_portfolioAInspect

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

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

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden, and it delivers: delete 'permanently removes' and 'archives deployed paper/live books', confirmLive is scoped to explicit user confirmation, orderExecution 'defaults to Market', and QuoteRelative 'normally executes immediately'. These disclose the dangerous and non-obvious behaviors an agent must know before calling.

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

Conciseness4/5

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

The description is roughly 170 words and every sentence earns its place: operation list, rename constraint, delete/archive semantics plus confirmLive gate, structured-path recommendation, orderExecution defaults, and positionScope distinction. It is dense but not bloated, and the most important safety guidance (delete) appears early.

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

Completeness4/5

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

For a complex multi-operation mutation tool with destroy semantics and zero annotations, the description covers the critical invocation caveats: permanence of delete, the confirmLive gate, default orderExecution, and the zero-cost structured path, with the schema handling the exhaustive parameter detail. The only gap is that deploy's chat→paper-trading implication lives in the schema rather than the description, which is acceptable given 100% schema coverage.

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

Parameters4/5

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

Schema coverage is 100% (the operations parameter has an extensive description), so baseline is 3, but the tool description adds genuine semantic value: rename requires a non-empty name, replaceStrategy/replaceStrategies need full strategyObjects 'same shape as create_portfolio', and RebalanceOption positionScope is explained as portfolio (single-book) vs strategy (multi-strategy). This goes beyond the schema's structural definition.

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

Purpose5/5

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

The opening sentence names a specific verb ('Deploy, undeploy, rename, delete, add/remove/replace strategies, or set deployment frequency') bound to the 'portfolios' resource, enumerating the full operation surface. This distinguishes it cleanly from siblings like create_portfolio (creation), get_portfolio/fetch_portfolios (reads), and the agent-management tools.

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

Usage Guidelines4/5

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

The description gives clear operational context: the structured operations-array path is flagged as 'zero LLM cost', the delete operation is explicitly gated with 'confirmLive:true only after explicit user confirmation', and it references create_portfolio for strategy shape. It lacks an explicit 'use create_portfolio instead for new portfolios' exclusion, but the division of labor is strongly implied.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updates
    • Changedbuild_portfolio2 fields changed
      • changedInput schema / $defs / indicator / description
        Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), MovingAverageConvergenceDivergence (MACD; needs targetAsset; optional fastLength/slowLength/signalLength defaulting to 12/26/9 with slowLength > fastLength, interval Day|Hour|Minute default Day, and line macd|signal|histogram selecting which of the three MACD outputs to emit), AverageDirectionalIndex (Wilder ADX trend-strength system 0-100; needs targetAsset+window; optional line adx|plusDi|minusDi — ADX measures strength, +DI/-DI direction), RelativeVolume (RVOL; needs targetAsset+window; current bar volume divided by the mean volume of the trailing N completed bars, ~1.0 is its recent pace), TrueRange/AverageTrueRange (need targetAsset; ATR also window), VWAP (needs targetAsset; resets each trading day), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), MovingAverageConvergenceDivergence (MACD; needs targetAsset; optional fastLength/slowLength/signalLength defaulting to 12/26/9 with slowLength > fastLength, interval Day|Hour|Minute default Day, and line macd|signal|histogram selecting which of the three MACD outputs to emit), AverageDirectionalIndex (Wilder ADX trend-strength system 0-100; needs targetAsset+window; optional line adx|plusDi|minusDi — ADX measures strength, +DI/-DI direction), RelativeVolume (RVOL; needs targetAsset+window; current bar volume divided by the mean volume of the trailing N completed bars, ~1.0 is its recent pace), Stochastic (needs targetAsset+window; optional smoothK/smoothD defaulting to 3/3 and line k|d), CommodityChannelIndex (CCI; needs targetAsset+window; optional constant defaulting to 0.015), WilliamsR (needs targetAsset+window; −100 to 0 scale), MoneyFlowIndex (MFI; needs targetAsset+window; volume-weighted 0-100), OnBalanceVolume (OBV; needs targetAsset; optional interval default Day), AccumulationDistribution (ADL; needs targetAsset; optional interval default Day), ChaikinMoneyFlow (CMF; needs targetAsset+window; −1 to +1 scale), DonchianChannel (needs targetAsset+window; optional line upper|lower|middle default upper), KeltnerChannel (needs targetAsset+window; optional multiplier default 2 and line upper|middle|lower default middle), Supertrend (needs targetAsset+window; optional multiplier default 3 and line value|direction default value, direction reads +1 up / −1 down), IchimokuCloud (needs targetAsset+window; optional spanLength default 52 and line tenkan|kijun|senkouA|senkouB|chikou default tenkan; lines unshifted), ParabolicSar (needs targetAsset; optional interval default Day, step default 0.02, maximum default 0.2), TrueRange/AverageTrueRange (need targetAsset; ATR also window), VWAP (needs targetAsset; resets each trading day), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), Correlation (rolling Pearson of two sub-indicators' returns; needs 2 sub-indicators + window with length >= 2), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
      • changedInput schema / $defs / indicator / properties / type / enum
        Previous value: -[
        -  "DaysSinceAgent",
        -  "MinutesSinceAgent",
        -  "DaysSinceAlert",
        -  "MinutesSinceAlert",
        -  "StockReport",
        -  "DaysUntilEarnings",
        -  "DaysSinceEarnings",
        -  "ImpliedVolatility",
        -  "IVRank",
        -  "IVPercentile",
        -  "IVHVRatio",
        -  "LastOrderPrice",
        -  "Fundamental",
        -  "Economic",
        -  "CustomIndicator",
        -  "Index",
        -  "BollingerBand",
        -  "RelativeStrengthIndex",
        -  "MovingAverageConvergenceDivergence",
        -  "AverageDirectionalIndex",
        -  "RelativeVolume",
        -  "PriceMeanAbsoluteDeviation",
        -  "ExponentialMovingAverage",
        -  "SimpleMovingAverage",
        -  "PriceStandardDeviation",
        -  "PriceRateOfChange",
        -  "MaxDrawdown",
        -  "MaxDrawup",
        -  "MinimumPrice",
        -  "MaximumPrice",
        -  "IndicatorMeanAbsoluteDeviation",
        -  "IndicatorExponentialMovingAverage",
        -  "IndicatorSimpleMovingAverage",
        -  "IndicatorStandardDeviation",
        -  "IndicatorRateOfChange",
        -  "DaysSinceOrder",
        -  "DaysSinceOptionOrder",
        -  "DaysSinceStrategyFired",
        -  "DaysSinceLastRebalanceOptionOrder",
        -  "MinutesSinceOptionOrder",
        -  "MinutesSinceOrder",
        -  "DaysSinceTransaction",
        -  "InitialValue",
        -  "BuyingPower",
        -  "PositionValue",
        -  "PositionPercentChange",
        -  "PortfolioValue",
        -  "RebalanceDecisionMetric",
        -  "Value",
        -  "Price",
        -  "Plus",
        -  "Minus",
        -  "Multiply",
        -  "Divide",
        -  "Negative",
        -  "AbsoluteValue",
        -  "SquareRoot",
        -  "Max",
        -  "Min",
        -  "Day",
        -  "Month",
        -  "Date",
        -  "Year",
        -  "CurrentTimeSeconds",
        -  "CurrentTimeMinutes",
        -  "CurrentTimeHours",
        -  "TrailingSum",
        -  "CompoundAnnualGrowthRate",
        -  "Log",
        -  "Exponentiation",
        -  "SumOrderQuantity",
        -  "SumOrderAmount",
        -  "MinutesAfterOpen",
        -  "OpeningPrice",
        -  "PreviousClosingPrice",
        -  "HighOfDay",
        -  "LowOfDay",
        -  "MinutesUntilClose",
        -  "PriceChangeSinceOpen",
        -  "GapSize",
        -  "GapPercentage",
        -  "TrueRange",
        -  "AverageTrueRange",
        -  "Volume",
        -  "VWAP",
        -  "BullishFairValueGap",
        -  "BearishFairValueGap",
        -  "IndicatorAtMinutesAfterOpen",
        -  "IndicatorWindowAgo",
        -  "IndicatorAtEntry",
        -  "IsIndexMember",
        -  "PoliticalTrades",
        -  "InsiderTrades",
        -  "IsIndustry",
        -  "IsAssetType",
        -  "IsAsset",
        -  "IsNotAsset",
        -  "CrossAbove",
        -  "CrossBelow",
        -  "PositionMaxDrawdown",
        -  "PositionMaxDrawup",
        -  "UnderlyingMaxDrawdown",
        -  "ConsecutiveTrue",
        -  "CountTrue",
        -  "OptionPositionValue",
        -  "OptionPositionCount",
        -  "OptionPositionPercentChange",
        -  "OptionPositionMaxDrawdown",
        -  "OptionDaysToExpiration",
        -  "OptionDaysHeld",
        -  "OptionCollateral",
        -  "OptionSpreadCount",
        -  "OptionSpreadEntryPrice",
        -  "OptionUnrealizedPnL",
        -  "OptionRealizedPnL",
        -  "OptionRealizedPremium",
        -  "OptionGrossExposurePercent"
        -]New value: +[
        +  "DaysSinceAgent",
        +  "MinutesSinceAgent",
        +  "DaysSinceAlert",
        +  "MinutesSinceAlert",
        +  "StockReport",
        +  "DaysUntilEarnings",
        +  "DaysSinceEarnings",
        +  "ImpliedVolatility",
        +  "IVRank",
        +  "IVPercentile",
        +  "IVHVRatio",
        +  "LastOrderPrice",
        +  "Fundamental",
        +  "Economic",
        +  "CustomIndicator",
        +  "Index",
        +  "BollingerBand",
        +  "RelativeStrengthIndex",
        +  "MovingAverageConvergenceDivergence",
        +  "AverageDirectionalIndex",
        +  "RelativeVolume",
        +  "Stochastic",
        +  "CommodityChannelIndex",
        +  "WilliamsR",
        +  "MoneyFlowIndex",
        +  "OnBalanceVolume",
        +  "AccumulationDistribution",
        +  "ChaikinMoneyFlow",
        +  "DonchianChannel",
        +  "KeltnerChannel",
        +  "Supertrend",
        +  "IchimokuCloud",
        +  "ParabolicSar",
        +  "PriceMeanAbsoluteDeviation",
        +  "ExponentialMovingAverage",
        +  "SimpleMovingAverage",
        +  "PriceStandardDeviation",
        +  "PriceRateOfChange",
        +  "MaxDrawdown",
        +  "MaxDrawup",
        +  "MinimumPrice",
        +  "MaximumPrice",
        +  "IndicatorMeanAbsoluteDeviation",
        +  "IndicatorExponentialMovingAverage",
        +  "IndicatorSimpleMovingAverage",
        +  "IndicatorStandardDeviation",
        +  "IndicatorRateOfChange",
        +  "DaysSinceOrder",
        +  "DaysSinceOptionOrder",
        +  "DaysSinceStrategyFired",
        +  "DaysSinceLastRebalanceOptionOrder",
        +  "MinutesSinceOptionOrder",
        +  "MinutesSinceOrder",
        +  "DaysSinceTransaction",
        +  "InitialValue",
        +  "BuyingPower",
        +  "PositionValue",
        +  "PositionPercentChange",
        +  "PortfolioValue",
        +  "RebalanceDecisionMetric",
        +  "Value",
        +  "Price",
        +  "Plus",
        +  "Minus",
        +  "Multiply",
        +  "Divide",
        +  "Negative",
        +  "AbsoluteValue",
        +  "SquareRoot",
        +  "Max",
        +  "Min",
        +  "Day",
        +  "Month",
        +  "Date",
        +  "Year",
        +  "CurrentTimeSeconds",
        +  "CurrentTimeMinutes",
        +  "CurrentTimeHours",
        +  "TrailingSum",
        +  "CompoundAnnualGrowthRate",
        +  "Log",
        +  "Exponentiation",
        +  "SumOrderQuantity",
        +  "SumOrderAmount",
        +  "MinutesAfterOpen",
        +  "OpeningPrice",
        +  "PreviousClosingPrice",
        +  "HighOfDay",
        +  "LowOfDay",
        +  "MinutesUntilClose",
        +  "PriceChangeSinceOpen",
        +  "GapSize",
        +  "GapPercentage",
        +  "TrueRange",
        +  "AverageTrueRange",
        +  "Volume",
        +  "VWAP",
        +  "BullishFairValueGap",
        +  "BearishFairValueGap",
        +  "IndicatorAtMinutesAfterOpen",
        +  "IndicatorWindowAgo",
        +  "IndicatorAtEntry",
        +  "IsIndexMember",
        +  "PoliticalTrades",
        +  "InsiderTrades",
        +  "IsIndustry",
        +  "IsAssetType",
        +  "IsAsset",
        +  "IsNotAsset",
        +  "CrossAbove",
        +  "CrossBelow",
        +  "Correlation",
        +  "PositionMaxDrawdown",
        +  "PositionMaxDrawup",
        +  "UnderlyingMaxDrawdown",
        +  "ConsecutiveTrue",
        +  "CountTrue",
        +  "OptionPositionValue",
        +  "OptionPositionCount",
        +  "OptionPositionPercentChange",
        +  "OptionPositionMaxDrawdown",
        +  "OptionDaysToExpiration",
        +  "OptionDaysHeld",
        +  "OptionCollateral",
        +  "OptionSpreadCount",
        +  "OptionSpreadEntryPrice",
        +  "OptionUnrealizedPnL",
        +  "OptionRealizedPnL",
        +  "OptionRealizedPremium",
        +  "OptionGrossExposurePercent"
        +]
    • Changedcreate_portfolio2 fields changed
      • changedInput schema / $defs / indicator / description
        Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), MovingAverageConvergenceDivergence (MACD; needs targetAsset; optional fastLength/slowLength/signalLength defaulting to 12/26/9 with slowLength > fastLength, interval Day|Hour|Minute default Day, and line macd|signal|histogram selecting which of the three MACD outputs to emit), AverageDirectionalIndex (Wilder ADX trend-strength system 0-100; needs targetAsset+window; optional line adx|plusDi|minusDi — ADX measures strength, +DI/-DI direction), RelativeVolume (RVOL; needs targetAsset+window; current bar volume divided by the mean volume of the trailing N completed bars, ~1.0 is its recent pace), TrueRange/AverageTrueRange (need targetAsset; ATR also window), VWAP (needs targetAsset; resets each trading day), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), MovingAverageConvergenceDivergence (MACD; needs targetAsset; optional fastLength/slowLength/signalLength defaulting to 12/26/9 with slowLength > fastLength, interval Day|Hour|Minute default Day, and line macd|signal|histogram selecting which of the three MACD outputs to emit), AverageDirectionalIndex (Wilder ADX trend-strength system 0-100; needs targetAsset+window; optional line adx|plusDi|minusDi — ADX measures strength, +DI/-DI direction), RelativeVolume (RVOL; needs targetAsset+window; current bar volume divided by the mean volume of the trailing N completed bars, ~1.0 is its recent pace), Stochastic (needs targetAsset+window; optional smoothK/smoothD defaulting to 3/3 and line k|d), CommodityChannelIndex (CCI; needs targetAsset+window; optional constant defaulting to 0.015), WilliamsR (needs targetAsset+window; −100 to 0 scale), MoneyFlowIndex (MFI; needs targetAsset+window; volume-weighted 0-100), OnBalanceVolume (OBV; needs targetAsset; optional interval default Day), AccumulationDistribution (ADL; needs targetAsset; optional interval default Day), ChaikinMoneyFlow (CMF; needs targetAsset+window; −1 to +1 scale), DonchianChannel (needs targetAsset+window; optional line upper|lower|middle default upper), KeltnerChannel (needs targetAsset+window; optional multiplier default 2 and line upper|middle|lower default middle), Supertrend (needs targetAsset+window; optional multiplier default 3 and line value|direction default value, direction reads +1 up / −1 down), IchimokuCloud (needs targetAsset+window; optional spanLength default 52 and line tenkan|kijun|senkouA|senkouB|chikou default tenkan; lines unshifted), ParabolicSar (needs targetAsset; optional interval default Day, step default 0.02, maximum default 0.2), TrueRange/AverageTrueRange (need targetAsset; ATR also window), VWAP (needs targetAsset; resets each trading day), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), Correlation (rolling Pearson of two sub-indicators' returns; needs 2 sub-indicators + window with length >= 2), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
      • changedInput schema / $defs / indicator / properties / type / enum
        Previous value: -[
        -  "DaysSinceAgent",
        -  "MinutesSinceAgent",
        -  "DaysSinceAlert",
        -  "MinutesSinceAlert",
        -  "StockReport",
        -  "DaysUntilEarnings",
        -  "DaysSinceEarnings",
        -  "ImpliedVolatility",
        -  "IVRank",
        -  "IVPercentile",
        -  "IVHVRatio",
        -  "LastOrderPrice",
        -  "Fundamental",
        -  "Economic",
        -  "CustomIndicator",
        -  "Index",
        -  "BollingerBand",
        -  "RelativeStrengthIndex",
        -  "MovingAverageConvergenceDivergence",
        -  "AverageDirectionalIndex",
        -  "RelativeVolume",
        -  "PriceMeanAbsoluteDeviation",
        -  "ExponentialMovingAverage",
        -  "SimpleMovingAverage",
        -  "PriceStandardDeviation",
        -  "PriceRateOfChange",
        -  "MaxDrawdown",
        -  "MaxDrawup",
        -  "MinimumPrice",
        -  "MaximumPrice",
        -  "IndicatorMeanAbsoluteDeviation",
        -  "IndicatorExponentialMovingAverage",
        -  "IndicatorSimpleMovingAverage",
        -  "IndicatorStandardDeviation",
        -  "IndicatorRateOfChange",
        -  "DaysSinceOrder",
        -  "DaysSinceOptionOrder",
        -  "DaysSinceStrategyFired",
        -  "DaysSinceLastRebalanceOptionOrder",
        -  "MinutesSinceOptionOrder",
        -  "MinutesSinceOrder",
        -  "DaysSinceTransaction",
        -  "InitialValue",
        -  "BuyingPower",
        -  "PositionValue",
        -  "PositionPercentChange",
        -  "PortfolioValue",
        -  "RebalanceDecisionMetric",
        -  "Value",
        -  "Price",
        -  "Plus",
        -  "Minus",
        -  "Multiply",
        -  "Divide",
        -  "Negative",
        -  "AbsoluteValue",
        -  "SquareRoot",
        -  "Max",
        -  "Min",
        -  "Day",
        -  "Month",
        -  "Date",
        -  "Year",
        -  "CurrentTimeSeconds",
        -  "CurrentTimeMinutes",
        -  "CurrentTimeHours",
        -  "TrailingSum",
        -  "CompoundAnnualGrowthRate",
        -  "Log",
        -  "Exponentiation",
        -  "SumOrderQuantity",
        -  "SumOrderAmount",
        -  "MinutesAfterOpen",
        -  "OpeningPrice",
        -  "PreviousClosingPrice",
        -  "HighOfDay",
        -  "LowOfDay",
        -  "MinutesUntilClose",
        -  "PriceChangeSinceOpen",
        -  "GapSize",
        -  "GapPercentage",
        -  "TrueRange",
        -  "AverageTrueRange",
        -  "Volume",
        -  "VWAP",
        -  "BullishFairValueGap",
        -  "BearishFairValueGap",
        -  "IndicatorAtMinutesAfterOpen",
        -  "IndicatorWindowAgo",
        -  "IndicatorAtEntry",
        -  "IsIndexMember",
        -  "PoliticalTrades",
        -  "InsiderTrades",
        -  "IsIndustry",
        -  "IsAssetType",
        -  "IsAsset",
        -  "IsNotAsset",
        -  "CrossAbove",
        -  "CrossBelow",
        -  "PositionMaxDrawdown",
        -  "PositionMaxDrawup",
        -  "UnderlyingMaxDrawdown",
        -  "ConsecutiveTrue",
        -  "CountTrue",
        -  "OptionPositionValue",
        -  "OptionPositionCount",
        -  "OptionPositionPercentChange",
        -  "OptionPositionMaxDrawdown",
        -  "OptionDaysToExpiration",
        -  "OptionDaysHeld",
        -  "OptionCollateral",
        -  "OptionSpreadCount",
        -  "OptionSpreadEntryPrice",
        -  "OptionUnrealizedPnL",
        -  "OptionRealizedPnL",
        -  "OptionRealizedPremium",
        -  "OptionGrossExposurePercent"
        -]New value: +[
        +  "DaysSinceAgent",
        +  "MinutesSinceAgent",
        +  "DaysSinceAlert",
        +  "MinutesSinceAlert",
        +  "StockReport",
        +  "DaysUntilEarnings",
        +  "DaysSinceEarnings",
        +  "ImpliedVolatility",
        +  "IVRank",
        +  "IVPercentile",
        +  "IVHVRatio",
        +  "LastOrderPrice",
        +  "Fundamental",
        +  "Economic",
        +  "CustomIndicator",
        +  "Index",
        +  "BollingerBand",
        +  "RelativeStrengthIndex",
        +  "MovingAverageConvergenceDivergence",
        +  "AverageDirectionalIndex",
        +  "RelativeVolume",
        +  "Stochastic",
        +  "CommodityChannelIndex",
        +  "WilliamsR",
        +  "MoneyFlowIndex",
        +  "OnBalanceVolume",
        +  "AccumulationDistribution",
        +  "ChaikinMoneyFlow",
        +  "DonchianChannel",
        +  "KeltnerChannel",
        +  "Supertrend",
        +  "IchimokuCloud",
        +  "ParabolicSar",
        +  "PriceMeanAbsoluteDeviation",
        +  "ExponentialMovingAverage",
        +  "SimpleMovingAverage",
        +  "PriceStandardDeviation",
        +  "PriceRateOfChange",
        +  "MaxDrawdown",
        +  "MaxDrawup",
        +  "MinimumPrice",
        +  "MaximumPrice",
        +  "IndicatorMeanAbsoluteDeviation",
        +  "IndicatorExponentialMovingAverage",
        +  "IndicatorSimpleMovingAverage",
        +  "IndicatorStandardDeviation",
        +  "IndicatorRateOfChange",
        +  "DaysSinceOrder",
        +  "DaysSinceOptionOrder",
        +  "DaysSinceStrategyFired",
        +  "DaysSinceLastRebalanceOptionOrder",
        +  "MinutesSinceOptionOrder",
        +  "MinutesSinceOrder",
        +  "DaysSinceTransaction",
        +  "InitialValue",
        +  "BuyingPower",
        +  "PositionValue",
        +  "PositionPercentChange",
        +  "PortfolioValue",
        +  "RebalanceDecisionMetric",
        +  "Value",
        +  "Price",
        +  "Plus",
        +  "Minus",
        +  "Multiply",
        +  "Divide",
        +  "Negative",
        +  "AbsoluteValue",
        +  "SquareRoot",
        +  "Max",
        +  "Min",
        +  "Day",
        +  "Month",
        +  "Date",
        +  "Year",
        +  "CurrentTimeSeconds",
        +  "CurrentTimeMinutes",
        +  "CurrentTimeHours",
        +  "TrailingSum",
        +  "CompoundAnnualGrowthRate",
        +  "Log",
        +  "Exponentiation",
        +  "SumOrderQuantity",
        +  "SumOrderAmount",
        +  "MinutesAfterOpen",
        +  "OpeningPrice",
        +  "PreviousClosingPrice",
        +  "HighOfDay",
        +  "LowOfDay",
        +  "MinutesUntilClose",
        +  "PriceChangeSinceOpen",
        +  "GapSize",
        +  "GapPercentage",
        +  "TrueRange",
        +  "AverageTrueRange",
        +  "Volume",
        +  "VWAP",
        +  "BullishFairValueGap",
        +  "BearishFairValueGap",
        +  "IndicatorAtMinutesAfterOpen",
        +  "IndicatorWindowAgo",
        +  "IndicatorAtEntry",
        +  "IsIndexMember",
        +  "PoliticalTrades",
        +  "InsiderTrades",
        +  "IsIndustry",
        +  "IsAssetType",
        +  "IsAsset",
        +  "IsNotAsset",
        +  "CrossAbove",
        +  "CrossBelow",
        +  "Correlation",
        +  "PositionMaxDrawdown",
        +  "PositionMaxDrawup",
        +  "UnderlyingMaxDrawdown",
        +  "ConsecutiveTrue",
        +  "CountTrue",
        +  "OptionPositionValue",
        +  "OptionPositionCount",
        +  "OptionPositionPercentChange",
        +  "OptionPositionMaxDrawdown",
        +  "OptionDaysToExpiration",
        +  "OptionDaysHeld",
        +  "OptionCollateral",
        +  "OptionSpreadCount",
        +  "OptionSpreadEntryPrice",
        +  "OptionUnrealizedPnL",
        +  "OptionRealizedPnL",
        +  "OptionRealizedPremium",
        +  "OptionGrossExposurePercent"
        +]
    • Changedupdate_portfolio2 fields changed
      • changedInput schema / $defs / indicator / description
        Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), MovingAverageConvergenceDivergence (MACD; needs targetAsset; optional fastLength/slowLength/signalLength defaulting to 12/26/9 with slowLength > fastLength, interval Day|Hour|Minute default Day, and line macd|signal|histogram selecting which of the three MACD outputs to emit), AverageDirectionalIndex (Wilder ADX trend-strength system 0-100; needs targetAsset+window; optional line adx|plusDi|minusDi — ADX measures strength, +DI/-DI direction), RelativeVolume (RVOL; needs targetAsset+window; current bar volume divided by the mean volume of the trailing N completed bars, ~1.0 is its recent pace), TrueRange/AverageTrueRange (need targetAsset; ATR also window), VWAP (needs targetAsset; resets each trading day), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), MovingAverageConvergenceDivergence (MACD; needs targetAsset; optional fastLength/slowLength/signalLength defaulting to 12/26/9 with slowLength > fastLength, interval Day|Hour|Minute default Day, and line macd|signal|histogram selecting which of the three MACD outputs to emit), AverageDirectionalIndex (Wilder ADX trend-strength system 0-100; needs targetAsset+window; optional line adx|plusDi|minusDi — ADX measures strength, +DI/-DI direction), RelativeVolume (RVOL; needs targetAsset+window; current bar volume divided by the mean volume of the trailing N completed bars, ~1.0 is its recent pace), Stochastic (needs targetAsset+window; optional smoothK/smoothD defaulting to 3/3 and line k|d), CommodityChannelIndex (CCI; needs targetAsset+window; optional constant defaulting to 0.015), WilliamsR (needs targetAsset+window; −100 to 0 scale), MoneyFlowIndex (MFI; needs targetAsset+window; volume-weighted 0-100), OnBalanceVolume (OBV; needs targetAsset; optional interval default Day), AccumulationDistribution (ADL; needs targetAsset; optional interval default Day), ChaikinMoneyFlow (CMF; needs targetAsset+window; −1 to +1 scale), DonchianChannel (needs targetAsset+window; optional line upper|lower|middle default upper), KeltnerChannel (needs targetAsset+window; optional multiplier default 2 and line upper|middle|lower default middle), Supertrend (needs targetAsset+window; optional multiplier default 3 and line value|direction default value, direction reads +1 up / −1 down), IchimokuCloud (needs targetAsset+window; optional spanLength default 52 and line tenkan|kijun|senkouA|senkouB|chikou default tenkan; lines unshifted), ParabolicSar (needs targetAsset; optional interval default Day, step default 0.02, maximum default 0.2), TrueRange/AverageTrueRange (need targetAsset; ATR also window), VWAP (needs targetAsset; resets each trading day), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), Correlation (rolling Pearson of two sub-indicators' returns; needs 2 sub-indicators + window with length >= 2), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
      • changedInput schema / $defs / indicator / properties / type / enum
        Previous value: -[
        -  "DaysSinceAgent",
        -  "MinutesSinceAgent",
        -  "DaysSinceAlert",
        -  "MinutesSinceAlert",
        -  "StockReport",
        -  "DaysUntilEarnings",
        -  "DaysSinceEarnings",
        -  "ImpliedVolatility",
        -  "IVRank",
        -  "IVPercentile",
        -  "IVHVRatio",
        -  "LastOrderPrice",
        -  "Fundamental",
        -  "Economic",
        -  "CustomIndicator",
        -  "Index",
        -  "BollingerBand",
        -  "RelativeStrengthIndex",
        -  "MovingAverageConvergenceDivergence",
        -  "AverageDirectionalIndex",
        -  "RelativeVolume",
        -  "PriceMeanAbsoluteDeviation",
        -  "ExponentialMovingAverage",
        -  "SimpleMovingAverage",
        -  "PriceStandardDeviation",
        -  "PriceRateOfChange",
        -  "MaxDrawdown",
        -  "MaxDrawup",
        -  "MinimumPrice",
        -  "MaximumPrice",
        -  "IndicatorMeanAbsoluteDeviation",
        -  "IndicatorExponentialMovingAverage",
        -  "IndicatorSimpleMovingAverage",
        -  "IndicatorStandardDeviation",
        -  "IndicatorRateOfChange",
        -  "DaysSinceOrder",
        -  "DaysSinceOptionOrder",
        -  "DaysSinceStrategyFired",
        -  "DaysSinceLastRebalanceOptionOrder",
        -  "MinutesSinceOptionOrder",
        -  "MinutesSinceOrder",
        -  "DaysSinceTransaction",
        -  "InitialValue",
        -  "BuyingPower",
        -  "PositionValue",
        -  "PositionPercentChange",
        -  "PortfolioValue",
        -  "RebalanceDecisionMetric",
        -  "Value",
        -  "Price",
        -  "Plus",
        -  "Minus",
        -  "Multiply",
        -  "Divide",
        -  "Negative",
        -  "AbsoluteValue",
        -  "SquareRoot",
        -  "Max",
        -  "Min",
        -  "Day",
        -  "Month",
        -  "Date",
        -  "Year",
        -  "CurrentTimeSeconds",
        -  "CurrentTimeMinutes",
        -  "CurrentTimeHours",
        -  "TrailingSum",
        -  "CompoundAnnualGrowthRate",
        -  "Log",
        -  "Exponentiation",
        -  "SumOrderQuantity",
        -  "SumOrderAmount",
        -  "MinutesAfterOpen",
        -  "OpeningPrice",
        -  "PreviousClosingPrice",
        -  "HighOfDay",
        -  "LowOfDay",
        -  "MinutesUntilClose",
        -  "PriceChangeSinceOpen",
        -  "GapSize",
        -  "GapPercentage",
        -  "TrueRange",
        -  "AverageTrueRange",
        -  "Volume",
        -  "VWAP",
        -  "BullishFairValueGap",
        -  "BearishFairValueGap",
        -  "IndicatorAtMinutesAfterOpen",
        -  "IndicatorWindowAgo",
        -  "IndicatorAtEntry",
        -  "IsIndexMember",
        -  "PoliticalTrades",
        -  "InsiderTrades",
        -  "IsIndustry",
        -  "IsAssetType",
        -  "IsAsset",
        -  "IsNotAsset",
        -  "CrossAbove",
        -  "CrossBelow",
        -  "PositionMaxDrawdown",
        -  "PositionMaxDrawup",
        -  "UnderlyingMaxDrawdown",
        -  "ConsecutiveTrue",
        -  "CountTrue",
        -  "OptionPositionValue",
        -  "OptionPositionCount",
        -  "OptionPositionPercentChange",
        -  "OptionPositionMaxDrawdown",
        -  "OptionDaysToExpiration",
        -  "OptionDaysHeld",
        -  "OptionCollateral",
        -  "OptionSpreadCount",
        -  "OptionSpreadEntryPrice",
        -  "OptionUnrealizedPnL",
        -  "OptionRealizedPnL",
        -  "OptionRealizedPremium",
        -  "OptionGrossExposurePercent"
        -]New value: +[
        +  "DaysSinceAgent",
        +  "MinutesSinceAgent",
        +  "DaysSinceAlert",
        +  "MinutesSinceAlert",
        +  "StockReport",
        +  "DaysUntilEarnings",
        +  "DaysSinceEarnings",
        +  "ImpliedVolatility",
        +  "IVRank",
        +  "IVPercentile",
        +  "IVHVRatio",
        +  "LastOrderPrice",
        +  "Fundamental",
        +  "Economic",
        +  "CustomIndicator",
        +  "Index",
        +  "BollingerBand",
        +  "RelativeStrengthIndex",
        +  "MovingAverageConvergenceDivergence",
        +  "AverageDirectionalIndex",
        +  "RelativeVolume",
        +  "Stochastic",
        +  "CommodityChannelIndex",
        +  "WilliamsR",
        +  "MoneyFlowIndex",
        +  "OnBalanceVolume",
        +  "AccumulationDistribution",
        +  "ChaikinMoneyFlow",
        +  "DonchianChannel",
        +  "KeltnerChannel",
        +  "Supertrend",
        +  "IchimokuCloud",
        +  "ParabolicSar",
        +  "PriceMeanAbsoluteDeviation",
        +  "ExponentialMovingAverage",
        +  "SimpleMovingAverage",
        +  "PriceStandardDeviation",
        +  "PriceRateOfChange",
        +  "MaxDrawdown",
        +  "MaxDrawup",
        +  "MinimumPrice",
        +  "MaximumPrice",
        +  "IndicatorMeanAbsoluteDeviation",
        +  "IndicatorExponentialMovingAverage",
        +  "IndicatorSimpleMovingAverage",
        +  "IndicatorStandardDeviation",
        +  "IndicatorRateOfChange",
        +  "DaysSinceOrder",
        +  "DaysSinceOptionOrder",
        +  "DaysSinceStrategyFired",
        +  "DaysSinceLastRebalanceOptionOrder",
        +  "MinutesSinceOptionOrder",
        +  "MinutesSinceOrder",
        +  "DaysSinceTransaction",
        +  "InitialValue",
        +  "BuyingPower",
        +  "PositionValue",
        +  "PositionPercentChange",
        +  "PortfolioValue",
        +  "RebalanceDecisionMetric",
        +  "Value",
        +  "Price",
        +  "Plus",
        +  "Minus",
        +  "Multiply",
        +  "Divide",
        +  "Negative",
        +  "AbsoluteValue",
        +  "SquareRoot",
        +  "Max",
        +  "Min",
        +  "Day",
        +  "Month",
        +  "Date",
        +  "Year",
        +  "CurrentTimeSeconds",
        +  "CurrentTimeMinutes",
        +  "CurrentTimeHours",
        +  "TrailingSum",
        +  "CompoundAnnualGrowthRate",
        +  "Log",
        +  "Exponentiation",
        +  "SumOrderQuantity",
        +  "SumOrderAmount",
        +  "MinutesAfterOpen",
        +  "OpeningPrice",
        +  "PreviousClosingPrice",
        +  "HighOfDay",
        +  "LowOfDay",
        +  "MinutesUntilClose",
        +  "PriceChangeSinceOpen",
        +  "GapSize",
        +  "GapPercentage",
        +  "TrueRange",
        +  "AverageTrueRange",
        +  "Volume",
        +  "VWAP",
        +  "BullishFairValueGap",
        +  "BearishFairValueGap",
        +  "IndicatorAtMinutesAfterOpen",
        +  "IndicatorWindowAgo",
        +  "IndicatorAtEntry",
        +  "IsIndexMember",
        +  "PoliticalTrades",
        +  "InsiderTrades",
        +  "IsIndustry",
        +  "IsAssetType",
        +  "IsAsset",
        +  "IsNotAsset",
        +  "CrossAbove",
        +  "CrossBelow",
        +  "Correlation",
        +  "PositionMaxDrawdown",
        +  "PositionMaxDrawup",
        +  "UnderlyingMaxDrawdown",
        +  "ConsecutiveTrue",
        +  "CountTrue",
        +  "OptionPositionValue",
        +  "OptionPositionCount",
        +  "OptionPositionPercentChange",
        +  "OptionPositionMaxDrawdown",
        +  "OptionDaysToExpiration",
        +  "OptionDaysHeld",
        +  "OptionCollateral",
        +  "OptionSpreadCount",
        +  "OptionSpreadEntryPrice",
        +  "OptionUnrealizedPnL",
        +  "OptionRealizedPnL",
        +  "OptionRealizedPremium",
        +  "OptionGrossExposurePercent"
        +]
  2. 3 tool updates
    • Changedbuild_portfolio2 fields changed
      • changedInput schema / $defs / indicator / description
        Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), MovingAverageConvergenceDivergence (MACD; needs targetAsset; optional fastLength/slowLength/signalLength defaulting to 12/26/9 with slowLength > fastLength, interval Day|Hour|Minute default Day, and line macd|signal|histogram selecting which of the three MACD outputs to emit), AverageDirectionalIndex (Wilder ADX trend-strength system 0-100; needs targetAsset+window; optional line adx|plusDi|minusDi — ADX measures strength, +DI/-DI direction), RelativeVolume (RVOL; needs targetAsset+window; current bar volume divided by the mean volume of the trailing N completed bars, ~1.0 is its recent pace), TrueRange/AverageTrueRange (need targetAsset; ATR also window), VWAP (needs targetAsset; resets each trading day), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
      • changedInput schema / $defs / indicator / properties / type / enum
        Previous value: -[
        -  "DaysSinceAgent",
        -  "MinutesSinceAgent",
        -  "DaysSinceAlert",
        -  "MinutesSinceAlert",
        -  "StockReport",
        -  "DaysUntilEarnings",
        -  "DaysSinceEarnings",
        -  "ImpliedVolatility",
        -  "IVRank",
        -  "IVPercentile",
        -  "IVHVRatio",
        -  "LastOrderPrice",
        -  "Fundamental",
        -  "Economic",
        -  "CustomIndicator",
        -  "Index",
        -  "BollingerBand",
        -  "RelativeStrengthIndex",
        -  "PriceMeanAbsoluteDeviation",
        -  "ExponentialMovingAverage",
        -  "SimpleMovingAverage",
        -  "PriceStandardDeviation",
        -  "PriceRateOfChange",
        -  "MaxDrawdown",
        -  "MaxDrawup",
        -  "MinimumPrice",
        -  "MaximumPrice",
        -  "IndicatorMeanAbsoluteDeviation",
        -  "IndicatorExponentialMovingAverage",
        -  "IndicatorSimpleMovingAverage",
        -  "IndicatorStandardDeviation",
        -  "IndicatorRateOfChange",
        -  "DaysSinceOrder",
        -  "DaysSinceOptionOrder",
        -  "DaysSinceStrategyFired",
        -  "DaysSinceLastRebalanceOptionOrder",
        -  "MinutesSinceOptionOrder",
        -  "MinutesSinceOrder",
        -  "DaysSinceTransaction",
        -  "InitialValue",
        -  "BuyingPower",
        -  "PositionValue",
        -  "PositionPercentChange",
        -  "PortfolioValue",
        -  "RebalanceDecisionMetric",
        -  "Value",
        -  "Price",
        -  "Plus",
        -  "Minus",
        -  "Multiply",
        -  "Divide",
        -  "Negative",
        -  "AbsoluteValue",
        -  "SquareRoot",
        -  "Max",
        -  "Min",
        -  "Day",
        -  "Month",
        -  "Date",
        -  "Year",
        -  "CurrentTimeSeconds",
        -  "CurrentTimeMinutes",
        -  "CurrentTimeHours",
        -  "TrailingSum",
        -  "CompoundAnnualGrowthRate",
        -  "Log",
        -  "Exponentiation",
        -  "SumOrderQuantity",
        -  "SumOrderAmount",
        -  "MinutesAfterOpen",
        -  "OpeningPrice",
        -  "PreviousClosingPrice",
        -  "HighOfDay",
        -  "LowOfDay",
        -  "MinutesUntilClose",
        -  "PriceChangeSinceOpen",
        -  "GapSize",
        -  "GapPercentage",
        -  "TrueRange",
        -  "AverageTrueRange",
        -  "Volume",
        -  "VWAP",
        -  "BullishFairValueGap",
        -  "BearishFairValueGap",
        -  "IndicatorAtMinutesAfterOpen",
        -  "IndicatorWindowAgo",
        -  "IndicatorAtEntry",
        -  "IsIndexMember",
        -  "PoliticalTrades",
        -  "InsiderTrades",
        -  "IsIndustry",
        -  "IsAssetType",
        -  "IsAsset",
        -  "IsNotAsset",
        -  "CrossAbove",
        -  "CrossBelow",
        -  "PositionMaxDrawdown",
        -  "PositionMaxDrawup",
        -  "UnderlyingMaxDrawdown",
        -  "ConsecutiveTrue",
        -  "CountTrue",
        -  "OptionPositionValue",
        -  "OptionPositionCount",
        -  "OptionPositionPercentChange",
        -  "OptionPositionMaxDrawdown",
        -  "OptionDaysToExpiration",
        -  "OptionDaysHeld",
        -  "OptionCollateral",
        -  "OptionSpreadCount",
        -  "OptionSpreadEntryPrice",
        -  "OptionUnrealizedPnL",
        -  "OptionRealizedPnL",
        -  "OptionRealizedPremium",
        -  "OptionGrossExposurePercent"
        -]New value: +[
        +  "DaysSinceAgent",
        +  "MinutesSinceAgent",
        +  "DaysSinceAlert",
        +  "MinutesSinceAlert",
        +  "StockReport",
        +  "DaysUntilEarnings",
        +  "DaysSinceEarnings",
        +  "ImpliedVolatility",
        +  "IVRank",
        +  "IVPercentile",
        +  "IVHVRatio",
        +  "LastOrderPrice",
        +  "Fundamental",
        +  "Economic",
        +  "CustomIndicator",
        +  "Index",
        +  "BollingerBand",
        +  "RelativeStrengthIndex",
        +  "MovingAverageConvergenceDivergence",
        +  "AverageDirectionalIndex",
        +  "RelativeVolume",
        +  "PriceMeanAbsoluteDeviation",
        +  "ExponentialMovingAverage",
        +  "SimpleMovingAverage",
        +  "PriceStandardDeviation",
        +  "PriceRateOfChange",
        +  "MaxDrawdown",
        +  "MaxDrawup",
        +  "MinimumPrice",
        +  "MaximumPrice",
        +  "IndicatorMeanAbsoluteDeviation",
        +  "IndicatorExponentialMovingAverage",
        +  "IndicatorSimpleMovingAverage",
        +  "IndicatorStandardDeviation",
        +  "IndicatorRateOfChange",
        +  "DaysSinceOrder",
        +  "DaysSinceOptionOrder",
        +  "DaysSinceStrategyFired",
        +  "DaysSinceLastRebalanceOptionOrder",
        +  "MinutesSinceOptionOrder",
        +  "MinutesSinceOrder",
        +  "DaysSinceTransaction",
        +  "InitialValue",
        +  "BuyingPower",
        +  "PositionValue",
        +  "PositionPercentChange",
        +  "PortfolioValue",
        +  "RebalanceDecisionMetric",
        +  "Value",
        +  "Price",
        +  "Plus",
        +  "Minus",
        +  "Multiply",
        +  "Divide",
        +  "Negative",
        +  "AbsoluteValue",
        +  "SquareRoot",
        +  "Max",
        +  "Min",
        +  "Day",
        +  "Month",
        +  "Date",
        +  "Year",
        +  "CurrentTimeSeconds",
        +  "CurrentTimeMinutes",
        +  "CurrentTimeHours",
        +  "TrailingSum",
        +  "CompoundAnnualGrowthRate",
        +  "Log",
        +  "Exponentiation",
        +  "SumOrderQuantity",
        +  "SumOrderAmount",
        +  "MinutesAfterOpen",
        +  "OpeningPrice",
        +  "PreviousClosingPrice",
        +  "HighOfDay",
        +  "LowOfDay",
        +  "MinutesUntilClose",
        +  "PriceChangeSinceOpen",
        +  "GapSize",
        +  "GapPercentage",
        +  "TrueRange",
        +  "AverageTrueRange",
        +  "Volume",
        +  "VWAP",
        +  "BullishFairValueGap",
        +  "BearishFairValueGap",
        +  "IndicatorAtMinutesAfterOpen",
        +  "IndicatorWindowAgo",
        +  "IndicatorAtEntry",
        +  "IsIndexMember",
        +  "PoliticalTrades",
        +  "InsiderTrades",
        +  "IsIndustry",
        +  "IsAssetType",
        +  "IsAsset",
        +  "IsNotAsset",
        +  "CrossAbove",
        +  "CrossBelow",
        +  "PositionMaxDrawdown",
        +  "PositionMaxDrawup",
        +  "UnderlyingMaxDrawdown",
        +  "ConsecutiveTrue",
        +  "CountTrue",
        +  "OptionPositionValue",
        +  "OptionPositionCount",
        +  "OptionPositionPercentChange",
        +  "OptionPositionMaxDrawdown",
        +  "OptionDaysToExpiration",
        +  "OptionDaysHeld",
        +  "OptionCollateral",
        +  "OptionSpreadCount",
        +  "OptionSpreadEntryPrice",
        +  "OptionUnrealizedPnL",
        +  "OptionRealizedPnL",
        +  "OptionRealizedPremium",
        +  "OptionGrossExposurePercent"
        +]
    • Changedcreate_portfolio2 fields changed
      • changedInput schema / $defs / indicator / description
        Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), MovingAverageConvergenceDivergence (MACD; needs targetAsset; optional fastLength/slowLength/signalLength defaulting to 12/26/9 with slowLength > fastLength, interval Day|Hour|Minute default Day, and line macd|signal|histogram selecting which of the three MACD outputs to emit), AverageDirectionalIndex (Wilder ADX trend-strength system 0-100; needs targetAsset+window; optional line adx|plusDi|minusDi — ADX measures strength, +DI/-DI direction), RelativeVolume (RVOL; needs targetAsset+window; current bar volume divided by the mean volume of the trailing N completed bars, ~1.0 is its recent pace), TrueRange/AverageTrueRange (need targetAsset; ATR also window), VWAP (needs targetAsset; resets each trading day), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
      • changedInput schema / $defs / indicator / properties / type / enum
        Previous value: -[
        -  "DaysSinceAgent",
        -  "MinutesSinceAgent",
        -  "DaysSinceAlert",
        -  "MinutesSinceAlert",
        -  "StockReport",
        -  "DaysUntilEarnings",
        -  "DaysSinceEarnings",
        -  "ImpliedVolatility",
        -  "IVRank",
        -  "IVPercentile",
        -  "IVHVRatio",
        -  "LastOrderPrice",
        -  "Fundamental",
        -  "Economic",
        -  "CustomIndicator",
        -  "Index",
        -  "BollingerBand",
        -  "RelativeStrengthIndex",
        -  "PriceMeanAbsoluteDeviation",
        -  "ExponentialMovingAverage",
        -  "SimpleMovingAverage",
        -  "PriceStandardDeviation",
        -  "PriceRateOfChange",
        -  "MaxDrawdown",
        -  "MaxDrawup",
        -  "MinimumPrice",
        -  "MaximumPrice",
        -  "IndicatorMeanAbsoluteDeviation",
        -  "IndicatorExponentialMovingAverage",
        -  "IndicatorSimpleMovingAverage",
        -  "IndicatorStandardDeviation",
        -  "IndicatorRateOfChange",
        -  "DaysSinceOrder",
        -  "DaysSinceOptionOrder",
        -  "DaysSinceStrategyFired",
        -  "DaysSinceLastRebalanceOptionOrder",
        -  "MinutesSinceOptionOrder",
        -  "MinutesSinceOrder",
        -  "DaysSinceTransaction",
        -  "InitialValue",
        -  "BuyingPower",
        -  "PositionValue",
        -  "PositionPercentChange",
        -  "PortfolioValue",
        -  "RebalanceDecisionMetric",
        -  "Value",
        -  "Price",
        -  "Plus",
        -  "Minus",
        -  "Multiply",
        -  "Divide",
        -  "Negative",
        -  "AbsoluteValue",
        -  "SquareRoot",
        -  "Max",
        -  "Min",
        -  "Day",
        -  "Month",
        -  "Date",
        -  "Year",
        -  "CurrentTimeSeconds",
        -  "CurrentTimeMinutes",
        -  "CurrentTimeHours",
        -  "TrailingSum",
        -  "CompoundAnnualGrowthRate",
        -  "Log",
        -  "Exponentiation",
        -  "SumOrderQuantity",
        -  "SumOrderAmount",
        -  "MinutesAfterOpen",
        -  "OpeningPrice",
        -  "PreviousClosingPrice",
        -  "HighOfDay",
        -  "LowOfDay",
        -  "MinutesUntilClose",
        -  "PriceChangeSinceOpen",
        -  "GapSize",
        -  "GapPercentage",
        -  "TrueRange",
        -  "AverageTrueRange",
        -  "Volume",
        -  "VWAP",
        -  "BullishFairValueGap",
        -  "BearishFairValueGap",
        -  "IndicatorAtMinutesAfterOpen",
        -  "IndicatorWindowAgo",
        -  "IndicatorAtEntry",
        -  "IsIndexMember",
        -  "PoliticalTrades",
        -  "InsiderTrades",
        -  "IsIndustry",
        -  "IsAssetType",
        -  "IsAsset",
        -  "IsNotAsset",
        -  "CrossAbove",
        -  "CrossBelow",
        -  "PositionMaxDrawdown",
        -  "PositionMaxDrawup",
        -  "UnderlyingMaxDrawdown",
        -  "ConsecutiveTrue",
        -  "CountTrue",
        -  "OptionPositionValue",
        -  "OptionPositionCount",
        -  "OptionPositionPercentChange",
        -  "OptionPositionMaxDrawdown",
        -  "OptionDaysToExpiration",
        -  "OptionDaysHeld",
        -  "OptionCollateral",
        -  "OptionSpreadCount",
        -  "OptionSpreadEntryPrice",
        -  "OptionUnrealizedPnL",
        -  "OptionRealizedPnL",
        -  "OptionRealizedPremium",
        -  "OptionGrossExposurePercent"
        -]New value: +[
        +  "DaysSinceAgent",
        +  "MinutesSinceAgent",
        +  "DaysSinceAlert",
        +  "MinutesSinceAlert",
        +  "StockReport",
        +  "DaysUntilEarnings",
        +  "DaysSinceEarnings",
        +  "ImpliedVolatility",
        +  "IVRank",
        +  "IVPercentile",
        +  "IVHVRatio",
        +  "LastOrderPrice",
        +  "Fundamental",
        +  "Economic",
        +  "CustomIndicator",
        +  "Index",
        +  "BollingerBand",
        +  "RelativeStrengthIndex",
        +  "MovingAverageConvergenceDivergence",
        +  "AverageDirectionalIndex",
        +  "RelativeVolume",
        +  "PriceMeanAbsoluteDeviation",
        +  "ExponentialMovingAverage",
        +  "SimpleMovingAverage",
        +  "PriceStandardDeviation",
        +  "PriceRateOfChange",
        +  "MaxDrawdown",
        +  "MaxDrawup",
        +  "MinimumPrice",
        +  "MaximumPrice",
        +  "IndicatorMeanAbsoluteDeviation",
        +  "IndicatorExponentialMovingAverage",
        +  "IndicatorSimpleMovingAverage",
        +  "IndicatorStandardDeviation",
        +  "IndicatorRateOfChange",
        +  "DaysSinceOrder",
        +  "DaysSinceOptionOrder",
        +  "DaysSinceStrategyFired",
        +  "DaysSinceLastRebalanceOptionOrder",
        +  "MinutesSinceOptionOrder",
        +  "MinutesSinceOrder",
        +  "DaysSinceTransaction",
        +  "InitialValue",
        +  "BuyingPower",
        +  "PositionValue",
        +  "PositionPercentChange",
        +  "PortfolioValue",
        +  "RebalanceDecisionMetric",
        +  "Value",
        +  "Price",
        +  "Plus",
        +  "Minus",
        +  "Multiply",
        +  "Divide",
        +  "Negative",
        +  "AbsoluteValue",
        +  "SquareRoot",
        +  "Max",
        +  "Min",
        +  "Day",
        +  "Month",
        +  "Date",
        +  "Year",
        +  "CurrentTimeSeconds",
        +  "CurrentTimeMinutes",
        +  "CurrentTimeHours",
        +  "TrailingSum",
        +  "CompoundAnnualGrowthRate",
        +  "Log",
        +  "Exponentiation",
        +  "SumOrderQuantity",
        +  "SumOrderAmount",
        +  "MinutesAfterOpen",
        +  "OpeningPrice",
        +  "PreviousClosingPrice",
        +  "HighOfDay",
        +  "LowOfDay",
        +  "MinutesUntilClose",
        +  "PriceChangeSinceOpen",
        +  "GapSize",
        +  "GapPercentage",
        +  "TrueRange",
        +  "AverageTrueRange",
        +  "Volume",
        +  "VWAP",
        +  "BullishFairValueGap",
        +  "BearishFairValueGap",
        +  "IndicatorAtMinutesAfterOpen",
        +  "IndicatorWindowAgo",
        +  "IndicatorAtEntry",
        +  "IsIndexMember",
        +  "PoliticalTrades",
        +  "InsiderTrades",
        +  "IsIndustry",
        +  "IsAssetType",
        +  "IsAsset",
        +  "IsNotAsset",
        +  "CrossAbove",
        +  "CrossBelow",
        +  "PositionMaxDrawdown",
        +  "PositionMaxDrawup",
        +  "UnderlyingMaxDrawdown",
        +  "ConsecutiveTrue",
        +  "CountTrue",
        +  "OptionPositionValue",
        +  "OptionPositionCount",
        +  "OptionPositionPercentChange",
        +  "OptionPositionMaxDrawdown",
        +  "OptionDaysToExpiration",
        +  "OptionDaysHeld",
        +  "OptionCollateral",
        +  "OptionSpreadCount",
        +  "OptionSpreadEntryPrice",
        +  "OptionUnrealizedPnL",
        +  "OptionRealizedPnL",
        +  "OptionRealizedPremium",
        +  "OptionGrossExposurePercent"
        +]
    • Changedupdate_portfolio2 fields changed
      • changedInput schema / $defs / indicator / description
        Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), MovingAverageConvergenceDivergence (MACD; needs targetAsset; optional fastLength/slowLength/signalLength defaulting to 12/26/9 with slowLength > fastLength, interval Day|Hour|Minute default Day, and line macd|signal|histogram selecting which of the three MACD outputs to emit), AverageDirectionalIndex (Wilder ADX trend-strength system 0-100; needs targetAsset+window; optional line adx|plusDi|minusDi — ADX measures strength, +DI/-DI direction), RelativeVolume (RVOL; needs targetAsset+window; current bar volume divided by the mean volume of the trailing N completed bars, ~1.0 is its recent pace), TrueRange/AverageTrueRange (need targetAsset; ATR also window), VWAP (needs targetAsset; resets each trading day), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
      • changedInput schema / $defs / indicator / properties / type / enum
        Previous value: -[
        -  "DaysSinceAgent",
        -  "MinutesSinceAgent",
        -  "DaysSinceAlert",
        -  "MinutesSinceAlert",
        -  "StockReport",
        -  "DaysUntilEarnings",
        -  "DaysSinceEarnings",
        -  "ImpliedVolatility",
        -  "IVRank",
        -  "IVPercentile",
        -  "IVHVRatio",
        -  "LastOrderPrice",
        -  "Fundamental",
        -  "Economic",
        -  "CustomIndicator",
        -  "Index",
        -  "BollingerBand",
        -  "RelativeStrengthIndex",
        -  "PriceMeanAbsoluteDeviation",
        -  "ExponentialMovingAverage",
        -  "SimpleMovingAverage",
        -  "PriceStandardDeviation",
        -  "PriceRateOfChange",
        -  "MaxDrawdown",
        -  "MaxDrawup",
        -  "MinimumPrice",
        -  "MaximumPrice",
        -  "IndicatorMeanAbsoluteDeviation",
        -  "IndicatorExponentialMovingAverage",
        -  "IndicatorSimpleMovingAverage",
        -  "IndicatorStandardDeviation",
        -  "IndicatorRateOfChange",
        -  "DaysSinceOrder",
        -  "DaysSinceOptionOrder",
        -  "DaysSinceStrategyFired",
        -  "DaysSinceLastRebalanceOptionOrder",
        -  "MinutesSinceOptionOrder",
        -  "MinutesSinceOrder",
        -  "DaysSinceTransaction",
        -  "InitialValue",
        -  "BuyingPower",
        -  "PositionValue",
        -  "PositionPercentChange",
        -  "PortfolioValue",
        -  "RebalanceDecisionMetric",
        -  "Value",
        -  "Price",
        -  "Plus",
        -  "Minus",
        -  "Multiply",
        -  "Divide",
        -  "Negative",
        -  "AbsoluteValue",
        -  "SquareRoot",
        -  "Max",
        -  "Min",
        -  "Day",
        -  "Month",
        -  "Date",
        -  "Year",
        -  "CurrentTimeSeconds",
        -  "CurrentTimeMinutes",
        -  "CurrentTimeHours",
        -  "TrailingSum",
        -  "CompoundAnnualGrowthRate",
        -  "Log",
        -  "Exponentiation",
        -  "SumOrderQuantity",
        -  "SumOrderAmount",
        -  "MinutesAfterOpen",
        -  "OpeningPrice",
        -  "PreviousClosingPrice",
        -  "HighOfDay",
        -  "LowOfDay",
        -  "MinutesUntilClose",
        -  "PriceChangeSinceOpen",
        -  "GapSize",
        -  "GapPercentage",
        -  "TrueRange",
        -  "AverageTrueRange",
        -  "Volume",
        -  "VWAP",
        -  "BullishFairValueGap",
        -  "BearishFairValueGap",
        -  "IndicatorAtMinutesAfterOpen",
        -  "IndicatorWindowAgo",
        -  "IndicatorAtEntry",
        -  "IsIndexMember",
        -  "PoliticalTrades",
        -  "InsiderTrades",
        -  "IsIndustry",
        -  "IsAssetType",
        -  "IsAsset",
        -  "IsNotAsset",
        -  "CrossAbove",
        -  "CrossBelow",
        -  "PositionMaxDrawdown",
        -  "PositionMaxDrawup",
        -  "UnderlyingMaxDrawdown",
        -  "ConsecutiveTrue",
        -  "CountTrue",
        -  "OptionPositionValue",
        -  "OptionPositionCount",
        -  "OptionPositionPercentChange",
        -  "OptionPositionMaxDrawdown",
        -  "OptionDaysToExpiration",
        -  "OptionDaysHeld",
        -  "OptionCollateral",
        -  "OptionSpreadCount",
        -  "OptionSpreadEntryPrice",
        -  "OptionUnrealizedPnL",
        -  "OptionRealizedPnL",
        -  "OptionRealizedPremium",
        -  "OptionGrossExposurePercent"
        -]New value: +[
        +  "DaysSinceAgent",
        +  "MinutesSinceAgent",
        +  "DaysSinceAlert",
        +  "MinutesSinceAlert",
        +  "StockReport",
        +  "DaysUntilEarnings",
        +  "DaysSinceEarnings",
        +  "ImpliedVolatility",
        +  "IVRank",
        +  "IVPercentile",
        +  "IVHVRatio",
        +  "LastOrderPrice",
        +  "Fundamental",
        +  "Economic",
        +  "CustomIndicator",
        +  "Index",
        +  "BollingerBand",
        +  "RelativeStrengthIndex",
        +  "MovingAverageConvergenceDivergence",
        +  "AverageDirectionalIndex",
        +  "RelativeVolume",
        +  "PriceMeanAbsoluteDeviation",
        +  "ExponentialMovingAverage",
        +  "SimpleMovingAverage",
        +  "PriceStandardDeviation",
        +  "PriceRateOfChange",
        +  "MaxDrawdown",
        +  "MaxDrawup",
        +  "MinimumPrice",
        +  "MaximumPrice",
        +  "IndicatorMeanAbsoluteDeviation",
        +  "IndicatorExponentialMovingAverage",
        +  "IndicatorSimpleMovingAverage",
        +  "IndicatorStandardDeviation",
        +  "IndicatorRateOfChange",
        +  "DaysSinceOrder",
        +  "DaysSinceOptionOrder",
        +  "DaysSinceStrategyFired",
        +  "DaysSinceLastRebalanceOptionOrder",
        +  "MinutesSinceOptionOrder",
        +  "MinutesSinceOrder",
        +  "DaysSinceTransaction",
        +  "InitialValue",
        +  "BuyingPower",
        +  "PositionValue",
        +  "PositionPercentChange",
        +  "PortfolioValue",
        +  "RebalanceDecisionMetric",
        +  "Value",
        +  "Price",
        +  "Plus",
        +  "Minus",
        +  "Multiply",
        +  "Divide",
        +  "Negative",
        +  "AbsoluteValue",
        +  "SquareRoot",
        +  "Max",
        +  "Min",
        +  "Day",
        +  "Month",
        +  "Date",
        +  "Year",
        +  "CurrentTimeSeconds",
        +  "CurrentTimeMinutes",
        +  "CurrentTimeHours",
        +  "TrailingSum",
        +  "CompoundAnnualGrowthRate",
        +  "Log",
        +  "Exponentiation",
        +  "SumOrderQuantity",
        +  "SumOrderAmount",
        +  "MinutesAfterOpen",
        +  "OpeningPrice",
        +  "PreviousClosingPrice",
        +  "HighOfDay",
        +  "LowOfDay",
        +  "MinutesUntilClose",
        +  "PriceChangeSinceOpen",
        +  "GapSize",
        +  "GapPercentage",
        +  "TrueRange",
        +  "AverageTrueRange",
        +  "Volume",
        +  "VWAP",
        +  "BullishFairValueGap",
        +  "BearishFairValueGap",
        +  "IndicatorAtMinutesAfterOpen",
        +  "IndicatorWindowAgo",
        +  "IndicatorAtEntry",
        +  "IsIndexMember",
        +  "PoliticalTrades",
        +  "InsiderTrades",
        +  "IsIndustry",
        +  "IsAssetType",
        +  "IsAsset",
        +  "IsNotAsset",
        +  "CrossAbove",
        +  "CrossBelow",
        +  "PositionMaxDrawdown",
        +  "PositionMaxDrawup",
        +  "UnderlyingMaxDrawdown",
        +  "ConsecutiveTrue",
        +  "CountTrue",
        +  "OptionPositionValue",
        +  "OptionPositionCount",
        +  "OptionPositionPercentChange",
        +  "OptionPositionMaxDrawdown",
        +  "OptionDaysToExpiration",
        +  "OptionDaysHeld",
        +  "OptionCollateral",
        +  "OptionSpreadCount",
        +  "OptionSpreadEntryPrice",
        +  "OptionUnrealizedPnL",
        +  "OptionRealizedPnL",
        +  "OptionRealizedPremium",
        +  "OptionGrossExposurePercent"
        +]
  3. 3 tool updates
    • Changedbuild_portfolio7 fields changed
      • changedInput schema / $defs / indicator / description
        Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
      • addedInput schema / $defs / indicator / properties / amountBasis
        Added value: +{
        +  "description": "PoliticalTrades disclosed range endpoint. LowerBound is conservative.",
        +  "enum": [
        +    "LowerBound",
        +    "Midpoint",
        +    "UpperBound"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / $defs / indicator / properties / chamber
        Added value: +{
        +  "description": "PoliticalTrades optional cohort filter. All combines House and Senate.",
        +  "enum": [
        +    "All",
        +    "House",
        +    "Senate"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / $defs / indicator / properties / filer
        Added value: +{
        +  "description": "PoliticalTrades member full or last name; empty means all members.",
        +  "type": "string"
        +}
      • addedInput schema / $defs / indicator / properties / instrument
        Added value: +{
        +  "description": "PoliticalTrades instrument class. Equity excludes confirmed options.",
        +  "enum": [
        +    "Equity",
        +    "Option",
        +    "All"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / $defs / indicator / properties / metric / description
        Previous value: -"Fundamental/CompoundAnnualGrowthRate: financial metric (e.g. 'peRatio'). Economic: economic indicator (e.g. 'UNRATE'). Index: index symbol (e.g. 'VIX', 'SPX'). RebalanceDecisionMetric: allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit."New value: +"PoliticalTrades: NetAmount, BuyAmount, SellAmount, BuyCount, SellCount, DistinctBuyers. Fundamental/CompoundAnnualGrowthRate: financial metric (e.g. 'peRatio'). Economic: economic indicator (e.g. 'UNRATE'). Index: index symbol (e.g. 'VIX', 'SPX'). RebalanceDecisionMetric: allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit."
      • addedInput schema / $defs / indicator / properties / windowDays
        Added value: +{
        +  "description": "PoliticalTrades / InsiderTrades trailing calendar days.",
        +  "maximum": 3650,
        +  "minimum": 1,
        +  "type": "integer"
        +}
    • Changedcreate_portfolio7 fields changed
      • changedInput schema / $defs / indicator / description
        Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
      • addedInput schema / $defs / indicator / properties / amountBasis
        Added value: +{
        +  "description": "PoliticalTrades disclosed range endpoint. LowerBound is conservative.",
        +  "enum": [
        +    "LowerBound",
        +    "Midpoint",
        +    "UpperBound"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / $defs / indicator / properties / chamber
        Added value: +{
        +  "description": "PoliticalTrades optional cohort filter. All combines House and Senate.",
        +  "enum": [
        +    "All",
        +    "House",
        +    "Senate"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / $defs / indicator / properties / filer
        Added value: +{
        +  "description": "PoliticalTrades member full or last name; empty means all members.",
        +  "type": "string"
        +}
      • addedInput schema / $defs / indicator / properties / instrument
        Added value: +{
        +  "description": "PoliticalTrades instrument class. Equity excludes confirmed options.",
        +  "enum": [
        +    "Equity",
        +    "Option",
        +    "All"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / $defs / indicator / properties / metric / description
        Previous value: -"Fundamental/CompoundAnnualGrowthRate: financial metric (e.g. 'peRatio'). Economic: economic indicator (e.g. 'UNRATE'). Index: index symbol (e.g. 'VIX', 'SPX'). RebalanceDecisionMetric: allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit."New value: +"PoliticalTrades: NetAmount, BuyAmount, SellAmount, BuyCount, SellCount, DistinctBuyers. Fundamental/CompoundAnnualGrowthRate: financial metric (e.g. 'peRatio'). Economic: economic indicator (e.g. 'UNRATE'). Index: index symbol (e.g. 'VIX', 'SPX'). RebalanceDecisionMetric: allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit."
      • addedInput schema / $defs / indicator / properties / windowDays
        Added value: +{
        +  "description": "PoliticalTrades / InsiderTrades trailing calendar days.",
        +  "maximum": 3650,
        +  "minimum": 1,
        +  "type": "integer"
        +}
    • Changedupdate_portfolio7 fields changed
      • changedInput schema / $defs / indicator / description
        Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. PoliticalTrades needs targetAsset, filer, metric, windowDays, amountBasis, instrument, and chamber; House and Senate are unified, so use chamber All unless explicitly filtering. Equity excludes confirmed option disclosures. Amount metrics use disclosed ranges and default to conservative LowerBound. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
      • addedInput schema / $defs / indicator / properties / amountBasis
        Added value: +{
        +  "description": "PoliticalTrades disclosed range endpoint. LowerBound is conservative.",
        +  "enum": [
        +    "LowerBound",
        +    "Midpoint",
        +    "UpperBound"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / $defs / indicator / properties / chamber
        Added value: +{
        +  "description": "PoliticalTrades optional cohort filter. All combines House and Senate.",
        +  "enum": [
        +    "All",
        +    "House",
        +    "Senate"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / $defs / indicator / properties / filer
        Added value: +{
        +  "description": "PoliticalTrades member full or last name; empty means all members.",
        +  "type": "string"
        +}
      • addedInput schema / $defs / indicator / properties / instrument
        Added value: +{
        +  "description": "PoliticalTrades instrument class. Equity excludes confirmed options.",
        +  "enum": [
        +    "Equity",
        +    "Option",
        +    "All"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / $defs / indicator / properties / metric / description
        Previous value: -"Fundamental/CompoundAnnualGrowthRate: financial metric (e.g. 'peRatio'). Economic: economic indicator (e.g. 'UNRATE'). Index: index symbol (e.g. 'VIX', 'SPX'). RebalanceDecisionMetric: allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit."New value: +"PoliticalTrades: NetAmount, BuyAmount, SellAmount, BuyCount, SellCount, DistinctBuyers. Fundamental/CompoundAnnualGrowthRate: financial metric (e.g. 'peRatio'). Economic: economic indicator (e.g. 'UNRATE'). Index: index symbol (e.g. 'VIX', 'SPX'). RebalanceDecisionMetric: allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit."
      • addedInput schema / $defs / indicator / properties / windowDays
        Added value: +{
        +  "description": "PoliticalTrades / InsiderTrades trailing calendar days.",
        +  "maximum": 3650,
        +  "minimum": 1,
        +  "type": "integer"
        +}
  4. 3 tool updates
    • Changedbuild_portfolio11 fields changed
      • changedInput schema / $defs / indicator / description
        Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
      • changedInput schema / $defs / indicator / properties / type / enum
        Previous value: -[
        -  "DaysSinceAgent",
        -  "MinutesSinceAgent",
        -  "DaysSinceAlert",
        -  "MinutesSinceAlert",
        -  "StockReport",
        -  "DaysUntilEarnings",
        -  "DaysSinceEarnings",
        -  "ImpliedVolatility",
        -  "IVRank",
        -  "IVPercentile",
        -  "IVHVRatio",
        -  "LastOrderPrice",
        -  "Fundamental",
        -  "Economic",
        -  "CustomIndicator",
        -  "Index",
        -  "BollingerBand",
        -  "RelativeStrengthIndex",
        -  "PriceMeanAbsoluteDeviation",
        -  "ExponentialMovingAverage",
        -  "SimpleMovingAverage",
        -  "PriceStandardDeviation",
        -  "PriceRateOfChange",
        -  "MaxDrawdown",
        -  "MaxDrawup",
        -  "MinimumPrice",
        -  "MaximumPrice",
        -  "IndicatorMeanAbsoluteDeviation",
        -  "IndicatorExponentialMovingAverage",
        -  "IndicatorSimpleMovingAverage",
        -  "IndicatorStandardDeviation",
        -  "IndicatorRateOfChange",
        -  "DaysSinceOrder",
        -  "DaysSinceOptionOrder",
        -  "DaysSinceStrategyFired",
        -  "DaysSinceLastRebalanceOptionOrder",
        -  "MinutesSinceOptionOrder",
        -  "MinutesSinceOrder",
        -  "DaysSinceTransaction",
        -  "InitialValue",
        -  "BuyingPower",
        -  "PositionValue",
        -  "PositionPercentChange",
        -  "PortfolioValue",
        -  "RebalanceDecisionMetric",
        -  "Value",
        -  "Price",
        -  "Plus",
        -  "Minus",
        -  "Multiply",
        -  "Divide",
        -  "Negative",
        -  "AbsoluteValue",
        -  "SquareRoot",
        -  "Max",
        -  "Min",
        -  "Day",
        -  "Month",
        -  "Date",
        -  "Year",
        -  "CurrentTimeSeconds",
        -  "CurrentTimeMinutes",
        -  "CurrentTimeHours",
        -  "TrailingSum",
        -  "CompoundAnnualGrowthRate",
        -  "Log",
        -  "Exponentiation",
        -  "SumOrderQuantity",
        -  "SumOrderAmount",
        -  "MinutesAfterOpen",
        -  "OpeningPrice",
        -  "PreviousClosingPrice",
        -  "HighOfDay",
        -  "LowOfDay",
        -  "MinutesUntilClose",
        -  "PriceChangeSinceOpen",
        -  "GapSize",
        -  "GapPercentage",
        -  "TrueRange",
        -  "AverageTrueRange",
        -  "Volume",
        -  "VWAP",
        -  "BullishFairValueGap",
        -  "BearishFairValueGap",
        -  "IndicatorAtMinutesAfterOpen",
        -  "IndicatorWindowAgo",
        -  "IndicatorAtEntry",
        -  "IsIndexMember",
        -  "IsIndustry",
        -  "IsAssetType",
        -  "IsAsset",
        -  "IsNotAsset",
        -  "CrossAbove",
        -  "CrossBelow",
        -  "PositionMaxDrawdown",
        -  "PositionMaxDrawup",
        -  "UnderlyingMaxDrawdown",
        -  "ConsecutiveTrue",
        -  "CountTrue",
        -  "OptionPositionValue",
        -  "OptionPositionCount",
        -  "OptionPositionPercentChange",
        -  "OptionPositionMaxDrawdown",
        -  "OptionDaysToExpiration",
        -  "OptionDaysHeld",
        -  "OptionCollateral",
        -  "OptionSpreadCount",
        -  "OptionUnrealizedPnL",
        -  "OptionRealizedPnL",
        -  "OptionRealizedPremium",
        -  "OptionGrossExposurePercent"
        -]New value: +[
        +  "DaysSinceAgent",
        +  "MinutesSinceAgent",
        +  "DaysSinceAlert",
        +  "MinutesSinceAlert",
        +  "StockReport",
        +  "DaysUntilEarnings",
        +  "DaysSinceEarnings",
        +  "ImpliedVolatility",
        +  "IVRank",
        +  "IVPercentile",
        +  "IVHVRatio",
        +  "LastOrderPrice",
        +  "Fundamental",
        +  "Economic",
        +  "CustomIndicator",
        +  "Index",
        +  "BollingerBand",
        +  "RelativeStrengthIndex",
        +  "PriceMeanAbsoluteDeviation",
        +  "ExponentialMovingAverage",
        +  "SimpleMovingAverage",
        +  "PriceStandardDeviation",
        +  "PriceRateOfChange",
        +  "MaxDrawdown",
        +  "MaxDrawup",
        +  "MinimumPrice",
        +  "MaximumPrice",
        +  "IndicatorMeanAbsoluteDeviation",
        +  "IndicatorExponentialMovingAverage",
        +  "IndicatorSimpleMovingAverage",
        +  "IndicatorStandardDeviation",
        +  "IndicatorRateOfChange",
        +  "DaysSinceOrder",
        +  "DaysSinceOptionOrder",
        +  "DaysSinceStrategyFired",
        +  "DaysSinceLastRebalanceOptionOrder",
        +  "MinutesSinceOptionOrder",
        +  "MinutesSinceOrder",
        +  "DaysSinceTransaction",
        +  "InitialValue",
        +  "BuyingPower",
        +  "PositionValue",
        +  "PositionPercentChange",
        +  "PortfolioValue",
        +  "RebalanceDecisionMetric",
        +  "Value",
        +  "Price",
        +  "Plus",
        +  "Minus",
        +  "Multiply",
        +  "Divide",
        +  "Negative",
        +  "AbsoluteValue",
        +  "SquareRoot",
        +  "Max",
        +  "Min",
        +  "Day",
        +  "Month",
        +  "Date",
        +  "Year",
        +  "CurrentTimeSeconds",
        +  "CurrentTimeMinutes",
        +  "CurrentTimeHours",
        +  "TrailingSum",
        +  "CompoundAnnualGrowthRate",
        +  "Log",
        +  "Exponentiation",
        +  "SumOrderQuantity",
        +  "SumOrderAmount",
        +  "MinutesAfterOpen",
        +  "OpeningPrice",
        +  "PreviousClosingPrice",
        +  "HighOfDay",
        +  "LowOfDay",
        +  "MinutesUntilClose",
        +  "PriceChangeSinceOpen",
        +  "GapSize",
        +  "GapPercentage",
        +  "TrueRange",
        +  "AverageTrueRange",
        +  "Volume",
        +  "VWAP",
        +  "BullishFairValueGap",
        +  "BearishFairValueGap",
        +  "IndicatorAtMinutesAfterOpen",
        +  "IndicatorWindowAgo",
        +  "IndicatorAtEntry",
        +  "IsIndexMember",
        +  "PoliticalTrades",
        +  "InsiderTrades",
        +  "IsIndustry",
        +  "IsAssetType",
        +  "IsAsset",
        +  "IsNotAsset",
        +  "CrossAbove",
        +  "CrossBelow",
        +  "PositionMaxDrawdown",
        +  "PositionMaxDrawup",
        +  "UnderlyingMaxDrawdown",
        +  "ConsecutiveTrue",
        +  "CountTrue",
        +  "OptionPositionValue",
        +  "OptionPositionCount",
        +  "OptionPositionPercentChange",
        +  "OptionPositionMaxDrawdown",
        +  "OptionDaysToExpiration",
        +  "OptionDaysHeld",
        +  "OptionCollateral",
        +  "OptionSpreadCount",
        +  "OptionSpreadEntryPrice",
        +  "OptionUnrealizedPnL",
        +  "OptionRealizedPnL",
        +  "OptionRealizedPremium",
        +  "OptionGrossExposurePercent"
        +]
      • changedInput schema / $defs / orderExecution / description
        Previous value: -"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
      • changedInput schema / $defs / orderExecution / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "type": {
        -        "const": "Market",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "price": {
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "UnitPrice",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MinimumNetCredit",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumNetDebit",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        -            "properties": {
        -              "reference": {
        -                "const": "Current",
        -                "type": "string"
        -              },
        -              "type": {
        -                "const": "QuoteRelative",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "reference"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "type": {
        -        "const": "Limit",
        -        "type": "string"
        -      },
        -      "workingTime": {
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        -            "properties": {
        -              "type": {
        -                "const": "Day",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "minutes": {
        -                "minimum": 1,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "Minutes",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "minutes"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "price"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "type": {
        +        "const": "Market",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "price": {
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        +            "properties": {
        +              "amount": {
        +                "minimum": 1e-8,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "UnitPrice",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        +            "properties": {
        +              "amount": {
        +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
        +                "oneOf": [
        +                  {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  {
        +                    "$ref": "#/$defs/indicator"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "MinimumNetCredit",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        +            "properties": {
        +              "amount": {
        +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
        +                "oneOf": [
        +                  {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  {
        +                    "$ref": "#/$defs/indicator"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "MaximumNetDebit",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        +            "properties": {
        +              "reference": {
        +                "const": "Current",
        +                "type": "string"
        +              },
        +              "type": {
        +                "const": "QuoteRelative",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "reference"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "type": {
        +        "const": "Limit",
        +        "type": "string"
        +      },
        +      "workingTime": {
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        +            "properties": {
        +              "type": {
        +                "const": "Day",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "minutes": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "Minutes",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "minutes"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "price"
        +    ],
        +    "type": "object"
        +  }
        +]
      • changedInput schema / $defs / strategy / description
        Previous value: -"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
      • changedInput schema / $defs / strategy / properties / orderExecution / description
        Previous value: -"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
      • changedInput schema / $defs / strategy / properties / orderExecution / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "type": {
        -        "const": "Market",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "price": {
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "UnitPrice",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MinimumNetCredit",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumNetDebit",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        -            "properties": {
        -              "reference": {
        -                "const": "Current",
        -                "type": "string"
        -              },
        -              "type": {
        -                "const": "QuoteRelative",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "reference"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "type": {
        -        "const": "Limit",
        -        "type": "string"
        -      },
        -      "workingTime": {
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        -            "properties": {
        -              "type": {
        -                "const": "Day",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "minutes": {
        -                "minimum": 1,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "Minutes",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "minutes"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "price"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "type": {
        +        "const": "Market",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "price": {
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        +            "properties": {
        +              "amount": {
        +                "minimum": 1e-8,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "UnitPrice",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        +            "properties": {
        +              "amount": {
        +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
        +                "oneOf": [
        +                  {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  {
        +                    "$ref": "#/$defs/indicator"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "MinimumNetCredit",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        +            "properties": {
        +              "amount": {
        +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
        +                "oneOf": [
        +                  {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  {
        +                    "$ref": "#/$defs/indicator"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "MaximumNetDebit",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        +            "properties": {
        +              "reference": {
        +                "const": "Current",
        +                "type": "string"
        +              },
        +              "type": {
        +                "const": "QuoteRelative",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "reference"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "type": {
        +        "const": "Limit",
        +        "type": "string"
        +      },
        +      "workingTime": {
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        +            "properties": {
        +              "type": {
        +                "const": "Day",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "minutes": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "Minutes",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "minutes"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "price"
        +    ],
        +    "type": "object"
        +  }
        +]
      • changedInput schema / properties / strategies / description
        Previous value: -"Array of strategies. Each strategy is { name, condition, action, orderExecution? }. RebalanceOption actions may include action.positionScope (portfolio | strategy). Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. See $defs.strategy / $defs.condition / $defs/indicator."New value: +"Array of strategies. Each strategy is { name, condition, action, orderExecution? }. RebalanceOption actions may include action.positionScope (portfolio | strategy). Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. See $defs.strategy / $defs.condition / $defs/indicator."
      • changedInput schema / properties / strategies / items / description
        Previous value: -"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
      • changedInput schema / properties / strategies / items / properties / orderExecution / description
        Previous value: -"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
      • changedInput schema / properties / strategies / items / properties / orderExecution / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "type": {
        -        "const": "Market",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "price": {
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "UnitPrice",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MinimumNetCredit",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumNetDebit",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        -            "properties": {
        -              "reference": {
        -                "const": "Current",
        -                "type": "string"
        -              },
        -              "type": {
        -                "const": "QuoteRelative",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "reference"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "type": {
        -        "const": "Limit",
        -        "type": "string"
        -      },
        -      "workingTime": {
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        -            "properties": {
        -              "type": {
        -                "const": "Day",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "minutes": {
        -                "minimum": 1,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "Minutes",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "minutes"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "price"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "type": {
        +        "const": "Market",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "price": {
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        +            "properties": {
        +              "amount": {
        +                "minimum": 1e-8,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "UnitPrice",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        +            "properties": {
        +              "amount": {
        +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
        +                "oneOf": [
        +                  {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  {
        +                    "$ref": "#/$defs/indicator"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "MinimumNetCredit",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        +            "properties": {
        +              "amount": {
        +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
        +                "oneOf": [
        +                  {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  {
        +                    "$ref": "#/$defs/indicator"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "MaximumNetDebit",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        +            "properties": {
        +              "reference": {
        +                "const": "Current",
        +                "type": "string"
        +              },
        +              "type": {
        +                "const": "QuoteRelative",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "reference"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "type": {
        +        "const": "Limit",
        +        "type": "string"
        +      },
        +      "workingTime": {
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        +            "properties": {
        +              "type": {
        +                "const": "Day",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "minutes": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "Minutes",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "minutes"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "price"
        +    ],
        +    "type": "object"
        +  }
        +]
    • Changedcreate_portfolio11 fields changed
      • changedInput schema / $defs / indicator / description
        Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
      • changedInput schema / $defs / indicator / properties / type / enum
        Previous value: -[
        -  "DaysSinceAgent",
        -  "MinutesSinceAgent",
        -  "DaysSinceAlert",
        -  "MinutesSinceAlert",
        -  "StockReport",
        -  "DaysUntilEarnings",
        -  "DaysSinceEarnings",
        -  "ImpliedVolatility",
        -  "IVRank",
        -  "IVPercentile",
        -  "IVHVRatio",
        -  "LastOrderPrice",
        -  "Fundamental",
        -  "Economic",
        -  "CustomIndicator",
        -  "Index",
        -  "BollingerBand",
        -  "RelativeStrengthIndex",
        -  "PriceMeanAbsoluteDeviation",
        -  "ExponentialMovingAverage",
        -  "SimpleMovingAverage",
        -  "PriceStandardDeviation",
        -  "PriceRateOfChange",
        -  "MaxDrawdown",
        -  "MaxDrawup",
        -  "MinimumPrice",
        -  "MaximumPrice",
        -  "IndicatorMeanAbsoluteDeviation",
        -  "IndicatorExponentialMovingAverage",
        -  "IndicatorSimpleMovingAverage",
        -  "IndicatorStandardDeviation",
        -  "IndicatorRateOfChange",
        -  "DaysSinceOrder",
        -  "DaysSinceOptionOrder",
        -  "DaysSinceStrategyFired",
        -  "DaysSinceLastRebalanceOptionOrder",
        -  "MinutesSinceOptionOrder",
        -  "MinutesSinceOrder",
        -  "DaysSinceTransaction",
        -  "InitialValue",
        -  "BuyingPower",
        -  "PositionValue",
        -  "PositionPercentChange",
        -  "PortfolioValue",
        -  "RebalanceDecisionMetric",
        -  "Value",
        -  "Price",
        -  "Plus",
        -  "Minus",
        -  "Multiply",
        -  "Divide",
        -  "Negative",
        -  "AbsoluteValue",
        -  "SquareRoot",
        -  "Max",
        -  "Min",
        -  "Day",
        -  "Month",
        -  "Date",
        -  "Year",
        -  "CurrentTimeSeconds",
        -  "CurrentTimeMinutes",
        -  "CurrentTimeHours",
        -  "TrailingSum",
        -  "CompoundAnnualGrowthRate",
        -  "Log",
        -  "Exponentiation",
        -  "SumOrderQuantity",
        -  "SumOrderAmount",
        -  "MinutesAfterOpen",
        -  "OpeningPrice",
        -  "PreviousClosingPrice",
        -  "HighOfDay",
        -  "LowOfDay",
        -  "MinutesUntilClose",
        -  "PriceChangeSinceOpen",
        -  "GapSize",
        -  "GapPercentage",
        -  "TrueRange",
        -  "AverageTrueRange",
        -  "Volume",
        -  "VWAP",
        -  "BullishFairValueGap",
        -  "BearishFairValueGap",
        -  "IndicatorAtMinutesAfterOpen",
        -  "IndicatorWindowAgo",
        -  "IndicatorAtEntry",
        -  "IsIndexMember",
        -  "IsIndustry",
        -  "IsAssetType",
        -  "IsAsset",
        -  "IsNotAsset",
        -  "CrossAbove",
        -  "CrossBelow",
        -  "PositionMaxDrawdown",
        -  "PositionMaxDrawup",
        -  "UnderlyingMaxDrawdown",
        -  "ConsecutiveTrue",
        -  "CountTrue",
        -  "OptionPositionValue",
        -  "OptionPositionCount",
        -  "OptionPositionPercentChange",
        -  "OptionPositionMaxDrawdown",
        -  "OptionDaysToExpiration",
        -  "OptionDaysHeld",
        -  "OptionCollateral",
        -  "OptionSpreadCount",
        -  "OptionUnrealizedPnL",
        -  "OptionRealizedPnL",
        -  "OptionRealizedPremium",
        -  "OptionGrossExposurePercent"
        -]New value: +[
        +  "DaysSinceAgent",
        +  "MinutesSinceAgent",
        +  "DaysSinceAlert",
        +  "MinutesSinceAlert",
        +  "StockReport",
        +  "DaysUntilEarnings",
        +  "DaysSinceEarnings",
        +  "ImpliedVolatility",
        +  "IVRank",
        +  "IVPercentile",
        +  "IVHVRatio",
        +  "LastOrderPrice",
        +  "Fundamental",
        +  "Economic",
        +  "CustomIndicator",
        +  "Index",
        +  "BollingerBand",
        +  "RelativeStrengthIndex",
        +  "PriceMeanAbsoluteDeviation",
        +  "ExponentialMovingAverage",
        +  "SimpleMovingAverage",
        +  "PriceStandardDeviation",
        +  "PriceRateOfChange",
        +  "MaxDrawdown",
        +  "MaxDrawup",
        +  "MinimumPrice",
        +  "MaximumPrice",
        +  "IndicatorMeanAbsoluteDeviation",
        +  "IndicatorExponentialMovingAverage",
        +  "IndicatorSimpleMovingAverage",
        +  "IndicatorStandardDeviation",
        +  "IndicatorRateOfChange",
        +  "DaysSinceOrder",
        +  "DaysSinceOptionOrder",
        +  "DaysSinceStrategyFired",
        +  "DaysSinceLastRebalanceOptionOrder",
        +  "MinutesSinceOptionOrder",
        +  "MinutesSinceOrder",
        +  "DaysSinceTransaction",
        +  "InitialValue",
        +  "BuyingPower",
        +  "PositionValue",
        +  "PositionPercentChange",
        +  "PortfolioValue",
        +  "RebalanceDecisionMetric",
        +  "Value",
        +  "Price",
        +  "Plus",
        +  "Minus",
        +  "Multiply",
        +  "Divide",
        +  "Negative",
        +  "AbsoluteValue",
        +  "SquareRoot",
        +  "Max",
        +  "Min",
        +  "Day",
        +  "Month",
        +  "Date",
        +  "Year",
        +  "CurrentTimeSeconds",
        +  "CurrentTimeMinutes",
        +  "CurrentTimeHours",
        +  "TrailingSum",
        +  "CompoundAnnualGrowthRate",
        +  "Log",
        +  "Exponentiation",
        +  "SumOrderQuantity",
        +  "SumOrderAmount",
        +  "MinutesAfterOpen",
        +  "OpeningPrice",
        +  "PreviousClosingPrice",
        +  "HighOfDay",
        +  "LowOfDay",
        +  "MinutesUntilClose",
        +  "PriceChangeSinceOpen",
        +  "GapSize",
        +  "GapPercentage",
        +  "TrueRange",
        +  "AverageTrueRange",
        +  "Volume",
        +  "VWAP",
        +  "BullishFairValueGap",
        +  "BearishFairValueGap",
        +  "IndicatorAtMinutesAfterOpen",
        +  "IndicatorWindowAgo",
        +  "IndicatorAtEntry",
        +  "IsIndexMember",
        +  "PoliticalTrades",
        +  "InsiderTrades",
        +  "IsIndustry",
        +  "IsAssetType",
        +  "IsAsset",
        +  "IsNotAsset",
        +  "CrossAbove",
        +  "CrossBelow",
        +  "PositionMaxDrawdown",
        +  "PositionMaxDrawup",
        +  "UnderlyingMaxDrawdown",
        +  "ConsecutiveTrue",
        +  "CountTrue",
        +  "OptionPositionValue",
        +  "OptionPositionCount",
        +  "OptionPositionPercentChange",
        +  "OptionPositionMaxDrawdown",
        +  "OptionDaysToExpiration",
        +  "OptionDaysHeld",
        +  "OptionCollateral",
        +  "OptionSpreadCount",
        +  "OptionSpreadEntryPrice",
        +  "OptionUnrealizedPnL",
        +  "OptionRealizedPnL",
        +  "OptionRealizedPremium",
        +  "OptionGrossExposurePercent"
        +]
      • changedInput schema / $defs / orderExecution / description
        Previous value: -"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
      • changedInput schema / $defs / orderExecution / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "type": {
        -        "const": "Market",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "price": {
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "UnitPrice",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MinimumNetCredit",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumNetDebit",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        -            "properties": {
        -              "reference": {
        -                "const": "Current",
        -                "type": "string"
        -              },
        -              "type": {
        -                "const": "QuoteRelative",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "reference"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "type": {
        -        "const": "Limit",
        -        "type": "string"
        -      },
        -      "workingTime": {
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        -            "properties": {
        -              "type": {
        -                "const": "Day",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "minutes": {
        -                "minimum": 1,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "Minutes",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "minutes"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "price"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "type": {
        +        "const": "Market",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "price": {
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        +            "properties": {
        +              "amount": {
        +                "minimum": 1e-8,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "UnitPrice",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        +            "properties": {
        +              "amount": {
        +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
        +                "oneOf": [
        +                  {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  {
        +                    "$ref": "#/$defs/indicator"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "MinimumNetCredit",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        +            "properties": {
        +              "amount": {
        +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
        +                "oneOf": [
        +                  {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  {
        +                    "$ref": "#/$defs/indicator"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "MaximumNetDebit",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        +            "properties": {
        +              "reference": {
        +                "const": "Current",
        +                "type": "string"
        +              },
        +              "type": {
        +                "const": "QuoteRelative",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "reference"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "type": {
        +        "const": "Limit",
        +        "type": "string"
        +      },
        +      "workingTime": {
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        +            "properties": {
        +              "type": {
        +                "const": "Day",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "minutes": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "Minutes",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "minutes"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "price"
        +    ],
        +    "type": "object"
        +  }
        +]
      • changedInput schema / $defs / strategy / description
        Previous value: -"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
      • changedInput schema / $defs / strategy / properties / orderExecution / description
        Previous value: -"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
      • changedInput schema / $defs / strategy / properties / orderExecution / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "type": {
        -        "const": "Market",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "price": {
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "UnitPrice",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MinimumNetCredit",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumNetDebit",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        -            "properties": {
        -              "reference": {
        -                "const": "Current",
        -                "type": "string"
        -              },
        -              "type": {
        -                "const": "QuoteRelative",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "reference"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "type": {
        -        "const": "Limit",
        -        "type": "string"
        -      },
        -      "workingTime": {
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        -            "properties": {
        -              "type": {
        -                "const": "Day",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "minutes": {
        -                "minimum": 1,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "Minutes",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "minutes"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "price"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "type": {
        +        "const": "Market",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "price": {
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        +            "properties": {
        +              "amount": {
        +                "minimum": 1e-8,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "UnitPrice",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        +            "properties": {
        +              "amount": {
        +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
        +                "oneOf": [
        +                  {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  {
        +                    "$ref": "#/$defs/indicator"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "MinimumNetCredit",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        +            "properties": {
        +              "amount": {
        +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
        +                "oneOf": [
        +                  {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  {
        +                    "$ref": "#/$defs/indicator"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "MaximumNetDebit",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        +            "properties": {
        +              "reference": {
        +                "const": "Current",
        +                "type": "string"
        +              },
        +              "type": {
        +                "const": "QuoteRelative",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "reference"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "type": {
        +        "const": "Limit",
        +        "type": "string"
        +      },
        +      "workingTime": {
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        +            "properties": {
        +              "type": {
        +                "const": "Day",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "minutes": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "Minutes",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "minutes"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "price"
        +    ],
        +    "type": "object"
        +  }
        +]
      • changedInput schema / properties / strategies / description
        Previous value: -"Array of strategies. Each strategy is { name, condition, action, orderExecution? }. RebalanceOption actions may include action.positionScope (portfolio | strategy). Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. See $defs.strategy / $defs.condition / $defs/indicator."New value: +"Array of strategies. Each strategy is { name, condition, action, orderExecution? }. RebalanceOption actions may include action.positionScope (portfolio | strategy). Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. See $defs.strategy / $defs.condition / $defs/indicator."
      • changedInput schema / properties / strategies / items / description
        Previous value: -"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
      • changedInput schema / properties / strategies / items / properties / orderExecution / description
        Previous value: -"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
      • changedInput schema / properties / strategies / items / properties / orderExecution / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "type": {
        -        "const": "Market",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "price": {
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "UnitPrice",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MinimumNetCredit",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumNetDebit",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        -            "properties": {
        -              "reference": {
        -                "const": "Current",
        -                "type": "string"
        -              },
        -              "type": {
        -                "const": "QuoteRelative",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "reference"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "type": {
        -        "const": "Limit",
        -        "type": "string"
        -      },
        -      "workingTime": {
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        -            "properties": {
        -              "type": {
        -                "const": "Day",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "minutes": {
        -                "minimum": 1,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "Minutes",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "minutes"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "price"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "type": {
        +        "const": "Market",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "price": {
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        +            "properties": {
        +              "amount": {
        +                "minimum": 1e-8,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "UnitPrice",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        +            "properties": {
        +              "amount": {
        +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
        +                "oneOf": [
        +                  {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  {
        +                    "$ref": "#/$defs/indicator"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "MinimumNetCredit",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        +            "properties": {
        +              "amount": {
        +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
        +                "oneOf": [
        +                  {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  {
        +                    "$ref": "#/$defs/indicator"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "MaximumNetDebit",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        +            "properties": {
        +              "reference": {
        +                "const": "Current",
        +                "type": "string"
        +              },
        +              "type": {
        +                "const": "QuoteRelative",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "reference"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "type": {
        +        "const": "Limit",
        +        "type": "string"
        +      },
        +      "workingTime": {
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        +            "properties": {
        +              "type": {
        +                "const": "Day",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "minutes": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "Minutes",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "minutes"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "price"
        +    ],
        +    "type": "object"
        +  }
        +]
    • Changedupdate_portfolio14 fields changed
      • changedInput schema / $defs / indicator / description
        Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionSpreadEntryPrice/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters; OptionSpreadEntryPrice is the contract-weighted net entry price per share of the matching open spreads, positive for a debit and negative for a credit, with no value when none match), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
      • changedInput schema / $defs / indicator / properties / type / enum
        Previous value: -[
        -  "DaysSinceAgent",
        -  "MinutesSinceAgent",
        -  "DaysSinceAlert",
        -  "MinutesSinceAlert",
        -  "StockReport",
        -  "DaysUntilEarnings",
        -  "DaysSinceEarnings",
        -  "ImpliedVolatility",
        -  "IVRank",
        -  "IVPercentile",
        -  "IVHVRatio",
        -  "LastOrderPrice",
        -  "Fundamental",
        -  "Economic",
        -  "CustomIndicator",
        -  "Index",
        -  "BollingerBand",
        -  "RelativeStrengthIndex",
        -  "PriceMeanAbsoluteDeviation",
        -  "ExponentialMovingAverage",
        -  "SimpleMovingAverage",
        -  "PriceStandardDeviation",
        -  "PriceRateOfChange",
        -  "MaxDrawdown",
        -  "MaxDrawup",
        -  "MinimumPrice",
        -  "MaximumPrice",
        -  "IndicatorMeanAbsoluteDeviation",
        -  "IndicatorExponentialMovingAverage",
        -  "IndicatorSimpleMovingAverage",
        -  "IndicatorStandardDeviation",
        -  "IndicatorRateOfChange",
        -  "DaysSinceOrder",
        -  "DaysSinceOptionOrder",
        -  "DaysSinceStrategyFired",
        -  "DaysSinceLastRebalanceOptionOrder",
        -  "MinutesSinceOptionOrder",
        -  "MinutesSinceOrder",
        -  "DaysSinceTransaction",
        -  "InitialValue",
        -  "BuyingPower",
        -  "PositionValue",
        -  "PositionPercentChange",
        -  "PortfolioValue",
        -  "RebalanceDecisionMetric",
        -  "Value",
        -  "Price",
        -  "Plus",
        -  "Minus",
        -  "Multiply",
        -  "Divide",
        -  "Negative",
        -  "AbsoluteValue",
        -  "SquareRoot",
        -  "Max",
        -  "Min",
        -  "Day",
        -  "Month",
        -  "Date",
        -  "Year",
        -  "CurrentTimeSeconds",
        -  "CurrentTimeMinutes",
        -  "CurrentTimeHours",
        -  "TrailingSum",
        -  "CompoundAnnualGrowthRate",
        -  "Log",
        -  "Exponentiation",
        -  "SumOrderQuantity",
        -  "SumOrderAmount",
        -  "MinutesAfterOpen",
        -  "OpeningPrice",
        -  "PreviousClosingPrice",
        -  "HighOfDay",
        -  "LowOfDay",
        -  "MinutesUntilClose",
        -  "PriceChangeSinceOpen",
        -  "GapSize",
        -  "GapPercentage",
        -  "TrueRange",
        -  "AverageTrueRange",
        -  "Volume",
        -  "VWAP",
        -  "BullishFairValueGap",
        -  "BearishFairValueGap",
        -  "IndicatorAtMinutesAfterOpen",
        -  "IndicatorWindowAgo",
        -  "IndicatorAtEntry",
        -  "IsIndexMember",
        -  "IsIndustry",
        -  "IsAssetType",
        -  "IsAsset",
        -  "IsNotAsset",
        -  "CrossAbove",
        -  "CrossBelow",
        -  "PositionMaxDrawdown",
        -  "PositionMaxDrawup",
        -  "UnderlyingMaxDrawdown",
        -  "ConsecutiveTrue",
        -  "CountTrue",
        -  "OptionPositionValue",
        -  "OptionPositionCount",
        -  "OptionPositionPercentChange",
        -  "OptionPositionMaxDrawdown",
        -  "OptionDaysToExpiration",
        -  "OptionDaysHeld",
        -  "OptionCollateral",
        -  "OptionSpreadCount",
        -  "OptionUnrealizedPnL",
        -  "OptionRealizedPnL",
        -  "OptionRealizedPremium",
        -  "OptionGrossExposurePercent"
        -]New value: +[
        +  "DaysSinceAgent",
        +  "MinutesSinceAgent",
        +  "DaysSinceAlert",
        +  "MinutesSinceAlert",
        +  "StockReport",
        +  "DaysUntilEarnings",
        +  "DaysSinceEarnings",
        +  "ImpliedVolatility",
        +  "IVRank",
        +  "IVPercentile",
        +  "IVHVRatio",
        +  "LastOrderPrice",
        +  "Fundamental",
        +  "Economic",
        +  "CustomIndicator",
        +  "Index",
        +  "BollingerBand",
        +  "RelativeStrengthIndex",
        +  "PriceMeanAbsoluteDeviation",
        +  "ExponentialMovingAverage",
        +  "SimpleMovingAverage",
        +  "PriceStandardDeviation",
        +  "PriceRateOfChange",
        +  "MaxDrawdown",
        +  "MaxDrawup",
        +  "MinimumPrice",
        +  "MaximumPrice",
        +  "IndicatorMeanAbsoluteDeviation",
        +  "IndicatorExponentialMovingAverage",
        +  "IndicatorSimpleMovingAverage",
        +  "IndicatorStandardDeviation",
        +  "IndicatorRateOfChange",
        +  "DaysSinceOrder",
        +  "DaysSinceOptionOrder",
        +  "DaysSinceStrategyFired",
        +  "DaysSinceLastRebalanceOptionOrder",
        +  "MinutesSinceOptionOrder",
        +  "MinutesSinceOrder",
        +  "DaysSinceTransaction",
        +  "InitialValue",
        +  "BuyingPower",
        +  "PositionValue",
        +  "PositionPercentChange",
        +  "PortfolioValue",
        +  "RebalanceDecisionMetric",
        +  "Value",
        +  "Price",
        +  "Plus",
        +  "Minus",
        +  "Multiply",
        +  "Divide",
        +  "Negative",
        +  "AbsoluteValue",
        +  "SquareRoot",
        +  "Max",
        +  "Min",
        +  "Day",
        +  "Month",
        +  "Date",
        +  "Year",
        +  "CurrentTimeSeconds",
        +  "CurrentTimeMinutes",
        +  "CurrentTimeHours",
        +  "TrailingSum",
        +  "CompoundAnnualGrowthRate",
        +  "Log",
        +  "Exponentiation",
        +  "SumOrderQuantity",
        +  "SumOrderAmount",
        +  "MinutesAfterOpen",
        +  "OpeningPrice",
        +  "PreviousClosingPrice",
        +  "HighOfDay",
        +  "LowOfDay",
        +  "MinutesUntilClose",
        +  "PriceChangeSinceOpen",
        +  "GapSize",
        +  "GapPercentage",
        +  "TrueRange",
        +  "AverageTrueRange",
        +  "Volume",
        +  "VWAP",
        +  "BullishFairValueGap",
        +  "BearishFairValueGap",
        +  "IndicatorAtMinutesAfterOpen",
        +  "IndicatorWindowAgo",
        +  "IndicatorAtEntry",
        +  "IsIndexMember",
        +  "PoliticalTrades",
        +  "InsiderTrades",
        +  "IsIndustry",
        +  "IsAssetType",
        +  "IsAsset",
        +  "IsNotAsset",
        +  "CrossAbove",
        +  "CrossBelow",
        +  "PositionMaxDrawdown",
        +  "PositionMaxDrawup",
        +  "UnderlyingMaxDrawdown",
        +  "ConsecutiveTrue",
        +  "CountTrue",
        +  "OptionPositionValue",
        +  "OptionPositionCount",
        +  "OptionPositionPercentChange",
        +  "OptionPositionMaxDrawdown",
        +  "OptionDaysToExpiration",
        +  "OptionDaysHeld",
        +  "OptionCollateral",
        +  "OptionSpreadCount",
        +  "OptionSpreadEntryPrice",
        +  "OptionUnrealizedPnL",
        +  "OptionRealizedPnL",
        +  "OptionRealizedPremium",
        +  "OptionGrossExposurePercent"
        +]
      • changedInput schema / $defs / orderExecution / description
        Previous value: -"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
      • changedInput schema / $defs / orderExecution / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "type": {
        -        "const": "Market",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "price": {
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "UnitPrice",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MinimumNetCredit",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumNetDebit",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        -            "properties": {
        -              "reference": {
        -                "const": "Current",
        -                "type": "string"
        -              },
        -              "type": {
        -                "const": "QuoteRelative",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "reference"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "type": {
        -        "const": "Limit",
        -        "type": "string"
        -      },
        -      "workingTime": {
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        -            "properties": {
        -              "type": {
        -                "const": "Day",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "minutes": {
        -                "minimum": 1,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "Minutes",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "minutes"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "price"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "type": {
        +        "const": "Market",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "price": {
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        +            "properties": {
        +              "amount": {
        +                "minimum": 1e-8,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "UnitPrice",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        +            "properties": {
        +              "amount": {
        +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
        +                "oneOf": [
        +                  {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  {
        +                    "$ref": "#/$defs/indicator"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "MinimumNetCredit",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        +            "properties": {
        +              "amount": {
        +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
        +                "oneOf": [
        +                  {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  {
        +                    "$ref": "#/$defs/indicator"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "MaximumNetDebit",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        +            "properties": {
        +              "reference": {
        +                "const": "Current",
        +                "type": "string"
        +              },
        +              "type": {
        +                "const": "QuoteRelative",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "reference"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "type": {
        +        "const": "Limit",
        +        "type": "string"
        +      },
        +      "workingTime": {
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        +            "properties": {
        +              "type": {
        +                "const": "Day",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "minutes": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "Minutes",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "minutes"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "price"
        +    ],
        +    "type": "object"
        +  }
        +]
      • changedInput schema / $defs / strategy / description
        Previous value: -"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
      • changedInput schema / $defs / strategy / properties / orderExecution / description
        Previous value: -"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
      • changedInput schema / $defs / strategy / properties / orderExecution / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "type": {
        -        "const": "Market",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "price": {
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "UnitPrice",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MinimumNetCredit",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumNetDebit",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        -            "properties": {
        -              "reference": {
        -                "const": "Current",
        -                "type": "string"
        -              },
        -              "type": {
        -                "const": "QuoteRelative",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "reference"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "type": {
        -        "const": "Limit",
        -        "type": "string"
        -      },
        -      "workingTime": {
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        -            "properties": {
        -              "type": {
        -                "const": "Day",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "minutes": {
        -                "minimum": 1,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "Minutes",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "minutes"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "price"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "type": {
        +        "const": "Market",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "price": {
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        +            "properties": {
        +              "amount": {
        +                "minimum": 1e-8,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "UnitPrice",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        +            "properties": {
        +              "amount": {
        +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
        +                "oneOf": [
        +                  {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  {
        +                    "$ref": "#/$defs/indicator"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "MinimumNetCredit",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        +            "properties": {
        +              "amount": {
        +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
        +                "oneOf": [
        +                  {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  {
        +                    "$ref": "#/$defs/indicator"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "MaximumNetDebit",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        +            "properties": {
        +              "reference": {
        +                "const": "Current",
        +                "type": "string"
        +              },
        +              "type": {
        +                "const": "QuoteRelative",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "reference"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "type": {
        +        "const": "Limit",
        +        "type": "string"
        +      },
        +      "workingTime": {
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        +            "properties": {
        +              "type": {
        +                "const": "Day",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "minutes": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "Minutes",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "minutes"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "price"
        +    ],
        +    "type": "object"
        +  }
        +]
      • changedInput schema / properties / operations / description
        Previous value: -"Array of edit operations. Each operation needs \"portfolioId\" (live, paper, or chat — server resolves automatically). Supported types include \"rename\" (requires non-empty \"name\"), \"delete\" (permanently remove a chat/paper/live portfolio; archives deployed books; pass confirmLive:true only after explicit user confirmation when deleting an active live portfolio). DEPLOY SAFETY: deploying a chat portfolio ID creates a NEW PAPER-TRADING portfolio (simulated money, no broker order ever placed). It cannot place real-money trades. A LIVE/real-brokerage deployment only happens when the target is an EXISTING real-brokerage portfolio (re-activating it, or addStrategies/replaceStrategies on a portfolio already connected to a live broker). You cannot create a live brokerage account from a chat portfolio through this tool. Fetch the portfolio first and use strategy IDs from the returned \"strategies\" array for removals. To add/replace strategies, pass FINISHED strategy objects ({name, condition, action, orderExecution?} — same shape as create_portfolio.strategies) via \"strategyObjects\" (or \"strategyObject\" for replaceStrategy). These are ingested deterministically with zero LLM cost; prefer them. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. RebalanceOption `action.positionScope`: `\"portfolio\"` (default for single-book portfolios — rotation-close and open-skip span all option spreads in the portfolio) or `\"strategy\"` (only spreads this strategy opened; use when multiple RebalanceOption strategies share one portfolio). Set on `create_portfolio` strategies[].action or on `update_portfolio` replaceStrategy/replaceStrategies `strategyObject.action`. Examples: [{\"type\":\"deploy\",\"portfolioId\":\"id\"}, {\"type\":\"undeploy\",\"portfolioId\":\"id\"}, {\"type\":\"delete\",\"portfolioId\":\"id\"}, {\"type\":\"addStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...},\"orderExecution\":{\"type\":\"Limit\",\"price\":{\"type\":\"UnitPrice\",\"amount\":150},\"workingTime\":{\"type\":\"Day\"}}}]}, {\"type\":\"removeStrategies\",\"portfolioId\":\"id\",\"strategyIds\":[\"strategyId\"]}, {\"type\":\"replaceStrategy\",\"portfolioId\":\"id\",\"targetStrategyId\":\"strategyId\",\"strategyObject\":{\"name\":\"...\",\"condition\":{...},\"action\":{\"type\":\"RebalanceOption\",\"positionScope\":\"portfolio\",...}}}, {\"type\":\"replaceStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...}}]}, {\"type\":\"setDeploymentFrequency\",\"portfolioId\":\"id\",\"deploymentFrequency\":\"Constant\"}, {\"type\":\"rename\",\"portfolioId\":\"id\",\"name\":\"New Portfolio Name\"}]"New value: +"Array of edit operations. Each operation needs \"portfolioId\" (live, paper, or chat — server resolves automatically). Supported types include \"rename\" (requires non-empty \"name\"), \"delete\" (permanently remove a chat/paper/live portfolio; archives deployed books; pass confirmLive:true only after explicit user confirmation when deleting an active live portfolio). DEPLOY SAFETY: deploying a chat portfolio ID creates a NEW PAPER-TRADING portfolio (simulated money, no broker order ever placed). It cannot place real-money trades. A LIVE/real-brokerage deployment only happens when the target is an EXISTING real-brokerage portfolio (re-activating it, or addStrategies/replaceStrategies on a portfolio already connected to a live broker). You cannot create a live brokerage account from a chat portfolio through this tool. Fetch the portfolio first and use strategy IDs from the returned \"strategies\" array for removals. To add/replace strategies, pass FINISHED strategy objects ({name, condition, action, orderExecution?} — same shape as create_portfolio.strategies) via \"strategyObjects\" (or \"strategyObject\" for replaceStrategy). These are ingested deterministically with zero LLM cost; prefer them. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. RebalanceOption `action.positionScope`: `\"portfolio\"` (default for single-book portfolios — rotation-close and open-skip span all option spreads in the portfolio) or `\"strategy\"` (only spreads this strategy opened; use when multiple RebalanceOption strategies share one portfolio). Set on `create_portfolio` strategies[].action or on `update_portfolio` replaceStrategy/replaceStrategies `strategyObject.action`. Examples: [{\"type\":\"deploy\",\"portfolioId\":\"id\"}, {\"type\":\"undeploy\",\"portfolioId\":\"id\"}, {\"type\":\"delete\",\"portfolioId\":\"id\"}, {\"type\":\"addStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...},\"orderExecution\":{\"type\":\"Limit\",\"price\":{\"type\":\"UnitPrice\",\"amount\":150},\"workingTime\":{\"type\":\"Day\"}}}]}, {\"type\":\"removeStrategies\",\"portfolioId\":\"id\",\"strategyIds\":[\"strategyId\"]}, {\"type\":\"replaceStrategy\",\"portfolioId\":\"id\",\"targetStrategyId\":\"strategyId\",\"strategyObject\":{\"name\":\"...\",\"condition\":{...},\"action\":{\"type\":\"RebalanceOption\",\"positionScope\":\"portfolio\",...}}}, {\"type\":\"replaceStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...}}]}, {\"type\":\"setDeploymentFrequency\",\"portfolioId\":\"id\",\"deploymentFrequency\":\"Constant\"}, {\"type\":\"rename\",\"portfolioId\":\"id\",\"name\":\"New Portfolio Name\"}]"
      • changedInput schema / properties / operations / items / properties / strategyObject / description
        Previous value: -"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
      • changedInput schema / properties / operations / items / properties / strategyObject / properties / orderExecution / description
        Previous value: -"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
      • changedInput schema / properties / operations / items / properties / strategyObject / properties / orderExecution / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "type": {
        -        "const": "Market",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "price": {
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "UnitPrice",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MinimumNetCredit",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumNetDebit",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        -            "properties": {
        -              "reference": {
        -                "const": "Current",
        -                "type": "string"
        -              },
        -              "type": {
        -                "const": "QuoteRelative",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "reference"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "type": {
        -        "const": "Limit",
        -        "type": "string"
        -      },
        -      "workingTime": {
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        -            "properties": {
        -              "type": {
        -                "const": "Day",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "minutes": {
        -                "minimum": 1,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "Minutes",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "minutes"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "price"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "type": {
        +        "const": "Market",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "price": {
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        +            "properties": {
        +              "amount": {
        +                "minimum": 1e-8,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "UnitPrice",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        +            "properties": {
        +              "amount": {
        +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
        +                "oneOf": [
        +                  {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  {
        +                    "$ref": "#/$defs/indicator"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "MinimumNetCredit",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        +            "properties": {
        +              "amount": {
        +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
        +                "oneOf": [
        +                  {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  {
        +                    "$ref": "#/$defs/indicator"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "MaximumNetDebit",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        +            "properties": {
        +              "reference": {
        +                "const": "Current",
        +                "type": "string"
        +              },
        +              "type": {
        +                "const": "QuoteRelative",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "reference"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "type": {
        +        "const": "Limit",
        +        "type": "string"
        +      },
        +      "workingTime": {
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        +            "properties": {
        +              "type": {
        +                "const": "Day",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "minutes": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "Minutes",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "minutes"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "price"
        +    ],
        +    "type": "object"
        +  }
        +]
      • changedInput schema / properties / operations / items / properties / strategyObjects / items / description
        Previous value: -"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
      • changedInput schema / properties / operations / items / properties / strategyObjects / items / properties / orderExecution / description
        Previous value: -"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."New value: +"Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. An option net limit `amount` may be an indicator instead of a number; it is evaluated when the strategy fires, e.g. `{type:\"Plus\",indicators:[{type:\"OptionSpreadEntryPrice\",underlying:\"SPX\",optionType:\"call\",direction:\"long\",spreadType:\"vertical\"},{type:\"Value\",value:0.5}]}` waits for a credit of at least the held debit spread's fill plus $0.50, and no order is placed when it has no positive value. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
      • changedInput schema / properties / operations / items / properties / strategyObjects / items / properties / orderExecution / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "type": {
        -        "const": "Market",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "price": {
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "UnitPrice",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MinimumNetCredit",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        -            "properties": {
        -              "amount": {
        -                "minimum": 1e-8,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumNetDebit",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "amount"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        -            "properties": {
        -              "reference": {
        -                "const": "Current",
        -                "type": "string"
        -              },
        -              "type": {
        -                "const": "QuoteRelative",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "reference"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "type": {
        -        "const": "Limit",
        -        "type": "string"
        -      },
        -      "workingTime": {
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        -            "properties": {
        -              "type": {
        -                "const": "Day",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "minutes": {
        -                "minimum": 1,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "Minutes",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "minutes"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "price"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "type": {
        +        "const": "Market",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "price": {
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        +            "properties": {
        +              "amount": {
        +                "minimum": 1e-8,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "UnitPrice",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        +            "properties": {
        +              "amount": {
        +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
        +                "oneOf": [
        +                  {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  {
        +                    "$ref": "#/$defs/indicator"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "MinimumNetCredit",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        +            "properties": {
        +              "amount": {
        +                "description": "Dollars per share: a positive number, or an indicator evaluated when the strategy fires (for example Plus of OptionSpreadEntryPrice and Value to price one spread off another spread's fill).",
        +                "oneOf": [
        +                  {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  {
        +                    "$ref": "#/$defs/indicator"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "MaximumNetDebit",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        +            "properties": {
        +              "reference": {
        +                "const": "Current",
        +                "type": "string"
        +              },
        +              "type": {
        +                "const": "QuoteRelative",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "reference"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "type": {
        +        "const": "Limit",
        +        "type": "string"
        +      },
        +      "workingTime": {
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        +            "properties": {
        +              "type": {
        +                "const": "Day",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "minutes": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "Minutes",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "minutes"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "price"
        +    ],
        +    "type": "object"
        +  }
        +]
  5. 3 tool updates
    • Changedbuild_portfolio8 fields changed
      • changedInput schema / $defs / action / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "description": "Buy or Sell a stock/crypto position.",
        -    "properties": {
        -      "amount": {
        -        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "percent of current positions",
        -              "dollars",
        -              "number of assets"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "targetAsset": {
        -        "additionalProperties": true,
        -        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -        "properties": {
        -          "name": {
        -            "type": "string"
        -          },
        -          "symbol": {
        -            "type": "string"
        -          },
        -          "type": {
        -            "enum": [
        -              "Stock",
        -              "Cryptocurrency",
        -              "Option",
        -              "Other"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "symbol"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "enum": [
        -          "Buy",
        -          "Sell"
        -        ],
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "targetAsset",
        -      "amount"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Send an alert message (no order).",
        -    "properties": {
        -      "message": {
        -        "type": "string"
        -      },
        -      "type": {
        -        "const": "Alert",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "message"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        -    "properties": {
        -      "allocationPolicy": {
        -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "expectedReturnShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "riskAversion": {
        -                "maximum": 1000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MeanVariance",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "riskAversion",
        -              "expectedReturnShrinkage",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "RiskParity",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumDiversification",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "canSell": {
        -        "$ref": "#/$defs/condition",
        -        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        -      },
        -      "deploymentPercent": {
        -        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        -        "maximum": 100,
        -        "minimum": 0,
        -        "type": "number"
        -      },
        -      "exposurePolicy": {
        -        "additionalProperties": false,
        -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        -        "properties": {
        -          "covarianceShrinkage": {
        -            "maximum": 1,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "estimatedTransactionCostBps": {
        -            "maximum": 10000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "lookbackPeriods": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "minimumObservations": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "targetAnnualizedVolatilityPercent": {
        -            "maximum": 1000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "const": "VolatilityTarget",
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "lookbackPeriods",
        -          "minimumObservations",
        -          "covarianceShrinkage",
        -          "targetAnnualizedVolatilityPercent",
        -          "estimatedTransactionCostBps"
        -        ],
        -        "type": "object"
        -      },
        -      "limit": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "perNameAllocation": {
        -        "additionalProperties": true,
        -        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
        -        "properties": {
        -          "amount": {
        -            "exclusiveMinimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "percent of portfolio",
        -              "dollars"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "pipeline": {
        -        "items": {
        -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "condition": {
        -                  "$ref": "#/$defs/condition"
        -                },
        -                "type": {
        -                  "const": "Filter",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "condition"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "limit": {
        -                  "minimum": 1,
        -                  "type": "number"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "type": {
        -                  "const": "SelectTop",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "limit",
        -                "direction"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "percentile": {
        -                  "maximum": 100,
        -                  "minimum": 0,
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "SelectPercentile",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "percentile",
        -                "direction"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "type": {
        -        "const": "DynamicRebalance",
        -        "type": "string"
        -      },
        -      "universe": {
        -        "additionalProperties": true,
        -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -        "properties": {
        -          "assets": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -              "properties": {
        -                "name": {
        -                  "type": "string"
        -                },
        -                "symbol": {
        -                  "type": "string"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "Stock",
        -                    "Cryptocurrency",
        -                    "Option",
        -                    "Other"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "symbol"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "source": {
        -            "enum": [
        -              "ALL_US_STOCKS",
        -              "SP500",
        -              "NASDAQ100",
        -              "DJIA",
        -              "CRYPTO",
        -              "SPECIFIC_ASSETS"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "weightIndicator": {
        -        "$ref": "#/$defs/indicator"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "universe",
        -      "pipeline",
        -      "weightIndicator"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        -    "properties": {
        -      "continueExisting": {
        -        "type": "boolean"
        -      },
        -      "cooldownMinutes": {
        -        "minimum": 0,
        -        "type": "number"
        -      },
        -      "executionModel": {
        -        "type": "string"
        -      },
        -      "includeMarketData": {
        -        "type": "boolean"
        -      },
        -      "initialMessage": {
        -        "type": "string"
        -      },
        -      "maxIterations": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "planningModel": {
        -        "type": "string"
        -      },
        -      "skipPlanning": {
        -        "type": "boolean"
        -      },
        -      "type": {
        -        "const": "LaunchAgent",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "planningModel",
        -      "executionModel",
        -      "initialMessage",
        -      "maxIterations",
        -      "includeMarketData",
        -      "continueExisting",
        -      "skipPlanning"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        -    "properties": {
        -      "against": {
        -        "additionalProperties": true,
        -        "description": "Optional parent-position selector (e.g. for covered calls).",
        -        "type": "object"
        -      },
        -      "allocation": {
        -        "additionalProperties": true,
        -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "contracts"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "builder": {
        -        "additionalProperties": true,
        -        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        -        "properties": {
        -          "dynamicUnderlying": {
        -            "additionalProperties": true,
        -            "properties": {
        -              "limit": {
        -                "minimum": 1,
        -                "type": "number"
        -              },
        -              "pipeline": {
        -                "items": {
        -                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -                  "oneOf": [
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "condition": {
        -                          "$ref": "#/$defs/condition"
        -                        },
        -                        "type": {
        -                          "const": "Filter",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "condition"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "Highest",
        -                            "Lowest"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "limit": {
        -                          "minimum": 1,
        -                          "type": "number"
        -                        },
        -                        "metric": {
        -                          "$ref": "#/$defs/indicator"
        -                        },
        -                        "type": {
        -                          "const": "SelectTop",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "metric",
        -                        "limit",
        -                        "direction"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "Highest",
        -                            "Lowest"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "metric": {
        -                          "$ref": "#/$defs/indicator"
        -                        },
        -                        "percentile": {
        -                          "maximum": 100,
        -                          "minimum": 0,
        -                          "type": "number"
        -                        },
        -                        "type": {
        -                          "const": "SelectPercentile",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "metric",
        -                        "percentile",
        -                        "direction"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ],
        -                  "type": "object"
        -                },
        -                "type": "array"
        -              },
        -              "universe": {
        -                "additionalProperties": true,
        -                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -                "properties": {
        -                  "assets": {
        -                    "items": {
        -                      "additionalProperties": true,
        -                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -                      "properties": {
        -                        "name": {
        -                          "type": "string"
        -                        },
        -                        "symbol": {
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "enum": [
        -                            "Stock",
        -                            "Cryptocurrency",
        -                            "Option",
        -                            "Other"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "symbol"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    "type": "array"
        -                  },
        -                  "source": {
        -                    "enum": [
        -                      "ALL_US_STOCKS",
        -                      "SP500",
        -                      "NASDAQ100",
        -                      "DJIA",
        -                      "CRYPTO",
        -                      "SPECIFIC_ASSETS"
        -                    ],
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "source"
        -                ],
        -                "type": "object"
        -              }
        -            },
        -            "required": [
        -              "universe"
        -            ],
        -            "type": "object"
        -          },
        -          "legs": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Single leg of an option builder.",
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "long",
        -                    "short"
        -                  ],
        -                  "type": "string"
        -                },
        -                "expirationRange": {
        -                  "additionalProperties": true,
        -                  "type": "object"
        -                },
        -                "expirationSelector": {
        -                  "properties": {
        -                    "maxDaysToExpiration": {
        -                      "minimum": 0,
        -                      "type": "number"
        -                    },
        -                    "minDaysToExpiration": {
        -                      "minimum": 0,
        -                      "type": "number"
        -                    },
        -                    "preference": {
        -                      "enum": [
        -                        "nearest",
        -                        "middle",
        -                        "furthest"
        -                      ],
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "minDaysToExpiration",
        -                    "maxDaysToExpiration",
        -                    "preference"
        -                  ],
        -                  "type": "object"
        -                },
        -                "fallbackStrikeSelector": {
        -                  "additionalProperties": false,
        -                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                  "properties": {
        -                    "distance": {
        -                      "type": "number"
        -                    },
        -                    "distanceType": {
        -                      "enum": [
        -                        "percent",
        -                        "dollars"
        -                      ],
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "distanceType",
        -                    "distance"
        -                  ],
        -                  "type": "object"
        -                },
        -                "greekFilter": {
        -                  "additionalProperties": true,
        -                  "description": "Optional min/max constraints on Greeks during resolution.",
        -                  "type": "object"
        -                },
        -                "liquidityFilter": {
        -                  "additionalProperties": false,
        -                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                  "properties": {
        -                    "maxSpreadAbsolute": {
        -                      "type": "number"
        -                    },
        -                    "maxSpreadPct": {
        -                      "type": "number"
        -                    },
        -                    "minBid": {
        -                      "type": "number"
        -                    }
        -                  },
        -                  "type": "object"
        -                },
        -                "optionType": {
        -                  "enum": [
        -                    "call",
        -                    "put"
        -                  ],
        -                  "type": "string"
        -                },
        -                "ratio": {
        -                  "type": "number"
        -                },
        -                "strikeRange": {
        -                  "additionalProperties": true,
        -                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                  "type": "object"
        -                },
        -                "strikeSelector": {
        -                  "properties": {
        -                    "distance": {
        -                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                      "type": "number"
        -                    },
        -                    "distanceType": {
        -                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "distanceType",
        -                    "distance"
        -                  ],
        -                  "type": "object"
        -                }
        -              },
        -              "required": [
        -                "optionType",
        -                "direction",
        -                "expirationSelector",
        -                "strikeSelector"
        -              ],
        -              "type": "object"
        -            },
        -            "minItems": 1,
        -            "type": "array"
        -          },
        -          "spreadType": {
        -            "enum": [
        -              "vertical",
        -              "calendar",
        -              "diagonal",
        -              "ironCondor",
        -              "straddle",
        -              "strangle",
        -              "custom"
        -            ],
        -            "type": "string"
        -          },
        -          "underlyingSymbol": {
        -            "type": "string"
        -          },
        -          "widthConstraint": {
        -            "additionalProperties": false,
        -            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -            "properties": {
        -              "minWidthDollars": {
        -                "exclusiveMinimum": 0,
        -                "type": "number"
        -              },
        -              "minWidthPercent": {
        -                "exclusiveMinimum": 0,
        -                "type": "number"
        -              }
        -            },
        -            "type": "object"
        -          }
        -        },
        -        "required": [
        -          "legs"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "const": "OpenOption",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "builder"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        -    "properties": {
        -      "allocationPolicy": {
        -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "expectedReturnShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "riskAversion": {
        -                "maximum": 1000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MeanVariance",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "riskAversion",
        -              "expectedReturnShrinkage",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "RiskParity",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumDiversification",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "exposurePolicy": {
        -        "additionalProperties": false,
        -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        -        "properties": {
        -          "covarianceShrinkage": {
        -            "maximum": 1,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "estimatedTransactionCostBps": {
        -            "maximum": 10000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "lookbackPeriods": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "minimumObservations": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "targetAnnualizedVolatilityPercent": {
        -            "maximum": 1000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "const": "VolatilityTarget",
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "lookbackPeriods",
        -          "minimumObservations",
        -          "covarianceShrinkage",
        -          "targetAnnualizedVolatilityPercent",
        -          "estimatedTransactionCostBps"
        -        ],
        -        "type": "object"
        -      },
        -      "limit": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "perNameAllocation": {
        -        "additionalProperties": true,
        -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "contracts"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "pipeline": {
        -        "items": {
        -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "condition": {
        -                  "$ref": "#/$defs/condition"
        -                },
        -                "type": {
        -                  "const": "Filter",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "condition"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "limit": {
        -                  "minimum": 1,
        -                  "type": "number"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "type": {
        -                  "const": "SelectTop",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "limit",
        -                "direction"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "percentile": {
        -                  "maximum": 100,
        -                  "minimum": 0,
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "SelectPercentile",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "percentile",
        -                "direction"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "positionScope": {
        -        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        -        "enum": [
        -          "portfolio",
        -          "strategy"
        -        ],
        -        "type": "string"
        -      },
        -      "sleeves": {
        -        "items": {
        -          "additionalProperties": true,
        -          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        -          "properties": {
        -            "limit": {
        -              "minimum": 1,
        -              "type": "number"
        -            },
        -            "name": {
        -              "type": "string"
        -            },
        -            "perNameAllocation": {
        -              "additionalProperties": true,
        -              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -              "properties": {
        -                "amount": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "dollars",
        -                    "percent of portfolio",
        -                    "percent of buying power",
        -                    "contracts"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "amount"
        -              ],
        -              "type": "object"
        -            },
        -            "pipeline": {
        -              "items": {
        -                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -                "oneOf": [
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "condition": {
        -                        "$ref": "#/$defs/condition"
        -                      },
        -                      "type": {
        -                        "const": "Filter",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "condition"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "direction": {
        -                        "enum": [
        -                          "Highest",
        -                          "Lowest"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "limit": {
        -                        "minimum": 1,
        -                        "type": "number"
        -                      },
        -                      "metric": {
        -                        "$ref": "#/$defs/indicator"
        -                      },
        -                      "type": {
        -                        "const": "SelectTop",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "metric",
        -                      "limit",
        -                      "direction"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "direction": {
        -                        "enum": [
        -                          "Highest",
        -                          "Lowest"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "metric": {
        -                        "$ref": "#/$defs/indicator"
        -                      },
        -                      "percentile": {
        -                        "maximum": 100,
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "type": {
        -                        "const": "SelectPercentile",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "metric",
        -                      "percentile",
        -                      "direction"
        -                    ],
        -                    "type": "object"
        -                  }
        -                ],
        -                "type": "object"
        -              },
        -              "type": "array"
        -            },
        -            "structureTemplates": {
        -              "items": {
        -                "additionalProperties": true,
        -                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        -                "properties": {
        -                  "eligibility": {
        -                    "$ref": "#/$defs/condition"
        -                  },
        -                  "legs": {
        -                    "items": {
        -                      "additionalProperties": true,
        -                      "description": "Single leg of an option builder.",
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "long",
        -                            "short"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "expirationRange": {
        -                          "additionalProperties": true,
        -                          "type": "object"
        -                        },
        -                        "expirationSelector": {
        -                          "properties": {
        -                            "maxDaysToExpiration": {
        -                              "minimum": 0,
        -                              "type": "number"
        -                            },
        -                            "minDaysToExpiration": {
        -                              "minimum": 0,
        -                              "type": "number"
        -                            },
        -                            "preference": {
        -                              "enum": [
        -                                "nearest",
        -                                "middle",
        -                                "furthest"
        -                              ],
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "minDaysToExpiration",
        -                            "maxDaysToExpiration",
        -                            "preference"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "fallbackStrikeSelector": {
        -                          "additionalProperties": false,
        -                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                          "properties": {
        -                            "distance": {
        -                              "type": "number"
        -                            },
        -                            "distanceType": {
        -                              "enum": [
        -                                "percent",
        -                                "dollars"
        -                              ],
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "distanceType",
        -                            "distance"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "greekFilter": {
        -                          "additionalProperties": true,
        -                          "description": "Optional min/max constraints on Greeks during resolution.",
        -                          "type": "object"
        -                        },
        -                        "liquidityFilter": {
        -                          "additionalProperties": false,
        -                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                          "properties": {
        -                            "maxSpreadAbsolute": {
        -                              "type": "number"
        -                            },
        -                            "maxSpreadPct": {
        -                              "type": "number"
        -                            },
        -                            "minBid": {
        -                              "type": "number"
        -                            }
        -                          },
        -                          "type": "object"
        -                        },
        -                        "optionType": {
        -                          "enum": [
        -                            "call",
        -                            "put"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "ratio": {
        -                          "type": "number"
        -                        },
        -                        "strikeRange": {
        -                          "additionalProperties": true,
        -                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                          "type": "object"
        -                        },
        -                        "strikeSelector": {
        -                          "properties": {
        -                            "distance": {
        -                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                              "type": "number"
        -                            },
        -                            "distanceType": {
        -                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "distanceType",
        -                            "distance"
        -                          ],
        -                          "type": "object"
        -                        }
        -                      },
        -                      "required": [
        -                        "optionType",
        -                        "direction",
        -                        "expirationSelector",
        -                        "strikeSelector"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    "minItems": 1,
        -                    "type": "array"
        -                  },
        -                  "name": {
        -                    "type": "string"
        -                  },
        -                  "spreadType": {
        -                    "enum": [
        -                      "vertical",
        -                      "calendar",
        -                      "diagonal",
        -                      "ironCondor",
        -                      "straddle",
        -                      "strangle",
        -                      "custom"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "widthConstraint": {
        -                    "additionalProperties": false,
        -                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -                    "properties": {
        -                      "minWidthDollars": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "number"
        -                      },
        -                      "minWidthPercent": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "number"
        -                      }
        -                    },
        -                    "type": "object"
        -                  }
        -                },
        -                "required": [
        -                  "legs"
        -                ],
        -                "type": "object"
        -              },
        -              "minItems": 1,
        -              "type": "array"
        -            },
        -            "universe": {
        -              "additionalProperties": true,
        -              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -              "properties": {
        -                "assets": {
        -                  "items": {
        -                    "additionalProperties": true,
        -                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -                    "properties": {
        -                      "name": {
        -                        "type": "string"
        -                      },
        -                      "symbol": {
        -                        "type": "string"
        -                      },
        -                      "type": {
        -                        "enum": [
        -                          "Stock",
        -                          "Cryptocurrency",
        -                          "Option",
        -                          "Other"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "symbol"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "type": "array"
        -                },
        -                "source": {
        -                  "enum": [
        -                    "ALL_US_STOCKS",
        -                    "SP500",
        -                    "NASDAQ100",
        -                    "DJIA",
        -                    "CRYPTO",
        -                    "SPECIFIC_ASSETS"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "source"
        -              ],
        -              "type": "object"
        -            },
        -            "weightIndicator": {
        -              "$ref": "#/$defs/indicator"
        -            }
        -          },
        -          "required": [
        -            "name"
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "structureTemplates": {
        -        "items": {
        -          "additionalProperties": true,
        -          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        -          "properties": {
        -            "eligibility": {
        -              "$ref": "#/$defs/condition"
        -            },
        -            "legs": {
        -              "items": {
        -                "additionalProperties": true,
        -                "description": "Single leg of an option builder.",
        -                "properties": {
        -                  "direction": {
        -                    "enum": [
        -                      "long",
        -                      "short"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "expirationRange": {
        -                    "additionalProperties": true,
        -                    "type": "object"
        -                  },
        -                  "expirationSelector": {
        -                    "properties": {
        -                      "maxDaysToExpiration": {
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "minDaysToExpiration": {
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "preference": {
        -                        "enum": [
        -                          "nearest",
        -                          "middle",
        -                          "furthest"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "minDaysToExpiration",
        -                      "maxDaysToExpiration",
        -                      "preference"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "fallbackStrikeSelector": {
        -                    "additionalProperties": false,
        -                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                    "properties": {
        -                      "distance": {
        -                        "type": "number"
        -                      },
        -                      "distanceType": {
        -                        "enum": [
        -                          "percent",
        -                          "dollars"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "distanceType",
        -                      "distance"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "greekFilter": {
        -                    "additionalProperties": true,
        -                    "description": "Optional min/max constraints on Greeks during resolution.",
        -                    "type": "object"
        -                  },
        -                  "liquidityFilter": {
        -                    "additionalProperties": false,
        -                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                    "properties": {
        -                      "maxSpreadAbsolute": {
        -                        "type": "number"
        -                      },
        -                      "maxSpreadPct": {
        -                        "type": "number"
        -                      },
        -                      "minBid": {
        -                        "type": "number"
        -                      }
        -                    },
        -                    "type": "object"
        -                  },
        -                  "optionType": {
        -                    "enum": [
        -                      "call",
        -                      "put"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "ratio": {
        -                    "type": "number"
        -                  },
        -                  "strikeRange": {
        -                    "additionalProperties": true,
        -                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                    "type": "object"
        -                  },
        -                  "strikeSelector": {
        -                    "properties": {
        -                      "distance": {
        -                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                        "type": "number"
        -                      },
        -                      "distanceType": {
        -                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "distanceType",
        -                      "distance"
        -                    ],
        -                    "type": "object"
        -                  }
        -                },
        -                "required": [
        -                  "optionType",
        -                  "direction",
        -                  "expirationSelector",
        -                  "strikeSelector"
        -                ],
        -                "type": "object"
        -              },
        -              "minItems": 1,
        -              "type": "array"
        -            },
        -            "name": {
        -              "type": "string"
        -            },
        -            "spreadType": {
        -              "enum": [
        -                "vertical",
        -                "calendar",
        -                "diagonal",
        -                "ironCondor",
        -                "straddle",
        -                "strangle",
        -                "custom"
        -              ],
        -              "type": "string"
        -            },
        -            "widthConstraint": {
        -              "additionalProperties": false,
        -              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -              "properties": {
        -                "minWidthDollars": {
        -                  "exclusiveMinimum": 0,
        -                  "type": "number"
        -                },
        -                "minWidthPercent": {
        -                  "exclusiveMinimum": 0,
        -                  "type": "number"
        -                }
        -              },
        -              "type": "object"
        -            }
        -          },
        -          "required": [
        -            "legs"
        -          ],
        -          "type": "object"
        -        },
        -        "minItems": 1,
        -        "type": "array"
        -      },
        -      "totalBudget": {
        -        "additionalProperties": true,
        -        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        -        "properties": {
        -          "amount": {
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "const": "RebalanceOption",
        -        "type": "string"
        -      },
        -      "universe": {
        -        "additionalProperties": true,
        -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -        "properties": {
        -          "assets": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -              "properties": {
        -                "name": {
        -                  "type": "string"
        -                },
        -                "symbol": {
        -                  "type": "string"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "Stock",
        -                    "Cryptocurrency",
        -                    "Option",
        -                    "Other"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "symbol"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "source": {
        -            "enum": [
        -              "ALL_US_STOCKS",
        -              "SP500",
        -              "NASDAQ100",
        -              "DJIA",
        -              "CRYPTO",
        -              "SPECIFIC_ASSETS"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "weightIndicator": {
        -        "$ref": "#/$defs/indicator"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "universe",
        -      "pipeline",
        -      "weightIndicator",
        -      "structureTemplates"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        -    "properties": {
        -      "closeScope": {
        -        "enum": [
        -          "spread",
        -          "leg"
        -        ],
        -        "type": "string"
        -      },
        -      "direction": {
        -        "enum": [
        -          "long",
        -          "short"
        -        ],
        -        "type": "string"
        -      },
        -      "optionType": {
        -        "enum": [
        -          "call",
        -          "put"
        -        ],
        -        "type": "string"
        -      },
        -      "quantity": {
        -        "additionalProperties": true,
        -        "description": "How many contracts to close. Defaults to all matching when omitted.",
        -        "type": "object"
        -      },
        -      "spreadType": {
        -        "enum": [
        -          "vertical",
        -          "calendar",
        -          "diagonal",
        -          "ironCondor",
        -          "straddle",
        -          "strangle",
        -          "custom"
        -        ],
        -        "type": "string"
        -      },
        -      "triggers": {
        -        "items": {
        -          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxPnlPercent": {
        -                  "type": "number"
        -                },
        -                "minPnlPercent": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "pnl",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxDte": {
        -                  "type": "number"
        -                },
        -                "minDte": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "dte",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxDaysHeld": {
        -                  "type": "number"
        -                },
        -                "minDaysHeld": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "daysHeld",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxIv": {
        -                  "type": "number"
        -                },
        -                "maxSpreadDelta": {
        -                  "type": "number"
        -                },
        -                "maxSpreadTheta": {
        -                  "type": "number"
        -                },
        -                "minIv": {
        -                  "type": "number"
        -                },
        -                "minSpreadDelta": {
        -                  "type": "number"
        -                },
        -                "minSpreadTheta": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "greeks",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "type": {
        -        "const": "CloseOption",
        -        "type": "string"
        -      },
        -      "underlyings": {
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array"
        -      }
        -    },
        -    "required": [
        -      "type"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": true,
        +    "description": "Buy or Sell a stock/crypto position.",
        +    "properties": {
        +      "amount": {
        +        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "percent of current positions",
        +              "dollars",
        +              "number of assets"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "targetAsset": {
        +        "additionalProperties": true,
        +        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +        "properties": {
        +          "name": {
        +            "type": "string"
        +          },
        +          "symbol": {
        +            "type": "string"
        +          },
        +          "type": {
        +            "enum": [
        +              "Stock",
        +              "Cryptocurrency",
        +              "Option",
        +              "Other"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "symbol"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "enum": [
        +          "Buy",
        +          "Sell"
        +        ],
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "targetAsset",
        +      "amount"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Send an alert message (no order).",
        +    "properties": {
        +      "message": {
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "Alert",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "message"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        +    "properties": {
        +      "allocationPolicy": {
        +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "expectedReturnShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "riskAversion": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MeanVariance",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "riskAversion",
        +              "expectedReturnShrinkage",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "RiskParity",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MaximumDiversification",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "canSell": {
        +        "$ref": "#/$defs/condition",
        +        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        +      },
        +      "deploymentPercent": {
        +        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        +        "maximum": 100,
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "exposurePolicy": {
        +        "additionalProperties": false,
        +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +        "properties": {
        +          "covarianceShrinkage": {
        +            "maximum": 1,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "estimatedTransactionCostBps": {
        +            "maximum": 10000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "lookbackPeriods": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "minimumObservations": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "targetAnnualizedVolatilityPercent": {
        +            "maximum": 1000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "const": "VolatilityTarget",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "lookbackPeriods",
        +          "minimumObservations",
        +          "covarianceShrinkage",
        +          "targetAnnualizedVolatilityPercent",
        +          "estimatedTransactionCostBps"
        +        ],
        +        "type": "object"
        +      },
        +      "limit": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "perNameAllocation": {
        +        "additionalProperties": true,
        +        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.",
        +        "properties": {
        +          "amount": {
        +            "exclusiveMinimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "percent of portfolio",
        +              "dollars"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "pipeline": {
        +        "items": {
        +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "condition": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "type": {
        +                  "const": "Filter",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "condition"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "type": {
        +                  "const": "SelectTop",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "limit",
        +                "direction"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "percentile": {
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "SelectPercentile",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "percentile",
        +                "direction"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "type": {
        +        "const": "DynamicRebalance",
        +        "type": "string"
        +      },
        +      "universe": {
        +        "additionalProperties": true,
        +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +        "properties": {
        +          "assets": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +              "properties": {
        +                "name": {
        +                  "type": "string"
        +                },
        +                "symbol": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Stock",
        +                    "Cryptocurrency",
        +                    "Option",
        +                    "Other"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "symbol"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "enum": [
        +              "ALL_US_STOCKS",
        +              "SP500",
        +              "NASDAQ100",
        +              "DJIA",
        +              "CRYPTO",
        +              "SPECIFIC_ASSETS"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "weightIndicator": {
        +        "$ref": "#/$defs/indicator"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "universe",
        +      "pipeline",
        +      "weightIndicator"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        +    "properties": {
        +      "continueExisting": {
        +        "type": "boolean"
        +      },
        +      "cooldownMinutes": {
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "executionModel": {
        +        "type": "string"
        +      },
        +      "includeMarketData": {
        +        "type": "boolean"
        +      },
        +      "initialMessage": {
        +        "type": "string"
        +      },
        +      "maxIterations": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "planningModel": {
        +        "type": "string"
        +      },
        +      "skipPlanning": {
        +        "type": "boolean"
        +      },
        +      "type": {
        +        "const": "LaunchAgent",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "planningModel",
        +      "executionModel",
        +      "initialMessage",
        +      "maxIterations",
        +      "includeMarketData",
        +      "continueExisting",
        +      "skipPlanning"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        +    "properties": {
        +      "against": {
        +        "additionalProperties": true,
        +        "description": "Optional parent-position selector (e.g. for covered calls).",
        +        "type": "object"
        +      },
        +      "allocation": {
        +        "additionalProperties": true,
        +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "contracts",
        +              "percent of realized premium"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "builder": {
        +        "additionalProperties": true,
        +        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        +        "properties": {
        +          "dynamicUnderlying": {
        +            "additionalProperties": true,
        +            "properties": {
        +              "limit": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "pipeline": {
        +                "items": {
        +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                  "oneOf": [
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "condition": {
        +                          "$ref": "#/$defs/condition"
        +                        },
        +                        "type": {
        +                          "const": "Filter",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "condition"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "limit": {
        +                          "minimum": 1,
        +                          "type": "number"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "type": {
        +                          "const": "SelectTop",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "limit",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "percentile": {
        +                          "maximum": 100,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "SelectPercentile",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "percentile",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "universe": {
        +                "additionalProperties": true,
        +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                "properties": {
        +                  "assets": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                      "properties": {
        +                        "name": {
        +                          "type": "string"
        +                        },
        +                        "symbol": {
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "enum": [
        +                            "Stock",
        +                            "Cryptocurrency",
        +                            "Option",
        +                            "Other"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "symbol"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "type": "array"
        +                  },
        +                  "source": {
        +                    "enum": [
        +                      "ALL_US_STOCKS",
        +                      "SP500",
        +                      "NASDAQ100",
        +                      "DJIA",
        +                      "CRYPTO",
        +                      "SPECIFIC_ASSETS"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "source"
        +                ],
        +                "type": "object"
        +              }
        +            },
        +            "required": [
        +              "universe"
        +            ],
        +            "type": "object"
        +          },
        +          "legs": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Single leg of an option builder.",
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "long",
        +                    "short"
        +                  ],
        +                  "type": "string"
        +                },
        +                "expirationRange": {
        +                  "additionalProperties": true,
        +                  "type": "object"
        +                },
        +                "expirationSelector": {
        +                  "properties": {
        +                    "maxDaysToExpiration": {
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "minDaysToExpiration": {
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "preference": {
        +                      "enum": [
        +                        "nearest",
        +                        "middle",
        +                        "furthest"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "minDaysToExpiration",
        +                    "maxDaysToExpiration",
        +                    "preference"
        +                  ],
        +                  "type": "object"
        +                },
        +                "fallbackStrikeSelector": {
        +                  "additionalProperties": false,
        +                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                  "properties": {
        +                    "distance": {
        +                      "type": "number"
        +                    },
        +                    "distanceType": {
        +                      "enum": [
        +                        "percent",
        +                        "dollars"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "distanceType",
        +                    "distance"
        +                  ],
        +                  "type": "object"
        +                },
        +                "greekFilter": {
        +                  "additionalProperties": true,
        +                  "description": "Optional min/max constraints on Greeks during resolution.",
        +                  "type": "object"
        +                },
        +                "liquidityFilter": {
        +                  "additionalProperties": false,
        +                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                  "properties": {
        +                    "maxSpreadAbsolute": {
        +                      "type": "number"
        +                    },
        +                    "maxSpreadPct": {
        +                      "type": "number"
        +                    },
        +                    "minBid": {
        +                      "type": "number"
        +                    }
        +                  },
        +                  "type": "object"
        +                },
        +                "optionType": {
        +                  "enum": [
        +                    "call",
        +                    "put"
        +                  ],
        +                  "type": "string"
        +                },
        +                "ratio": {
        +                  "type": "number"
        +                },
        +                "strikeRange": {
        +                  "additionalProperties": true,
        +                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                  "type": "object"
        +                },
        +                "strikeSelector": {
        +                  "properties": {
        +                    "distance": {
        +                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                      "type": "number"
        +                    },
        +                    "distanceType": {
        +                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "distanceType",
        +                    "distance"
        +                  ],
        +                  "type": "object"
        +                }
        +              },
        +              "required": [
        +                "optionType",
        +                "direction",
        +                "expirationSelector",
        +                "strikeSelector"
        +              ],
        +              "type": "object"
        +            },
        +            "minItems": 1,
        +            "type": "array"
        +          },
        +          "spreadType": {
        +            "enum": [
        +              "vertical",
        +              "calendar",
        +              "diagonal",
        +              "ironCondor",
        +              "straddle",
        +              "strangle",
        +              "custom"
        +            ],
        +            "type": "string"
        +          },
        +          "underlyingSymbol": {
        +            "type": "string"
        +          },
        +          "widthConstraint": {
        +            "additionalProperties": false,
        +            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +            "properties": {
        +              "minWidthDollars": {
        +                "exclusiveMinimum": 0,
        +                "type": "number"
        +              },
        +              "minWidthPercent": {
        +                "exclusiveMinimum": 0,
        +                "type": "number"
        +              }
        +            },
        +            "type": "object"
        +          }
        +        },
        +        "required": [
        +          "legs"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "const": "OpenOption",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "builder"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        +    "properties": {
        +      "allocationPolicy": {
        +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "expectedReturnShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "riskAversion": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MeanVariance",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "riskAversion",
        +              "expectedReturnShrinkage",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "RiskParity",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MaximumDiversification",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "exposurePolicy": {
        +        "additionalProperties": false,
        +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +        "properties": {
        +          "covarianceShrinkage": {
        +            "maximum": 1,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "estimatedTransactionCostBps": {
        +            "maximum": 10000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "lookbackPeriods": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "minimumObservations": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "targetAnnualizedVolatilityPercent": {
        +            "maximum": 1000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "const": "VolatilityTarget",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "lookbackPeriods",
        +          "minimumObservations",
        +          "covarianceShrinkage",
        +          "targetAnnualizedVolatilityPercent",
        +          "estimatedTransactionCostBps"
        +        ],
        +        "type": "object"
        +      },
        +      "limit": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "perNameAllocation": {
        +        "additionalProperties": true,
        +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "contracts",
        +              "percent of realized premium"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "pipeline": {
        +        "items": {
        +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "condition": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "type": {
        +                  "const": "Filter",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "condition"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "type": {
        +                  "const": "SelectTop",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "limit",
        +                "direction"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "percentile": {
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "SelectPercentile",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "percentile",
        +                "direction"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "positionScope": {
        +        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        +        "enum": [
        +          "portfolio",
        +          "strategy"
        +        ],
        +        "type": "string"
        +      },
        +      "sleeves": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        +          "properties": {
        +            "limit": {
        +              "minimum": 1,
        +              "type": "number"
        +            },
        +            "name": {
        +              "type": "string"
        +            },
        +            "perNameAllocation": {
        +              "additionalProperties": true,
        +              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +              "properties": {
        +                "amount": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "dollars",
        +                    "percent of portfolio",
        +                    "percent of buying power",
        +                    "contracts",
        +                    "percent of realized premium"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "amount"
        +              ],
        +              "type": "object"
        +            },
        +            "pipeline": {
        +              "items": {
        +                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                "oneOf": [
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "condition": {
        +                        "$ref": "#/$defs/condition"
        +                      },
        +                      "type": {
        +                        "const": "Filter",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "condition"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "direction": {
        +                        "enum": [
        +                          "Highest",
        +                          "Lowest"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "limit": {
        +                        "minimum": 1,
        +                        "type": "number"
        +                      },
        +                      "metric": {
        +                        "$ref": "#/$defs/indicator"
        +                      },
        +                      "type": {
        +                        "const": "SelectTop",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "metric",
        +                      "limit",
        +                      "direction"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "direction": {
        +                        "enum": [
        +                          "Highest",
        +                          "Lowest"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "metric": {
        +                        "$ref": "#/$defs/indicator"
        +                      },
        +                      "percentile": {
        +                        "maximum": 100,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "SelectPercentile",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "metric",
        +                      "percentile",
        +                      "direction"
        +                    ],
        +                    "type": "object"
        +                  }
        +                ],
        +                "type": "object"
        +              },
        +              "type": "array"
        +            },
        +            "structureTemplates": {
        +              "items": {
        +                "additionalProperties": true,
        +                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +                "properties": {
        +                  "eligibility": {
        +                    "$ref": "#/$defs/condition"
        +                  },
        +                  "legs": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Single leg of an option builder.",
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "long",
        +                            "short"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "expirationRange": {
        +                          "additionalProperties": true,
        +                          "type": "object"
        +                        },
        +                        "expirationSelector": {
        +                          "properties": {
        +                            "maxDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "minDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "preference": {
        +                              "enum": [
        +                                "nearest",
        +                                "middle",
        +                                "furthest"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "minDaysToExpiration",
        +                            "maxDaysToExpiration",
        +                            "preference"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "fallbackStrikeSelector": {
        +                          "additionalProperties": false,
        +                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                          "properties": {
        +                            "distance": {
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "enum": [
        +                                "percent",
        +                                "dollars"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "greekFilter": {
        +                          "additionalProperties": true,
        +                          "description": "Optional min/max constraints on Greeks during resolution.",
        +                          "type": "object"
        +                        },
        +                        "liquidityFilter": {
        +                          "additionalProperties": false,
        +                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                          "properties": {
        +                            "maxSpreadAbsolute": {
        +                              "type": "number"
        +                            },
        +                            "maxSpreadPct": {
        +                              "type": "number"
        +                            },
        +                            "minBid": {
        +                              "type": "number"
        +                            }
        +                          },
        +                          "type": "object"
        +                        },
        +                        "optionType": {
        +                          "enum": [
        +                            "call",
        +                            "put"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "ratio": {
        +                          "type": "number"
        +                        },
        +                        "strikeRange": {
        +                          "additionalProperties": true,
        +                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                          "type": "object"
        +                        },
        +                        "strikeSelector": {
        +                          "properties": {
        +                            "distance": {
        +                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        }
        +                      },
        +                      "required": [
        +                        "optionType",
        +                        "direction",
        +                        "expirationSelector",
        +                        "strikeSelector"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "minItems": 1,
        +                    "type": "array"
        +                  },
        +                  "name": {
        +                    "type": "string"
        +                  },
        +                  "spreadType": {
        +                    "enum": [
        +                      "vertical",
        +                      "calendar",
        +                      "diagonal",
        +                      "ironCondor",
        +                      "straddle",
        +                      "strangle",
        +                      "custom"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "widthConstraint": {
        +                    "additionalProperties": false,
        +                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                    "properties": {
        +                      "minWidthDollars": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minWidthPercent": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "legs"
        +                ],
        +                "type": "object"
        +              },
        +              "minItems": 1,
        +              "type": "array"
        +            },
        +            "universe": {
        +              "additionalProperties": true,
        +              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +              "properties": {
        +                "assets": {
        +                  "items": {
        +                    "additionalProperties": true,
        +                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                    "properties": {
        +                      "name": {
        +                        "type": "string"
        +                      },
        +                      "symbol": {
        +                        "type": "string"
        +                      },
        +                      "type": {
        +                        "enum": [
        +                          "Stock",
        +                          "Cryptocurrency",
        +                          "Option",
        +                          "Other"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "symbol"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "type": "array"
        +                },
        +                "source": {
        +                  "enum": [
        +                    "ALL_US_STOCKS",
        +                    "SP500",
        +                    "NASDAQ100",
        +                    "DJIA",
        +                    "CRYPTO",
        +                    "SPECIFIC_ASSETS"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "source"
        +              ],
        +              "type": "object"
        +            },
        +            "weightIndicator": {
        +              "$ref": "#/$defs/indicator"
        +            }
        +          },
        +          "required": [
        +            "name"
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "structureTemplates": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +          "properties": {
        +            "eligibility": {
        +              "$ref": "#/$defs/condition"
        +            },
        +            "legs": {
        +              "items": {
        +                "additionalProperties": true,
        +                "description": "Single leg of an option builder.",
        +                "properties": {
        +                  "direction": {
        +                    "enum": [
        +                      "long",
        +                      "short"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "expirationRange": {
        +                    "additionalProperties": true,
        +                    "type": "object"
        +                  },
        +                  "expirationSelector": {
        +                    "properties": {
        +                      "maxDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "preference": {
        +                        "enum": [
        +                          "nearest",
        +                          "middle",
        +                          "furthest"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "minDaysToExpiration",
        +                      "maxDaysToExpiration",
        +                      "preference"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "fallbackStrikeSelector": {
        +                    "additionalProperties": false,
        +                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                    "properties": {
        +                      "distance": {
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "enum": [
        +                          "percent",
        +                          "dollars"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "greekFilter": {
        +                    "additionalProperties": true,
        +                    "description": "Optional min/max constraints on Greeks during resolution.",
        +                    "type": "object"
        +                  },
        +                  "liquidityFilter": {
        +                    "additionalProperties": false,
        +                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                    "properties": {
        +                      "maxSpreadAbsolute": {
        +                        "type": "number"
        +                      },
        +                      "maxSpreadPct": {
        +                        "type": "number"
        +                      },
        +                      "minBid": {
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  },
        +                  "optionType": {
        +                    "enum": [
        +                      "call",
        +                      "put"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "ratio": {
        +                    "type": "number"
        +                  },
        +                  "strikeRange": {
        +                    "additionalProperties": true,
        +                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                    "type": "object"
        +                  },
        +                  "strikeSelector": {
        +                    "properties": {
        +                      "distance": {
        +                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "optionType",
        +                  "direction",
        +                  "expirationSelector",
        +                  "strikeSelector"
        +                ],
        +                "type": "object"
        +              },
        +              "minItems": 1,
        +              "type": "array"
        +            },
        +            "name": {
        +              "type": "string"
        +            },
        +            "spreadType": {
        +              "enum": [
        +                "vertical",
        +                "calendar",
        +                "diagonal",
        +                "ironCondor",
        +                "straddle",
        +                "strangle",
        +                "custom"
        +              ],
        +              "type": "string"
        +            },
        +            "widthConstraint": {
        +              "additionalProperties": false,
        +              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +              "properties": {
        +                "minWidthDollars": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                },
        +                "minWidthPercent": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                }
        +              },
        +              "type": "object"
        +            }
        +          },
        +          "required": [
        +            "legs"
        +          ],
        +          "type": "object"
        +        },
        +        "minItems": 1,
        +        "type": "array"
        +      },
        +      "totalBudget": {
        +        "additionalProperties": true,
        +        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        +        "properties": {
        +          "amount": {
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "const": "RebalanceOption",
        +        "type": "string"
        +      },
        +      "universe": {
        +        "additionalProperties": true,
        +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +        "properties": {
        +          "assets": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +              "properties": {
        +                "name": {
        +                  "type": "string"
        +                },
        +                "symbol": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Stock",
        +                    "Cryptocurrency",
        +                    "Option",
        +                    "Other"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "symbol"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "enum": [
        +              "ALL_US_STOCKS",
        +              "SP500",
        +              "NASDAQ100",
        +              "DJIA",
        +              "CRYPTO",
        +              "SPECIFIC_ASSETS"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "weightIndicator": {
        +        "$ref": "#/$defs/indicator"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "universe",
        +      "pipeline",
        +      "weightIndicator",
        +      "structureTemplates"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        +    "properties": {
        +      "closeScope": {
        +        "enum": [
        +          "spread",
        +          "leg"
        +        ],
        +        "type": "string"
        +      },
        +      "direction": {
        +        "enum": [
        +          "long",
        +          "short"
        +        ],
        +        "type": "string"
        +      },
        +      "optionType": {
        +        "enum": [
        +          "call",
        +          "put"
        +        ],
        +        "type": "string"
        +      },
        +      "quantity": {
        +        "additionalProperties": true,
        +        "description": "How many contracts to close. Defaults to all matching when omitted.",
        +        "type": "object"
        +      },
        +      "spreadType": {
        +        "enum": [
        +          "vertical",
        +          "calendar",
        +          "diagonal",
        +          "ironCondor",
        +          "straddle",
        +          "strangle",
        +          "custom"
        +        ],
        +        "type": "string"
        +      },
        +      "triggers": {
        +        "items": {
        +          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxPnlPercent": {
        +                  "type": "number"
        +                },
        +                "minPnlPercent": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "pnl",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxDte": {
        +                  "type": "number"
        +                },
        +                "minDte": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "dte",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxDaysHeld": {
        +                  "type": "number"
        +                },
        +                "minDaysHeld": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "daysHeld",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxIv": {
        +                  "type": "number"
        +                },
        +                "maxSpreadDelta": {
        +                  "type": "number"
        +                },
        +                "maxSpreadTheta": {
        +                  "type": "number"
        +                },
        +                "minIv": {
        +                  "type": "number"
        +                },
        +                "minSpreadDelta": {
        +                  "type": "number"
        +                },
        +                "minSpreadTheta": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "greeks",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "type": {
        +        "const": "CloseOption",
        +        "type": "string"
        +      },
        +      "underlyings": {
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  }
        +]
      • changedInput schema / $defs / indicator / description
        Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), Option* indicators (need underlying + optionType + direction + spreadType), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
      • addedInput schema / $defs / indicator / properties / lookbackDays
        Added value: +{
        +  "description": "OptionRealizedPnL / OptionRealizedPremium: only count activity within this many days of the evaluation date. Omit for the whole life of the book.",
        +  "maximum": 36500,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • changedInput schema / $defs / indicator / properties / type / enum
        Previous value: -[
        -  "DaysSinceAgent",
        -  "MinutesSinceAgent",
        -  "DaysSinceAlert",
        -  "MinutesSinceAlert",
        -  "StockReport",
        -  "DaysUntilEarnings",
        -  "DaysSinceEarnings",
        -  "ImpliedVolatility",
        -  "IVRank",
        -  "IVPercentile",
        -  "IVHVRatio",
        -  "LastOrderPrice",
        -  "Fundamental",
        -  "Economic",
        -  "CustomIndicator",
        -  "Index",
        -  "BollingerBand",
        -  "RelativeStrengthIndex",
        -  "PriceMeanAbsoluteDeviation",
        -  "ExponentialMovingAverage",
        -  "SimpleMovingAverage",
        -  "PriceStandardDeviation",
        -  "PriceRateOfChange",
        -  "MaxDrawdown",
        -  "MaxDrawup",
        -  "MinimumPrice",
        -  "MaximumPrice",
        -  "IndicatorMeanAbsoluteDeviation",
        -  "IndicatorExponentialMovingAverage",
        -  "IndicatorSimpleMovingAverage",
        -  "IndicatorStandardDeviation",
        -  "IndicatorRateOfChange",
        -  "DaysSinceOrder",
        -  "DaysSinceOptionOrder",
        -  "DaysSinceStrategyFired",
        -  "DaysSinceLastRebalanceOptionOrder",
        -  "MinutesSinceOptionOrder",
        -  "MinutesSinceOrder",
        -  "DaysSinceTransaction",
        -  "InitialValue",
        -  "BuyingPower",
        -  "PositionValue",
        -  "PositionPercentChange",
        -  "PortfolioValue",
        -  "RebalanceDecisionMetric",
        -  "Value",
        -  "Price",
        -  "Plus",
        -  "Minus",
        -  "Multiply",
        -  "Divide",
        -  "Negative",
        -  "AbsoluteValue",
        -  "SquareRoot",
        -  "Max",
        -  "Min",
        -  "Day",
        -  "Month",
        -  "Date",
        -  "Year",
        -  "CurrentTimeSeconds",
        -  "CurrentTimeMinutes",
        -  "CurrentTimeHours",
        -  "TrailingSum",
        -  "CompoundAnnualGrowthRate",
        -  "Log",
        -  "Exponentiation",
        -  "SumOrderQuantity",
        -  "SumOrderAmount",
        -  "MinutesAfterOpen",
        -  "OpeningPrice",
        -  "PreviousClosingPrice",
        -  "HighOfDay",
        -  "LowOfDay",
        -  "MinutesUntilClose",
        -  "PriceChangeSinceOpen",
        -  "GapSize",
        -  "GapPercentage",
        -  "TrueRange",
        -  "AverageTrueRange",
        -  "Volume",
        -  "VWAP",
        -  "BullishFairValueGap",
        -  "BearishFairValueGap",
        -  "IndicatorAtMinutesAfterOpen",
        -  "IndicatorWindowAgo",
        -  "IndicatorAtEntry",
        -  "IsIndexMember",
        -  "IsIndustry",
        -  "IsAssetType",
        -  "IsAsset",
        -  "IsNotAsset",
        -  "CrossAbove",
        -  "CrossBelow",
        -  "PositionMaxDrawdown",
        -  "PositionMaxDrawup",
        -  "UnderlyingMaxDrawdown",
        -  "ConsecutiveTrue",
        -  "CountTrue",
        -  "OptionPositionValue",
        -  "OptionPositionCount",
        -  "OptionPositionPercentChange",
        -  "OptionPositionMaxDrawdown",
        -  "OptionDaysToExpiration",
        -  "OptionDaysHeld",
        -  "OptionCollateral",
        -  "OptionSpreadCount",
        -  "OptionUnrealizedPnL",
        -  "OptionGrossExposurePercent"
        -]New value: +[
        +  "DaysSinceAgent",
        +  "MinutesSinceAgent",
        +  "DaysSinceAlert",
        +  "MinutesSinceAlert",
        +  "StockReport",
        +  "DaysUntilEarnings",
        +  "DaysSinceEarnings",
        +  "ImpliedVolatility",
        +  "IVRank",
        +  "IVPercentile",
        +  "IVHVRatio",
        +  "LastOrderPrice",
        +  "Fundamental",
        +  "Economic",
        +  "CustomIndicator",
        +  "Index",
        +  "BollingerBand",
        +  "RelativeStrengthIndex",
        +  "PriceMeanAbsoluteDeviation",
        +  "ExponentialMovingAverage",
        +  "SimpleMovingAverage",
        +  "PriceStandardDeviation",
        +  "PriceRateOfChange",
        +  "MaxDrawdown",
        +  "MaxDrawup",
        +  "MinimumPrice",
        +  "MaximumPrice",
        +  "IndicatorMeanAbsoluteDeviation",
        +  "IndicatorExponentialMovingAverage",
        +  "IndicatorSimpleMovingAverage",
        +  "IndicatorStandardDeviation",
        +  "IndicatorRateOfChange",
        +  "DaysSinceOrder",
        +  "DaysSinceOptionOrder",
        +  "DaysSinceStrategyFired",
        +  "DaysSinceLastRebalanceOptionOrder",
        +  "MinutesSinceOptionOrder",
        +  "MinutesSinceOrder",
        +  "DaysSinceTransaction",
        +  "InitialValue",
        +  "BuyingPower",
        +  "PositionValue",
        +  "PositionPercentChange",
        +  "PortfolioValue",
        +  "RebalanceDecisionMetric",
        +  "Value",
        +  "Price",
        +  "Plus",
        +  "Minus",
        +  "Multiply",
        +  "Divide",
        +  "Negative",
        +  "AbsoluteValue",
        +  "SquareRoot",
        +  "Max",
        +  "Min",
        +  "Day",
        +  "Month",
        +  "Date",
        +  "Year",
        +  "CurrentTimeSeconds",
        +  "CurrentTimeMinutes",
        +  "CurrentTimeHours",
        +  "TrailingSum",
        +  "CompoundAnnualGrowthRate",
        +  "Log",
        +  "Exponentiation",
        +  "SumOrderQuantity",
        +  "SumOrderAmount",
        +  "MinutesAfterOpen",
        +  "OpeningPrice",
        +  "PreviousClosingPrice",
        +  "HighOfDay",
        +  "LowOfDay",
        +  "MinutesUntilClose",
        +  "PriceChangeSinceOpen",
        +  "GapSize",
        +  "GapPercentage",
        +  "TrueRange",
        +  "AverageTrueRange",
        +  "Volume",
        +  "VWAP",
        +  "BullishFairValueGap",
        +  "BearishFairValueGap",
        +  "IndicatorAtMinutesAfterOpen",
        +  "IndicatorWindowAgo",
        +  "IndicatorAtEntry",
        +  "IsIndexMember",
        +  "IsIndustry",
        +  "IsAssetType",
        +  "IsAsset",
        +  "IsNotAsset",
        +  "CrossAbove",
        +  "CrossBelow",
        +  "PositionMaxDrawdown",
        +  "PositionMaxDrawup",
        +  "UnderlyingMaxDrawdown",
        +  "ConsecutiveTrue",
        +  "CountTrue",
        +  "OptionPositionValue",
        +  "OptionPositionCount",
        +  "OptionPositionPercentChange",
        +  "OptionPositionMaxDrawdown",
        +  "OptionDaysToExpiration",
        +  "OptionDaysHeld",
        +  "OptionCollateral",
        +  "OptionSpreadCount",
        +  "OptionUnrealizedPnL",
        +  "OptionRealizedPnL",
        +  "OptionRealizedPremium",
        +  "OptionGrossExposurePercent"
        +]
      • changedInput schema / $defs / rebalanceOptionSleeve / properties / perNameAllocation / description
        Previous value: -"Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'."New value: +"Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'."
      • changedInput schema / $defs / rebalanceOptionSleeve / properties / perNameAllocation / properties / type / enum
        Previous value: -[
        -  "dollars",
        -  "percent of portfolio",
        -  "percent of buying power",
        -  "contracts"
        -]New value: +[
        +  "dollars",
        +  "percent of portfolio",
        +  "percent of buying power",
        +  "contracts",
        +  "percent of realized premium"
        +]
      • changedInput schema / $defs / strategy / properties / action / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "description": "Buy or Sell a stock/crypto position.",
        -    "properties": {
        -      "amount": {
        -        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "percent of current positions",
        -              "dollars",
        -              "number of assets"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "targetAsset": {
        -        "additionalProperties": true,
        -        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -        "properties": {
        -          "name": {
        -            "type": "string"
        -          },
        -          "symbol": {
        -            "type": "string"
        -          },
        -          "type": {
        -            "enum": [
        -              "Stock",
        -              "Cryptocurrency",
        -              "Option",
        -              "Other"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "symbol"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "enum": [
        -          "Buy",
        -          "Sell"
        -        ],
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "targetAsset",
        -      "amount"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Send an alert message (no order).",
        -    "properties": {
        -      "message": {
        -        "type": "string"
        -      },
        -      "type": {
        -        "const": "Alert",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "message"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        -    "properties": {
        -      "allocationPolicy": {
        -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "expectedReturnShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "riskAversion": {
        -                "maximum": 1000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MeanVariance",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "riskAversion",
        -              "expectedReturnShrinkage",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "RiskParity",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumDiversification",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "canSell": {
        -        "$ref": "#/$defs/condition",
        -        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        -      },
        -      "deploymentPercent": {
        -        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        -        "maximum": 100,
        -        "minimum": 0,
        -        "type": "number"
        -      },
        -      "exposurePolicy": {
        -        "additionalProperties": false,
        -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        -        "properties": {
        -          "covarianceShrinkage": {
        -            "maximum": 1,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "estimatedTransactionCostBps": {
        -            "maximum": 10000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "lookbackPeriods": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "minimumObservations": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "targetAnnualizedVolatilityPercent": {
        -            "maximum": 1000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "const": "VolatilityTarget",
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "lookbackPeriods",
        -          "minimumObservations",
        -          "covarianceShrinkage",
        -          "targetAnnualizedVolatilityPercent",
        -          "estimatedTransactionCostBps"
        -        ],
        -        "type": "object"
        -      },
        -      "limit": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "perNameAllocation": {
        -        "additionalProperties": true,
        -        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
        -        "properties": {
        -          "amount": {
        -            "exclusiveMinimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "percent of portfolio",
        -              "dollars"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "pipeline": {
        -        "items": {
        -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "condition": {
        -                  "$ref": "#/$defs/condition"
        -                },
        -                "type": {
        -                  "const": "Filter",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "condition"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "limit": {
        -                  "minimum": 1,
        -                  "type": "number"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "type": {
        -                  "const": "SelectTop",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "limit",
        -                "direction"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "percentile": {
        -                  "maximum": 100,
        -                  "minimum": 0,
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "SelectPercentile",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "percentile",
        -                "direction"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "type": {
        -        "const": "DynamicRebalance",
        -        "type": "string"
        -      },
        -      "universe": {
        -        "additionalProperties": true,
        -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -        "properties": {
        -          "assets": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -              "properties": {
        -                "name": {
        -                  "type": "string"
        -                },
        -                "symbol": {
        -                  "type": "string"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "Stock",
        -                    "Cryptocurrency",
        -                    "Option",
        -                    "Other"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "symbol"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "source": {
        -            "enum": [
        -              "ALL_US_STOCKS",
        -              "SP500",
        -              "NASDAQ100",
        -              "DJIA",
        -              "CRYPTO",
        -              "SPECIFIC_ASSETS"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "weightIndicator": {
        -        "$ref": "#/$defs/indicator"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "universe",
        -      "pipeline",
        -      "weightIndicator"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        -    "properties": {
        -      "continueExisting": {
        -        "type": "boolean"
        -      },
        -      "cooldownMinutes": {
        -        "minimum": 0,
        -        "type": "number"
        -      },
        -      "executionModel": {
        -        "type": "string"
        -      },
        -      "includeMarketData": {
        -        "type": "boolean"
        -      },
        -      "initialMessage": {
        -        "type": "string"
        -      },
        -      "maxIterations": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "planningModel": {
        -        "type": "string"
        -      },
        -      "skipPlanning": {
        -        "type": "boolean"
        -      },
        -      "type": {
        -        "const": "LaunchAgent",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "planningModel",
        -      "executionModel",
        -      "initialMessage",
        -      "maxIterations",
        -      "includeMarketData",
        -      "continueExisting",
        -      "skipPlanning"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        -    "properties": {
        -      "against": {
        -        "additionalProperties": true,
        -        "description": "Optional parent-position selector (e.g. for covered calls).",
        -        "type": "object"
        -      },
        -      "allocation": {
        -        "additionalProperties": true,
        -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "contracts"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "builder": {
        -        "additionalProperties": true,
        -        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        -        "properties": {
        -          "dynamicUnderlying": {
        -            "additionalProperties": true,
        -            "properties": {
        -              "limit": {
        -                "minimum": 1,
        -                "type": "number"
        -              },
        -              "pipeline": {
        -                "items": {
        -                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -                  "oneOf": [
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "condition": {
        -                          "$ref": "#/$defs/condition"
        -                        },
        -                        "type": {
        -                          "const": "Filter",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "condition"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "Highest",
        -                            "Lowest"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "limit": {
        -                          "minimum": 1,
        -                          "type": "number"
        -                        },
        -                        "metric": {
        -                          "$ref": "#/$defs/indicator"
        -                        },
        -                        "type": {
        -                          "const": "SelectTop",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "metric",
        -                        "limit",
        -                        "direction"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "Highest",
        -                            "Lowest"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "metric": {
        -                          "$ref": "#/$defs/indicator"
        -                        },
        -                        "percentile": {
        -                          "maximum": 100,
        -                          "minimum": 0,
        -                          "type": "number"
        -                        },
        -                        "type": {
        -                          "const": "SelectPercentile",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "metric",
        -                        "percentile",
        -                        "direction"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ],
        -                  "type": "object"
        -                },
        -                "type": "array"
        -              },
        -              "universe": {
        -                "additionalProperties": true,
        -                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -                "properties": {
        -                  "assets": {
        -                    "items": {
        -                      "additionalProperties": true,
        -                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -                      "properties": {
        -                        "name": {
        -                          "type": "string"
        -                        },
        -                        "symbol": {
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "enum": [
        -                            "Stock",
        -                            "Cryptocurrency",
        -                            "Option",
        -                            "Other"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "symbol"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    "type": "array"
        -                  },
        -                  "source": {
        -                    "enum": [
        -                      "ALL_US_STOCKS",
        -                      "SP500",
        -                      "NASDAQ100",
        -                      "DJIA",
        -                      "CRYPTO",
        -                      "SPECIFIC_ASSETS"
        -                    ],
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "source"
        -                ],
        -                "type": "object"
        -              }
        -            },
        -            "required": [
        -              "universe"
        -            ],
        -            "type": "object"
        -          },
        -          "legs": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Single leg of an option builder.",
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "long",
        -                    "short"
        -                  ],
        -                  "type": "string"
        -                },
        -                "expirationRange": {
        -                  "additionalProperties": true,
        -                  "type": "object"
        -                },
        -                "expirationSelector": {
        -                  "properties": {
        -                    "maxDaysToExpiration": {
        -                      "minimum": 0,
        -                      "type": "number"
        -                    },
        -                    "minDaysToExpiration": {
        -                      "minimum": 0,
        -                      "type": "number"
        -                    },
        -                    "preference": {
        -                      "enum": [
        -                        "nearest",
        -                        "middle",
        -                        "furthest"
        -                      ],
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "minDaysToExpiration",
        -                    "maxDaysToExpiration",
        -                    "preference"
        -                  ],
        -                  "type": "object"
        -                },
        -                "fallbackStrikeSelector": {
        -                  "additionalProperties": false,
        -                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                  "properties": {
        -                    "distance": {
        -                      "type": "number"
        -                    },
        -                    "distanceType": {
        -                      "enum": [
        -                        "percent",
        -                        "dollars"
        -                      ],
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "distanceType",
        -                    "distance"
        -                  ],
        -                  "type": "object"
        -                },
        -                "greekFilter": {
        -                  "additionalProperties": true,
        -                  "description": "Optional min/max constraints on Greeks during resolution.",
        -                  "type": "object"
        -                },
        -                "liquidityFilter": {
        -                  "additionalProperties": false,
        -                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                  "properties": {
        -                    "maxSpreadAbsolute": {
        -                      "type": "number"
        -                    },
        -                    "maxSpreadPct": {
        -                      "type": "number"
        -                    },
        -                    "minBid": {
        -                      "type": "number"
        -                    }
        -                  },
        -                  "type": "object"
        -                },
        -                "optionType": {
        -                  "enum": [
        -                    "call",
        -                    "put"
        -                  ],
        -                  "type": "string"
        -                },
        -                "ratio": {
        -                  "type": "number"
        -                },
        -                "strikeRange": {
        -                  "additionalProperties": true,
        -                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                  "type": "object"
        -                },
        -                "strikeSelector": {
        -                  "properties": {
        -                    "distance": {
        -                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                      "type": "number"
        -                    },
        -                    "distanceType": {
        -                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "distanceType",
        -                    "distance"
        -                  ],
        -                  "type": "object"
        -                }
        -              },
        -              "required": [
        -                "optionType",
        -                "direction",
        -                "expirationSelector",
        -                "strikeSelector"
        -              ],
        -              "type": "object"
        -            },
        -            "minItems": 1,
        -            "type": "array"
        -          },
        -          "spreadType": {
        -            "enum": [
        -              "vertical",
        -              "calendar",
        -              "diagonal",
        -              "ironCondor",
        -              "straddle",
        -              "strangle",
        -              "custom"
        -            ],
        -            "type": "string"
        -          },
        -          "underlyingSymbol": {
        -            "type": "string"
        -          },
        -          "widthConstraint": {
        -            "additionalProperties": false,
        -            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -            "properties": {
        -              "minWidthDollars": {
        -                "exclusiveMinimum": 0,
        -                "type": "number"
        -              },
        -              "minWidthPercent": {
        -                "exclusiveMinimum": 0,
        -                "type": "number"
        -              }
        -            },
        -            "type": "object"
        -          }
        -        },
        -        "required": [
        -          "legs"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "const": "OpenOption",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "builder"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        -    "properties": {
        -      "allocationPolicy": {
        -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "expectedReturnShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "riskAversion": {
        -                "maximum": 1000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MeanVariance",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "riskAversion",
        -              "expectedReturnShrinkage",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "RiskParity",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumDiversification",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "exposurePolicy": {
        -        "additionalProperties": false,
        -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        -        "properties": {
        -          "covarianceShrinkage": {
        -            "maximum": 1,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "estimatedTransactionCostBps": {
        -            "maximum": 10000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "lookbackPeriods": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "minimumObservations": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "targetAnnualizedVolatilityPercent": {
        -            "maximum": 1000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "const": "VolatilityTarget",
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "lookbackPeriods",
        -          "minimumObservations",
        -          "covarianceShrinkage",
        -          "targetAnnualizedVolatilityPercent",
        -          "estimatedTransactionCostBps"
        -        ],
        -        "type": "object"
        -      },
        -      "limit": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "perNameAllocation": {
        -        "additionalProperties": true,
        -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "contracts"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "pipeline": {
        -        "items": {
        -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "condition": {
        -                  "$ref": "#/$defs/condition"
        -                },
        -                "type": {
        -                  "const": "Filter",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "condition"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "limit": {
        -                  "minimum": 1,
        -                  "type": "number"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "type": {
        -                  "const": "SelectTop",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "limit",
        -                "direction"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "percentile": {
        -                  "maximum": 100,
        -                  "minimum": 0,
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "SelectPercentile",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "percentile",
        -                "direction"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "positionScope": {
        -        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        -        "enum": [
        -          "portfolio",
        -          "strategy"
        -        ],
        -        "type": "string"
        -      },
        -      "sleeves": {
        -        "items": {
        -          "additionalProperties": true,
        -          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        -          "properties": {
        -            "limit": {
        -              "minimum": 1,
        -              "type": "number"
        -            },
        -            "name": {
        -              "type": "string"
        -            },
        -            "perNameAllocation": {
        -              "additionalProperties": true,
        -              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -              "properties": {
        -                "amount": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "dollars",
        -                    "percent of portfolio",
        -                    "percent of buying power",
        -                    "contracts"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "amount"
        -              ],
        -              "type": "object"
        -            },
        -            "pipeline": {
        -              "items": {
        -                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -                "oneOf": [
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "condition": {
        -                        "$ref": "#/$defs/condition"
        -                      },
        -                      "type": {
        -                        "const": "Filter",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "condition"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "direction": {
        -                        "enum": [
        -                          "Highest",
        -                          "Lowest"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "limit": {
        -                        "minimum": 1,
        -                        "type": "number"
        -                      },
        -                      "metric": {
        -                        "$ref": "#/$defs/indicator"
        -                      },
        -                      "type": {
        -                        "const": "SelectTop",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "metric",
        -                      "limit",
        -                      "direction"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "direction": {
        -                        "enum": [
        -                          "Highest",
        -                          "Lowest"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "metric": {
        -                        "$ref": "#/$defs/indicator"
        -                      },
        -                      "percentile": {
        -                        "maximum": 100,
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "type": {
        -                        "const": "SelectPercentile",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "metric",
        -                      "percentile",
        -                      "direction"
        -                    ],
        -                    "type": "object"
        -                  }
        -                ],
        -                "type": "object"
        -              },
        -              "type": "array"
        -            },
        -            "structureTemplates": {
        -              "items": {
        -                "additionalProperties": true,
        -                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        -                "properties": {
        -                  "eligibility": {
        -                    "$ref": "#/$defs/condition"
        -                  },
        -                  "legs": {
        -                    "items": {
        -                      "additionalProperties": true,
        -                      "description": "Single leg of an option builder.",
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "long",
        -                            "short"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "expirationRange": {
        -                          "additionalProperties": true,
        -                          "type": "object"
        -                        },
        -                        "expirationSelector": {
        -                          "properties": {
        -                            "maxDaysToExpiration": {
        -                              "minimum": 0,
        -                              "type": "number"
        -                            },
        -                            "minDaysToExpiration": {
        -                              "minimum": 0,
        -                              "type": "number"
        -                            },
        -                            "preference": {
        -                              "enum": [
        -                                "nearest",
        -                                "middle",
        -                                "furthest"
        -                              ],
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "minDaysToExpiration",
        -                            "maxDaysToExpiration",
        -                            "preference"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "fallbackStrikeSelector": {
        -                          "additionalProperties": false,
        -                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                          "properties": {
        -                            "distance": {
        -                              "type": "number"
        -                            },
        -                            "distanceType": {
        -                              "enum": [
        -                                "percent",
        -                                "dollars"
        -                              ],
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "distanceType",
        -                            "distance"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "greekFilter": {
        -                          "additionalProperties": true,
        -                          "description": "Optional min/max constraints on Greeks during resolution.",
        -                          "type": "object"
        -                        },
        -                        "liquidityFilter": {
        -                          "additionalProperties": false,
        -                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                          "properties": {
        -                            "maxSpreadAbsolute": {
        -                              "type": "number"
        -                            },
        -                            "maxSpreadPct": {
        -                              "type": "number"
        -                            },
        -                            "minBid": {
        -                              "type": "number"
        -                            }
        -                          },
        -                          "type": "object"
        -                        },
        -                        "optionType": {
        -                          "enum": [
        -                            "call",
        -                            "put"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "ratio": {
        -                          "type": "number"
        -                        },
        -                        "strikeRange": {
        -                          "additionalProperties": true,
        -                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                          "type": "object"
        -                        },
        -                        "strikeSelector": {
        -                          "properties": {
        -                            "distance": {
        -                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                              "type": "number"
        -                            },
        -                            "distanceType": {
        -                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "distanceType",
        -                            "distance"
        -                          ],
        -                          "type": "object"
        -                        }
        -                      },
        -                      "required": [
        -                        "optionType",
        -                        "direction",
        -                        "expirationSelector",
        -                        "strikeSelector"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    "minItems": 1,
        -                    "type": "array"
        -                  },
        -                  "name": {
        -                    "type": "string"
        -                  },
        -                  "spreadType": {
        -                    "enum": [
        -                      "vertical",
        -                      "calendar",
        -                      "diagonal",
        -                      "ironCondor",
        -                      "straddle",
        -                      "strangle",
        -                      "custom"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "widthConstraint": {
        -                    "additionalProperties": false,
        -                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -                    "properties": {
        -                      "minWidthDollars": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "number"
        -                      },
        -                      "minWidthPercent": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "number"
        -                      }
        -                    },
        -                    "type": "object"
        -                  }
        -                },
        -                "required": [
        -                  "legs"
        -                ],
        -                "type": "object"
        -              },
        -              "minItems": 1,
        -              "type": "array"
        -            },
        -            "universe": {
        -              "additionalProperties": true,
        -              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -              "properties": {
        -                "assets": {
        -                  "items": {
        -                    "additionalProperties": true,
        -                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -                    "properties": {
        -                      "name": {
        -                        "type": "string"
        -                      },
        -                      "symbol": {
        -                        "type": "string"
        -                      },
        -                      "type": {
        -                        "enum": [
        -                          "Stock",
        -                          "Cryptocurrency",
        -                          "Option",
        -                          "Other"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "symbol"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "type": "array"
        -                },
        -                "source": {
        -                  "enum": [
        -                    "ALL_US_STOCKS",
        -                    "SP500",
        -                    "NASDAQ100",
        -                    "DJIA",
        -                    "CRYPTO",
        -                    "SPECIFIC_ASSETS"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "source"
        -              ],
        -              "type": "object"
        -            },
        -            "weightIndicator": {
        -              "$ref": "#/$defs/indicator"
        -            }
        -          },
        -          "required": [
        -            "name"
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "structureTemplates": {
        -        "items": {
        -          "additionalProperties": true,
        -          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        -          "properties": {
        -            "eligibility": {
        -              "$ref": "#/$defs/condition"
        -            },
        -            "legs": {
        -              "items": {
        -                "additionalProperties": true,
        -                "description": "Single leg of an option builder.",
        -                "properties": {
        -                  "direction": {
        -                    "enum": [
        -                      "long",
        -                      "short"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "expirationRange": {
        -                    "additionalProperties": true,
        -                    "type": "object"
        -                  },
        -                  "expirationSelector": {
        -                    "properties": {
        -                      "maxDaysToExpiration": {
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "minDaysToExpiration": {
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "preference": {
        -                        "enum": [
        -                          "nearest",
        -                          "middle",
        -                          "furthest"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "minDaysToExpiration",
        -                      "maxDaysToExpiration",
        -                      "preference"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "fallbackStrikeSelector": {
        -                    "additionalProperties": false,
        -                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                    "properties": {
        -                      "distance": {
        -                        "type": "number"
        -                      },
        -                      "distanceType": {
        -                        "enum": [
        -                          "percent",
        -                          "dollars"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "distanceType",
        -                      "distance"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "greekFilter": {
        -                    "additionalProperties": true,
        -                    "description": "Optional min/max constraints on Greeks during resolution.",
        -                    "type": "object"
        -                  },
        -                  "liquidityFilter": {
        -                    "additionalProperties": false,
        -                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                    "properties": {
        -                      "maxSpreadAbsolute": {
        -                        "type": "number"
        -                      },
        -                      "maxSpreadPct": {
        -                        "type": "number"
        -                      },
        -                      "minBid": {
        -                        "type": "number"
        -                      }
        -                    },
        -                    "type": "object"
        -                  },
        -                  "optionType": {
        -                    "enum": [
        -                      "call",
        -                      "put"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "ratio": {
        -                    "type": "number"
        -                  },
        -                  "strikeRange": {
        -                    "additionalProperties": true,
        -                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                    "type": "object"
        -                  },
        -                  "strikeSelector": {
        -                    "properties": {
        -                      "distance": {
        -                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                        "type": "number"
        -                      },
        -                      "distanceType": {
        -                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "distanceType",
        -                      "distance"
        -                    ],
        -                    "type": "object"
        -                  }
        -                },
        -                "required": [
        -                  "optionType",
        -                  "direction",
        -                  "expirationSelector",
        -                  "strikeSelector"
        -                ],
        -                "type": "object"
        -              },
        -              "minItems": 1,
        -              "type": "array"
        -            },
        -            "name": {
        -              "type": "string"
        -            },
        -            "spreadType": {
        -              "enum": [
        -                "vertical",
        -                "calendar",
        -                "diagonal",
        -                "ironCondor",
        -                "straddle",
        -                "strangle",
        -                "custom"
        -              ],
        -              "type": "string"
        -            },
        -            "widthConstraint": {
        -              "additionalProperties": false,
        -              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -              "properties": {
        -                "minWidthDollars": {
        -                  "exclusiveMinimum": 0,
        -                  "type": "number"
        -                },
        -                "minWidthPercent": {
        -                  "exclusiveMinimum": 0,
        -                  "type": "number"
        -                }
        -              },
        -              "type": "object"
        -            }
        -          },
        -          "required": [
        -            "legs"
        -          ],
        -          "type": "object"
        -        },
        -        "minItems": 1,
        -        "type": "array"
        -      },
        -      "totalBudget": {
        -        "additionalProperties": true,
        -        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        -        "properties": {
        -          "amount": {
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "const": "RebalanceOption",
        -        "type": "string"
        -      },
        -      "universe": {
        -        "additionalProperties": true,
        -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -        "properties": {
        -          "assets": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -              "properties": {
        -                "name": {
        -                  "type": "string"
        -                },
        -                "symbol": {
        -                  "type": "string"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "Stock",
        -                    "Cryptocurrency",
        -                    "Option",
        -                    "Other"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "symbol"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "source": {
        -            "enum": [
        -              "ALL_US_STOCKS",
        -              "SP500",
        -              "NASDAQ100",
        -              "DJIA",
        -              "CRYPTO",
        -              "SPECIFIC_ASSETS"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "weightIndicator": {
        -        "$ref": "#/$defs/indicator"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "universe",
        -      "pipeline",
        -      "weightIndicator",
        -      "structureTemplates"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        -    "properties": {
        -      "closeScope": {
        -        "enum": [
        -          "spread",
        -          "leg"
        -        ],
        -        "type": "string"
        -      },
        -      "direction": {
        -        "enum": [
        -          "long",
        -          "short"
        -        ],
        -        "type": "string"
        -      },
        -      "optionType": {
        -        "enum": [
        -          "call",
        -          "put"
        -        ],
        -        "type": "string"
        -      },
        -      "quantity": {
        -        "additionalProperties": true,
        -        "description": "How many contracts to close. Defaults to all matching when omitted.",
        -        "type": "object"
        -      },
        -      "spreadType": {
        -        "enum": [
        -          "vertical",
        -          "calendar",
        -          "diagonal",
        -          "ironCondor",
        -          "straddle",
        -          "strangle",
        -          "custom"
        -        ],
        -        "type": "string"
        -      },
        -      "triggers": {
        -        "items": {
        -          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxPnlPercent": {
        -                  "type": "number"
        -                },
        -                "minPnlPercent": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "pnl",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxDte": {
        -                  "type": "number"
        -                },
        -                "minDte": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "dte",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxDaysHeld": {
        -                  "type": "number"
        -                },
        -                "minDaysHeld": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "daysHeld",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxIv": {
        -                  "type": "number"
        -                },
        -                "maxSpreadDelta": {
        -                  "type": "number"
        -                },
        -                "maxSpreadTheta": {
        -                  "type": "number"
        -                },
        -                "minIv": {
        -                  "type": "number"
        -                },
        -                "minSpreadDelta": {
        -                  "type": "number"
        -                },
        -                "minSpreadTheta": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "greeks",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "type": {
        -        "const": "CloseOption",
        -        "type": "string"
        -      },
        -      "underlyings": {
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array"
        -      }
        -    },
        -    "required": [
        -      "type"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": true,
        +    "description": "Buy or Sell a stock/crypto position.",
        +    "properties": {
        +      "amount": {
        +        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "percent of current positions",
        +              "dollars",
        +              "number of assets"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "targetAsset": {
        +        "additionalProperties": true,
        +        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +        "properties": {
        +          "name": {
        +            "type": "string"
        +          },
        +          "symbol": {
        +            "type": "string"
        +          },
        +          "type": {
        +            "enum": [
        +              "Stock",
        +              "Cryptocurrency",
        +              "Option",
        +              "Other"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "symbol"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "enum": [
        +          "Buy",
        +          "Sell"
        +        ],
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "targetAsset",
        +      "amount"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Send an alert message (no order).",
        +    "properties": {
        +      "message": {
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "Alert",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "message"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        +    "properties": {
        +      "allocationPolicy": {
        +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "expectedReturnShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "riskAversion": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MeanVariance",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "riskAversion",
        +              "expectedReturnShrinkage",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "RiskParity",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MaximumDiversification",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "canSell": {
        +        "$ref": "#/$defs/condition",
        +        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        +      },
        +      "deploymentPercent": {
        +        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        +        "maximum": 100,
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "exposurePolicy": {
        +        "additionalProperties": false,
        +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +        "properties": {
        +          "covarianceShrinkage": {
        +            "maximum": 1,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "estimatedTransactionCostBps": {
        +            "maximum": 10000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "lookbackPeriods": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "minimumObservations": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "targetAnnualizedVolatilityPercent": {
        +            "maximum": 1000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "const": "VolatilityTarget",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "lookbackPeriods",
        +          "minimumObservations",
        +          "covarianceShrinkage",
        +          "targetAnnualizedVolatilityPercent",
        +          "estimatedTransactionCostBps"
        +        ],
        +        "type": "object"
        +      },
        +      "limit": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "perNameAllocation": {
        +        "additionalProperties": true,
        +        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.",
        +        "properties": {
        +          "amount": {
        +            "exclusiveMinimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "percent of portfolio",
        +              "dollars"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "pipeline": {
        +        "items": {
        +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "condition": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "type": {
        +                  "const": "Filter",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "condition"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "type": {
        +                  "const": "SelectTop",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "limit",
        +                "direction"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "percentile": {
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "SelectPercentile",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "percentile",
        +                "direction"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "type": {
        +        "const": "DynamicRebalance",
        +        "type": "string"
        +      },
        +      "universe": {
        +        "additionalProperties": true,
        +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +        "properties": {
        +          "assets": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +              "properties": {
        +                "name": {
        +                  "type": "string"
        +                },
        +                "symbol": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Stock",
        +                    "Cryptocurrency",
        +                    "Option",
        +                    "Other"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "symbol"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "enum": [
        +              "ALL_US_STOCKS",
        +              "SP500",
        +              "NASDAQ100",
        +              "DJIA",
        +              "CRYPTO",
        +              "SPECIFIC_ASSETS"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "weightIndicator": {
        +        "$ref": "#/$defs/indicator"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "universe",
        +      "pipeline",
        +      "weightIndicator"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        +    "properties": {
        +      "continueExisting": {
        +        "type": "boolean"
        +      },
        +      "cooldownMinutes": {
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "executionModel": {
        +        "type": "string"
        +      },
        +      "includeMarketData": {
        +        "type": "boolean"
        +      },
        +      "initialMessage": {
        +        "type": "string"
        +      },
        +      "maxIterations": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "planningModel": {
        +        "type": "string"
        +      },
        +      "skipPlanning": {
        +        "type": "boolean"
        +      },
        +      "type": {
        +        "const": "LaunchAgent",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "planningModel",
        +      "executionModel",
        +      "initialMessage",
        +      "maxIterations",
        +      "includeMarketData",
        +      "continueExisting",
        +      "skipPlanning"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        +    "properties": {
        +      "against": {
        +        "additionalProperties": true,
        +        "description": "Optional parent-position selector (e.g. for covered calls).",
        +        "type": "object"
        +      },
        +      "allocation": {
        +        "additionalProperties": true,
        +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "contracts",
        +              "percent of realized premium"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "builder": {
        +        "additionalProperties": true,
        +        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        +        "properties": {
        +          "dynamicUnderlying": {
        +            "additionalProperties": true,
        +            "properties": {
        +              "limit": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "pipeline": {
        +                "items": {
        +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                  "oneOf": [
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "condition": {
        +                          "$ref": "#/$defs/condition"
        +                        },
        +                        "type": {
        +                          "const": "Filter",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "condition"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "limit": {
        +                          "minimum": 1,
        +                          "type": "number"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "type": {
        +                          "const": "SelectTop",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "limit",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "percentile": {
        +                          "maximum": 100,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "SelectPercentile",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "percentile",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "universe": {
        +                "additionalProperties": true,
        +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                "properties": {
        +                  "assets": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                      "properties": {
        +                        "name": {
        +                          "type": "string"
        +                        },
        +                        "symbol": {
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "enum": [
        +                            "Stock",
        +                            "Cryptocurrency",
        +                            "Option",
        +                            "Other"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "symbol"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "type": "array"
        +                  },
        +                  "source": {
        +                    "enum": [
        +                      "ALL_US_STOCKS",
        +                      "SP500",
        +                      "NASDAQ100",
        +                      "DJIA",
        +                      "CRYPTO",
        +                      "SPECIFIC_ASSETS"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "source"
        +                ],
        +                "type": "object"
        +              }
        +            },
        +            "required": [
        +              "universe"
        +            ],
        +            "type": "object"
        +          },
        +          "legs": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Single leg of an option builder.",
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "long",
        +                    "short"
        +                  ],
        +                  "type": "string"
        +                },
        +                "expirationRange": {
        +                  "additionalProperties": true,
        +                  "type": "object"
        +                },
        +                "expirationSelector": {
        +                  "properties": {
        +                    "maxDaysToExpiration": {
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "minDaysToExpiration": {
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "preference": {
        +                      "enum": [
        +                        "nearest",
        +                        "middle",
        +                        "furthest"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "minDaysToExpiration",
        +                    "maxDaysToExpiration",
        +                    "preference"
        +                  ],
        +                  "type": "object"
        +                },
        +                "fallbackStrikeSelector": {
        +                  "additionalProperties": false,
        +                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                  "properties": {
        +                    "distance": {
        +                      "type": "number"
        +                    },
        +                    "distanceType": {
        +                      "enum": [
        +                        "percent",
        +                        "dollars"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "distanceType",
        +                    "distance"
        +                  ],
        +                  "type": "object"
        +                },
        +                "greekFilter": {
        +                  "additionalProperties": true,
        +                  "description": "Optional min/max constraints on Greeks during resolution.",
        +                  "type": "object"
        +                },
        +                "liquidityFilter": {
        +                  "additionalProperties": false,
        +                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                  "properties": {
        +                    "maxSpreadAbsolute": {
        +                      "type": "number"
        +                    },
        +                    "maxSpreadPct": {
        +                      "type": "number"
        +                    },
        +                    "minBid": {
        +                      "type": "number"
        +                    }
        +                  },
        +                  "type": "object"
        +                },
        +                "optionType": {
        +                  "enum": [
        +                    "call",
        +                    "put"
        +                  ],
        +                  "type": "string"
        +                },
        +                "ratio": {
        +                  "type": "number"
        +                },
        +                "strikeRange": {
        +                  "additionalProperties": true,
        +                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                  "type": "object"
        +                },
        +                "strikeSelector": {
        +                  "properties": {
        +                    "distance": {
        +                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                      "type": "number"
        +                    },
        +                    "distanceType": {
        +                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "distanceType",
        +                    "distance"
        +                  ],
        +                  "type": "object"
        +                }
        +              },
        +              "required": [
        +                "optionType",
        +                "direction",
        +                "expirationSelector",
        +                "strikeSelector"
        +              ],
        +              "type": "object"
        +            },
        +            "minItems": 1,
        +            "type": "array"
        +          },
        +          "spreadType": {
        +            "enum": [
        +              "vertical",
        +              "calendar",
        +              "diagonal",
        +              "ironCondor",
        +              "straddle",
        +              "strangle",
        +              "custom"
        +            ],
        +            "type": "string"
        +          },
        +          "underlyingSymbol": {
        +            "type": "string"
        +          },
        +          "widthConstraint": {
        +            "additionalProperties": false,
        +            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +            "properties": {
        +              "minWidthDollars": {
        +                "exclusiveMinimum": 0,
        +                "type": "number"
        +              },
        +              "minWidthPercent": {
        +                "exclusiveMinimum": 0,
        +                "type": "number"
        +              }
        +            },
        +            "type": "object"
        +          }
        +        },
        +        "required": [
        +          "legs"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "const": "OpenOption",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "builder"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        +    "properties": {
        +      "allocationPolicy": {
        +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "expectedReturnShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "riskAversion": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MeanVariance",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "riskAversion",
        +              "expectedReturnShrinkage",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "RiskParity",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MaximumDiversification",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "exposurePolicy": {
        +        "additionalProperties": false,
        +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +        "properties": {
        +          "covarianceShrinkage": {
        +            "maximum": 1,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "estimatedTransactionCostBps": {
        +            "maximum": 10000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "lookbackPeriods": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "minimumObservations": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "targetAnnualizedVolatilityPercent": {
        +            "maximum": 1000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "const": "VolatilityTarget",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "lookbackPeriods",
        +          "minimumObservations",
        +          "covarianceShrinkage",
        +          "targetAnnualizedVolatilityPercent",
        +          "estimatedTransactionCostBps"
        +        ],
        +        "type": "object"
        +      },
        +      "limit": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "perNameAllocation": {
        +        "additionalProperties": true,
        +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "contracts",
        +              "percent of realized premium"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "pipeline": {
        +        "items": {
        +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "condition": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "type": {
        +                  "const": "Filter",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "condition"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "type": {
        +                  "const": "SelectTop",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "limit",
        +                "direction"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "percentile": {
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "SelectPercentile",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "percentile",
        +                "direction"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "positionScope": {
        +        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        +        "enum": [
        +          "portfolio",
        +          "strategy"
        +        ],
        +        "type": "string"
        +      },
        +      "sleeves": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        +          "properties": {
        +            "limit": {
        +              "minimum": 1,
        +              "type": "number"
        +            },
        +            "name": {
        +              "type": "string"
        +            },
        +            "perNameAllocation": {
        +              "additionalProperties": true,
        +              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +              "properties": {
        +                "amount": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "dollars",
        +                    "percent of portfolio",
        +                    "percent of buying power",
        +                    "contracts",
        +                    "percent of realized premium"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "amount"
        +              ],
        +              "type": "object"
        +            },
        +            "pipeline": {
        +              "items": {
        +                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                "oneOf": [
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "condition": {
        +                        "$ref": "#/$defs/condition"
        +                      },
        +                      "type": {
        +                        "const": "Filter",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "condition"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "direction": {
        +                        "enum": [
        +                          "Highest",
        +                          "Lowest"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "limit": {
        +                        "minimum": 1,
        +                        "type": "number"
        +                      },
        +                      "metric": {
        +                        "$ref": "#/$defs/indicator"
        +                      },
        +                      "type": {
        +                        "const": "SelectTop",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "metric",
        +                      "limit",
        +                      "direction"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "direction": {
        +                        "enum": [
        +                          "Highest",
        +                          "Lowest"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "metric": {
        +                        "$ref": "#/$defs/indicator"
        +                      },
        +                      "percentile": {
        +                        "maximum": 100,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "SelectPercentile",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "metric",
        +                      "percentile",
        +                      "direction"
        +                    ],
        +                    "type": "object"
        +                  }
        +                ],
        +                "type": "object"
        +              },
        +              "type": "array"
        +            },
        +            "structureTemplates": {
        +              "items": {
        +                "additionalProperties": true,
        +                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +                "properties": {
        +                  "eligibility": {
        +                    "$ref": "#/$defs/condition"
        +                  },
        +                  "legs": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Single leg of an option builder.",
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "long",
        +                            "short"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "expirationRange": {
        +                          "additionalProperties": true,
        +                          "type": "object"
        +                        },
        +                        "expirationSelector": {
        +                          "properties": {
        +                            "maxDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "minDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "preference": {
        +                              "enum": [
        +                                "nearest",
        +                                "middle",
        +                                "furthest"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "minDaysToExpiration",
        +                            "maxDaysToExpiration",
        +                            "preference"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "fallbackStrikeSelector": {
        +                          "additionalProperties": false,
        +                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                          "properties": {
        +                            "distance": {
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "enum": [
        +                                "percent",
        +                                "dollars"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "greekFilter": {
        +                          "additionalProperties": true,
        +                          "description": "Optional min/max constraints on Greeks during resolution.",
        +                          "type": "object"
        +                        },
        +                        "liquidityFilter": {
        +                          "additionalProperties": false,
        +                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                          "properties": {
        +                            "maxSpreadAbsolute": {
        +                              "type": "number"
        +                            },
        +                            "maxSpreadPct": {
        +                              "type": "number"
        +                            },
        +                            "minBid": {
        +                              "type": "number"
        +                            }
        +                          },
        +                          "type": "object"
        +                        },
        +                        "optionType": {
        +                          "enum": [
        +                            "call",
        +                            "put"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "ratio": {
        +                          "type": "number"
        +                        },
        +                        "strikeRange": {
        +                          "additionalProperties": true,
        +                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                          "type": "object"
        +                        },
        +                        "strikeSelector": {
        +                          "properties": {
        +                            "distance": {
        +                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        }
        +                      },
        +                      "required": [
        +                        "optionType",
        +                        "direction",
        +                        "expirationSelector",
        +                        "strikeSelector"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "minItems": 1,
        +                    "type": "array"
        +                  },
        +                  "name": {
        +                    "type": "string"
        +                  },
        +                  "spreadType": {
        +                    "enum": [
        +                      "vertical",
        +                      "calendar",
        +                      "diagonal",
        +                      "ironCondor",
        +                      "straddle",
        +                      "strangle",
        +                      "custom"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "widthConstraint": {
        +                    "additionalProperties": false,
        +                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                    "properties": {
        +                      "minWidthDollars": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minWidthPercent": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "legs"
        +                ],
        +                "type": "object"
        +              },
        +              "minItems": 1,
        +              "type": "array"
        +            },
        +            "universe": {
        +              "additionalProperties": true,
        +              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +              "properties": {
        +                "assets": {
        +                  "items": {
        +                    "additionalProperties": true,
        +                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                    "properties": {
        +                      "name": {
        +                        "type": "string"
        +                      },
        +                      "symbol": {
        +                        "type": "string"
        +                      },
        +                      "type": {
        +                        "enum": [
        +                          "Stock",
        +                          "Cryptocurrency",
        +                          "Option",
        +                          "Other"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "symbol"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "type": "array"
        +                },
        +                "source": {
        +                  "enum": [
        +                    "ALL_US_STOCKS",
        +                    "SP500",
        +                    "NASDAQ100",
        +                    "DJIA",
        +                    "CRYPTO",
        +                    "SPECIFIC_ASSETS"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "source"
        +              ],
        +              "type": "object"
        +            },
        +            "weightIndicator": {
        +              "$ref": "#/$defs/indicator"
        +            }
        +          },
        +          "required": [
        +            "name"
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "structureTemplates": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +          "properties": {
        +            "eligibility": {
        +              "$ref": "#/$defs/condition"
        +            },
        +            "legs": {
        +              "items": {
        +                "additionalProperties": true,
        +                "description": "Single leg of an option builder.",
        +                "properties": {
        +                  "direction": {
        +                    "enum": [
        +                      "long",
        +                      "short"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "expirationRange": {
        +                    "additionalProperties": true,
        +                    "type": "object"
        +                  },
        +                  "expirationSelector": {
        +                    "properties": {
        +                      "maxDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "preference": {
        +                        "enum": [
        +                          "nearest",
        +                          "middle",
        +                          "furthest"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "minDaysToExpiration",
        +                      "maxDaysToExpiration",
        +                      "preference"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "fallbackStrikeSelector": {
        +                    "additionalProperties": false,
        +                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                    "properties": {
        +                      "distance": {
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "enum": [
        +                          "percent",
        +                          "dollars"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "greekFilter": {
        +                    "additionalProperties": true,
        +                    "description": "Optional min/max constraints on Greeks during resolution.",
        +                    "type": "object"
        +                  },
        +                  "liquidityFilter": {
        +                    "additionalProperties": false,
        +                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                    "properties": {
        +                      "maxSpreadAbsolute": {
        +                        "type": "number"
        +                      },
        +                      "maxSpreadPct": {
        +                        "type": "number"
        +                      },
        +                      "minBid": {
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  },
        +                  "optionType": {
        +                    "enum": [
        +                      "call",
        +                      "put"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "ratio": {
        +                    "type": "number"
        +                  },
        +                  "strikeRange": {
        +                    "additionalProperties": true,
        +                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                    "type": "object"
        +                  },
        +                  "strikeSelector": {
        +                    "properties": {
        +                      "distance": {
        +                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "optionType",
        +                  "direction",
        +                  "expirationSelector",
        +                  "strikeSelector"
        +                ],
        +                "type": "object"
        +              },
        +              "minItems": 1,
        +              "type": "array"
        +            },
        +            "name": {
        +              "type": "string"
        +            },
        +            "spreadType": {
        +              "enum": [
        +                "vertical",
        +                "calendar",
        +                "diagonal",
        +                "ironCondor",
        +                "straddle",
        +                "strangle",
        +                "custom"
        +              ],
        +              "type": "string"
        +            },
        +            "widthConstraint": {
        +              "additionalProperties": false,
        +              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +              "properties": {
        +                "minWidthDollars": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                },
        +                "minWidthPercent": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                }
        +              },
        +              "type": "object"
        +            }
        +          },
        +          "required": [
        +            "legs"
        +          ],
        +          "type": "object"
        +        },
        +        "minItems": 1,
        +        "type": "array"
        +      },
        +      "totalBudget": {
        +        "additionalProperties": true,
        +        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        +        "properties": {
        +          "amount": {
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "const": "RebalanceOption",
        +        "type": "string"
        +      },
        +      "universe": {
        +        "additionalProperties": true,
        +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +        "properties": {
        +          "assets": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +              "properties": {
        +                "name": {
        +                  "type": "string"
        +                },
        +                "symbol": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Stock",
        +                    "Cryptocurrency",
        +                    "Option",
        +                    "Other"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "symbol"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "enum": [
        +              "ALL_US_STOCKS",
        +              "SP500",
        +              "NASDAQ100",
        +              "DJIA",
        +              "CRYPTO",
        +              "SPECIFIC_ASSETS"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "weightIndicator": {
        +        "$ref": "#/$defs/indicator"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "universe",
        +      "pipeline",
        +      "weightIndicator",
        +      "structureTemplates"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        +    "properties": {
        +      "closeScope": {
        +        "enum": [
        +          "spread",
        +          "leg"
        +        ],
        +        "type": "string"
        +      },
        +      "direction": {
        +        "enum": [
        +          "long",
        +          "short"
        +        ],
        +        "type": "string"
        +      },
        +      "optionType": {
        +        "enum": [
        +          "call",
        +          "put"
        +        ],
        +        "type": "string"
        +      },
        +      "quantity": {
        +        "additionalProperties": true,
        +        "description": "How many contracts to close. Defaults to all matching when omitted.",
        +        "type": "object"
        +      },
        +      "spreadType": {
        +        "enum": [
        +          "vertical",
        +          "calendar",
        +          "diagonal",
        +          "ironCondor",
        +          "straddle",
        +          "strangle",
        +          "custom"
        +        ],
        +        "type": "string"
        +      },
        +      "triggers": {
        +        "items": {
        +          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxPnlPercent": {
        +                  "type": "number"
        +                },
        +                "minPnlPercent": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "pnl",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxDte": {
        +                  "type": "number"
        +                },
        +                "minDte": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "dte",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxDaysHeld": {
        +                  "type": "number"
        +                },
        +                "minDaysHeld": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "daysHeld",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxIv": {
        +                  "type": "number"
        +                },
        +                "maxSpreadDelta": {
        +                  "type": "number"
        +                },
        +                "maxSpreadTheta": {
        +                  "type": "number"
        +                },
        +                "minIv": {
        +                  "type": "number"
        +                },
        +                "minSpreadDelta": {
        +                  "type": "number"
        +                },
        +                "minSpreadTheta": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "greeks",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "type": {
        +        "const": "CloseOption",
        +        "type": "string"
        +      },
        +      "underlyings": {
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  }
        +]
      • changedInput schema / properties / strategies / items / properties / action / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "description": "Buy or Sell a stock/crypto position.",
        -    "properties": {
        -      "amount": {
        -        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "percent of current positions",
        -              "dollars",
        -              "number of assets"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "targetAsset": {
        -        "additionalProperties": true,
        -        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -        "properties": {
        -          "name": {
        -            "type": "string"
        -          },
        -          "symbol": {
        -            "type": "string"
        -          },
        -          "type": {
        -            "enum": [
        -              "Stock",
        -              "Cryptocurrency",
        -              "Option",
        -              "Other"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "symbol"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "enum": [
        -          "Buy",
        -          "Sell"
        -        ],
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "targetAsset",
        -      "amount"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Send an alert message (no order).",
        -    "properties": {
        -      "message": {
        -        "type": "string"
        -      },
        -      "type": {
        -        "const": "Alert",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "message"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        -    "properties": {
        -      "allocationPolicy": {
        -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "expectedReturnShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "riskAversion": {
        -                "maximum": 1000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MeanVariance",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "riskAversion",
        -              "expectedReturnShrinkage",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "RiskParity",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumDiversification",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "canSell": {
        -        "$ref": "#/$defs/condition",
        -        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        -      },
        -      "deploymentPercent": {
        -        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        -        "maximum": 100,
        -        "minimum": 0,
        -        "type": "number"
        -      },
        -      "exposurePolicy": {
        -        "additionalProperties": false,
        -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        -        "properties": {
        -          "covarianceShrinkage": {
        -            "maximum": 1,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "estimatedTransactionCostBps": {
        -            "maximum": 10000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "lookbackPeriods": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "minimumObservations": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "targetAnnualizedVolatilityPercent": {
        -            "maximum": 1000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "const": "VolatilityTarget",
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "lookbackPeriods",
        -          "minimumObservations",
        -          "covarianceShrinkage",
        -          "targetAnnualizedVolatilityPercent",
        -          "estimatedTransactionCostBps"
        -        ],
        -        "type": "object"
        -      },
        -      "limit": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "perNameAllocation": {
        -        "additionalProperties": true,
        -        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
        -        "properties": {
        -          "amount": {
        -            "exclusiveMinimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "percent of portfolio",
        -              "dollars"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "pipeline": {
        -        "items": {
        -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "condition": {
        -                  "$ref": "#/$defs/condition"
        -                },
        -                "type": {
        -                  "const": "Filter",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "condition"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "limit": {
        -                  "minimum": 1,
        -                  "type": "number"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "type": {
        -                  "const": "SelectTop",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "limit",
        -                "direction"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "percentile": {
        -                  "maximum": 100,
        -                  "minimum": 0,
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "SelectPercentile",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "percentile",
        -                "direction"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "type": {
        -        "const": "DynamicRebalance",
        -        "type": "string"
        -      },
        -      "universe": {
        -        "additionalProperties": true,
        -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -        "properties": {
        -          "assets": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -              "properties": {
        -                "name": {
        -                  "type": "string"
        -                },
        -                "symbol": {
        -                  "type": "string"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "Stock",
        -                    "Cryptocurrency",
        -                    "Option",
        -                    "Other"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "symbol"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "source": {
        -            "enum": [
        -              "ALL_US_STOCKS",
        -              "SP500",
        -              "NASDAQ100",
        -              "DJIA",
        -              "CRYPTO",
        -              "SPECIFIC_ASSETS"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "weightIndicator": {
        -        "$ref": "#/$defs/indicator"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "universe",
        -      "pipeline",
        -      "weightIndicator"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        -    "properties": {
        -      "continueExisting": {
        -        "type": "boolean"
        -      },
        -      "cooldownMinutes": {
        -        "minimum": 0,
        -        "type": "number"
        -      },
        -      "executionModel": {
        -        "type": "string"
        -      },
        -      "includeMarketData": {
        -        "type": "boolean"
        -      },
        -      "initialMessage": {
        -        "type": "string"
        -      },
        -      "maxIterations": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "planningModel": {
        -        "type": "string"
        -      },
        -      "skipPlanning": {
        -        "type": "boolean"
        -      },
        -      "type": {
        -        "const": "LaunchAgent",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "planningModel",
        -      "executionModel",
        -      "initialMessage",
        -      "maxIterations",
        -      "includeMarketData",
        -      "continueExisting",
        -      "skipPlanning"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        -    "properties": {
        -      "against": {
        -        "additionalProperties": true,
        -        "description": "Optional parent-position selector (e.g. for covered calls).",
        -        "type": "object"
        -      },
        -      "allocation": {
        -        "additionalProperties": true,
        -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "contracts"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "builder": {
        -        "additionalProperties": true,
        -        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        -        "properties": {
        -          "dynamicUnderlying": {
        -            "additionalProperties": true,
        -            "properties": {
        -              "limit": {
        -                "minimum": 1,
        -                "type": "number"
        -              },
        -              "pipeline": {
        -                "items": {
        -                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -                  "oneOf": [
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "condition": {
        -                          "$ref": "#/$defs/condition"
        -                        },
        -                        "type": {
        -                          "const": "Filter",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "condition"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "Highest",
        -                            "Lowest"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "limit": {
        -                          "minimum": 1,
        -                          "type": "number"
        -                        },
        -                        "metric": {
        -                          "$ref": "#/$defs/indicator"
        -                        },
        -                        "type": {
        -                          "const": "SelectTop",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "metric",
        -                        "limit",
        -                        "direction"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "Highest",
        -                            "Lowest"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "metric": {
        -                          "$ref": "#/$defs/indicator"
        -                        },
        -                        "percentile": {
        -                          "maximum": 100,
        -                          "minimum": 0,
        -                          "type": "number"
        -                        },
        -                        "type": {
        -                          "const": "SelectPercentile",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "metric",
        -                        "percentile",
        -                        "direction"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ],
        -                  "type": "object"
        -                },
        -                "type": "array"
        -              },
        -              "universe": {
        -                "additionalProperties": true,
        -                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -                "properties": {
        -                  "assets": {
        -                    "items": {
        -                      "additionalProperties": true,
        -                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -                      "properties": {
        -                        "name": {
        -                          "type": "string"
        -                        },
        -                        "symbol": {
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "enum": [
        -                            "Stock",
        -                            "Cryptocurrency",
        -                            "Option",
        -                            "Other"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "symbol"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    "type": "array"
        -                  },
        -                  "source": {
        -                    "enum": [
        -                      "ALL_US_STOCKS",
        -                      "SP500",
        -                      "NASDAQ100",
        -                      "DJIA",
        -                      "CRYPTO",
        -                      "SPECIFIC_ASSETS"
        -                    ],
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "source"
        -                ],
        -                "type": "object"
        -              }
        -            },
        -            "required": [
        -              "universe"
        -            ],
        -            "type": "object"
        -          },
        -          "legs": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Single leg of an option builder.",
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "long",
        -                    "short"
        -                  ],
        -                  "type": "string"
        -                },
        -                "expirationRange": {
        -                  "additionalProperties": true,
        -                  "type": "object"
        -                },
        -                "expirationSelector": {
        -                  "properties": {
        -                    "maxDaysToExpiration": {
        -                      "minimum": 0,
        -                      "type": "number"
        -                    },
        -                    "minDaysToExpiration": {
        -                      "minimum": 0,
        -                      "type": "number"
        -                    },
        -                    "preference": {
        -                      "enum": [
        -                        "nearest",
        -                        "middle",
        -                        "furthest"
        -                      ],
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "minDaysToExpiration",
        -                    "maxDaysToExpiration",
        -                    "preference"
        -                  ],
        -                  "type": "object"
        -                },
        -                "fallbackStrikeSelector": {
        -                  "additionalProperties": false,
        -                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                  "properties": {
        -                    "distance": {
        -                      "type": "number"
        -                    },
        -                    "distanceType": {
        -                      "enum": [
        -                        "percent",
        -                        "dollars"
        -                      ],
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "distanceType",
        -                    "distance"
        -                  ],
        -                  "type": "object"
        -                },
        -                "greekFilter": {
        -                  "additionalProperties": true,
        -                  "description": "Optional min/max constraints on Greeks during resolution.",
        -                  "type": "object"
        -                },
        -                "liquidityFilter": {
        -                  "additionalProperties": false,
        -                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                  "properties": {
        -                    "maxSpreadAbsolute": {
        -                      "type": "number"
        -                    },
        -                    "maxSpreadPct": {
        -                      "type": "number"
        -                    },
        -                    "minBid": {
        -                      "type": "number"
        -                    }
        -                  },
        -                  "type": "object"
        -                },
        -                "optionType": {
        -                  "enum": [
        -                    "call",
        -                    "put"
        -                  ],
        -                  "type": "string"
        -                },
        -                "ratio": {
        -                  "type": "number"
        -                },
        -                "strikeRange": {
        -                  "additionalProperties": true,
        -                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                  "type": "object"
        -                },
        -                "strikeSelector": {
        -                  "properties": {
        -                    "distance": {
        -                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                      "type": "number"
        -                    },
        -                    "distanceType": {
        -                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "distanceType",
        -                    "distance"
        -                  ],
        -                  "type": "object"
        -                }
        -              },
        -              "required": [
        -                "optionType",
        -                "direction",
        -                "expirationSelector",
        -                "strikeSelector"
        -              ],
        -              "type": "object"
        -            },
        -            "minItems": 1,
        -            "type": "array"
        -          },
        -          "spreadType": {
        -            "enum": [
        -              "vertical",
        -              "calendar",
        -              "diagonal",
        -              "ironCondor",
        -              "straddle",
        -              "strangle",
        -              "custom"
        -            ],
        -            "type": "string"
        -          },
        -          "underlyingSymbol": {
        -            "type": "string"
        -          },
        -          "widthConstraint": {
        -            "additionalProperties": false,
        -            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -            "properties": {
        -              "minWidthDollars": {
        -                "exclusiveMinimum": 0,
        -                "type": "number"
        -              },
        -              "minWidthPercent": {
        -                "exclusiveMinimum": 0,
        -                "type": "number"
        -              }
        -            },
        -            "type": "object"
        -          }
        -        },
        -        "required": [
        -          "legs"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "const": "OpenOption",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "builder"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        -    "properties": {
        -      "allocationPolicy": {
        -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "expectedReturnShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "riskAversion": {
        -                "maximum": 1000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MeanVariance",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "riskAversion",
        -              "expectedReturnShrinkage",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "RiskParity",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumDiversification",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "exposurePolicy": {
        -        "additionalProperties": false,
        -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        -        "properties": {
        -          "covarianceShrinkage": {
        -            "maximum": 1,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "estimatedTransactionCostBps": {
        -            "maximum": 10000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "lookbackPeriods": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "minimumObservations": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "targetAnnualizedVolatilityPercent": {
        -            "maximum": 1000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "const": "VolatilityTarget",
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "lookbackPeriods",
        -          "minimumObservations",
        -          "covarianceShrinkage",
        -          "targetAnnualizedVolatilityPercent",
        -          "estimatedTransactionCostBps"
        -        ],
        -        "type": "object"
        -      },
        -      "limit": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "perNameAllocation": {
        -        "additionalProperties": true,
        -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "contracts"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "pipeline": {
        -        "items": {
        -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "condition": {
        -                  "$ref": "#/$defs/condition"
        -                },
        -                "type": {
        -                  "const": "Filter",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "condition"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "limit": {
        -                  "minimum": 1,
        -                  "type": "number"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "type": {
        -                  "const": "SelectTop",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "limit",
        -                "direction"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "percentile": {
        -                  "maximum": 100,
        -                  "minimum": 0,
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "SelectPercentile",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "percentile",
        -                "direction"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "positionScope": {
        -        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        -        "enum": [
        -          "portfolio",
        -          "strategy"
        -        ],
        -        "type": "string"
        -      },
        -      "sleeves": {
        -        "items": {
        -          "additionalProperties": true,
        -          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        -          "properties": {
        -            "limit": {
        -              "minimum": 1,
        -              "type": "number"
        -            },
        -            "name": {
        -              "type": "string"
        -            },
        -            "perNameAllocation": {
        -              "additionalProperties": true,
        -              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -              "properties": {
        -                "amount": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "dollars",
        -                    "percent of portfolio",
        -                    "percent of buying power",
        -                    "contracts"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "amount"
        -              ],
        -              "type": "object"
        -            },
        -            "pipeline": {
        -              "items": {
        -                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -                "oneOf": [
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "condition": {
        -                        "$ref": "#/$defs/condition"
        -                      },
        -                      "type": {
        -                        "const": "Filter",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "condition"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "direction": {
        -                        "enum": [
        -                          "Highest",
        -                          "Lowest"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "limit": {
        -                        "minimum": 1,
        -                        "type": "number"
        -                      },
        -                      "metric": {
        -                        "$ref": "#/$defs/indicator"
        -                      },
        -                      "type": {
        -                        "const": "SelectTop",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "metric",
        -                      "limit",
        -                      "direction"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "direction": {
        -                        "enum": [
        -                          "Highest",
        -                          "Lowest"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "metric": {
        -                        "$ref": "#/$defs/indicator"
        -                      },
        -                      "percentile": {
        -                        "maximum": 100,
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "type": {
        -                        "const": "SelectPercentile",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "metric",
        -                      "percentile",
        -                      "direction"
        -                    ],
        -                    "type": "object"
        -                  }
        -                ],
        -                "type": "object"
        -              },
        -              "type": "array"
        -            },
        -            "structureTemplates": {
        -              "items": {
        -                "additionalProperties": true,
        -                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        -                "properties": {
        -                  "eligibility": {
        -                    "$ref": "#/$defs/condition"
        -                  },
        -                  "legs": {
        -                    "items": {
        -                      "additionalProperties": true,
        -                      "description": "Single leg of an option builder.",
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "long",
        -                            "short"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "expirationRange": {
        -                          "additionalProperties": true,
        -                          "type": "object"
        -                        },
        -                        "expirationSelector": {
        -                          "properties": {
        -                            "maxDaysToExpiration": {
        -                              "minimum": 0,
        -                              "type": "number"
        -                            },
        -                            "minDaysToExpiration": {
        -                              "minimum": 0,
        -                              "type": "number"
        -                            },
        -                            "preference": {
        -                              "enum": [
        -                                "nearest",
        -                                "middle",
        -                                "furthest"
        -                              ],
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "minDaysToExpiration",
        -                            "maxDaysToExpiration",
        -                            "preference"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "fallbackStrikeSelector": {
        -                          "additionalProperties": false,
        -                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                          "properties": {
        -                            "distance": {
        -                              "type": "number"
        -                            },
        -                            "distanceType": {
        -                              "enum": [
        -                                "percent",
        -                                "dollars"
        -                              ],
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "distanceType",
        -                            "distance"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "greekFilter": {
        -                          "additionalProperties": true,
        -                          "description": "Optional min/max constraints on Greeks during resolution.",
        -                          "type": "object"
        -                        },
        -                        "liquidityFilter": {
        -                          "additionalProperties": false,
        -                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                          "properties": {
        -                            "maxSpreadAbsolute": {
        -                              "type": "number"
        -                            },
        -                            "maxSpreadPct": {
        -                              "type": "number"
        -                            },
        -                            "minBid": {
        -                              "type": "number"
        -                            }
        -                          },
        -                          "type": "object"
        -                        },
        -                        "optionType": {
        -                          "enum": [
        -                            "call",
        -                            "put"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "ratio": {
        -                          "type": "number"
        -                        },
        -                        "strikeRange": {
        -                          "additionalProperties": true,
        -                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                          "type": "object"
        -                        },
        -                        "strikeSelector": {
        -                          "properties": {
        -                            "distance": {
        -                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                              "type": "number"
        -                            },
        -                            "distanceType": {
        -                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "distanceType",
        -                            "distance"
        -                          ],
        -                          "type": "object"
        -                        }
        -                      },
        -                      "required": [
        -                        "optionType",
        -                        "direction",
        -                        "expirationSelector",
        -                        "strikeSelector"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    "minItems": 1,
        -                    "type": "array"
        -                  },
        -                  "name": {
        -                    "type": "string"
        -                  },
        -                  "spreadType": {
        -                    "enum": [
        -                      "vertical",
        -                      "calendar",
        -                      "diagonal",
        -                      "ironCondor",
        -                      "straddle",
        -                      "strangle",
        -                      "custom"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "widthConstraint": {
        -                    "additionalProperties": false,
        -                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -                    "properties": {
        -                      "minWidthDollars": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "number"
        -                      },
        -                      "minWidthPercent": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "number"
        -                      }
        -                    },
        -                    "type": "object"
        -                  }
        -                },
        -                "required": [
        -                  "legs"
        -                ],
        -                "type": "object"
        -              },
        -              "minItems": 1,
        -              "type": "array"
        -            },
        -            "universe": {
        -              "additionalProperties": true,
        -              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -              "properties": {
        -                "assets": {
        -                  "items": {
        -                    "additionalProperties": true,
        -                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -                    "properties": {
        -                      "name": {
        -                        "type": "string"
        -                      },
        -                      "symbol": {
        -                        "type": "string"
        -                      },
        -                      "type": {
        -                        "enum": [
        -                          "Stock",
        -                          "Cryptocurrency",
        -                          "Option",
        -                          "Other"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "symbol"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "type": "array"
        -                },
        -                "source": {
        -                  "enum": [
        -                    "ALL_US_STOCKS",
        -                    "SP500",
        -                    "NASDAQ100",
        -                    "DJIA",
        -                    "CRYPTO",
        -                    "SPECIFIC_ASSETS"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "source"
        -              ],
        -              "type": "object"
        -            },
        -            "weightIndicator": {
        -              "$ref": "#/$defs/indicator"
        -            }
        -          },
        -          "required": [
        -            "name"
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "structureTemplates": {
        -        "items": {
        -          "additionalProperties": true,
        -          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        -          "properties": {
        -            "eligibility": {
        -              "$ref": "#/$defs/condition"
        -            },
        -            "legs": {
        -              "items": {
        -                "additionalProperties": true,
        -                "description": "Single leg of an option builder.",
        -                "properties": {
        -                  "direction": {
        -                    "enum": [
        -                      "long",
        -                      "short"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "expirationRange": {
        -                    "additionalProperties": true,
        -                    "type": "object"
        -                  },
        -                  "expirationSelector": {
        -                    "properties": {
        -                      "maxDaysToExpiration": {
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "minDaysToExpiration": {
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "preference": {
        -                        "enum": [
        -                          "nearest",
        -                          "middle",
        -                          "furthest"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "minDaysToExpiration",
        -                      "maxDaysToExpiration",
        -                      "preference"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "fallbackStrikeSelector": {
        -                    "additionalProperties": false,
        -                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                    "properties": {
        -                      "distance": {
        -                        "type": "number"
        -                      },
        -                      "distanceType": {
        -                        "enum": [
        -                          "percent",
        -                          "dollars"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "distanceType",
        -                      "distance"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "greekFilter": {
        -                    "additionalProperties": true,
        -                    "description": "Optional min/max constraints on Greeks during resolution.",
        -                    "type": "object"
        -                  },
        -                  "liquidityFilter": {
        -                    "additionalProperties": false,
        -                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                    "properties": {
        -                      "maxSpreadAbsolute": {
        -                        "type": "number"
        -                      },
        -                      "maxSpreadPct": {
        -                        "type": "number"
        -                      },
        -                      "minBid": {
        -                        "type": "number"
        -                      }
        -                    },
        -                    "type": "object"
        -                  },
        -                  "optionType": {
        -                    "enum": [
        -                      "call",
        -                      "put"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "ratio": {
        -                    "type": "number"
        -                  },
        -                  "strikeRange": {
        -                    "additionalProperties": true,
        -                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                    "type": "object"
        -                  },
        -                  "strikeSelector": {
        -                    "properties": {
        -                      "distance": {
        -                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                        "type": "number"
        -                      },
        -                      "distanceType": {
        -                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "distanceType",
        -                      "distance"
        -                    ],
        -                    "type": "object"
        -                  }
        -                },
        -                "required": [
        -                  "optionType",
        -                  "direction",
        -                  "expirationSelector",
        -                  "strikeSelector"
        -                ],
        -                "type": "object"
        -              },
        -              "minItems": 1,
        -              "type": "array"
        -            },
        -            "name": {
        -              "type": "string"
        -            },
        -            "spreadType": {
        -              "enum": [
        -                "vertical",
        -                "calendar",
        -                "diagonal",
        -                "ironCondor",
        -                "straddle",
        -                "strangle",
        -                "custom"
        -              ],
        -              "type": "string"
        -            },
        -            "widthConstraint": {
        -              "additionalProperties": false,
        -              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -              "properties": {
        -                "minWidthDollars": {
        -                  "exclusiveMinimum": 0,
        -                  "type": "number"
        -                },
        -                "minWidthPercent": {
        -                  "exclusiveMinimum": 0,
        -                  "type": "number"
        -                }
        -              },
        -              "type": "object"
        -            }
        -          },
        -          "required": [
        -            "legs"
        -          ],
        -          "type": "object"
        -        },
        -        "minItems": 1,
        -        "type": "array"
        -      },
        -      "totalBudget": {
        -        "additionalProperties": true,
        -        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        -        "properties": {
        -          "amount": {
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "const": "RebalanceOption",
        -        "type": "string"
        -      },
        -      "universe": {
        -        "additionalProperties": true,
        -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -        "properties": {
        -          "assets": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -              "properties": {
        -                "name": {
        -                  "type": "string"
        -                },
        -                "symbol": {
        -                  "type": "string"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "Stock",
        -                    "Cryptocurrency",
        -                    "Option",
        -                    "Other"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "symbol"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "source": {
        -            "enum": [
        -              "ALL_US_STOCKS",
        -              "SP500",
        -              "NASDAQ100",
        -              "DJIA",
        -              "CRYPTO",
        -              "SPECIFIC_ASSETS"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "weightIndicator": {
        -        "$ref": "#/$defs/indicator"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "universe",
        -      "pipeline",
        -      "weightIndicator",
        -      "structureTemplates"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        -    "properties": {
        -      "closeScope": {
        -        "enum": [
        -          "spread",
        -          "leg"
        -        ],
        -        "type": "string"
        -      },
        -      "direction": {
        -        "enum": [
        -          "long",
        -          "short"
        -        ],
        -        "type": "string"
        -      },
        -      "optionType": {
        -        "enum": [
        -          "call",
        -          "put"
        -        ],
        -        "type": "string"
        -      },
        -      "quantity": {
        -        "additionalProperties": true,
        -        "description": "How many contracts to close. Defaults to all matching when omitted.",
        -        "type": "object"
        -      },
        -      "spreadType": {
        -        "enum": [
        -          "vertical",
        -          "calendar",
        -          "diagonal",
        -          "ironCondor",
        -          "straddle",
        -          "strangle",
        -          "custom"
        -        ],
        -        "type": "string"
        -      },
        -      "triggers": {
        -        "items": {
        -          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxPnlPercent": {
        -                  "type": "number"
        -                },
        -                "minPnlPercent": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "pnl",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxDte": {
        -                  "type": "number"
        -                },
        -                "minDte": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "dte",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxDaysHeld": {
        -                  "type": "number"
        -                },
        -                "minDaysHeld": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "daysHeld",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxIv": {
        -                  "type": "number"
        -                },
        -                "maxSpreadDelta": {
        -                  "type": "number"
        -                },
        -                "maxSpreadTheta": {
        -                  "type": "number"
        -                },
        -                "minIv": {
        -                  "type": "number"
        -                },
        -                "minSpreadDelta": {
        -                  "type": "number"
        -                },
        -                "minSpreadTheta": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "greeks",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "type": {
        -        "const": "CloseOption",
        -        "type": "string"
        -      },
        -      "underlyings": {
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array"
        -      }
        -    },
        -    "required": [
        -      "type"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": true,
        +    "description": "Buy or Sell a stock/crypto position.",
        +    "properties": {
        +      "amount": {
        +        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "percent of current positions",
        +              "dollars",
        +              "number of assets"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "targetAsset": {
        +        "additionalProperties": true,
        +        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +        "properties": {
        +          "name": {
        +            "type": "string"
        +          },
        +          "symbol": {
        +            "type": "string"
        +          },
        +          "type": {
        +            "enum": [
        +              "Stock",
        +              "Cryptocurrency",
        +              "Option",
        +              "Other"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "symbol"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "enum": [
        +          "Buy",
        +          "Sell"
        +        ],
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "targetAsset",
        +      "amount"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Send an alert message (no order).",
        +    "properties": {
        +      "message": {
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "Alert",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "message"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        +    "properties": {
        +      "allocationPolicy": {
        +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "expectedReturnShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "riskAversion": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MeanVariance",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "riskAversion",
        +              "expectedReturnShrinkage",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "RiskParity",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MaximumDiversification",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "canSell": {
        +        "$ref": "#/$defs/condition",
        +        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        +      },
        +      "deploymentPercent": {
        +        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        +        "maximum": 100,
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "exposurePolicy": {
        +        "additionalProperties": false,
        +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +        "properties": {
        +          "covarianceShrinkage": {
        +            "maximum": 1,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "estimatedTransactionCostBps": {
        +            "maximum": 10000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "lookbackPeriods": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "minimumObservations": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "targetAnnualizedVolatilityPercent": {
        +            "maximum": 1000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "const": "VolatilityTarget",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "lookbackPeriods",
        +          "minimumObservations",
        +          "covarianceShrinkage",
        +          "targetAnnualizedVolatilityPercent",
        +          "estimatedTransactionCostBps"
        +        ],
        +        "type": "object"
        +      },
        +      "limit": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "perNameAllocation": {
        +        "additionalProperties": true,
        +        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.",
        +        "properties": {
        +          "amount": {
        +            "exclusiveMinimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "percent of portfolio",
        +              "dollars"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "pipeline": {
        +        "items": {
        +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "condition": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "type": {
        +                  "const": "Filter",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "condition"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "type": {
        +                  "const": "SelectTop",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "limit",
        +                "direction"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "percentile": {
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "SelectPercentile",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "percentile",
        +                "direction"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "type": {
        +        "const": "DynamicRebalance",
        +        "type": "string"
        +      },
        +      "universe": {
        +        "additionalProperties": true,
        +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +        "properties": {
        +          "assets": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +              "properties": {
        +                "name": {
        +                  "type": "string"
        +                },
        +                "symbol": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Stock",
        +                    "Cryptocurrency",
        +                    "Option",
        +                    "Other"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "symbol"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "enum": [
        +              "ALL_US_STOCKS",
        +              "SP500",
        +              "NASDAQ100",
        +              "DJIA",
        +              "CRYPTO",
        +              "SPECIFIC_ASSETS"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "weightIndicator": {
        +        "$ref": "#/$defs/indicator"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "universe",
        +      "pipeline",
        +      "weightIndicator"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        +    "properties": {
        +      "continueExisting": {
        +        "type": "boolean"
        +      },
        +      "cooldownMinutes": {
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "executionModel": {
        +        "type": "string"
        +      },
        +      "includeMarketData": {
        +        "type": "boolean"
        +      },
        +      "initialMessage": {
        +        "type": "string"
        +      },
        +      "maxIterations": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "planningModel": {
        +        "type": "string"
        +      },
        +      "skipPlanning": {
        +        "type": "boolean"
        +      },
        +      "type": {
        +        "const": "LaunchAgent",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "planningModel",
        +      "executionModel",
        +      "initialMessage",
        +      "maxIterations",
        +      "includeMarketData",
        +      "continueExisting",
        +      "skipPlanning"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        +    "properties": {
        +      "against": {
        +        "additionalProperties": true,
        +        "description": "Optional parent-position selector (e.g. for covered calls).",
        +        "type": "object"
        +      },
        +      "allocation": {
        +        "additionalProperties": true,
        +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "contracts",
        +              "percent of realized premium"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "builder": {
        +        "additionalProperties": true,
        +        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        +        "properties": {
        +          "dynamicUnderlying": {
        +            "additionalProperties": true,
        +            "properties": {
        +              "limit": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "pipeline": {
        +                "items": {
        +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                  "oneOf": [
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "condition": {
        +                          "$ref": "#/$defs/condition"
        +                        },
        +                        "type": {
        +                          "const": "Filter",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "condition"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "limit": {
        +                          "minimum": 1,
        +                          "type": "number"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "type": {
        +                          "const": "SelectTop",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "limit",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "percentile": {
        +                          "maximum": 100,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "SelectPercentile",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "percentile",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "universe": {
        +                "additionalProperties": true,
        +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                "properties": {
        +                  "assets": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                      "properties": {
        +                        "name": {
        +                          "type": "string"
        +                        },
        +                        "symbol": {
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "enum": [
        +                            "Stock",
        +                            "Cryptocurrency",
        +                            "Option",
        +                            "Other"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "symbol"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "type": "array"
        +                  },
        +                  "source": {
        +                    "enum": [
        +                      "ALL_US_STOCKS",
        +                      "SP500",
        +                      "NASDAQ100",
        +                      "DJIA",
        +                      "CRYPTO",
        +                      "SPECIFIC_ASSETS"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "source"
        +                ],
        +                "type": "object"
        +              }
        +            },
        +            "required": [
        +              "universe"
        +            ],
        +            "type": "object"
        +          },
        +          "legs": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Single leg of an option builder.",
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "long",
        +                    "short"
        +                  ],
        +                  "type": "string"
        +                },
        +                "expirationRange": {
        +                  "additionalProperties": true,
        +                  "type": "object"
        +                },
        +                "expirationSelector": {
        +                  "properties": {
        +                    "maxDaysToExpiration": {
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "minDaysToExpiration": {
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "preference": {
        +                      "enum": [
        +                        "nearest",
        +                        "middle",
        +                        "furthest"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "minDaysToExpiration",
        +                    "maxDaysToExpiration",
        +                    "preference"
        +                  ],
        +                  "type": "object"
        +                },
        +                "fallbackStrikeSelector": {
        +                  "additionalProperties": false,
        +                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                  "properties": {
        +                    "distance": {
        +                      "type": "number"
        +                    },
        +                    "distanceType": {
        +                      "enum": [
        +                        "percent",
        +                        "dollars"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "distanceType",
        +                    "distance"
        +                  ],
        +                  "type": "object"
        +                },
        +                "greekFilter": {
        +                  "additionalProperties": true,
        +                  "description": "Optional min/max constraints on Greeks during resolution.",
        +                  "type": "object"
        +                },
        +                "liquidityFilter": {
        +                  "additionalProperties": false,
        +                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                  "properties": {
        +                    "maxSpreadAbsolute": {
        +                      "type": "number"
        +                    },
        +                    "maxSpreadPct": {
        +                      "type": "number"
        +                    },
        +                    "minBid": {
        +                      "type": "number"
        +                    }
        +                  },
        +                  "type": "object"
        +                },
        +                "optionType": {
        +                  "enum": [
        +                    "call",
        +                    "put"
        +                  ],
        +                  "type": "string"
        +                },
        +                "ratio": {
        +                  "type": "number"
        +                },
        +                "strikeRange": {
        +                  "additionalProperties": true,
        +                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                  "type": "object"
        +                },
        +                "strikeSelector": {
        +                  "properties": {
        +                    "distance": {
        +                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                      "type": "number"
        +                    },
        +                    "distanceType": {
        +                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "distanceType",
        +                    "distance"
        +                  ],
        +                  "type": "object"
        +                }
        +              },
        +              "required": [
        +                "optionType",
        +                "direction",
        +                "expirationSelector",
        +                "strikeSelector"
        +              ],
        +              "type": "object"
        +            },
        +            "minItems": 1,
        +            "type": "array"
        +          },
        +          "spreadType": {
        +            "enum": [
        +              "vertical",
        +              "calendar",
        +              "diagonal",
        +              "ironCondor",
        +              "straddle",
        +              "strangle",
        +              "custom"
        +            ],
        +            "type": "string"
        +          },
        +          "underlyingSymbol": {
        +            "type": "string"
        +          },
        +          "widthConstraint": {
        +            "additionalProperties": false,
        +            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +            "properties": {
        +              "minWidthDollars": {
        +                "exclusiveMinimum": 0,
        +                "type": "number"
        +              },
        +              "minWidthPercent": {
        +                "exclusiveMinimum": 0,
        +                "type": "number"
        +              }
        +            },
        +            "type": "object"
        +          }
        +        },
        +        "required": [
        +          "legs"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "const": "OpenOption",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "builder"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        +    "properties": {
        +      "allocationPolicy": {
        +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "expectedReturnShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "riskAversion": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MeanVariance",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "riskAversion",
        +              "expectedReturnShrinkage",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "RiskParity",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MaximumDiversification",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "exposurePolicy": {
        +        "additionalProperties": false,
        +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +        "properties": {
        +          "covarianceShrinkage": {
        +            "maximum": 1,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "estimatedTransactionCostBps": {
        +            "maximum": 10000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "lookbackPeriods": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "minimumObservations": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "targetAnnualizedVolatilityPercent": {
        +            "maximum": 1000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "const": "VolatilityTarget",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "lookbackPeriods",
        +          "minimumObservations",
        +          "covarianceShrinkage",
        +          "targetAnnualizedVolatilityPercent",
        +          "estimatedTransactionCostBps"
        +        ],
        +        "type": "object"
        +      },
        +      "limit": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "perNameAllocation": {
        +        "additionalProperties": true,
        +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "contracts",
        +              "percent of realized premium"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "pipeline": {
        +        "items": {
        +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "condition": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "type": {
        +                  "const": "Filter",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "condition"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "type": {
        +                  "const": "SelectTop",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "limit",
        +                "direction"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "percentile": {
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "SelectPercentile",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "percentile",
        +                "direction"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "positionScope": {
        +        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        +        "enum": [
        +          "portfolio",
        +          "strategy"
        +        ],
        +        "type": "string"
        +      },
        +      "sleeves": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        +          "properties": {
        +            "limit": {
        +              "minimum": 1,
        +              "type": "number"
        +            },
        +            "name": {
        +              "type": "string"
        +            },
        +            "perNameAllocation": {
        +              "additionalProperties": true,
        +              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +              "properties": {
        +                "amount": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "dollars",
        +                    "percent of portfolio",
        +                    "percent of buying power",
        +                    "contracts",
        +                    "percent of realized premium"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "amount"
        +              ],
        +              "type": "object"
        +            },
        +            "pipeline": {
        +              "items": {
        +                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                "oneOf": [
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "condition": {
        +                        "$ref": "#/$defs/condition"
        +                      },
        +                      "type": {
        +                        "const": "Filter",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "condition"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "direction": {
        +                        "enum": [
        +                          "Highest",
        +                          "Lowest"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "limit": {
        +                        "minimum": 1,
        +                        "type": "number"
        +                      },
        +                      "metric": {
        +                        "$ref": "#/$defs/indicator"
        +                      },
        +                      "type": {
        +                        "const": "SelectTop",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "metric",
        +                      "limit",
        +                      "direction"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "direction": {
        +                        "enum": [
        +                          "Highest",
        +                          "Lowest"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "metric": {
        +                        "$ref": "#/$defs/indicator"
        +                      },
        +                      "percentile": {
        +                        "maximum": 100,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "SelectPercentile",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "metric",
        +                      "percentile",
        +                      "direction"
        +                    ],
        +                    "type": "object"
        +                  }
        +                ],
        +                "type": "object"
        +              },
        +              "type": "array"
        +            },
        +            "structureTemplates": {
        +              "items": {
        +                "additionalProperties": true,
        +                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +                "properties": {
        +                  "eligibility": {
        +                    "$ref": "#/$defs/condition"
        +                  },
        +                  "legs": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Single leg of an option builder.",
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "long",
        +                            "short"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "expirationRange": {
        +                          "additionalProperties": true,
        +                          "type": "object"
        +                        },
        +                        "expirationSelector": {
        +                          "properties": {
        +                            "maxDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "minDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "preference": {
        +                              "enum": [
        +                                "nearest",
        +                                "middle",
        +                                "furthest"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "minDaysToExpiration",
        +                            "maxDaysToExpiration",
        +                            "preference"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "fallbackStrikeSelector": {
        +                          "additionalProperties": false,
        +                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                          "properties": {
        +                            "distance": {
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "enum": [
        +                                "percent",
        +                                "dollars"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "greekFilter": {
        +                          "additionalProperties": true,
        +                          "description": "Optional min/max constraints on Greeks during resolution.",
        +                          "type": "object"
        +                        },
        +                        "liquidityFilter": {
        +                          "additionalProperties": false,
        +                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                          "properties": {
        +                            "maxSpreadAbsolute": {
        +                              "type": "number"
        +                            },
        +                            "maxSpreadPct": {
        +                              "type": "number"
        +                            },
        +                            "minBid": {
        +                              "type": "number"
        +                            }
        +                          },
        +                          "type": "object"
        +                        },
        +                        "optionType": {
        +                          "enum": [
        +                            "call",
        +                            "put"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "ratio": {
        +                          "type": "number"
        +                        },
        +                        "strikeRange": {
        +                          "additionalProperties": true,
        +                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                          "type": "object"
        +                        },
        +                        "strikeSelector": {
        +                          "properties": {
        +                            "distance": {
        +                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        }
        +                      },
        +                      "required": [
        +                        "optionType",
        +                        "direction",
        +                        "expirationSelector",
        +                        "strikeSelector"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "minItems": 1,
        +                    "type": "array"
        +                  },
        +                  "name": {
        +                    "type": "string"
        +                  },
        +                  "spreadType": {
        +                    "enum": [
        +                      "vertical",
        +                      "calendar",
        +                      "diagonal",
        +                      "ironCondor",
        +                      "straddle",
        +                      "strangle",
        +                      "custom"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "widthConstraint": {
        +                    "additionalProperties": false,
        +                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                    "properties": {
        +                      "minWidthDollars": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minWidthPercent": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "legs"
        +                ],
        +                "type": "object"
        +              },
        +              "minItems": 1,
        +              "type": "array"
        +            },
        +            "universe": {
        +              "additionalProperties": true,
        +              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +              "properties": {
        +                "assets": {
        +                  "items": {
        +                    "additionalProperties": true,
        +                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                    "properties": {
        +                      "name": {
        +                        "type": "string"
        +                      },
        +                      "symbol": {
        +                        "type": "string"
        +                      },
        +                      "type": {
        +                        "enum": [
        +                          "Stock",
        +                          "Cryptocurrency",
        +                          "Option",
        +                          "Other"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "symbol"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "type": "array"
        +                },
        +                "source": {
        +                  "enum": [
        +                    "ALL_US_STOCKS",
        +                    "SP500",
        +                    "NASDAQ100",
        +                    "DJIA",
        +                    "CRYPTO",
        +                    "SPECIFIC_ASSETS"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "source"
        +              ],
        +              "type": "object"
        +            },
        +            "weightIndicator": {
        +              "$ref": "#/$defs/indicator"
        +            }
        +          },
        +          "required": [
        +            "name"
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "structureTemplates": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +          "properties": {
        +            "eligibility": {
        +              "$ref": "#/$defs/condition"
        +            },
        +            "legs": {
        +              "items": {
        +                "additionalProperties": true,
        +                "description": "Single leg of an option builder.",
        +                "properties": {
        +                  "direction": {
        +                    "enum": [
        +                      "long",
        +                      "short"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "expirationRange": {
        +                    "additionalProperties": true,
        +                    "type": "object"
        +                  },
        +                  "expirationSelector": {
        +                    "properties": {
        +                      "maxDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "preference": {
        +                        "enum": [
        +                          "nearest",
        +                          "middle",
        +                          "furthest"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "minDaysToExpiration",
        +                      "maxDaysToExpiration",
        +                      "preference"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "fallbackStrikeSelector": {
        +                    "additionalProperties": false,
        +                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                    "properties": {
        +                      "distance": {
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "enum": [
        +                          "percent",
        +                          "dollars"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "greekFilter": {
        +                    "additionalProperties": true,
        +                    "description": "Optional min/max constraints on Greeks during resolution.",
        +                    "type": "object"
        +                  },
        +                  "liquidityFilter": {
        +                    "additionalProperties": false,
        +                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                    "properties": {
        +                      "maxSpreadAbsolute": {
        +                        "type": "number"
        +                      },
        +                      "maxSpreadPct": {
        +                        "type": "number"
        +                      },
        +                      "minBid": {
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  },
        +                  "optionType": {
        +                    "enum": [
        +                      "call",
        +                      "put"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "ratio": {
        +                    "type": "number"
        +                  },
        +                  "strikeRange": {
        +                    "additionalProperties": true,
        +                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                    "type": "object"
        +                  },
        +                  "strikeSelector": {
        +                    "properties": {
        +                      "distance": {
        +                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "optionType",
        +                  "direction",
        +                  "expirationSelector",
        +                  "strikeSelector"
        +                ],
        +                "type": "object"
        +              },
        +              "minItems": 1,
        +              "type": "array"
        +            },
        +            "name": {
        +              "type": "string"
        +            },
        +            "spreadType": {
        +              "enum": [
        +                "vertical",
        +                "calendar",
        +                "diagonal",
        +                "ironCondor",
        +                "straddle",
        +                "strangle",
        +                "custom"
        +              ],
        +              "type": "string"
        +            },
        +            "widthConstraint": {
        +              "additionalProperties": false,
        +              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +              "properties": {
        +                "minWidthDollars": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                },
        +                "minWidthPercent": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                }
        +              },
        +              "type": "object"
        +            }
        +          },
        +          "required": [
        +            "legs"
        +          ],
        +          "type": "object"
        +        },
        +        "minItems": 1,
        +        "type": "array"
        +      },
        +      "totalBudget": {
        +        "additionalProperties": true,
        +        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        +        "properties": {
        +          "amount": {
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "const": "RebalanceOption",
        +        "type": "string"
        +      },
        +      "universe": {
        +        "additionalProperties": true,
        +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +        "properties": {
        +          "assets": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +              "properties": {
        +                "name": {
        +                  "type": "string"
        +                },
        +                "symbol": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Stock",
        +                    "Cryptocurrency",
        +                    "Option",
        +                    "Other"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "symbol"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "enum": [
        +              "ALL_US_STOCKS",
        +              "SP500",
        +              "NASDAQ100",
        +              "DJIA",
        +              "CRYPTO",
        +              "SPECIFIC_ASSETS"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "weightIndicator": {
        +        "$ref": "#/$defs/indicator"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "universe",
        +      "pipeline",
        +      "weightIndicator",
        +      "structureTemplates"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        +    "properties": {
        +      "closeScope": {
        +        "enum": [
        +          "spread",
        +          "leg"
        +        ],
        +        "type": "string"
        +      },
        +      "direction": {
        +        "enum": [
        +          "long",
        +          "short"
        +        ],
        +        "type": "string"
        +      },
        +      "optionType": {
        +        "enum": [
        +          "call",
        +          "put"
        +        ],
        +        "type": "string"
        +      },
        +      "quantity": {
        +        "additionalProperties": true,
        +        "description": "How many contracts to close. Defaults to all matching when omitted.",
        +        "type": "object"
        +      },
        +      "spreadType": {
        +        "enum": [
        +          "vertical",
        +          "calendar",
        +          "diagonal",
        +          "ironCondor",
        +          "straddle",
        +          "strangle",
        +          "custom"
        +        ],
        +        "type": "string"
        +      },
        +      "triggers": {
        +        "items": {
        +          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxPnlPercent": {
        +                  "type": "number"
        +                },
        +                "minPnlPercent": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "pnl",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxDte": {
        +                  "type": "number"
        +                },
        +                "minDte": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "dte",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxDaysHeld": {
        +                  "type": "number"
        +                },
        +                "minDaysHeld": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "daysHeld",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxIv": {
        +                  "type": "number"
        +                },
        +                "maxSpreadDelta": {
        +                  "type": "number"
        +                },
        +                "maxSpreadTheta": {
        +                  "type": "number"
        +                },
        +                "minIv": {
        +                  "type": "number"
        +                },
        +                "minSpreadDelta": {
        +                  "type": "number"
        +                },
        +                "minSpreadTheta": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "greeks",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "type": {
        +        "const": "CloseOption",
        +        "type": "string"
        +      },
        +      "underlyings": {
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  }
        +]
    • Changedcreate_portfolio8 fields changed
      • changedInput schema / $defs / action / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "description": "Buy or Sell a stock/crypto position.",
        -    "properties": {
        -      "amount": {
        -        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "percent of current positions",
        -              "dollars",
        -              "number of assets"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "targetAsset": {
        -        "additionalProperties": true,
        -        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -        "properties": {
        -          "name": {
        -            "type": "string"
        -          },
        -          "symbol": {
        -            "type": "string"
        -          },
        -          "type": {
        -            "enum": [
        -              "Stock",
        -              "Cryptocurrency",
        -              "Option",
        -              "Other"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "symbol"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "enum": [
        -          "Buy",
        -          "Sell"
        -        ],
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "targetAsset",
        -      "amount"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Send an alert message (no order).",
        -    "properties": {
        -      "message": {
        -        "type": "string"
        -      },
        -      "type": {
        -        "const": "Alert",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "message"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        -    "properties": {
        -      "allocationPolicy": {
        -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "expectedReturnShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "riskAversion": {
        -                "maximum": 1000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MeanVariance",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "riskAversion",
        -              "expectedReturnShrinkage",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "RiskParity",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumDiversification",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "canSell": {
        -        "$ref": "#/$defs/condition",
        -        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        -      },
        -      "deploymentPercent": {
        -        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        -        "maximum": 100,
        -        "minimum": 0,
        -        "type": "number"
        -      },
        -      "exposurePolicy": {
        -        "additionalProperties": false,
        -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        -        "properties": {
        -          "covarianceShrinkage": {
        -            "maximum": 1,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "estimatedTransactionCostBps": {
        -            "maximum": 10000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "lookbackPeriods": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "minimumObservations": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "targetAnnualizedVolatilityPercent": {
        -            "maximum": 1000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "const": "VolatilityTarget",
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "lookbackPeriods",
        -          "minimumObservations",
        -          "covarianceShrinkage",
        -          "targetAnnualizedVolatilityPercent",
        -          "estimatedTransactionCostBps"
        -        ],
        -        "type": "object"
        -      },
        -      "limit": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "perNameAllocation": {
        -        "additionalProperties": true,
        -        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
        -        "properties": {
        -          "amount": {
        -            "exclusiveMinimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "percent of portfolio",
        -              "dollars"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "pipeline": {
        -        "items": {
        -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "condition": {
        -                  "$ref": "#/$defs/condition"
        -                },
        -                "type": {
        -                  "const": "Filter",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "condition"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "limit": {
        -                  "minimum": 1,
        -                  "type": "number"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "type": {
        -                  "const": "SelectTop",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "limit",
        -                "direction"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "percentile": {
        -                  "maximum": 100,
        -                  "minimum": 0,
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "SelectPercentile",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "percentile",
        -                "direction"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "type": {
        -        "const": "DynamicRebalance",
        -        "type": "string"
        -      },
        -      "universe": {
        -        "additionalProperties": true,
        -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -        "properties": {
        -          "assets": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -              "properties": {
        -                "name": {
        -                  "type": "string"
        -                },
        -                "symbol": {
        -                  "type": "string"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "Stock",
        -                    "Cryptocurrency",
        -                    "Option",
        -                    "Other"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "symbol"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "source": {
        -            "enum": [
        -              "ALL_US_STOCKS",
        -              "SP500",
        -              "NASDAQ100",
        -              "DJIA",
        -              "CRYPTO",
        -              "SPECIFIC_ASSETS"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "weightIndicator": {
        -        "$ref": "#/$defs/indicator"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "universe",
        -      "pipeline",
        -      "weightIndicator"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        -    "properties": {
        -      "continueExisting": {
        -        "type": "boolean"
        -      },
        -      "cooldownMinutes": {
        -        "minimum": 0,
        -        "type": "number"
        -      },
        -      "executionModel": {
        -        "type": "string"
        -      },
        -      "includeMarketData": {
        -        "type": "boolean"
        -      },
        -      "initialMessage": {
        -        "type": "string"
        -      },
        -      "maxIterations": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "planningModel": {
        -        "type": "string"
        -      },
        -      "skipPlanning": {
        -        "type": "boolean"
        -      },
        -      "type": {
        -        "const": "LaunchAgent",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "planningModel",
        -      "executionModel",
        -      "initialMessage",
        -      "maxIterations",
        -      "includeMarketData",
        -      "continueExisting",
        -      "skipPlanning"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        -    "properties": {
        -      "against": {
        -        "additionalProperties": true,
        -        "description": "Optional parent-position selector (e.g. for covered calls).",
        -        "type": "object"
        -      },
        -      "allocation": {
        -        "additionalProperties": true,
        -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "contracts"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "builder": {
        -        "additionalProperties": true,
        -        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        -        "properties": {
        -          "dynamicUnderlying": {
        -            "additionalProperties": true,
        -            "properties": {
        -              "limit": {
        -                "minimum": 1,
        -                "type": "number"
        -              },
        -              "pipeline": {
        -                "items": {
        -                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -                  "oneOf": [
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "condition": {
        -                          "$ref": "#/$defs/condition"
        -                        },
        -                        "type": {
        -                          "const": "Filter",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "condition"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "Highest",
        -                            "Lowest"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "limit": {
        -                          "minimum": 1,
        -                          "type": "number"
        -                        },
        -                        "metric": {
        -                          "$ref": "#/$defs/indicator"
        -                        },
        -                        "type": {
        -                          "const": "SelectTop",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "metric",
        -                        "limit",
        -                        "direction"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "Highest",
        -                            "Lowest"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "metric": {
        -                          "$ref": "#/$defs/indicator"
        -                        },
        -                        "percentile": {
        -                          "maximum": 100,
        -                          "minimum": 0,
        -                          "type": "number"
        -                        },
        -                        "type": {
        -                          "const": "SelectPercentile",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "metric",
        -                        "percentile",
        -                        "direction"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ],
        -                  "type": "object"
        -                },
        -                "type": "array"
        -              },
        -              "universe": {
        -                "additionalProperties": true,
        -                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -                "properties": {
        -                  "assets": {
        -                    "items": {
        -                      "additionalProperties": true,
        -                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -                      "properties": {
        -                        "name": {
        -                          "type": "string"
        -                        },
        -                        "symbol": {
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "enum": [
        -                            "Stock",
        -                            "Cryptocurrency",
        -                            "Option",
        -                            "Other"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "symbol"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    "type": "array"
        -                  },
        -                  "source": {
        -                    "enum": [
        -                      "ALL_US_STOCKS",
        -                      "SP500",
        -                      "NASDAQ100",
        -                      "DJIA",
        -                      "CRYPTO",
        -                      "SPECIFIC_ASSETS"
        -                    ],
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "source"
        -                ],
        -                "type": "object"
        -              }
        -            },
        -            "required": [
        -              "universe"
        -            ],
        -            "type": "object"
        -          },
        -          "legs": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Single leg of an option builder.",
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "long",
        -                    "short"
        -                  ],
        -                  "type": "string"
        -                },
        -                "expirationRange": {
        -                  "additionalProperties": true,
        -                  "type": "object"
        -                },
        -                "expirationSelector": {
        -                  "properties": {
        -                    "maxDaysToExpiration": {
        -                      "minimum": 0,
        -                      "type": "number"
        -                    },
        -                    "minDaysToExpiration": {
        -                      "minimum": 0,
        -                      "type": "number"
        -                    },
        -                    "preference": {
        -                      "enum": [
        -                        "nearest",
        -                        "middle",
        -                        "furthest"
        -                      ],
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "minDaysToExpiration",
        -                    "maxDaysToExpiration",
        -                    "preference"
        -                  ],
        -                  "type": "object"
        -                },
        -                "fallbackStrikeSelector": {
        -                  "additionalProperties": false,
        -                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                  "properties": {
        -                    "distance": {
        -                      "type": "number"
        -                    },
        -                    "distanceType": {
        -                      "enum": [
        -                        "percent",
        -                        "dollars"
        -                      ],
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "distanceType",
        -                    "distance"
        -                  ],
        -                  "type": "object"
        -                },
        -                "greekFilter": {
        -                  "additionalProperties": true,
        -                  "description": "Optional min/max constraints on Greeks during resolution.",
        -                  "type": "object"
        -                },
        -                "liquidityFilter": {
        -                  "additionalProperties": false,
        -                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                  "properties": {
        -                    "maxSpreadAbsolute": {
        -                      "type": "number"
        -                    },
        -                    "maxSpreadPct": {
        -                      "type": "number"
        -                    },
        -                    "minBid": {
        -                      "type": "number"
        -                    }
        -                  },
        -                  "type": "object"
        -                },
        -                "optionType": {
        -                  "enum": [
        -                    "call",
        -                    "put"
        -                  ],
        -                  "type": "string"
        -                },
        -                "ratio": {
        -                  "type": "number"
        -                },
        -                "strikeRange": {
        -                  "additionalProperties": true,
        -                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                  "type": "object"
        -                },
        -                "strikeSelector": {
        -                  "properties": {
        -                    "distance": {
        -                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                      "type": "number"
        -                    },
        -                    "distanceType": {
        -                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "distanceType",
        -                    "distance"
        -                  ],
        -                  "type": "object"
        -                }
        -              },
        -              "required": [
        -                "optionType",
        -                "direction",
        -                "expirationSelector",
        -                "strikeSelector"
        -              ],
        -              "type": "object"
        -            },
        -            "minItems": 1,
        -            "type": "array"
        -          },
        -          "spreadType": {
        -            "enum": [
        -              "vertical",
        -              "calendar",
        -              "diagonal",
        -              "ironCondor",
        -              "straddle",
        -              "strangle",
        -              "custom"
        -            ],
        -            "type": "string"
        -          },
        -          "underlyingSymbol": {
        -            "type": "string"
        -          },
        -          "widthConstraint": {
        -            "additionalProperties": false,
        -            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -            "properties": {
        -              "minWidthDollars": {
        -                "exclusiveMinimum": 0,
        -                "type": "number"
        -              },
        -              "minWidthPercent": {
        -                "exclusiveMinimum": 0,
        -                "type": "number"
        -              }
        -            },
        -            "type": "object"
        -          }
        -        },
        -        "required": [
        -          "legs"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "const": "OpenOption",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "builder"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        -    "properties": {
        -      "allocationPolicy": {
        -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "expectedReturnShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "riskAversion": {
        -                "maximum": 1000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MeanVariance",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "riskAversion",
        -              "expectedReturnShrinkage",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "RiskParity",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumDiversification",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "exposurePolicy": {
        -        "additionalProperties": false,
        -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        -        "properties": {
        -          "covarianceShrinkage": {
        -            "maximum": 1,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "estimatedTransactionCostBps": {
        -            "maximum": 10000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "lookbackPeriods": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "minimumObservations": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "targetAnnualizedVolatilityPercent": {
        -            "maximum": 1000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "const": "VolatilityTarget",
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "lookbackPeriods",
        -          "minimumObservations",
        -          "covarianceShrinkage",
        -          "targetAnnualizedVolatilityPercent",
        -          "estimatedTransactionCostBps"
        -        ],
        -        "type": "object"
        -      },
        -      "limit": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "perNameAllocation": {
        -        "additionalProperties": true,
        -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "contracts"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "pipeline": {
        -        "items": {
        -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "condition": {
        -                  "$ref": "#/$defs/condition"
        -                },
        -                "type": {
        -                  "const": "Filter",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "condition"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "limit": {
        -                  "minimum": 1,
        -                  "type": "number"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "type": {
        -                  "const": "SelectTop",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "limit",
        -                "direction"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "percentile": {
        -                  "maximum": 100,
        -                  "minimum": 0,
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "SelectPercentile",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "percentile",
        -                "direction"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "positionScope": {
        -        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        -        "enum": [
        -          "portfolio",
        -          "strategy"
        -        ],
        -        "type": "string"
        -      },
        -      "sleeves": {
        -        "items": {
        -          "additionalProperties": true,
        -          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        -          "properties": {
        -            "limit": {
        -              "minimum": 1,
        -              "type": "number"
        -            },
        -            "name": {
        -              "type": "string"
        -            },
        -            "perNameAllocation": {
        -              "additionalProperties": true,
        -              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -              "properties": {
        -                "amount": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "dollars",
        -                    "percent of portfolio",
        -                    "percent of buying power",
        -                    "contracts"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "amount"
        -              ],
        -              "type": "object"
        -            },
        -            "pipeline": {
        -              "items": {
        -                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -                "oneOf": [
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "condition": {
        -                        "$ref": "#/$defs/condition"
        -                      },
        -                      "type": {
        -                        "const": "Filter",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "condition"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "direction": {
        -                        "enum": [
        -                          "Highest",
        -                          "Lowest"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "limit": {
        -                        "minimum": 1,
        -                        "type": "number"
        -                      },
        -                      "metric": {
        -                        "$ref": "#/$defs/indicator"
        -                      },
        -                      "type": {
        -                        "const": "SelectTop",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "metric",
        -                      "limit",
        -                      "direction"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "direction": {
        -                        "enum": [
        -                          "Highest",
        -                          "Lowest"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "metric": {
        -                        "$ref": "#/$defs/indicator"
        -                      },
        -                      "percentile": {
        -                        "maximum": 100,
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "type": {
        -                        "const": "SelectPercentile",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "metric",
        -                      "percentile",
        -                      "direction"
        -                    ],
        -                    "type": "object"
        -                  }
        -                ],
        -                "type": "object"
        -              },
        -              "type": "array"
        -            },
        -            "structureTemplates": {
        -              "items": {
        -                "additionalProperties": true,
        -                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        -                "properties": {
        -                  "eligibility": {
        -                    "$ref": "#/$defs/condition"
        -                  },
        -                  "legs": {
        -                    "items": {
        -                      "additionalProperties": true,
        -                      "description": "Single leg of an option builder.",
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "long",
        -                            "short"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "expirationRange": {
        -                          "additionalProperties": true,
        -                          "type": "object"
        -                        },
        -                        "expirationSelector": {
        -                          "properties": {
        -                            "maxDaysToExpiration": {
        -                              "minimum": 0,
        -                              "type": "number"
        -                            },
        -                            "minDaysToExpiration": {
        -                              "minimum": 0,
        -                              "type": "number"
        -                            },
        -                            "preference": {
        -                              "enum": [
        -                                "nearest",
        -                                "middle",
        -                                "furthest"
        -                              ],
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "minDaysToExpiration",
        -                            "maxDaysToExpiration",
        -                            "preference"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "fallbackStrikeSelector": {
        -                          "additionalProperties": false,
        -                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                          "properties": {
        -                            "distance": {
        -                              "type": "number"
        -                            },
        -                            "distanceType": {
        -                              "enum": [
        -                                "percent",
        -                                "dollars"
        -                              ],
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "distanceType",
        -                            "distance"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "greekFilter": {
        -                          "additionalProperties": true,
        -                          "description": "Optional min/max constraints on Greeks during resolution.",
        -                          "type": "object"
        -                        },
        -                        "liquidityFilter": {
        -                          "additionalProperties": false,
        -                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                          "properties": {
        -                            "maxSpreadAbsolute": {
        -                              "type": "number"
        -                            },
        -                            "maxSpreadPct": {
        -                              "type": "number"
        -                            },
        -                            "minBid": {
        -                              "type": "number"
        -                            }
        -                          },
        -                          "type": "object"
        -                        },
        -                        "optionType": {
        -                          "enum": [
        -                            "call",
        -                            "put"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "ratio": {
        -                          "type": "number"
        -                        },
        -                        "strikeRange": {
        -                          "additionalProperties": true,
        -                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                          "type": "object"
        -                        },
        -                        "strikeSelector": {
        -                          "properties": {
        -                            "distance": {
        -                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                              "type": "number"
        -                            },
        -                            "distanceType": {
        -                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "distanceType",
        -                            "distance"
        -                          ],
        -                          "type": "object"
        -                        }
        -                      },
        -                      "required": [
        -                        "optionType",
        -                        "direction",
        -                        "expirationSelector",
        -                        "strikeSelector"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    "minItems": 1,
        -                    "type": "array"
        -                  },
        -                  "name": {
        -                    "type": "string"
        -                  },
        -                  "spreadType": {
        -                    "enum": [
        -                      "vertical",
        -                      "calendar",
        -                      "diagonal",
        -                      "ironCondor",
        -                      "straddle",
        -                      "strangle",
        -                      "custom"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "widthConstraint": {
        -                    "additionalProperties": false,
        -                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -                    "properties": {
        -                      "minWidthDollars": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "number"
        -                      },
        -                      "minWidthPercent": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "number"
        -                      }
        -                    },
        -                    "type": "object"
        -                  }
        -                },
        -                "required": [
        -                  "legs"
        -                ],
        -                "type": "object"
        -              },
        -              "minItems": 1,
        -              "type": "array"
        -            },
        -            "universe": {
        -              "additionalProperties": true,
        -              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -              "properties": {
        -                "assets": {
        -                  "items": {
        -                    "additionalProperties": true,
        -                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -                    "properties": {
        -                      "name": {
        -                        "type": "string"
        -                      },
        -                      "symbol": {
        -                        "type": "string"
        -                      },
        -                      "type": {
        -                        "enum": [
        -                          "Stock",
        -                          "Cryptocurrency",
        -                          "Option",
        -                          "Other"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "symbol"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "type": "array"
        -                },
        -                "source": {
        -                  "enum": [
        -                    "ALL_US_STOCKS",
        -                    "SP500",
        -                    "NASDAQ100",
        -                    "DJIA",
        -                    "CRYPTO",
        -                    "SPECIFIC_ASSETS"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "source"
        -              ],
        -              "type": "object"
        -            },
        -            "weightIndicator": {
        -              "$ref": "#/$defs/indicator"
        -            }
        -          },
        -          "required": [
        -            "name"
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "structureTemplates": {
        -        "items": {
        -          "additionalProperties": true,
        -          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        -          "properties": {
        -            "eligibility": {
        -              "$ref": "#/$defs/condition"
        -            },
        -            "legs": {
        -              "items": {
        -                "additionalProperties": true,
        -                "description": "Single leg of an option builder.",
        -                "properties": {
        -                  "direction": {
        -                    "enum": [
        -                      "long",
        -                      "short"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "expirationRange": {
        -                    "additionalProperties": true,
        -                    "type": "object"
        -                  },
        -                  "expirationSelector": {
        -                    "properties": {
        -                      "maxDaysToExpiration": {
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "minDaysToExpiration": {
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "preference": {
        -                        "enum": [
        -                          "nearest",
        -                          "middle",
        -                          "furthest"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "minDaysToExpiration",
        -                      "maxDaysToExpiration",
        -                      "preference"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "fallbackStrikeSelector": {
        -                    "additionalProperties": false,
        -                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                    "properties": {
        -                      "distance": {
        -                        "type": "number"
        -                      },
        -                      "distanceType": {
        -                        "enum": [
        -                          "percent",
        -                          "dollars"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "distanceType",
        -                      "distance"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "greekFilter": {
        -                    "additionalProperties": true,
        -                    "description": "Optional min/max constraints on Greeks during resolution.",
        -                    "type": "object"
        -                  },
        -                  "liquidityFilter": {
        -                    "additionalProperties": false,
        -                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                    "properties": {
        -                      "maxSpreadAbsolute": {
        -                        "type": "number"
        -                      },
        -                      "maxSpreadPct": {
        -                        "type": "number"
        -                      },
        -                      "minBid": {
        -                        "type": "number"
        -                      }
        -                    },
        -                    "type": "object"
        -                  },
        -                  "optionType": {
        -                    "enum": [
        -                      "call",
        -                      "put"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "ratio": {
        -                    "type": "number"
        -                  },
        -                  "strikeRange": {
        -                    "additionalProperties": true,
        -                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                    "type": "object"
        -                  },
        -                  "strikeSelector": {
        -                    "properties": {
        -                      "distance": {
        -                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                        "type": "number"
        -                      },
        -                      "distanceType": {
        -                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "distanceType",
        -                      "distance"
        -                    ],
        -                    "type": "object"
        -                  }
        -                },
        -                "required": [
        -                  "optionType",
        -                  "direction",
        -                  "expirationSelector",
        -                  "strikeSelector"
        -                ],
        -                "type": "object"
        -              },
        -              "minItems": 1,
        -              "type": "array"
        -            },
        -            "name": {
        -              "type": "string"
        -            },
        -            "spreadType": {
        -              "enum": [
        -                "vertical",
        -                "calendar",
        -                "diagonal",
        -                "ironCondor",
        -                "straddle",
        -                "strangle",
        -                "custom"
        -              ],
        -              "type": "string"
        -            },
        -            "widthConstraint": {
        -              "additionalProperties": false,
        -              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -              "properties": {
        -                "minWidthDollars": {
        -                  "exclusiveMinimum": 0,
        -                  "type": "number"
        -                },
        -                "minWidthPercent": {
        -                  "exclusiveMinimum": 0,
        -                  "type": "number"
        -                }
        -              },
        -              "type": "object"
        -            }
        -          },
        -          "required": [
        -            "legs"
        -          ],
        -          "type": "object"
        -        },
        -        "minItems": 1,
        -        "type": "array"
        -      },
        -      "totalBudget": {
        -        "additionalProperties": true,
        -        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        -        "properties": {
        -          "amount": {
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "const": "RebalanceOption",
        -        "type": "string"
        -      },
        -      "universe": {
        -        "additionalProperties": true,
        -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -        "properties": {
        -          "assets": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -              "properties": {
        -                "name": {
        -                  "type": "string"
        -                },
        -                "symbol": {
        -                  "type": "string"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "Stock",
        -                    "Cryptocurrency",
        -                    "Option",
        -                    "Other"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "symbol"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "source": {
        -            "enum": [
        -              "ALL_US_STOCKS",
        -              "SP500",
        -              "NASDAQ100",
        -              "DJIA",
        -              "CRYPTO",
        -              "SPECIFIC_ASSETS"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "weightIndicator": {
        -        "$ref": "#/$defs/indicator"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "universe",
        -      "pipeline",
        -      "weightIndicator",
        -      "structureTemplates"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        -    "properties": {
        -      "closeScope": {
        -        "enum": [
        -          "spread",
        -          "leg"
        -        ],
        -        "type": "string"
        -      },
        -      "direction": {
        -        "enum": [
        -          "long",
        -          "short"
        -        ],
        -        "type": "string"
        -      },
        -      "optionType": {
        -        "enum": [
        -          "call",
        -          "put"
        -        ],
        -        "type": "string"
        -      },
        -      "quantity": {
        -        "additionalProperties": true,
        -        "description": "How many contracts to close. Defaults to all matching when omitted.",
        -        "type": "object"
        -      },
        -      "spreadType": {
        -        "enum": [
        -          "vertical",
        -          "calendar",
        -          "diagonal",
        -          "ironCondor",
        -          "straddle",
        -          "strangle",
        -          "custom"
        -        ],
        -        "type": "string"
        -      },
        -      "triggers": {
        -        "items": {
        -          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxPnlPercent": {
        -                  "type": "number"
        -                },
        -                "minPnlPercent": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "pnl",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxDte": {
        -                  "type": "number"
        -                },
        -                "minDte": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "dte",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxDaysHeld": {
        -                  "type": "number"
        -                },
        -                "minDaysHeld": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "daysHeld",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxIv": {
        -                  "type": "number"
        -                },
        -                "maxSpreadDelta": {
        -                  "type": "number"
        -                },
        -                "maxSpreadTheta": {
        -                  "type": "number"
        -                },
        -                "minIv": {
        -                  "type": "number"
        -                },
        -                "minSpreadDelta": {
        -                  "type": "number"
        -                },
        -                "minSpreadTheta": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "greeks",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "type": {
        -        "const": "CloseOption",
        -        "type": "string"
        -      },
        -      "underlyings": {
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array"
        -      }
        -    },
        -    "required": [
        -      "type"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": true,
        +    "description": "Buy or Sell a stock/crypto position.",
        +    "properties": {
        +      "amount": {
        +        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "percent of current positions",
        +              "dollars",
        +              "number of assets"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "targetAsset": {
        +        "additionalProperties": true,
        +        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +        "properties": {
        +          "name": {
        +            "type": "string"
        +          },
        +          "symbol": {
        +            "type": "string"
        +          },
        +          "type": {
        +            "enum": [
        +              "Stock",
        +              "Cryptocurrency",
        +              "Option",
        +              "Other"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "symbol"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "enum": [
        +          "Buy",
        +          "Sell"
        +        ],
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "targetAsset",
        +      "amount"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Send an alert message (no order).",
        +    "properties": {
        +      "message": {
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "Alert",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "message"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        +    "properties": {
        +      "allocationPolicy": {
        +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "expectedReturnShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "riskAversion": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MeanVariance",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "riskAversion",
        +              "expectedReturnShrinkage",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "RiskParity",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MaximumDiversification",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "canSell": {
        +        "$ref": "#/$defs/condition",
        +        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        +      },
        +      "deploymentPercent": {
        +        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        +        "maximum": 100,
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "exposurePolicy": {
        +        "additionalProperties": false,
        +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +        "properties": {
        +          "covarianceShrinkage": {
        +            "maximum": 1,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "estimatedTransactionCostBps": {
        +            "maximum": 10000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "lookbackPeriods": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "minimumObservations": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "targetAnnualizedVolatilityPercent": {
        +            "maximum": 1000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "const": "VolatilityTarget",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "lookbackPeriods",
        +          "minimumObservations",
        +          "covarianceShrinkage",
        +          "targetAnnualizedVolatilityPercent",
        +          "estimatedTransactionCostBps"
        +        ],
        +        "type": "object"
        +      },
        +      "limit": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "perNameAllocation": {
        +        "additionalProperties": true,
        +        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.",
        +        "properties": {
        +          "amount": {
        +            "exclusiveMinimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "percent of portfolio",
        +              "dollars"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "pipeline": {
        +        "items": {
        +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "condition": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "type": {
        +                  "const": "Filter",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "condition"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "type": {
        +                  "const": "SelectTop",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "limit",
        +                "direction"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "percentile": {
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "SelectPercentile",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "percentile",
        +                "direction"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "type": {
        +        "const": "DynamicRebalance",
        +        "type": "string"
        +      },
        +      "universe": {
        +        "additionalProperties": true,
        +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +        "properties": {
        +          "assets": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +              "properties": {
        +                "name": {
        +                  "type": "string"
        +                },
        +                "symbol": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Stock",
        +                    "Cryptocurrency",
        +                    "Option",
        +                    "Other"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "symbol"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "enum": [
        +              "ALL_US_STOCKS",
        +              "SP500",
        +              "NASDAQ100",
        +              "DJIA",
        +              "CRYPTO",
        +              "SPECIFIC_ASSETS"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "weightIndicator": {
        +        "$ref": "#/$defs/indicator"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "universe",
        +      "pipeline",
        +      "weightIndicator"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        +    "properties": {
        +      "continueExisting": {
        +        "type": "boolean"
        +      },
        +      "cooldownMinutes": {
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "executionModel": {
        +        "type": "string"
        +      },
        +      "includeMarketData": {
        +        "type": "boolean"
        +      },
        +      "initialMessage": {
        +        "type": "string"
        +      },
        +      "maxIterations": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "planningModel": {
        +        "type": "string"
        +      },
        +      "skipPlanning": {
        +        "type": "boolean"
        +      },
        +      "type": {
        +        "const": "LaunchAgent",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "planningModel",
        +      "executionModel",
        +      "initialMessage",
        +      "maxIterations",
        +      "includeMarketData",
        +      "continueExisting",
        +      "skipPlanning"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        +    "properties": {
        +      "against": {
        +        "additionalProperties": true,
        +        "description": "Optional parent-position selector (e.g. for covered calls).",
        +        "type": "object"
        +      },
        +      "allocation": {
        +        "additionalProperties": true,
        +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "contracts",
        +              "percent of realized premium"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "builder": {
        +        "additionalProperties": true,
        +        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        +        "properties": {
        +          "dynamicUnderlying": {
        +            "additionalProperties": true,
        +            "properties": {
        +              "limit": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "pipeline": {
        +                "items": {
        +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                  "oneOf": [
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "condition": {
        +                          "$ref": "#/$defs/condition"
        +                        },
        +                        "type": {
        +                          "const": "Filter",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "condition"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "limit": {
        +                          "minimum": 1,
        +                          "type": "number"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "type": {
        +                          "const": "SelectTop",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "limit",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "percentile": {
        +                          "maximum": 100,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "SelectPercentile",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "percentile",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "universe": {
        +                "additionalProperties": true,
        +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                "properties": {
        +                  "assets": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                      "properties": {
        +                        "name": {
        +                          "type": "string"
        +                        },
        +                        "symbol": {
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "enum": [
        +                            "Stock",
        +                            "Cryptocurrency",
        +                            "Option",
        +                            "Other"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "symbol"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "type": "array"
        +                  },
        +                  "source": {
        +                    "enum": [
        +                      "ALL_US_STOCKS",
        +                      "SP500",
        +                      "NASDAQ100",
        +                      "DJIA",
        +                      "CRYPTO",
        +                      "SPECIFIC_ASSETS"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "source"
        +                ],
        +                "type": "object"
        +              }
        +            },
        +            "required": [
        +              "universe"
        +            ],
        +            "type": "object"
        +          },
        +          "legs": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Single leg of an option builder.",
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "long",
        +                    "short"
        +                  ],
        +                  "type": "string"
        +                },
        +                "expirationRange": {
        +                  "additionalProperties": true,
        +                  "type": "object"
        +                },
        +                "expirationSelector": {
        +                  "properties": {
        +                    "maxDaysToExpiration": {
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "minDaysToExpiration": {
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "preference": {
        +                      "enum": [
        +                        "nearest",
        +                        "middle",
        +                        "furthest"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "minDaysToExpiration",
        +                    "maxDaysToExpiration",
        +                    "preference"
        +                  ],
        +                  "type": "object"
        +                },
        +                "fallbackStrikeSelector": {
        +                  "additionalProperties": false,
        +                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                  "properties": {
        +                    "distance": {
        +                      "type": "number"
        +                    },
        +                    "distanceType": {
        +                      "enum": [
        +                        "percent",
        +                        "dollars"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "distanceType",
        +                    "distance"
        +                  ],
        +                  "type": "object"
        +                },
        +                "greekFilter": {
        +                  "additionalProperties": true,
        +                  "description": "Optional min/max constraints on Greeks during resolution.",
        +                  "type": "object"
        +                },
        +                "liquidityFilter": {
        +                  "additionalProperties": false,
        +                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                  "properties": {
        +                    "maxSpreadAbsolute": {
        +                      "type": "number"
        +                    },
        +                    "maxSpreadPct": {
        +                      "type": "number"
        +                    },
        +                    "minBid": {
        +                      "type": "number"
        +                    }
        +                  },
        +                  "type": "object"
        +                },
        +                "optionType": {
        +                  "enum": [
        +                    "call",
        +                    "put"
        +                  ],
        +                  "type": "string"
        +                },
        +                "ratio": {
        +                  "type": "number"
        +                },
        +                "strikeRange": {
        +                  "additionalProperties": true,
        +                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                  "type": "object"
        +                },
        +                "strikeSelector": {
        +                  "properties": {
        +                    "distance": {
        +                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                      "type": "number"
        +                    },
        +                    "distanceType": {
        +                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "distanceType",
        +                    "distance"
        +                  ],
        +                  "type": "object"
        +                }
        +              },
        +              "required": [
        +                "optionType",
        +                "direction",
        +                "expirationSelector",
        +                "strikeSelector"
        +              ],
        +              "type": "object"
        +            },
        +            "minItems": 1,
        +            "type": "array"
        +          },
        +          "spreadType": {
        +            "enum": [
        +              "vertical",
        +              "calendar",
        +              "diagonal",
        +              "ironCondor",
        +              "straddle",
        +              "strangle",
        +              "custom"
        +            ],
        +            "type": "string"
        +          },
        +          "underlyingSymbol": {
        +            "type": "string"
        +          },
        +          "widthConstraint": {
        +            "additionalProperties": false,
        +            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +            "properties": {
        +              "minWidthDollars": {
        +                "exclusiveMinimum": 0,
        +                "type": "number"
        +              },
        +              "minWidthPercent": {
        +                "exclusiveMinimum": 0,
        +                "type": "number"
        +              }
        +            },
        +            "type": "object"
        +          }
        +        },
        +        "required": [
        +          "legs"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "const": "OpenOption",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "builder"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        +    "properties": {
        +      "allocationPolicy": {
        +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "expectedReturnShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "riskAversion": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MeanVariance",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "riskAversion",
        +              "expectedReturnShrinkage",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "RiskParity",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MaximumDiversification",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "exposurePolicy": {
        +        "additionalProperties": false,
        +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +        "properties": {
        +          "covarianceShrinkage": {
        +            "maximum": 1,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "estimatedTransactionCostBps": {
        +            "maximum": 10000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "lookbackPeriods": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "minimumObservations": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "targetAnnualizedVolatilityPercent": {
        +            "maximum": 1000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "const": "VolatilityTarget",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "lookbackPeriods",
        +          "minimumObservations",
        +          "covarianceShrinkage",
        +          "targetAnnualizedVolatilityPercent",
        +          "estimatedTransactionCostBps"
        +        ],
        +        "type": "object"
        +      },
        +      "limit": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "perNameAllocation": {
        +        "additionalProperties": true,
        +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "contracts",
        +              "percent of realized premium"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "pipeline": {
        +        "items": {
        +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "condition": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "type": {
        +                  "const": "Filter",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "condition"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "type": {
        +                  "const": "SelectTop",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "limit",
        +                "direction"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "percentile": {
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "SelectPercentile",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "percentile",
        +                "direction"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "positionScope": {
        +        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        +        "enum": [
        +          "portfolio",
        +          "strategy"
        +        ],
        +        "type": "string"
        +      },
        +      "sleeves": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        +          "properties": {
        +            "limit": {
        +              "minimum": 1,
        +              "type": "number"
        +            },
        +            "name": {
        +              "type": "string"
        +            },
        +            "perNameAllocation": {
        +              "additionalProperties": true,
        +              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +              "properties": {
        +                "amount": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "dollars",
        +                    "percent of portfolio",
        +                    "percent of buying power",
        +                    "contracts",
        +                    "percent of realized premium"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "amount"
        +              ],
        +              "type": "object"
        +            },
        +            "pipeline": {
        +              "items": {
        +                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                "oneOf": [
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "condition": {
        +                        "$ref": "#/$defs/condition"
        +                      },
        +                      "type": {
        +                        "const": "Filter",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "condition"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "direction": {
        +                        "enum": [
        +                          "Highest",
        +                          "Lowest"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "limit": {
        +                        "minimum": 1,
        +                        "type": "number"
        +                      },
        +                      "metric": {
        +                        "$ref": "#/$defs/indicator"
        +                      },
        +                      "type": {
        +                        "const": "SelectTop",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "metric",
        +                      "limit",
        +                      "direction"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "direction": {
        +                        "enum": [
        +                          "Highest",
        +                          "Lowest"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "metric": {
        +                        "$ref": "#/$defs/indicator"
        +                      },
        +                      "percentile": {
        +                        "maximum": 100,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "SelectPercentile",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "metric",
        +                      "percentile",
        +                      "direction"
        +                    ],
        +                    "type": "object"
        +                  }
        +                ],
        +                "type": "object"
        +              },
        +              "type": "array"
        +            },
        +            "structureTemplates": {
        +              "items": {
        +                "additionalProperties": true,
        +                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +                "properties": {
        +                  "eligibility": {
        +                    "$ref": "#/$defs/condition"
        +                  },
        +                  "legs": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Single leg of an option builder.",
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "long",
        +                            "short"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "expirationRange": {
        +                          "additionalProperties": true,
        +                          "type": "object"
        +                        },
        +                        "expirationSelector": {
        +                          "properties": {
        +                            "maxDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "minDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "preference": {
        +                              "enum": [
        +                                "nearest",
        +                                "middle",
        +                                "furthest"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "minDaysToExpiration",
        +                            "maxDaysToExpiration",
        +                            "preference"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "fallbackStrikeSelector": {
        +                          "additionalProperties": false,
        +                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                          "properties": {
        +                            "distance": {
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "enum": [
        +                                "percent",
        +                                "dollars"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "greekFilter": {
        +                          "additionalProperties": true,
        +                          "description": "Optional min/max constraints on Greeks during resolution.",
        +                          "type": "object"
        +                        },
        +                        "liquidityFilter": {
        +                          "additionalProperties": false,
        +                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                          "properties": {
        +                            "maxSpreadAbsolute": {
        +                              "type": "number"
        +                            },
        +                            "maxSpreadPct": {
        +                              "type": "number"
        +                            },
        +                            "minBid": {
        +                              "type": "number"
        +                            }
        +                          },
        +                          "type": "object"
        +                        },
        +                        "optionType": {
        +                          "enum": [
        +                            "call",
        +                            "put"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "ratio": {
        +                          "type": "number"
        +                        },
        +                        "strikeRange": {
        +                          "additionalProperties": true,
        +                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                          "type": "object"
        +                        },
        +                        "strikeSelector": {
        +                          "properties": {
        +                            "distance": {
        +                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        }
        +                      },
        +                      "required": [
        +                        "optionType",
        +                        "direction",
        +                        "expirationSelector",
        +                        "strikeSelector"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "minItems": 1,
        +                    "type": "array"
        +                  },
        +                  "name": {
        +                    "type": "string"
        +                  },
        +                  "spreadType": {
        +                    "enum": [
        +                      "vertical",
        +                      "calendar",
        +                      "diagonal",
        +                      "ironCondor",
        +                      "straddle",
        +                      "strangle",
        +                      "custom"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "widthConstraint": {
        +                    "additionalProperties": false,
        +                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                    "properties": {
        +                      "minWidthDollars": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minWidthPercent": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "legs"
        +                ],
        +                "type": "object"
        +              },
        +              "minItems": 1,
        +              "type": "array"
        +            },
        +            "universe": {
        +              "additionalProperties": true,
        +              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +              "properties": {
        +                "assets": {
        +                  "items": {
        +                    "additionalProperties": true,
        +                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                    "properties": {
        +                      "name": {
        +                        "type": "string"
        +                      },
        +                      "symbol": {
        +                        "type": "string"
        +                      },
        +                      "type": {
        +                        "enum": [
        +                          "Stock",
        +                          "Cryptocurrency",
        +                          "Option",
        +                          "Other"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "symbol"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "type": "array"
        +                },
        +                "source": {
        +                  "enum": [
        +                    "ALL_US_STOCKS",
        +                    "SP500",
        +                    "NASDAQ100",
        +                    "DJIA",
        +                    "CRYPTO",
        +                    "SPECIFIC_ASSETS"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "source"
        +              ],
        +              "type": "object"
        +            },
        +            "weightIndicator": {
        +              "$ref": "#/$defs/indicator"
        +            }
        +          },
        +          "required": [
        +            "name"
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "structureTemplates": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +          "properties": {
        +            "eligibility": {
        +              "$ref": "#/$defs/condition"
        +            },
        +            "legs": {
        +              "items": {
        +                "additionalProperties": true,
        +                "description": "Single leg of an option builder.",
        +                "properties": {
        +                  "direction": {
        +                    "enum": [
        +                      "long",
        +                      "short"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "expirationRange": {
        +                    "additionalProperties": true,
        +                    "type": "object"
        +                  },
        +                  "expirationSelector": {
        +                    "properties": {
        +                      "maxDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "preference": {
        +                        "enum": [
        +                          "nearest",
        +                          "middle",
        +                          "furthest"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "minDaysToExpiration",
        +                      "maxDaysToExpiration",
        +                      "preference"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "fallbackStrikeSelector": {
        +                    "additionalProperties": false,
        +                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                    "properties": {
        +                      "distance": {
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "enum": [
        +                          "percent",
        +                          "dollars"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "greekFilter": {
        +                    "additionalProperties": true,
        +                    "description": "Optional min/max constraints on Greeks during resolution.",
        +                    "type": "object"
        +                  },
        +                  "liquidityFilter": {
        +                    "additionalProperties": false,
        +                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                    "properties": {
        +                      "maxSpreadAbsolute": {
        +                        "type": "number"
        +                      },
        +                      "maxSpreadPct": {
        +                        "type": "number"
        +                      },
        +                      "minBid": {
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  },
        +                  "optionType": {
        +                    "enum": [
        +                      "call",
        +                      "put"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "ratio": {
        +                    "type": "number"
        +                  },
        +                  "strikeRange": {
        +                    "additionalProperties": true,
        +                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                    "type": "object"
        +                  },
        +                  "strikeSelector": {
        +                    "properties": {
        +                      "distance": {
        +                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "optionType",
        +                  "direction",
        +                  "expirationSelector",
        +                  "strikeSelector"
        +                ],
        +                "type": "object"
        +              },
        +              "minItems": 1,
        +              "type": "array"
        +            },
        +            "name": {
        +              "type": "string"
        +            },
        +            "spreadType": {
        +              "enum": [
        +                "vertical",
        +                "calendar",
        +                "diagonal",
        +                "ironCondor",
        +                "straddle",
        +                "strangle",
        +                "custom"
        +              ],
        +              "type": "string"
        +            },
        +            "widthConstraint": {
        +              "additionalProperties": false,
        +              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +              "properties": {
        +                "minWidthDollars": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                },
        +                "minWidthPercent": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                }
        +              },
        +              "type": "object"
        +            }
        +          },
        +          "required": [
        +            "legs"
        +          ],
        +          "type": "object"
        +        },
        +        "minItems": 1,
        +        "type": "array"
        +      },
        +      "totalBudget": {
        +        "additionalProperties": true,
        +        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        +        "properties": {
        +          "amount": {
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "const": "RebalanceOption",
        +        "type": "string"
        +      },
        +      "universe": {
        +        "additionalProperties": true,
        +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +        "properties": {
        +          "assets": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +              "properties": {
        +                "name": {
        +                  "type": "string"
        +                },
        +                "symbol": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Stock",
        +                    "Cryptocurrency",
        +                    "Option",
        +                    "Other"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "symbol"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "enum": [
        +              "ALL_US_STOCKS",
        +              "SP500",
        +              "NASDAQ100",
        +              "DJIA",
        +              "CRYPTO",
        +              "SPECIFIC_ASSETS"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "weightIndicator": {
        +        "$ref": "#/$defs/indicator"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "universe",
        +      "pipeline",
        +      "weightIndicator",
        +      "structureTemplates"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        +    "properties": {
        +      "closeScope": {
        +        "enum": [
        +          "spread",
        +          "leg"
        +        ],
        +        "type": "string"
        +      },
        +      "direction": {
        +        "enum": [
        +          "long",
        +          "short"
        +        ],
        +        "type": "string"
        +      },
        +      "optionType": {
        +        "enum": [
        +          "call",
        +          "put"
        +        ],
        +        "type": "string"
        +      },
        +      "quantity": {
        +        "additionalProperties": true,
        +        "description": "How many contracts to close. Defaults to all matching when omitted.",
        +        "type": "object"
        +      },
        +      "spreadType": {
        +        "enum": [
        +          "vertical",
        +          "calendar",
        +          "diagonal",
        +          "ironCondor",
        +          "straddle",
        +          "strangle",
        +          "custom"
        +        ],
        +        "type": "string"
        +      },
        +      "triggers": {
        +        "items": {
        +          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxPnlPercent": {
        +                  "type": "number"
        +                },
        +                "minPnlPercent": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "pnl",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxDte": {
        +                  "type": "number"
        +                },
        +                "minDte": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "dte",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxDaysHeld": {
        +                  "type": "number"
        +                },
        +                "minDaysHeld": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "daysHeld",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxIv": {
        +                  "type": "number"
        +                },
        +                "maxSpreadDelta": {
        +                  "type": "number"
        +                },
        +                "maxSpreadTheta": {
        +                  "type": "number"
        +                },
        +                "minIv": {
        +                  "type": "number"
        +                },
        +                "minSpreadDelta": {
        +                  "type": "number"
        +                },
        +                "minSpreadTheta": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "greeks",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "type": {
        +        "const": "CloseOption",
        +        "type": "string"
        +      },
        +      "underlyings": {
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  }
        +]
      • changedInput schema / $defs / indicator / description
        Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), Option* indicators (need underlying + optionType + direction + spreadType), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
      • addedInput schema / $defs / indicator / properties / lookbackDays
        Added value: +{
        +  "description": "OptionRealizedPnL / OptionRealizedPremium: only count activity within this many days of the evaluation date. Omit for the whole life of the book.",
        +  "maximum": 36500,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • changedInput schema / $defs / indicator / properties / type / enum
        Previous value: -[
        -  "DaysSinceAgent",
        -  "MinutesSinceAgent",
        -  "DaysSinceAlert",
        -  "MinutesSinceAlert",
        -  "StockReport",
        -  "DaysUntilEarnings",
        -  "DaysSinceEarnings",
        -  "ImpliedVolatility",
        -  "IVRank",
        -  "IVPercentile",
        -  "IVHVRatio",
        -  "LastOrderPrice",
        -  "Fundamental",
        -  "Economic",
        -  "CustomIndicator",
        -  "Index",
        -  "BollingerBand",
        -  "RelativeStrengthIndex",
        -  "PriceMeanAbsoluteDeviation",
        -  "ExponentialMovingAverage",
        -  "SimpleMovingAverage",
        -  "PriceStandardDeviation",
        -  "PriceRateOfChange",
        -  "MaxDrawdown",
        -  "MaxDrawup",
        -  "MinimumPrice",
        -  "MaximumPrice",
        -  "IndicatorMeanAbsoluteDeviation",
        -  "IndicatorExponentialMovingAverage",
        -  "IndicatorSimpleMovingAverage",
        -  "IndicatorStandardDeviation",
        -  "IndicatorRateOfChange",
        -  "DaysSinceOrder",
        -  "DaysSinceOptionOrder",
        -  "DaysSinceStrategyFired",
        -  "DaysSinceLastRebalanceOptionOrder",
        -  "MinutesSinceOptionOrder",
        -  "MinutesSinceOrder",
        -  "DaysSinceTransaction",
        -  "InitialValue",
        -  "BuyingPower",
        -  "PositionValue",
        -  "PositionPercentChange",
        -  "PortfolioValue",
        -  "RebalanceDecisionMetric",
        -  "Value",
        -  "Price",
        -  "Plus",
        -  "Minus",
        -  "Multiply",
        -  "Divide",
        -  "Negative",
        -  "AbsoluteValue",
        -  "SquareRoot",
        -  "Max",
        -  "Min",
        -  "Day",
        -  "Month",
        -  "Date",
        -  "Year",
        -  "CurrentTimeSeconds",
        -  "CurrentTimeMinutes",
        -  "CurrentTimeHours",
        -  "TrailingSum",
        -  "CompoundAnnualGrowthRate",
        -  "Log",
        -  "Exponentiation",
        -  "SumOrderQuantity",
        -  "SumOrderAmount",
        -  "MinutesAfterOpen",
        -  "OpeningPrice",
        -  "PreviousClosingPrice",
        -  "HighOfDay",
        -  "LowOfDay",
        -  "MinutesUntilClose",
        -  "PriceChangeSinceOpen",
        -  "GapSize",
        -  "GapPercentage",
        -  "TrueRange",
        -  "AverageTrueRange",
        -  "Volume",
        -  "VWAP",
        -  "BullishFairValueGap",
        -  "BearishFairValueGap",
        -  "IndicatorAtMinutesAfterOpen",
        -  "IndicatorWindowAgo",
        -  "IndicatorAtEntry",
        -  "IsIndexMember",
        -  "IsIndustry",
        -  "IsAssetType",
        -  "IsAsset",
        -  "IsNotAsset",
        -  "CrossAbove",
        -  "CrossBelow",
        -  "PositionMaxDrawdown",
        -  "PositionMaxDrawup",
        -  "UnderlyingMaxDrawdown",
        -  "ConsecutiveTrue",
        -  "CountTrue",
        -  "OptionPositionValue",
        -  "OptionPositionCount",
        -  "OptionPositionPercentChange",
        -  "OptionPositionMaxDrawdown",
        -  "OptionDaysToExpiration",
        -  "OptionDaysHeld",
        -  "OptionCollateral",
        -  "OptionSpreadCount",
        -  "OptionUnrealizedPnL",
        -  "OptionGrossExposurePercent"
        -]New value: +[
        +  "DaysSinceAgent",
        +  "MinutesSinceAgent",
        +  "DaysSinceAlert",
        +  "MinutesSinceAlert",
        +  "StockReport",
        +  "DaysUntilEarnings",
        +  "DaysSinceEarnings",
        +  "ImpliedVolatility",
        +  "IVRank",
        +  "IVPercentile",
        +  "IVHVRatio",
        +  "LastOrderPrice",
        +  "Fundamental",
        +  "Economic",
        +  "CustomIndicator",
        +  "Index",
        +  "BollingerBand",
        +  "RelativeStrengthIndex",
        +  "PriceMeanAbsoluteDeviation",
        +  "ExponentialMovingAverage",
        +  "SimpleMovingAverage",
        +  "PriceStandardDeviation",
        +  "PriceRateOfChange",
        +  "MaxDrawdown",
        +  "MaxDrawup",
        +  "MinimumPrice",
        +  "MaximumPrice",
        +  "IndicatorMeanAbsoluteDeviation",
        +  "IndicatorExponentialMovingAverage",
        +  "IndicatorSimpleMovingAverage",
        +  "IndicatorStandardDeviation",
        +  "IndicatorRateOfChange",
        +  "DaysSinceOrder",
        +  "DaysSinceOptionOrder",
        +  "DaysSinceStrategyFired",
        +  "DaysSinceLastRebalanceOptionOrder",
        +  "MinutesSinceOptionOrder",
        +  "MinutesSinceOrder",
        +  "DaysSinceTransaction",
        +  "InitialValue",
        +  "BuyingPower",
        +  "PositionValue",
        +  "PositionPercentChange",
        +  "PortfolioValue",
        +  "RebalanceDecisionMetric",
        +  "Value",
        +  "Price",
        +  "Plus",
        +  "Minus",
        +  "Multiply",
        +  "Divide",
        +  "Negative",
        +  "AbsoluteValue",
        +  "SquareRoot",
        +  "Max",
        +  "Min",
        +  "Day",
        +  "Month",
        +  "Date",
        +  "Year",
        +  "CurrentTimeSeconds",
        +  "CurrentTimeMinutes",
        +  "CurrentTimeHours",
        +  "TrailingSum",
        +  "CompoundAnnualGrowthRate",
        +  "Log",
        +  "Exponentiation",
        +  "SumOrderQuantity",
        +  "SumOrderAmount",
        +  "MinutesAfterOpen",
        +  "OpeningPrice",
        +  "PreviousClosingPrice",
        +  "HighOfDay",
        +  "LowOfDay",
        +  "MinutesUntilClose",
        +  "PriceChangeSinceOpen",
        +  "GapSize",
        +  "GapPercentage",
        +  "TrueRange",
        +  "AverageTrueRange",
        +  "Volume",
        +  "VWAP",
        +  "BullishFairValueGap",
        +  "BearishFairValueGap",
        +  "IndicatorAtMinutesAfterOpen",
        +  "IndicatorWindowAgo",
        +  "IndicatorAtEntry",
        +  "IsIndexMember",
        +  "IsIndustry",
        +  "IsAssetType",
        +  "IsAsset",
        +  "IsNotAsset",
        +  "CrossAbove",
        +  "CrossBelow",
        +  "PositionMaxDrawdown",
        +  "PositionMaxDrawup",
        +  "UnderlyingMaxDrawdown",
        +  "ConsecutiveTrue",
        +  "CountTrue",
        +  "OptionPositionValue",
        +  "OptionPositionCount",
        +  "OptionPositionPercentChange",
        +  "OptionPositionMaxDrawdown",
        +  "OptionDaysToExpiration",
        +  "OptionDaysHeld",
        +  "OptionCollateral",
        +  "OptionSpreadCount",
        +  "OptionUnrealizedPnL",
        +  "OptionRealizedPnL",
        +  "OptionRealizedPremium",
        +  "OptionGrossExposurePercent"
        +]
      • changedInput schema / $defs / rebalanceOptionSleeve / properties / perNameAllocation / description
        Previous value: -"Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'."New value: +"Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'."
      • changedInput schema / $defs / rebalanceOptionSleeve / properties / perNameAllocation / properties / type / enum
        Previous value: -[
        -  "dollars",
        -  "percent of portfolio",
        -  "percent of buying power",
        -  "contracts"
        -]New value: +[
        +  "dollars",
        +  "percent of portfolio",
        +  "percent of buying power",
        +  "contracts",
        +  "percent of realized premium"
        +]
      • changedInput schema / $defs / strategy / properties / action / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "description": "Buy or Sell a stock/crypto position.",
        -    "properties": {
        -      "amount": {
        -        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "percent of current positions",
        -              "dollars",
        -              "number of assets"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "targetAsset": {
        -        "additionalProperties": true,
        -        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -        "properties": {
        -          "name": {
        -            "type": "string"
        -          },
        -          "symbol": {
        -            "type": "string"
        -          },
        -          "type": {
        -            "enum": [
        -              "Stock",
        -              "Cryptocurrency",
        -              "Option",
        -              "Other"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "symbol"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "enum": [
        -          "Buy",
        -          "Sell"
        -        ],
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "targetAsset",
        -      "amount"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Send an alert message (no order).",
        -    "properties": {
        -      "message": {
        -        "type": "string"
        -      },
        -      "type": {
        -        "const": "Alert",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "message"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        -    "properties": {
        -      "allocationPolicy": {
        -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "expectedReturnShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "riskAversion": {
        -                "maximum": 1000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MeanVariance",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "riskAversion",
        -              "expectedReturnShrinkage",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "RiskParity",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumDiversification",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "canSell": {
        -        "$ref": "#/$defs/condition",
        -        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        -      },
        -      "deploymentPercent": {
        -        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        -        "maximum": 100,
        -        "minimum": 0,
        -        "type": "number"
        -      },
        -      "exposurePolicy": {
        -        "additionalProperties": false,
        -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        -        "properties": {
        -          "covarianceShrinkage": {
        -            "maximum": 1,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "estimatedTransactionCostBps": {
        -            "maximum": 10000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "lookbackPeriods": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "minimumObservations": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "targetAnnualizedVolatilityPercent": {
        -            "maximum": 1000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "const": "VolatilityTarget",
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "lookbackPeriods",
        -          "minimumObservations",
        -          "covarianceShrinkage",
        -          "targetAnnualizedVolatilityPercent",
        -          "estimatedTransactionCostBps"
        -        ],
        -        "type": "object"
        -      },
        -      "limit": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "perNameAllocation": {
        -        "additionalProperties": true,
        -        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
        -        "properties": {
        -          "amount": {
        -            "exclusiveMinimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "percent of portfolio",
        -              "dollars"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "pipeline": {
        -        "items": {
        -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "condition": {
        -                  "$ref": "#/$defs/condition"
        -                },
        -                "type": {
        -                  "const": "Filter",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "condition"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "limit": {
        -                  "minimum": 1,
        -                  "type": "number"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "type": {
        -                  "const": "SelectTop",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "limit",
        -                "direction"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "percentile": {
        -                  "maximum": 100,
        -                  "minimum": 0,
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "SelectPercentile",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "percentile",
        -                "direction"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "type": {
        -        "const": "DynamicRebalance",
        -        "type": "string"
        -      },
        -      "universe": {
        -        "additionalProperties": true,
        -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -        "properties": {
        -          "assets": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -              "properties": {
        -                "name": {
        -                  "type": "string"
        -                },
        -                "symbol": {
        -                  "type": "string"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "Stock",
        -                    "Cryptocurrency",
        -                    "Option",
        -                    "Other"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "symbol"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "source": {
        -            "enum": [
        -              "ALL_US_STOCKS",
        -              "SP500",
        -              "NASDAQ100",
        -              "DJIA",
        -              "CRYPTO",
        -              "SPECIFIC_ASSETS"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "weightIndicator": {
        -        "$ref": "#/$defs/indicator"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "universe",
        -      "pipeline",
        -      "weightIndicator"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        -    "properties": {
        -      "continueExisting": {
        -        "type": "boolean"
        -      },
        -      "cooldownMinutes": {
        -        "minimum": 0,
        -        "type": "number"
        -      },
        -      "executionModel": {
        -        "type": "string"
        -      },
        -      "includeMarketData": {
        -        "type": "boolean"
        -      },
        -      "initialMessage": {
        -        "type": "string"
        -      },
        -      "maxIterations": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "planningModel": {
        -        "type": "string"
        -      },
        -      "skipPlanning": {
        -        "type": "boolean"
        -      },
        -      "type": {
        -        "const": "LaunchAgent",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "planningModel",
        -      "executionModel",
        -      "initialMessage",
        -      "maxIterations",
        -      "includeMarketData",
        -      "continueExisting",
        -      "skipPlanning"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        -    "properties": {
        -      "against": {
        -        "additionalProperties": true,
        -        "description": "Optional parent-position selector (e.g. for covered calls).",
        -        "type": "object"
        -      },
        -      "allocation": {
        -        "additionalProperties": true,
        -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "contracts"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "builder": {
        -        "additionalProperties": true,
        -        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        -        "properties": {
        -          "dynamicUnderlying": {
        -            "additionalProperties": true,
        -            "properties": {
        -              "limit": {
        -                "minimum": 1,
        -                "type": "number"
        -              },
        -              "pipeline": {
        -                "items": {
        -                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -                  "oneOf": [
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "condition": {
        -                          "$ref": "#/$defs/condition"
        -                        },
        -                        "type": {
        -                          "const": "Filter",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "condition"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "Highest",
        -                            "Lowest"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "limit": {
        -                          "minimum": 1,
        -                          "type": "number"
        -                        },
        -                        "metric": {
        -                          "$ref": "#/$defs/indicator"
        -                        },
        -                        "type": {
        -                          "const": "SelectTop",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "metric",
        -                        "limit",
        -                        "direction"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "Highest",
        -                            "Lowest"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "metric": {
        -                          "$ref": "#/$defs/indicator"
        -                        },
        -                        "percentile": {
        -                          "maximum": 100,
        -                          "minimum": 0,
        -                          "type": "number"
        -                        },
        -                        "type": {
        -                          "const": "SelectPercentile",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "metric",
        -                        "percentile",
        -                        "direction"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ],
        -                  "type": "object"
        -                },
        -                "type": "array"
        -              },
        -              "universe": {
        -                "additionalProperties": true,
        -                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -                "properties": {
        -                  "assets": {
        -                    "items": {
        -                      "additionalProperties": true,
        -                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -                      "properties": {
        -                        "name": {
        -                          "type": "string"
        -                        },
        -                        "symbol": {
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "enum": [
        -                            "Stock",
        -                            "Cryptocurrency",
        -                            "Option",
        -                            "Other"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "symbol"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    "type": "array"
        -                  },
        -                  "source": {
        -                    "enum": [
        -                      "ALL_US_STOCKS",
        -                      "SP500",
        -                      "NASDAQ100",
        -                      "DJIA",
        -                      "CRYPTO",
        -                      "SPECIFIC_ASSETS"
        -                    ],
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "source"
        -                ],
        -                "type": "object"
        -              }
        -            },
        -            "required": [
        -              "universe"
        -            ],
        -            "type": "object"
        -          },
        -          "legs": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Single leg of an option builder.",
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "long",
        -                    "short"
        -                  ],
        -                  "type": "string"
        -                },
        -                "expirationRange": {
        -                  "additionalProperties": true,
        -                  "type": "object"
        -                },
        -                "expirationSelector": {
        -                  "properties": {
        -                    "maxDaysToExpiration": {
        -                      "minimum": 0,
        -                      "type": "number"
        -                    },
        -                    "minDaysToExpiration": {
        -                      "minimum": 0,
        -                      "type": "number"
        -                    },
        -                    "preference": {
        -                      "enum": [
        -                        "nearest",
        -                        "middle",
        -                        "furthest"
        -                      ],
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "minDaysToExpiration",
        -                    "maxDaysToExpiration",
        -                    "preference"
        -                  ],
        -                  "type": "object"
        -                },
        -                "fallbackStrikeSelector": {
        -                  "additionalProperties": false,
        -                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                  "properties": {
        -                    "distance": {
        -                      "type": "number"
        -                    },
        -                    "distanceType": {
        -                      "enum": [
        -                        "percent",
        -                        "dollars"
        -                      ],
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "distanceType",
        -                    "distance"
        -                  ],
        -                  "type": "object"
        -                },
        -                "greekFilter": {
        -                  "additionalProperties": true,
        -                  "description": "Optional min/max constraints on Greeks during resolution.",
        -                  "type": "object"
        -                },
        -                "liquidityFilter": {
        -                  "additionalProperties": false,
        -                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                  "properties": {
        -                    "maxSpreadAbsolute": {
        -                      "type": "number"
        -                    },
        -                    "maxSpreadPct": {
        -                      "type": "number"
        -                    },
        -                    "minBid": {
        -                      "type": "number"
        -                    }
        -                  },
        -                  "type": "object"
        -                },
        -                "optionType": {
        -                  "enum": [
        -                    "call",
        -                    "put"
        -                  ],
        -                  "type": "string"
        -                },
        -                "ratio": {
        -                  "type": "number"
        -                },
        -                "strikeRange": {
        -                  "additionalProperties": true,
        -                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                  "type": "object"
        -                },
        -                "strikeSelector": {
        -                  "properties": {
        -                    "distance": {
        -                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                      "type": "number"
        -                    },
        -                    "distanceType": {
        -                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "distanceType",
        -                    "distance"
        -                  ],
        -                  "type": "object"
        -                }
        -              },
        -              "required": [
        -                "optionType",
        -                "direction",
        -                "expirationSelector",
        -                "strikeSelector"
        -              ],
        -              "type": "object"
        -            },
        -            "minItems": 1,
        -            "type": "array"
        -          },
        -          "spreadType": {
        -            "enum": [
        -              "vertical",
        -              "calendar",
        -              "diagonal",
        -              "ironCondor",
        -              "straddle",
        -              "strangle",
        -              "custom"
        -            ],
        -            "type": "string"
        -          },
        -          "underlyingSymbol": {
        -            "type": "string"
        -          },
        -          "widthConstraint": {
        -            "additionalProperties": false,
        -            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -            "properties": {
        -              "minWidthDollars": {
        -                "exclusiveMinimum": 0,
        -                "type": "number"
        -              },
        -              "minWidthPercent": {
        -                "exclusiveMinimum": 0,
        -                "type": "number"
        -              }
        -            },
        -            "type": "object"
        -          }
        -        },
        -        "required": [
        -          "legs"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "const": "OpenOption",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "builder"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        -    "properties": {
        -      "allocationPolicy": {
        -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "expectedReturnShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "riskAversion": {
        -                "maximum": 1000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MeanVariance",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "riskAversion",
        -              "expectedReturnShrinkage",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "RiskParity",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumDiversification",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "exposurePolicy": {
        -        "additionalProperties": false,
        -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        -        "properties": {
        -          "covarianceShrinkage": {
        -            "maximum": 1,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "estimatedTransactionCostBps": {
        -            "maximum": 10000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "lookbackPeriods": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "minimumObservations": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "targetAnnualizedVolatilityPercent": {
        -            "maximum": 1000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "const": "VolatilityTarget",
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "lookbackPeriods",
        -          "minimumObservations",
        -          "covarianceShrinkage",
        -          "targetAnnualizedVolatilityPercent",
        -          "estimatedTransactionCostBps"
        -        ],
        -        "type": "object"
        -      },
        -      "limit": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "perNameAllocation": {
        -        "additionalProperties": true,
        -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "contracts"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "pipeline": {
        -        "items": {
        -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "condition": {
        -                  "$ref": "#/$defs/condition"
        -                },
        -                "type": {
        -                  "const": "Filter",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "condition"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "limit": {
        -                  "minimum": 1,
        -                  "type": "number"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "type": {
        -                  "const": "SelectTop",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "limit",
        -                "direction"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "percentile": {
        -                  "maximum": 100,
        -                  "minimum": 0,
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "SelectPercentile",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "percentile",
        -                "direction"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "positionScope": {
        -        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        -        "enum": [
        -          "portfolio",
        -          "strategy"
        -        ],
        -        "type": "string"
        -      },
        -      "sleeves": {
        -        "items": {
        -          "additionalProperties": true,
        -          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        -          "properties": {
        -            "limit": {
        -              "minimum": 1,
        -              "type": "number"
        -            },
        -            "name": {
        -              "type": "string"
        -            },
        -            "perNameAllocation": {
        -              "additionalProperties": true,
        -              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -              "properties": {
        -                "amount": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "dollars",
        -                    "percent of portfolio",
        -                    "percent of buying power",
        -                    "contracts"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "amount"
        -              ],
        -              "type": "object"
        -            },
        -            "pipeline": {
        -              "items": {
        -                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -                "oneOf": [
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "condition": {
        -                        "$ref": "#/$defs/condition"
        -                      },
        -                      "type": {
        -                        "const": "Filter",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "condition"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "direction": {
        -                        "enum": [
        -                          "Highest",
        -                          "Lowest"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "limit": {
        -                        "minimum": 1,
        -                        "type": "number"
        -                      },
        -                      "metric": {
        -                        "$ref": "#/$defs/indicator"
        -                      },
        -                      "type": {
        -                        "const": "SelectTop",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "metric",
        -                      "limit",
        -                      "direction"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "direction": {
        -                        "enum": [
        -                          "Highest",
        -                          "Lowest"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "metric": {
        -                        "$ref": "#/$defs/indicator"
        -                      },
        -                      "percentile": {
        -                        "maximum": 100,
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "type": {
        -                        "const": "SelectPercentile",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "metric",
        -                      "percentile",
        -                      "direction"
        -                    ],
        -                    "type": "object"
        -                  }
        -                ],
        -                "type": "object"
        -              },
        -              "type": "array"
        -            },
        -            "structureTemplates": {
        -              "items": {
        -                "additionalProperties": true,
        -                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        -                "properties": {
        -                  "eligibility": {
        -                    "$ref": "#/$defs/condition"
        -                  },
        -                  "legs": {
        -                    "items": {
        -                      "additionalProperties": true,
        -                      "description": "Single leg of an option builder.",
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "long",
        -                            "short"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "expirationRange": {
        -                          "additionalProperties": true,
        -                          "type": "object"
        -                        },
        -                        "expirationSelector": {
        -                          "properties": {
        -                            "maxDaysToExpiration": {
        -                              "minimum": 0,
        -                              "type": "number"
        -                            },
        -                            "minDaysToExpiration": {
        -                              "minimum": 0,
        -                              "type": "number"
        -                            },
        -                            "preference": {
        -                              "enum": [
        -                                "nearest",
        -                                "middle",
        -                                "furthest"
        -                              ],
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "minDaysToExpiration",
        -                            "maxDaysToExpiration",
        -                            "preference"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "fallbackStrikeSelector": {
        -                          "additionalProperties": false,
        -                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                          "properties": {
        -                            "distance": {
        -                              "type": "number"
        -                            },
        -                            "distanceType": {
        -                              "enum": [
        -                                "percent",
        -                                "dollars"
        -                              ],
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "distanceType",
        -                            "distance"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "greekFilter": {
        -                          "additionalProperties": true,
        -                          "description": "Optional min/max constraints on Greeks during resolution.",
        -                          "type": "object"
        -                        },
        -                        "liquidityFilter": {
        -                          "additionalProperties": false,
        -                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                          "properties": {
        -                            "maxSpreadAbsolute": {
        -                              "type": "number"
        -                            },
        -                            "maxSpreadPct": {
        -                              "type": "number"
        -                            },
        -                            "minBid": {
        -                              "type": "number"
        -                            }
        -                          },
        -                          "type": "object"
        -                        },
        -                        "optionType": {
        -                          "enum": [
        -                            "call",
        -                            "put"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "ratio": {
        -                          "type": "number"
        -                        },
        -                        "strikeRange": {
        -                          "additionalProperties": true,
        -                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                          "type": "object"
        -                        },
        -                        "strikeSelector": {
        -                          "properties": {
        -                            "distance": {
        -                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                              "type": "number"
        -                            },
        -                            "distanceType": {
        -                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "distanceType",
        -                            "distance"
        -                          ],
        -                          "type": "object"
        -                        }
        -                      },
        -                      "required": [
        -                        "optionType",
        -                        "direction",
        -                        "expirationSelector",
        -                        "strikeSelector"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    "minItems": 1,
        -                    "type": "array"
        -                  },
        -                  "name": {
        -                    "type": "string"
        -                  },
        -                  "spreadType": {
        -                    "enum": [
        -                      "vertical",
        -                      "calendar",
        -                      "diagonal",
        -                      "ironCondor",
        -                      "straddle",
        -                      "strangle",
        -                      "custom"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "widthConstraint": {
        -                    "additionalProperties": false,
        -                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -                    "properties": {
        -                      "minWidthDollars": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "number"
        -                      },
        -                      "minWidthPercent": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "number"
        -                      }
        -                    },
        -                    "type": "object"
        -                  }
        -                },
        -                "required": [
        -                  "legs"
        -                ],
        -                "type": "object"
        -              },
        -              "minItems": 1,
        -              "type": "array"
        -            },
        -            "universe": {
        -              "additionalProperties": true,
        -              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -              "properties": {
        -                "assets": {
        -                  "items": {
        -                    "additionalProperties": true,
        -                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -                    "properties": {
        -                      "name": {
        -                        "type": "string"
        -                      },
        -                      "symbol": {
        -                        "type": "string"
        -                      },
        -                      "type": {
        -                        "enum": [
        -                          "Stock",
        -                          "Cryptocurrency",
        -                          "Option",
        -                          "Other"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "symbol"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "type": "array"
        -                },
        -                "source": {
        -                  "enum": [
        -                    "ALL_US_STOCKS",
        -                    "SP500",
        -                    "NASDAQ100",
        -                    "DJIA",
        -                    "CRYPTO",
        -                    "SPECIFIC_ASSETS"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "source"
        -              ],
        -              "type": "object"
        -            },
        -            "weightIndicator": {
        -              "$ref": "#/$defs/indicator"
        -            }
        -          },
        -          "required": [
        -            "name"
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "structureTemplates": {
        -        "items": {
        -          "additionalProperties": true,
        -          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        -          "properties": {
        -            "eligibility": {
        -              "$ref": "#/$defs/condition"
        -            },
        -            "legs": {
        -              "items": {
        -                "additionalProperties": true,
        -                "description": "Single leg of an option builder.",
        -                "properties": {
        -                  "direction": {
        -                    "enum": [
        -                      "long",
        -                      "short"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "expirationRange": {
        -                    "additionalProperties": true,
        -                    "type": "object"
        -                  },
        -                  "expirationSelector": {
        -                    "properties": {
        -                      "maxDaysToExpiration": {
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "minDaysToExpiration": {
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "preference": {
        -                        "enum": [
        -                          "nearest",
        -                          "middle",
        -                          "furthest"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "minDaysToExpiration",
        -                      "maxDaysToExpiration",
        -                      "preference"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "fallbackStrikeSelector": {
        -                    "additionalProperties": false,
        -                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                    "properties": {
        -                      "distance": {
        -                        "type": "number"
        -                      },
        -                      "distanceType": {
        -                        "enum": [
        -                          "percent",
        -                          "dollars"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "distanceType",
        -                      "distance"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "greekFilter": {
        -                    "additionalProperties": true,
        -                    "description": "Optional min/max constraints on Greeks during resolution.",
        -                    "type": "object"
        -                  },
        -                  "liquidityFilter": {
        -                    "additionalProperties": false,
        -                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                    "properties": {
        -                      "maxSpreadAbsolute": {
        -                        "type": "number"
        -                      },
        -                      "maxSpreadPct": {
        -                        "type": "number"
        -                      },
        -                      "minBid": {
        -                        "type": "number"
        -                      }
        -                    },
        -                    "type": "object"
        -                  },
        -                  "optionType": {
        -                    "enum": [
        -                      "call",
        -                      "put"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "ratio": {
        -                    "type": "number"
        -                  },
        -                  "strikeRange": {
        -                    "additionalProperties": true,
        -                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                    "type": "object"
        -                  },
        -                  "strikeSelector": {
        -                    "properties": {
        -                      "distance": {
        -                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                        "type": "number"
        -                      },
        -                      "distanceType": {
        -                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "distanceType",
        -                      "distance"
        -                    ],
        -                    "type": "object"
        -                  }
        -                },
        -                "required": [
        -                  "optionType",
        -                  "direction",
        -                  "expirationSelector",
        -                  "strikeSelector"
        -                ],
        -                "type": "object"
        -              },
        -              "minItems": 1,
        -              "type": "array"
        -            },
        -            "name": {
        -              "type": "string"
        -            },
        -            "spreadType": {
        -              "enum": [
        -                "vertical",
        -                "calendar",
        -                "diagonal",
        -                "ironCondor",
        -                "straddle",
        -                "strangle",
        -                "custom"
        -              ],
        -              "type": "string"
        -            },
        -            "widthConstraint": {
        -              "additionalProperties": false,
        -              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -              "properties": {
        -                "minWidthDollars": {
        -                  "exclusiveMinimum": 0,
        -                  "type": "number"
        -                },
        -                "minWidthPercent": {
        -                  "exclusiveMinimum": 0,
        -                  "type": "number"
        -                }
        -              },
        -              "type": "object"
        -            }
        -          },
        -          "required": [
        -            "legs"
        -          ],
        -          "type": "object"
        -        },
        -        "minItems": 1,
        -        "type": "array"
        -      },
        -      "totalBudget": {
        -        "additionalProperties": true,
        -        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        -        "properties": {
        -          "amount": {
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "const": "RebalanceOption",
        -        "type": "string"
        -      },
        -      "universe": {
        -        "additionalProperties": true,
        -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -        "properties": {
        -          "assets": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -              "properties": {
        -                "name": {
        -                  "type": "string"
        -                },
        -                "symbol": {
        -                  "type": "string"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "Stock",
        -                    "Cryptocurrency",
        -                    "Option",
        -                    "Other"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "symbol"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "source": {
        -            "enum": [
        -              "ALL_US_STOCKS",
        -              "SP500",
        -              "NASDAQ100",
        -              "DJIA",
        -              "CRYPTO",
        -              "SPECIFIC_ASSETS"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "weightIndicator": {
        -        "$ref": "#/$defs/indicator"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "universe",
        -      "pipeline",
        -      "weightIndicator",
        -      "structureTemplates"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        -    "properties": {
        -      "closeScope": {
        -        "enum": [
        -          "spread",
        -          "leg"
        -        ],
        -        "type": "string"
        -      },
        -      "direction": {
        -        "enum": [
        -          "long",
        -          "short"
        -        ],
        -        "type": "string"
        -      },
        -      "optionType": {
        -        "enum": [
        -          "call",
        -          "put"
        -        ],
        -        "type": "string"
        -      },
        -      "quantity": {
        -        "additionalProperties": true,
        -        "description": "How many contracts to close. Defaults to all matching when omitted.",
        -        "type": "object"
        -      },
        -      "spreadType": {
        -        "enum": [
        -          "vertical",
        -          "calendar",
        -          "diagonal",
        -          "ironCondor",
        -          "straddle",
        -          "strangle",
        -          "custom"
        -        ],
        -        "type": "string"
        -      },
        -      "triggers": {
        -        "items": {
        -          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxPnlPercent": {
        -                  "type": "number"
        -                },
        -                "minPnlPercent": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "pnl",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxDte": {
        -                  "type": "number"
        -                },
        -                "minDte": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "dte",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxDaysHeld": {
        -                  "type": "number"
        -                },
        -                "minDaysHeld": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "daysHeld",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxIv": {
        -                  "type": "number"
        -                },
        -                "maxSpreadDelta": {
        -                  "type": "number"
        -                },
        -                "maxSpreadTheta": {
        -                  "type": "number"
        -                },
        -                "minIv": {
        -                  "type": "number"
        -                },
        -                "minSpreadDelta": {
        -                  "type": "number"
        -                },
        -                "minSpreadTheta": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "greeks",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "type": {
        -        "const": "CloseOption",
        -        "type": "string"
        -      },
        -      "underlyings": {
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array"
        -      }
        -    },
        -    "required": [
        -      "type"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": true,
        +    "description": "Buy or Sell a stock/crypto position.",
        +    "properties": {
        +      "amount": {
        +        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "percent of current positions",
        +              "dollars",
        +              "number of assets"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "targetAsset": {
        +        "additionalProperties": true,
        +        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +        "properties": {
        +          "name": {
        +            "type": "string"
        +          },
        +          "symbol": {
        +            "type": "string"
        +          },
        +          "type": {
        +            "enum": [
        +              "Stock",
        +              "Cryptocurrency",
        +              "Option",
        +              "Other"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "symbol"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "enum": [
        +          "Buy",
        +          "Sell"
        +        ],
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "targetAsset",
        +      "amount"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Send an alert message (no order).",
        +    "properties": {
        +      "message": {
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "Alert",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "message"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        +    "properties": {
        +      "allocationPolicy": {
        +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "expectedReturnShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "riskAversion": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MeanVariance",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "riskAversion",
        +              "expectedReturnShrinkage",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "RiskParity",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MaximumDiversification",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "canSell": {
        +        "$ref": "#/$defs/condition",
        +        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        +      },
        +      "deploymentPercent": {
        +        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        +        "maximum": 100,
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "exposurePolicy": {
        +        "additionalProperties": false,
        +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +        "properties": {
        +          "covarianceShrinkage": {
        +            "maximum": 1,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "estimatedTransactionCostBps": {
        +            "maximum": 10000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "lookbackPeriods": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "minimumObservations": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "targetAnnualizedVolatilityPercent": {
        +            "maximum": 1000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "const": "VolatilityTarget",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "lookbackPeriods",
        +          "minimumObservations",
        +          "covarianceShrinkage",
        +          "targetAnnualizedVolatilityPercent",
        +          "estimatedTransactionCostBps"
        +        ],
        +        "type": "object"
        +      },
        +      "limit": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "perNameAllocation": {
        +        "additionalProperties": true,
        +        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.",
        +        "properties": {
        +          "amount": {
        +            "exclusiveMinimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "percent of portfolio",
        +              "dollars"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "pipeline": {
        +        "items": {
        +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "condition": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "type": {
        +                  "const": "Filter",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "condition"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "type": {
        +                  "const": "SelectTop",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "limit",
        +                "direction"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "percentile": {
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "SelectPercentile",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "percentile",
        +                "direction"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "type": {
        +        "const": "DynamicRebalance",
        +        "type": "string"
        +      },
        +      "universe": {
        +        "additionalProperties": true,
        +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +        "properties": {
        +          "assets": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +              "properties": {
        +                "name": {
        +                  "type": "string"
        +                },
        +                "symbol": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Stock",
        +                    "Cryptocurrency",
        +                    "Option",
        +                    "Other"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "symbol"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "enum": [
        +              "ALL_US_STOCKS",
        +              "SP500",
        +              "NASDAQ100",
        +              "DJIA",
        +              "CRYPTO",
        +              "SPECIFIC_ASSETS"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "weightIndicator": {
        +        "$ref": "#/$defs/indicator"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "universe",
        +      "pipeline",
        +      "weightIndicator"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        +    "properties": {
        +      "continueExisting": {
        +        "type": "boolean"
        +      },
        +      "cooldownMinutes": {
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "executionModel": {
        +        "type": "string"
        +      },
        +      "includeMarketData": {
        +        "type": "boolean"
        +      },
        +      "initialMessage": {
        +        "type": "string"
        +      },
        +      "maxIterations": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "planningModel": {
        +        "type": "string"
        +      },
        +      "skipPlanning": {
        +        "type": "boolean"
        +      },
        +      "type": {
        +        "const": "LaunchAgent",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "planningModel",
        +      "executionModel",
        +      "initialMessage",
        +      "maxIterations",
        +      "includeMarketData",
        +      "continueExisting",
        +      "skipPlanning"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        +    "properties": {
        +      "against": {
        +        "additionalProperties": true,
        +        "description": "Optional parent-position selector (e.g. for covered calls).",
        +        "type": "object"
        +      },
        +      "allocation": {
        +        "additionalProperties": true,
        +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "contracts",
        +              "percent of realized premium"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "builder": {
        +        "additionalProperties": true,
        +        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        +        "properties": {
        +          "dynamicUnderlying": {
        +            "additionalProperties": true,
        +            "properties": {
        +              "limit": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "pipeline": {
        +                "items": {
        +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                  "oneOf": [
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "condition": {
        +                          "$ref": "#/$defs/condition"
        +                        },
        +                        "type": {
        +                          "const": "Filter",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "condition"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "limit": {
        +                          "minimum": 1,
        +                          "type": "number"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "type": {
        +                          "const": "SelectTop",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "limit",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "percentile": {
        +                          "maximum": 100,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "SelectPercentile",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "percentile",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "universe": {
        +                "additionalProperties": true,
        +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                "properties": {
        +                  "assets": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                      "properties": {
        +                        "name": {
        +                          "type": "string"
        +                        },
        +                        "symbol": {
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "enum": [
        +                            "Stock",
        +                            "Cryptocurrency",
        +                            "Option",
        +                            "Other"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "symbol"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "type": "array"
        +                  },
        +                  "source": {
        +                    "enum": [
        +                      "ALL_US_STOCKS",
        +                      "SP500",
        +                      "NASDAQ100",
        +                      "DJIA",
        +                      "CRYPTO",
        +                      "SPECIFIC_ASSETS"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "source"
        +                ],
        +                "type": "object"
        +              }
        +            },
        +            "required": [
        +              "universe"
        +            ],
        +            "type": "object"
        +          },
        +          "legs": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Single leg of an option builder.",
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "long",
        +                    "short"
        +                  ],
        +                  "type": "string"
        +                },
        +                "expirationRange": {
        +                  "additionalProperties": true,
        +                  "type": "object"
        +                },
        +                "expirationSelector": {
        +                  "properties": {
        +                    "maxDaysToExpiration": {
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "minDaysToExpiration": {
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "preference": {
        +                      "enum": [
        +                        "nearest",
        +                        "middle",
        +                        "furthest"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "minDaysToExpiration",
        +                    "maxDaysToExpiration",
        +                    "preference"
        +                  ],
        +                  "type": "object"
        +                },
        +                "fallbackStrikeSelector": {
        +                  "additionalProperties": false,
        +                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                  "properties": {
        +                    "distance": {
        +                      "type": "number"
        +                    },
        +                    "distanceType": {
        +                      "enum": [
        +                        "percent",
        +                        "dollars"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "distanceType",
        +                    "distance"
        +                  ],
        +                  "type": "object"
        +                },
        +                "greekFilter": {
        +                  "additionalProperties": true,
        +                  "description": "Optional min/max constraints on Greeks during resolution.",
        +                  "type": "object"
        +                },
        +                "liquidityFilter": {
        +                  "additionalProperties": false,
        +                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                  "properties": {
        +                    "maxSpreadAbsolute": {
        +                      "type": "number"
        +                    },
        +                    "maxSpreadPct": {
        +                      "type": "number"
        +                    },
        +                    "minBid": {
        +                      "type": "number"
        +                    }
        +                  },
        +                  "type": "object"
        +                },
        +                "optionType": {
        +                  "enum": [
        +                    "call",
        +                    "put"
        +                  ],
        +                  "type": "string"
        +                },
        +                "ratio": {
        +                  "type": "number"
        +                },
        +                "strikeRange": {
        +                  "additionalProperties": true,
        +                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                  "type": "object"
        +                },
        +                "strikeSelector": {
        +                  "properties": {
        +                    "distance": {
        +                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                      "type": "number"
        +                    },
        +                    "distanceType": {
        +                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "distanceType",
        +                    "distance"
        +                  ],
        +                  "type": "object"
        +                }
        +              },
        +              "required": [
        +                "optionType",
        +                "direction",
        +                "expirationSelector",
        +                "strikeSelector"
        +              ],
        +              "type": "object"
        +            },
        +            "minItems": 1,
        +            "type": "array"
        +          },
        +          "spreadType": {
        +            "enum": [
        +              "vertical",
        +              "calendar",
        +              "diagonal",
        +              "ironCondor",
        +              "straddle",
        +              "strangle",
        +              "custom"
        +            ],
        +            "type": "string"
        +          },
        +          "underlyingSymbol": {
        +            "type": "string"
        +          },
        +          "widthConstraint": {
        +            "additionalProperties": false,
        +            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +            "properties": {
        +              "minWidthDollars": {
        +                "exclusiveMinimum": 0,
        +                "type": "number"
        +              },
        +              "minWidthPercent": {
        +                "exclusiveMinimum": 0,
        +                "type": "number"
        +              }
        +            },
        +            "type": "object"
        +          }
        +        },
        +        "required": [
        +          "legs"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "const": "OpenOption",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "builder"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        +    "properties": {
        +      "allocationPolicy": {
        +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "expectedReturnShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "riskAversion": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MeanVariance",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "riskAversion",
        +              "expectedReturnShrinkage",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "RiskParity",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MaximumDiversification",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "exposurePolicy": {
        +        "additionalProperties": false,
        +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +        "properties": {
        +          "covarianceShrinkage": {
        +            "maximum": 1,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "estimatedTransactionCostBps": {
        +            "maximum": 10000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "lookbackPeriods": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "minimumObservations": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "targetAnnualizedVolatilityPercent": {
        +            "maximum": 1000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "const": "VolatilityTarget",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "lookbackPeriods",
        +          "minimumObservations",
        +          "covarianceShrinkage",
        +          "targetAnnualizedVolatilityPercent",
        +          "estimatedTransactionCostBps"
        +        ],
        +        "type": "object"
        +      },
        +      "limit": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "perNameAllocation": {
        +        "additionalProperties": true,
        +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "contracts",
        +              "percent of realized premium"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "pipeline": {
        +        "items": {
        +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "condition": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "type": {
        +                  "const": "Filter",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "condition"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "type": {
        +                  "const": "SelectTop",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "limit",
        +                "direction"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "percentile": {
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "SelectPercentile",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "percentile",
        +                "direction"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "positionScope": {
        +        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        +        "enum": [
        +          "portfolio",
        +          "strategy"
        +        ],
        +        "type": "string"
        +      },
        +      "sleeves": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        +          "properties": {
        +            "limit": {
        +              "minimum": 1,
        +              "type": "number"
        +            },
        +            "name": {
        +              "type": "string"
        +            },
        +            "perNameAllocation": {
        +              "additionalProperties": true,
        +              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +              "properties": {
        +                "amount": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "dollars",
        +                    "percent of portfolio",
        +                    "percent of buying power",
        +                    "contracts",
        +                    "percent of realized premium"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "amount"
        +              ],
        +              "type": "object"
        +            },
        +            "pipeline": {
        +              "items": {
        +                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                "oneOf": [
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "condition": {
        +                        "$ref": "#/$defs/condition"
        +                      },
        +                      "type": {
        +                        "const": "Filter",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "condition"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "direction": {
        +                        "enum": [
        +                          "Highest",
        +                          "Lowest"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "limit": {
        +                        "minimum": 1,
        +                        "type": "number"
        +                      },
        +                      "metric": {
        +                        "$ref": "#/$defs/indicator"
        +                      },
        +                      "type": {
        +                        "const": "SelectTop",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "metric",
        +                      "limit",
        +                      "direction"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "direction": {
        +                        "enum": [
        +                          "Highest",
        +                          "Lowest"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "metric": {
        +                        "$ref": "#/$defs/indicator"
        +                      },
        +                      "percentile": {
        +                        "maximum": 100,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "SelectPercentile",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "metric",
        +                      "percentile",
        +                      "direction"
        +                    ],
        +                    "type": "object"
        +                  }
        +                ],
        +                "type": "object"
        +              },
        +              "type": "array"
        +            },
        +            "structureTemplates": {
        +              "items": {
        +                "additionalProperties": true,
        +                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +                "properties": {
        +                  "eligibility": {
        +                    "$ref": "#/$defs/condition"
        +                  },
        +                  "legs": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Single leg of an option builder.",
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "long",
        +                            "short"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "expirationRange": {
        +                          "additionalProperties": true,
        +                          "type": "object"
        +                        },
        +                        "expirationSelector": {
        +                          "properties": {
        +                            "maxDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "minDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "preference": {
        +                              "enum": [
        +                                "nearest",
        +                                "middle",
        +                                "furthest"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "minDaysToExpiration",
        +                            "maxDaysToExpiration",
        +                            "preference"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "fallbackStrikeSelector": {
        +                          "additionalProperties": false,
        +                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                          "properties": {
        +                            "distance": {
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "enum": [
        +                                "percent",
        +                                "dollars"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "greekFilter": {
        +                          "additionalProperties": true,
        +                          "description": "Optional min/max constraints on Greeks during resolution.",
        +                          "type": "object"
        +                        },
        +                        "liquidityFilter": {
        +                          "additionalProperties": false,
        +                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                          "properties": {
        +                            "maxSpreadAbsolute": {
        +                              "type": "number"
        +                            },
        +                            "maxSpreadPct": {
        +                              "type": "number"
        +                            },
        +                            "minBid": {
        +                              "type": "number"
        +                            }
        +                          },
        +                          "type": "object"
        +                        },
        +                        "optionType": {
        +                          "enum": [
        +                            "call",
        +                            "put"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "ratio": {
        +                          "type": "number"
        +                        },
        +                        "strikeRange": {
        +                          "additionalProperties": true,
        +                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                          "type": "object"
        +                        },
        +                        "strikeSelector": {
        +                          "properties": {
        +                            "distance": {
        +                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        }
        +                      },
        +                      "required": [
        +                        "optionType",
        +                        "direction",
        +                        "expirationSelector",
        +                        "strikeSelector"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "minItems": 1,
        +                    "type": "array"
        +                  },
        +                  "name": {
        +                    "type": "string"
        +                  },
        +                  "spreadType": {
        +                    "enum": [
        +                      "vertical",
        +                      "calendar",
        +                      "diagonal",
        +                      "ironCondor",
        +                      "straddle",
        +                      "strangle",
        +                      "custom"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "widthConstraint": {
        +                    "additionalProperties": false,
        +                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                    "properties": {
        +                      "minWidthDollars": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minWidthPercent": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "legs"
        +                ],
        +                "type": "object"
        +              },
        +              "minItems": 1,
        +              "type": "array"
        +            },
        +            "universe": {
        +              "additionalProperties": true,
        +              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +              "properties": {
        +                "assets": {
        +                  "items": {
        +                    "additionalProperties": true,
        +                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                    "properties": {
        +                      "name": {
        +                        "type": "string"
        +                      },
        +                      "symbol": {
        +                        "type": "string"
        +                      },
        +                      "type": {
        +                        "enum": [
        +                          "Stock",
        +                          "Cryptocurrency",
        +                          "Option",
        +                          "Other"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "symbol"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "type": "array"
        +                },
        +                "source": {
        +                  "enum": [
        +                    "ALL_US_STOCKS",
        +                    "SP500",
        +                    "NASDAQ100",
        +                    "DJIA",
        +                    "CRYPTO",
        +                    "SPECIFIC_ASSETS"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "source"
        +              ],
        +              "type": "object"
        +            },
        +            "weightIndicator": {
        +              "$ref": "#/$defs/indicator"
        +            }
        +          },
        +          "required": [
        +            "name"
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "structureTemplates": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +          "properties": {
        +            "eligibility": {
        +              "$ref": "#/$defs/condition"
        +            },
        +            "legs": {
        +              "items": {
        +                "additionalProperties": true,
        +                "description": "Single leg of an option builder.",
        +                "properties": {
        +                  "direction": {
        +                    "enum": [
        +                      "long",
        +                      "short"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "expirationRange": {
        +                    "additionalProperties": true,
        +                    "type": "object"
        +                  },
        +                  "expirationSelector": {
        +                    "properties": {
        +                      "maxDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "preference": {
        +                        "enum": [
        +                          "nearest",
        +                          "middle",
        +                          "furthest"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "minDaysToExpiration",
        +                      "maxDaysToExpiration",
        +                      "preference"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "fallbackStrikeSelector": {
        +                    "additionalProperties": false,
        +                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                    "properties": {
        +                      "distance": {
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "enum": [
        +                          "percent",
        +                          "dollars"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "greekFilter": {
        +                    "additionalProperties": true,
        +                    "description": "Optional min/max constraints on Greeks during resolution.",
        +                    "type": "object"
        +                  },
        +                  "liquidityFilter": {
        +                    "additionalProperties": false,
        +                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                    "properties": {
        +                      "maxSpreadAbsolute": {
        +                        "type": "number"
        +                      },
        +                      "maxSpreadPct": {
        +                        "type": "number"
        +                      },
        +                      "minBid": {
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  },
        +                  "optionType": {
        +                    "enum": [
        +                      "call",
        +                      "put"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "ratio": {
        +                    "type": "number"
        +                  },
        +                  "strikeRange": {
        +                    "additionalProperties": true,
        +                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                    "type": "object"
        +                  },
        +                  "strikeSelector": {
        +                    "properties": {
        +                      "distance": {
        +                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "optionType",
        +                  "direction",
        +                  "expirationSelector",
        +                  "strikeSelector"
        +                ],
        +                "type": "object"
        +              },
        +              "minItems": 1,
        +              "type": "array"
        +            },
        +            "name": {
        +              "type": "string"
        +            },
        +            "spreadType": {
        +              "enum": [
        +                "vertical",
        +                "calendar",
        +                "diagonal",
        +                "ironCondor",
        +                "straddle",
        +                "strangle",
        +                "custom"
        +              ],
        +              "type": "string"
        +            },
        +            "widthConstraint": {
        +              "additionalProperties": false,
        +              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +              "properties": {
        +                "minWidthDollars": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                },
        +                "minWidthPercent": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                }
        +              },
        +              "type": "object"
        +            }
        +          },
        +          "required": [
        +            "legs"
        +          ],
        +          "type": "object"
        +        },
        +        "minItems": 1,
        +        "type": "array"
        +      },
        +      "totalBudget": {
        +        "additionalProperties": true,
        +        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        +        "properties": {
        +          "amount": {
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "const": "RebalanceOption",
        +        "type": "string"
        +      },
        +      "universe": {
        +        "additionalProperties": true,
        +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +        "properties": {
        +          "assets": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +              "properties": {
        +                "name": {
        +                  "type": "string"
        +                },
        +                "symbol": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Stock",
        +                    "Cryptocurrency",
        +                    "Option",
        +                    "Other"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "symbol"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "enum": [
        +              "ALL_US_STOCKS",
        +              "SP500",
        +              "NASDAQ100",
        +              "DJIA",
        +              "CRYPTO",
        +              "SPECIFIC_ASSETS"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "weightIndicator": {
        +        "$ref": "#/$defs/indicator"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "universe",
        +      "pipeline",
        +      "weightIndicator",
        +      "structureTemplates"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        +    "properties": {
        +      "closeScope": {
        +        "enum": [
        +          "spread",
        +          "leg"
        +        ],
        +        "type": "string"
        +      },
        +      "direction": {
        +        "enum": [
        +          "long",
        +          "short"
        +        ],
        +        "type": "string"
        +      },
        +      "optionType": {
        +        "enum": [
        +          "call",
        +          "put"
        +        ],
        +        "type": "string"
        +      },
        +      "quantity": {
        +        "additionalProperties": true,
        +        "description": "How many contracts to close. Defaults to all matching when omitted.",
        +        "type": "object"
        +      },
        +      "spreadType": {
        +        "enum": [
        +          "vertical",
        +          "calendar",
        +          "diagonal",
        +          "ironCondor",
        +          "straddle",
        +          "strangle",
        +          "custom"
        +        ],
        +        "type": "string"
        +      },
        +      "triggers": {
        +        "items": {
        +          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxPnlPercent": {
        +                  "type": "number"
        +                },
        +                "minPnlPercent": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "pnl",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxDte": {
        +                  "type": "number"
        +                },
        +                "minDte": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "dte",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxDaysHeld": {
        +                  "type": "number"
        +                },
        +                "minDaysHeld": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "daysHeld",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxIv": {
        +                  "type": "number"
        +                },
        +                "maxSpreadDelta": {
        +                  "type": "number"
        +                },
        +                "maxSpreadTheta": {
        +                  "type": "number"
        +                },
        +                "minIv": {
        +                  "type": "number"
        +                },
        +                "minSpreadDelta": {
        +                  "type": "number"
        +                },
        +                "minSpreadTheta": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "greeks",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "type": {
        +        "const": "CloseOption",
        +        "type": "string"
        +      },
        +      "underlyings": {
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  }
        +]
      • changedInput schema / properties / strategies / items / properties / action / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "description": "Buy or Sell a stock/crypto position.",
        -    "properties": {
        -      "amount": {
        -        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "percent of current positions",
        -              "dollars",
        -              "number of assets"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "targetAsset": {
        -        "additionalProperties": true,
        -        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -        "properties": {
        -          "name": {
        -            "type": "string"
        -          },
        -          "symbol": {
        -            "type": "string"
        -          },
        -          "type": {
        -            "enum": [
        -              "Stock",
        -              "Cryptocurrency",
        -              "Option",
        -              "Other"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "symbol"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "enum": [
        -          "Buy",
        -          "Sell"
        -        ],
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "targetAsset",
        -      "amount"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Send an alert message (no order).",
        -    "properties": {
        -      "message": {
        -        "type": "string"
        -      },
        -      "type": {
        -        "const": "Alert",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "message"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        -    "properties": {
        -      "allocationPolicy": {
        -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "expectedReturnShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "riskAversion": {
        -                "maximum": 1000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MeanVariance",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "riskAversion",
        -              "expectedReturnShrinkage",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "RiskParity",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumDiversification",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "canSell": {
        -        "$ref": "#/$defs/condition",
        -        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        -      },
        -      "deploymentPercent": {
        -        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        -        "maximum": 100,
        -        "minimum": 0,
        -        "type": "number"
        -      },
        -      "exposurePolicy": {
        -        "additionalProperties": false,
        -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        -        "properties": {
        -          "covarianceShrinkage": {
        -            "maximum": 1,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "estimatedTransactionCostBps": {
        -            "maximum": 10000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "lookbackPeriods": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "minimumObservations": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "targetAnnualizedVolatilityPercent": {
        -            "maximum": 1000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "const": "VolatilityTarget",
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "lookbackPeriods",
        -          "minimumObservations",
        -          "covarianceShrinkage",
        -          "targetAnnualizedVolatilityPercent",
        -          "estimatedTransactionCostBps"
        -        ],
        -        "type": "object"
        -      },
        -      "limit": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "perNameAllocation": {
        -        "additionalProperties": true,
        -        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
        -        "properties": {
        -          "amount": {
        -            "exclusiveMinimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "percent of portfolio",
        -              "dollars"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "pipeline": {
        -        "items": {
        -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "condition": {
        -                  "$ref": "#/$defs/condition"
        -                },
        -                "type": {
        -                  "const": "Filter",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "condition"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "limit": {
        -                  "minimum": 1,
        -                  "type": "number"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "type": {
        -                  "const": "SelectTop",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "limit",
        -                "direction"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "percentile": {
        -                  "maximum": 100,
        -                  "minimum": 0,
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "SelectPercentile",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "percentile",
        -                "direction"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "type": {
        -        "const": "DynamicRebalance",
        -        "type": "string"
        -      },
        -      "universe": {
        -        "additionalProperties": true,
        -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -        "properties": {
        -          "assets": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -              "properties": {
        -                "name": {
        -                  "type": "string"
        -                },
        -                "symbol": {
        -                  "type": "string"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "Stock",
        -                    "Cryptocurrency",
        -                    "Option",
        -                    "Other"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "symbol"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "source": {
        -            "enum": [
        -              "ALL_US_STOCKS",
        -              "SP500",
        -              "NASDAQ100",
        -              "DJIA",
        -              "CRYPTO",
        -              "SPECIFIC_ASSETS"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "weightIndicator": {
        -        "$ref": "#/$defs/indicator"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "universe",
        -      "pipeline",
        -      "weightIndicator"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        -    "properties": {
        -      "continueExisting": {
        -        "type": "boolean"
        -      },
        -      "cooldownMinutes": {
        -        "minimum": 0,
        -        "type": "number"
        -      },
        -      "executionModel": {
        -        "type": "string"
        -      },
        -      "includeMarketData": {
        -        "type": "boolean"
        -      },
        -      "initialMessage": {
        -        "type": "string"
        -      },
        -      "maxIterations": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "planningModel": {
        -        "type": "string"
        -      },
        -      "skipPlanning": {
        -        "type": "boolean"
        -      },
        -      "type": {
        -        "const": "LaunchAgent",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "planningModel",
        -      "executionModel",
        -      "initialMessage",
        -      "maxIterations",
        -      "includeMarketData",
        -      "continueExisting",
        -      "skipPlanning"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        -    "properties": {
        -      "against": {
        -        "additionalProperties": true,
        -        "description": "Optional parent-position selector (e.g. for covered calls).",
        -        "type": "object"
        -      },
        -      "allocation": {
        -        "additionalProperties": true,
        -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "contracts"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "builder": {
        -        "additionalProperties": true,
        -        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        -        "properties": {
        -          "dynamicUnderlying": {
        -            "additionalProperties": true,
        -            "properties": {
        -              "limit": {
        -                "minimum": 1,
        -                "type": "number"
        -              },
        -              "pipeline": {
        -                "items": {
        -                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -                  "oneOf": [
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "condition": {
        -                          "$ref": "#/$defs/condition"
        -                        },
        -                        "type": {
        -                          "const": "Filter",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "condition"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "Highest",
        -                            "Lowest"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "limit": {
        -                          "minimum": 1,
        -                          "type": "number"
        -                        },
        -                        "metric": {
        -                          "$ref": "#/$defs/indicator"
        -                        },
        -                        "type": {
        -                          "const": "SelectTop",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "metric",
        -                        "limit",
        -                        "direction"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "Highest",
        -                            "Lowest"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "metric": {
        -                          "$ref": "#/$defs/indicator"
        -                        },
        -                        "percentile": {
        -                          "maximum": 100,
        -                          "minimum": 0,
        -                          "type": "number"
        -                        },
        -                        "type": {
        -                          "const": "SelectPercentile",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "metric",
        -                        "percentile",
        -                        "direction"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ],
        -                  "type": "object"
        -                },
        -                "type": "array"
        -              },
        -              "universe": {
        -                "additionalProperties": true,
        -                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -                "properties": {
        -                  "assets": {
        -                    "items": {
        -                      "additionalProperties": true,
        -                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -                      "properties": {
        -                        "name": {
        -                          "type": "string"
        -                        },
        -                        "symbol": {
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "enum": [
        -                            "Stock",
        -                            "Cryptocurrency",
        -                            "Option",
        -                            "Other"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "symbol"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    "type": "array"
        -                  },
        -                  "source": {
        -                    "enum": [
        -                      "ALL_US_STOCKS",
        -                      "SP500",
        -                      "NASDAQ100",
        -                      "DJIA",
        -                      "CRYPTO",
        -                      "SPECIFIC_ASSETS"
        -                    ],
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "source"
        -                ],
        -                "type": "object"
        -              }
        -            },
        -            "required": [
        -              "universe"
        -            ],
        -            "type": "object"
        -          },
        -          "legs": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Single leg of an option builder.",
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "long",
        -                    "short"
        -                  ],
        -                  "type": "string"
        -                },
        -                "expirationRange": {
        -                  "additionalProperties": true,
        -                  "type": "object"
        -                },
        -                "expirationSelector": {
        -                  "properties": {
        -                    "maxDaysToExpiration": {
        -                      "minimum": 0,
        -                      "type": "number"
        -                    },
        -                    "minDaysToExpiration": {
        -                      "minimum": 0,
        -                      "type": "number"
        -                    },
        -                    "preference": {
        -                      "enum": [
        -                        "nearest",
        -                        "middle",
        -                        "furthest"
        -                      ],
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "minDaysToExpiration",
        -                    "maxDaysToExpiration",
        -                    "preference"
        -                  ],
        -                  "type": "object"
        -                },
        -                "fallbackStrikeSelector": {
        -                  "additionalProperties": false,
        -                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                  "properties": {
        -                    "distance": {
        -                      "type": "number"
        -                    },
        -                    "distanceType": {
        -                      "enum": [
        -                        "percent",
        -                        "dollars"
        -                      ],
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "distanceType",
        -                    "distance"
        -                  ],
        -                  "type": "object"
        -                },
        -                "greekFilter": {
        -                  "additionalProperties": true,
        -                  "description": "Optional min/max constraints on Greeks during resolution.",
        -                  "type": "object"
        -                },
        -                "liquidityFilter": {
        -                  "additionalProperties": false,
        -                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                  "properties": {
        -                    "maxSpreadAbsolute": {
        -                      "type": "number"
        -                    },
        -                    "maxSpreadPct": {
        -                      "type": "number"
        -                    },
        -                    "minBid": {
        -                      "type": "number"
        -                    }
        -                  },
        -                  "type": "object"
        -                },
        -                "optionType": {
        -                  "enum": [
        -                    "call",
        -                    "put"
        -                  ],
        -                  "type": "string"
        -                },
        -                "ratio": {
        -                  "type": "number"
        -                },
        -                "strikeRange": {
        -                  "additionalProperties": true,
        -                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                  "type": "object"
        -                },
        -                "strikeSelector": {
        -                  "properties": {
        -                    "distance": {
        -                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                      "type": "number"
        -                    },
        -                    "distanceType": {
        -                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "distanceType",
        -                    "distance"
        -                  ],
        -                  "type": "object"
        -                }
        -              },
        -              "required": [
        -                "optionType",
        -                "direction",
        -                "expirationSelector",
        -                "strikeSelector"
        -              ],
        -              "type": "object"
        -            },
        -            "minItems": 1,
        -            "type": "array"
        -          },
        -          "spreadType": {
        -            "enum": [
        -              "vertical",
        -              "calendar",
        -              "diagonal",
        -              "ironCondor",
        -              "straddle",
        -              "strangle",
        -              "custom"
        -            ],
        -            "type": "string"
        -          },
        -          "underlyingSymbol": {
        -            "type": "string"
        -          },
        -          "widthConstraint": {
        -            "additionalProperties": false,
        -            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -            "properties": {
        -              "minWidthDollars": {
        -                "exclusiveMinimum": 0,
        -                "type": "number"
        -              },
        -              "minWidthPercent": {
        -                "exclusiveMinimum": 0,
        -                "type": "number"
        -              }
        -            },
        -            "type": "object"
        -          }
        -        },
        -        "required": [
        -          "legs"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "const": "OpenOption",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "builder"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        -    "properties": {
        -      "allocationPolicy": {
        -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "expectedReturnShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "riskAversion": {
        -                "maximum": 1000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MeanVariance",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "riskAversion",
        -              "expectedReturnShrinkage",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "RiskParity",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumDiversification",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "exposurePolicy": {
        -        "additionalProperties": false,
        -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        -        "properties": {
        -          "covarianceShrinkage": {
        -            "maximum": 1,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "estimatedTransactionCostBps": {
        -            "maximum": 10000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "lookbackPeriods": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "minimumObservations": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "targetAnnualizedVolatilityPercent": {
        -            "maximum": 1000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "const": "VolatilityTarget",
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "lookbackPeriods",
        -          "minimumObservations",
        -          "covarianceShrinkage",
        -          "targetAnnualizedVolatilityPercent",
        -          "estimatedTransactionCostBps"
        -        ],
        -        "type": "object"
        -      },
        -      "limit": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "perNameAllocation": {
        -        "additionalProperties": true,
        -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "contracts"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "pipeline": {
        -        "items": {
        -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "condition": {
        -                  "$ref": "#/$defs/condition"
        -                },
        -                "type": {
        -                  "const": "Filter",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "condition"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "limit": {
        -                  "minimum": 1,
        -                  "type": "number"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "type": {
        -                  "const": "SelectTop",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "limit",
        -                "direction"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "percentile": {
        -                  "maximum": 100,
        -                  "minimum": 0,
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "SelectPercentile",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "percentile",
        -                "direction"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "positionScope": {
        -        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        -        "enum": [
        -          "portfolio",
        -          "strategy"
        -        ],
        -        "type": "string"
        -      },
        -      "sleeves": {
        -        "items": {
        -          "additionalProperties": true,
        -          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        -          "properties": {
        -            "limit": {
        -              "minimum": 1,
        -              "type": "number"
        -            },
        -            "name": {
        -              "type": "string"
        -            },
        -            "perNameAllocation": {
        -              "additionalProperties": true,
        -              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -              "properties": {
        -                "amount": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "dollars",
        -                    "percent of portfolio",
        -                    "percent of buying power",
        -                    "contracts"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "amount"
        -              ],
        -              "type": "object"
        -            },
        -            "pipeline": {
        -              "items": {
        -                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -                "oneOf": [
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "condition": {
        -                        "$ref": "#/$defs/condition"
        -                      },
        -                      "type": {
        -                        "const": "Filter",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "condition"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "direction": {
        -                        "enum": [
        -                          "Highest",
        -                          "Lowest"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "limit": {
        -                        "minimum": 1,
        -                        "type": "number"
        -                      },
        -                      "metric": {
        -                        "$ref": "#/$defs/indicator"
        -                      },
        -                      "type": {
        -                        "const": "SelectTop",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "metric",
        -                      "limit",
        -                      "direction"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "direction": {
        -                        "enum": [
        -                          "Highest",
        -                          "Lowest"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "metric": {
        -                        "$ref": "#/$defs/indicator"
        -                      },
        -                      "percentile": {
        -                        "maximum": 100,
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "type": {
        -                        "const": "SelectPercentile",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "metric",
        -                      "percentile",
        -                      "direction"
        -                    ],
        -                    "type": "object"
        -                  }
        -                ],
        -                "type": "object"
        -              },
        -              "type": "array"
        -            },
        -            "structureTemplates": {
        -              "items": {
        -                "additionalProperties": true,
        -                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        -                "properties": {
        -                  "eligibility": {
        -                    "$ref": "#/$defs/condition"
        -                  },
        -                  "legs": {
        -                    "items": {
        -                      "additionalProperties": true,
        -                      "description": "Single leg of an option builder.",
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "long",
        -                            "short"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "expirationRange": {
        -                          "additionalProperties": true,
        -                          "type": "object"
        -                        },
        -                        "expirationSelector": {
        -                          "properties": {
        -                            "maxDaysToExpiration": {
        -                              "minimum": 0,
        -                              "type": "number"
        -                            },
        -                            "minDaysToExpiration": {
        -                              "minimum": 0,
        -                              "type": "number"
        -                            },
        -                            "preference": {
        -                              "enum": [
        -                                "nearest",
        -                                "middle",
        -                                "furthest"
        -                              ],
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "minDaysToExpiration",
        -                            "maxDaysToExpiration",
        -                            "preference"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "fallbackStrikeSelector": {
        -                          "additionalProperties": false,
        -                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                          "properties": {
        -                            "distance": {
        -                              "type": "number"
        -                            },
        -                            "distanceType": {
        -                              "enum": [
        -                                "percent",
        -                                "dollars"
        -                              ],
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "distanceType",
        -                            "distance"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "greekFilter": {
        -                          "additionalProperties": true,
        -                          "description": "Optional min/max constraints on Greeks during resolution.",
        -                          "type": "object"
        -                        },
        -                        "liquidityFilter": {
        -                          "additionalProperties": false,
        -                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                          "properties": {
        -                            "maxSpreadAbsolute": {
        -                              "type": "number"
        -                            },
        -                            "maxSpreadPct": {
        -                              "type": "number"
        -                            },
        -                            "minBid": {
        -                              "type": "number"
        -                            }
        -                          },
        -                          "type": "object"
        -                        },
        -                        "optionType": {
        -                          "enum": [
        -                            "call",
        -                            "put"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "ratio": {
        -                          "type": "number"
        -                        },
        -                        "strikeRange": {
        -                          "additionalProperties": true,
        -                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                          "type": "object"
        -                        },
        -                        "strikeSelector": {
        -                          "properties": {
        -                            "distance": {
        -                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                              "type": "number"
        -                            },
        -                            "distanceType": {
        -                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "distanceType",
        -                            "distance"
        -                          ],
        -                          "type": "object"
        -                        }
        -                      },
        -                      "required": [
        -                        "optionType",
        -                        "direction",
        -                        "expirationSelector",
        -                        "strikeSelector"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    "minItems": 1,
        -                    "type": "array"
        -                  },
        -                  "name": {
        -                    "type": "string"
        -                  },
        -                  "spreadType": {
        -                    "enum": [
        -                      "vertical",
        -                      "calendar",
        -                      "diagonal",
        -                      "ironCondor",
        -                      "straddle",
        -                      "strangle",
        -                      "custom"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "widthConstraint": {
        -                    "additionalProperties": false,
        -                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -                    "properties": {
        -                      "minWidthDollars": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "number"
        -                      },
        -                      "minWidthPercent": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "number"
        -                      }
        -                    },
        -                    "type": "object"
        -                  }
        -                },
        -                "required": [
        -                  "legs"
        -                ],
        -                "type": "object"
        -              },
        -              "minItems": 1,
        -              "type": "array"
        -            },
        -            "universe": {
        -              "additionalProperties": true,
        -              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -              "properties": {
        -                "assets": {
        -                  "items": {
        -                    "additionalProperties": true,
        -                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -                    "properties": {
        -                      "name": {
        -                        "type": "string"
        -                      },
        -                      "symbol": {
        -                        "type": "string"
        -                      },
        -                      "type": {
        -                        "enum": [
        -                          "Stock",
        -                          "Cryptocurrency",
        -                          "Option",
        -                          "Other"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "symbol"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "type": "array"
        -                },
        -                "source": {
        -                  "enum": [
        -                    "ALL_US_STOCKS",
        -                    "SP500",
        -                    "NASDAQ100",
        -                    "DJIA",
        -                    "CRYPTO",
        -                    "SPECIFIC_ASSETS"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "source"
        -              ],
        -              "type": "object"
        -            },
        -            "weightIndicator": {
        -              "$ref": "#/$defs/indicator"
        -            }
        -          },
        -          "required": [
        -            "name"
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "structureTemplates": {
        -        "items": {
        -          "additionalProperties": true,
        -          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        -          "properties": {
        -            "eligibility": {
        -              "$ref": "#/$defs/condition"
        -            },
        -            "legs": {
        -              "items": {
        -                "additionalProperties": true,
        -                "description": "Single leg of an option builder.",
        -                "properties": {
        -                  "direction": {
        -                    "enum": [
        -                      "long",
        -                      "short"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "expirationRange": {
        -                    "additionalProperties": true,
        -                    "type": "object"
        -                  },
        -                  "expirationSelector": {
        -                    "properties": {
        -                      "maxDaysToExpiration": {
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "minDaysToExpiration": {
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "preference": {
        -                        "enum": [
        -                          "nearest",
        -                          "middle",
        -                          "furthest"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "minDaysToExpiration",
        -                      "maxDaysToExpiration",
        -                      "preference"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "fallbackStrikeSelector": {
        -                    "additionalProperties": false,
        -                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                    "properties": {
        -                      "distance": {
        -                        "type": "number"
        -                      },
        -                      "distanceType": {
        -                        "enum": [
        -                          "percent",
        -                          "dollars"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "distanceType",
        -                      "distance"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "greekFilter": {
        -                    "additionalProperties": true,
        -                    "description": "Optional min/max constraints on Greeks during resolution.",
        -                    "type": "object"
        -                  },
        -                  "liquidityFilter": {
        -                    "additionalProperties": false,
        -                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                    "properties": {
        -                      "maxSpreadAbsolute": {
        -                        "type": "number"
        -                      },
        -                      "maxSpreadPct": {
        -                        "type": "number"
        -                      },
        -                      "minBid": {
        -                        "type": "number"
        -                      }
        -                    },
        -                    "type": "object"
        -                  },
        -                  "optionType": {
        -                    "enum": [
        -                      "call",
        -                      "put"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "ratio": {
        -                    "type": "number"
        -                  },
        -                  "strikeRange": {
        -                    "additionalProperties": true,
        -                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                    "type": "object"
        -                  },
        -                  "strikeSelector": {
        -                    "properties": {
        -                      "distance": {
        -                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                        "type": "number"
        -                      },
        -                      "distanceType": {
        -                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "distanceType",
        -                      "distance"
        -                    ],
        -                    "type": "object"
        -                  }
        -                },
        -                "required": [
        -                  "optionType",
        -                  "direction",
        -                  "expirationSelector",
        -                  "strikeSelector"
        -                ],
        -                "type": "object"
        -              },
        -              "minItems": 1,
        -              "type": "array"
        -            },
        -            "name": {
        -              "type": "string"
        -            },
        -            "spreadType": {
        -              "enum": [
        -                "vertical",
        -                "calendar",
        -                "diagonal",
        -                "ironCondor",
        -                "straddle",
        -                "strangle",
        -                "custom"
        -              ],
        -              "type": "string"
        -            },
        -            "widthConstraint": {
        -              "additionalProperties": false,
        -              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -              "properties": {
        -                "minWidthDollars": {
        -                  "exclusiveMinimum": 0,
        -                  "type": "number"
        -                },
        -                "minWidthPercent": {
        -                  "exclusiveMinimum": 0,
        -                  "type": "number"
        -                }
        -              },
        -              "type": "object"
        -            }
        -          },
        -          "required": [
        -            "legs"
        -          ],
        -          "type": "object"
        -        },
        -        "minItems": 1,
        -        "type": "array"
        -      },
        -      "totalBudget": {
        -        "additionalProperties": true,
        -        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        -        "properties": {
        -          "amount": {
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "const": "RebalanceOption",
        -        "type": "string"
        -      },
        -      "universe": {
        -        "additionalProperties": true,
        -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -        "properties": {
        -          "assets": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -              "properties": {
        -                "name": {
        -                  "type": "string"
        -                },
        -                "symbol": {
        -                  "type": "string"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "Stock",
        -                    "Cryptocurrency",
        -                    "Option",
        -                    "Other"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "symbol"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "source": {
        -            "enum": [
        -              "ALL_US_STOCKS",
        -              "SP500",
        -              "NASDAQ100",
        -              "DJIA",
        -              "CRYPTO",
        -              "SPECIFIC_ASSETS"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "weightIndicator": {
        -        "$ref": "#/$defs/indicator"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "universe",
        -      "pipeline",
        -      "weightIndicator",
        -      "structureTemplates"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        -    "properties": {
        -      "closeScope": {
        -        "enum": [
        -          "spread",
        -          "leg"
        -        ],
        -        "type": "string"
        -      },
        -      "direction": {
        -        "enum": [
        -          "long",
        -          "short"
        -        ],
        -        "type": "string"
        -      },
        -      "optionType": {
        -        "enum": [
        -          "call",
        -          "put"
        -        ],
        -        "type": "string"
        -      },
        -      "quantity": {
        -        "additionalProperties": true,
        -        "description": "How many contracts to close. Defaults to all matching when omitted.",
        -        "type": "object"
        -      },
        -      "spreadType": {
        -        "enum": [
        -          "vertical",
        -          "calendar",
        -          "diagonal",
        -          "ironCondor",
        -          "straddle",
        -          "strangle",
        -          "custom"
        -        ],
        -        "type": "string"
        -      },
        -      "triggers": {
        -        "items": {
        -          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxPnlPercent": {
        -                  "type": "number"
        -                },
        -                "minPnlPercent": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "pnl",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxDte": {
        -                  "type": "number"
        -                },
        -                "minDte": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "dte",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxDaysHeld": {
        -                  "type": "number"
        -                },
        -                "minDaysHeld": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "daysHeld",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxIv": {
        -                  "type": "number"
        -                },
        -                "maxSpreadDelta": {
        -                  "type": "number"
        -                },
        -                "maxSpreadTheta": {
        -                  "type": "number"
        -                },
        -                "minIv": {
        -                  "type": "number"
        -                },
        -                "minSpreadDelta": {
        -                  "type": "number"
        -                },
        -                "minSpreadTheta": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "greeks",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "type": {
        -        "const": "CloseOption",
        -        "type": "string"
        -      },
        -      "underlyings": {
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array"
        -      }
        -    },
        -    "required": [
        -      "type"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": true,
        +    "description": "Buy or Sell a stock/crypto position.",
        +    "properties": {
        +      "amount": {
        +        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "percent of current positions",
        +              "dollars",
        +              "number of assets"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "targetAsset": {
        +        "additionalProperties": true,
        +        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +        "properties": {
        +          "name": {
        +            "type": "string"
        +          },
        +          "symbol": {
        +            "type": "string"
        +          },
        +          "type": {
        +            "enum": [
        +              "Stock",
        +              "Cryptocurrency",
        +              "Option",
        +              "Other"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "symbol"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "enum": [
        +          "Buy",
        +          "Sell"
        +        ],
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "targetAsset",
        +      "amount"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Send an alert message (no order).",
        +    "properties": {
        +      "message": {
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "Alert",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "message"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        +    "properties": {
        +      "allocationPolicy": {
        +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "expectedReturnShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "riskAversion": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MeanVariance",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "riskAversion",
        +              "expectedReturnShrinkage",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "RiskParity",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MaximumDiversification",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "canSell": {
        +        "$ref": "#/$defs/condition",
        +        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        +      },
        +      "deploymentPercent": {
        +        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        +        "maximum": 100,
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "exposurePolicy": {
        +        "additionalProperties": false,
        +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +        "properties": {
        +          "covarianceShrinkage": {
        +            "maximum": 1,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "estimatedTransactionCostBps": {
        +            "maximum": 10000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "lookbackPeriods": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "minimumObservations": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "targetAnnualizedVolatilityPercent": {
        +            "maximum": 1000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "const": "VolatilityTarget",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "lookbackPeriods",
        +          "minimumObservations",
        +          "covarianceShrinkage",
        +          "targetAnnualizedVolatilityPercent",
        +          "estimatedTransactionCostBps"
        +        ],
        +        "type": "object"
        +      },
        +      "limit": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "perNameAllocation": {
        +        "additionalProperties": true,
        +        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.",
        +        "properties": {
        +          "amount": {
        +            "exclusiveMinimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "percent of portfolio",
        +              "dollars"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "pipeline": {
        +        "items": {
        +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "condition": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "type": {
        +                  "const": "Filter",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "condition"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "type": {
        +                  "const": "SelectTop",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "limit",
        +                "direction"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "percentile": {
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "SelectPercentile",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "percentile",
        +                "direction"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "type": {
        +        "const": "DynamicRebalance",
        +        "type": "string"
        +      },
        +      "universe": {
        +        "additionalProperties": true,
        +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +        "properties": {
        +          "assets": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +              "properties": {
        +                "name": {
        +                  "type": "string"
        +                },
        +                "symbol": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Stock",
        +                    "Cryptocurrency",
        +                    "Option",
        +                    "Other"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "symbol"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "enum": [
        +              "ALL_US_STOCKS",
        +              "SP500",
        +              "NASDAQ100",
        +              "DJIA",
        +              "CRYPTO",
        +              "SPECIFIC_ASSETS"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "weightIndicator": {
        +        "$ref": "#/$defs/indicator"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "universe",
        +      "pipeline",
        +      "weightIndicator"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        +    "properties": {
        +      "continueExisting": {
        +        "type": "boolean"
        +      },
        +      "cooldownMinutes": {
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "executionModel": {
        +        "type": "string"
        +      },
        +      "includeMarketData": {
        +        "type": "boolean"
        +      },
        +      "initialMessage": {
        +        "type": "string"
        +      },
        +      "maxIterations": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "planningModel": {
        +        "type": "string"
        +      },
        +      "skipPlanning": {
        +        "type": "boolean"
        +      },
        +      "type": {
        +        "const": "LaunchAgent",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "planningModel",
        +      "executionModel",
        +      "initialMessage",
        +      "maxIterations",
        +      "includeMarketData",
        +      "continueExisting",
        +      "skipPlanning"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        +    "properties": {
        +      "against": {
        +        "additionalProperties": true,
        +        "description": "Optional parent-position selector (e.g. for covered calls).",
        +        "type": "object"
        +      },
        +      "allocation": {
        +        "additionalProperties": true,
        +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "contracts",
        +              "percent of realized premium"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "builder": {
        +        "additionalProperties": true,
        +        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        +        "properties": {
        +          "dynamicUnderlying": {
        +            "additionalProperties": true,
        +            "properties": {
        +              "limit": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "pipeline": {
        +                "items": {
        +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                  "oneOf": [
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "condition": {
        +                          "$ref": "#/$defs/condition"
        +                        },
        +                        "type": {
        +                          "const": "Filter",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "condition"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "limit": {
        +                          "minimum": 1,
        +                          "type": "number"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "type": {
        +                          "const": "SelectTop",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "limit",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "percentile": {
        +                          "maximum": 100,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "SelectPercentile",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "percentile",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "universe": {
        +                "additionalProperties": true,
        +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                "properties": {
        +                  "assets": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                      "properties": {
        +                        "name": {
        +                          "type": "string"
        +                        },
        +                        "symbol": {
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "enum": [
        +                            "Stock",
        +                            "Cryptocurrency",
        +                            "Option",
        +                            "Other"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "symbol"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "type": "array"
        +                  },
        +                  "source": {
        +                    "enum": [
        +                      "ALL_US_STOCKS",
        +                      "SP500",
        +                      "NASDAQ100",
        +                      "DJIA",
        +                      "CRYPTO",
        +                      "SPECIFIC_ASSETS"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "source"
        +                ],
        +                "type": "object"
        +              }
        +            },
        +            "required": [
        +              "universe"
        +            ],
        +            "type": "object"
        +          },
        +          "legs": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Single leg of an option builder.",
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "long",
        +                    "short"
        +                  ],
        +                  "type": "string"
        +                },
        +                "expirationRange": {
        +                  "additionalProperties": true,
        +                  "type": "object"
        +                },
        +                "expirationSelector": {
        +                  "properties": {
        +                    "maxDaysToExpiration": {
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "minDaysToExpiration": {
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "preference": {
        +                      "enum": [
        +                        "nearest",
        +                        "middle",
        +                        "furthest"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "minDaysToExpiration",
        +                    "maxDaysToExpiration",
        +                    "preference"
        +                  ],
        +                  "type": "object"
        +                },
        +                "fallbackStrikeSelector": {
        +                  "additionalProperties": false,
        +                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                  "properties": {
        +                    "distance": {
        +                      "type": "number"
        +                    },
        +                    "distanceType": {
        +                      "enum": [
        +                        "percent",
        +                        "dollars"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "distanceType",
        +                    "distance"
        +                  ],
        +                  "type": "object"
        +                },
        +                "greekFilter": {
        +                  "additionalProperties": true,
        +                  "description": "Optional min/max constraints on Greeks during resolution.",
        +                  "type": "object"
        +                },
        +                "liquidityFilter": {
        +                  "additionalProperties": false,
        +                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                  "properties": {
        +                    "maxSpreadAbsolute": {
        +                      "type": "number"
        +                    },
        +                    "maxSpreadPct": {
        +                      "type": "number"
        +                    },
        +                    "minBid": {
        +                      "type": "number"
        +                    }
        +                  },
        +                  "type": "object"
        +                },
        +                "optionType": {
        +                  "enum": [
        +                    "call",
        +                    "put"
        +                  ],
        +                  "type": "string"
        +                },
        +                "ratio": {
        +                  "type": "number"
        +                },
        +                "strikeRange": {
        +                  "additionalProperties": true,
        +                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                  "type": "object"
        +                },
        +                "strikeSelector": {
        +                  "properties": {
        +                    "distance": {
        +                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                      "type": "number"
        +                    },
        +                    "distanceType": {
        +                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "distanceType",
        +                    "distance"
        +                  ],
        +                  "type": "object"
        +                }
        +              },
        +              "required": [
        +                "optionType",
        +                "direction",
        +                "expirationSelector",
        +                "strikeSelector"
        +              ],
        +              "type": "object"
        +            },
        +            "minItems": 1,
        +            "type": "array"
        +          },
        +          "spreadType": {
        +            "enum": [
        +              "vertical",
        +              "calendar",
        +              "diagonal",
        +              "ironCondor",
        +              "straddle",
        +              "strangle",
        +              "custom"
        +            ],
        +            "type": "string"
        +          },
        +          "underlyingSymbol": {
        +            "type": "string"
        +          },
        +          "widthConstraint": {
        +            "additionalProperties": false,
        +            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +            "properties": {
        +              "minWidthDollars": {
        +                "exclusiveMinimum": 0,
        +                "type": "number"
        +              },
        +              "minWidthPercent": {
        +                "exclusiveMinimum": 0,
        +                "type": "number"
        +              }
        +            },
        +            "type": "object"
        +          }
        +        },
        +        "required": [
        +          "legs"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "const": "OpenOption",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "builder"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        +    "properties": {
        +      "allocationPolicy": {
        +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "expectedReturnShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "riskAversion": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MeanVariance",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "riskAversion",
        +              "expectedReturnShrinkage",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "RiskParity",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MaximumDiversification",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "exposurePolicy": {
        +        "additionalProperties": false,
        +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +        "properties": {
        +          "covarianceShrinkage": {
        +            "maximum": 1,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "estimatedTransactionCostBps": {
        +            "maximum": 10000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "lookbackPeriods": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "minimumObservations": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "targetAnnualizedVolatilityPercent": {
        +            "maximum": 1000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "const": "VolatilityTarget",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "lookbackPeriods",
        +          "minimumObservations",
        +          "covarianceShrinkage",
        +          "targetAnnualizedVolatilityPercent",
        +          "estimatedTransactionCostBps"
        +        ],
        +        "type": "object"
        +      },
        +      "limit": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "perNameAllocation": {
        +        "additionalProperties": true,
        +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "contracts",
        +              "percent of realized premium"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "pipeline": {
        +        "items": {
        +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "condition": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "type": {
        +                  "const": "Filter",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "condition"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "type": {
        +                  "const": "SelectTop",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "limit",
        +                "direction"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "percentile": {
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "SelectPercentile",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "percentile",
        +                "direction"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "positionScope": {
        +        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        +        "enum": [
        +          "portfolio",
        +          "strategy"
        +        ],
        +        "type": "string"
        +      },
        +      "sleeves": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        +          "properties": {
        +            "limit": {
        +              "minimum": 1,
        +              "type": "number"
        +            },
        +            "name": {
        +              "type": "string"
        +            },
        +            "perNameAllocation": {
        +              "additionalProperties": true,
        +              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +              "properties": {
        +                "amount": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "dollars",
        +                    "percent of portfolio",
        +                    "percent of buying power",
        +                    "contracts",
        +                    "percent of realized premium"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "amount"
        +              ],
        +              "type": "object"
        +            },
        +            "pipeline": {
        +              "items": {
        +                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                "oneOf": [
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "condition": {
        +                        "$ref": "#/$defs/condition"
        +                      },
        +                      "type": {
        +                        "const": "Filter",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "condition"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "direction": {
        +                        "enum": [
        +                          "Highest",
        +                          "Lowest"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "limit": {
        +                        "minimum": 1,
        +                        "type": "number"
        +                      },
        +                      "metric": {
        +                        "$ref": "#/$defs/indicator"
        +                      },
        +                      "type": {
        +                        "const": "SelectTop",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "metric",
        +                      "limit",
        +                      "direction"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "direction": {
        +                        "enum": [
        +                          "Highest",
        +                          "Lowest"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "metric": {
        +                        "$ref": "#/$defs/indicator"
        +                      },
        +                      "percentile": {
        +                        "maximum": 100,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "SelectPercentile",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "metric",
        +                      "percentile",
        +                      "direction"
        +                    ],
        +                    "type": "object"
        +                  }
        +                ],
        +                "type": "object"
        +              },
        +              "type": "array"
        +            },
        +            "structureTemplates": {
        +              "items": {
        +                "additionalProperties": true,
        +                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +                "properties": {
        +                  "eligibility": {
        +                    "$ref": "#/$defs/condition"
        +                  },
        +                  "legs": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Single leg of an option builder.",
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "long",
        +                            "short"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "expirationRange": {
        +                          "additionalProperties": true,
        +                          "type": "object"
        +                        },
        +                        "expirationSelector": {
        +                          "properties": {
        +                            "maxDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "minDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "preference": {
        +                              "enum": [
        +                                "nearest",
        +                                "middle",
        +                                "furthest"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "minDaysToExpiration",
        +                            "maxDaysToExpiration",
        +                            "preference"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "fallbackStrikeSelector": {
        +                          "additionalProperties": false,
        +                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                          "properties": {
        +                            "distance": {
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "enum": [
        +                                "percent",
        +                                "dollars"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "greekFilter": {
        +                          "additionalProperties": true,
        +                          "description": "Optional min/max constraints on Greeks during resolution.",
        +                          "type": "object"
        +                        },
        +                        "liquidityFilter": {
        +                          "additionalProperties": false,
        +                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                          "properties": {
        +                            "maxSpreadAbsolute": {
        +                              "type": "number"
        +                            },
        +                            "maxSpreadPct": {
        +                              "type": "number"
        +                            },
        +                            "minBid": {
        +                              "type": "number"
        +                            }
        +                          },
        +                          "type": "object"
        +                        },
        +                        "optionType": {
        +                          "enum": [
        +                            "call",
        +                            "put"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "ratio": {
        +                          "type": "number"
        +                        },
        +                        "strikeRange": {
        +                          "additionalProperties": true,
        +                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                          "type": "object"
        +                        },
        +                        "strikeSelector": {
        +                          "properties": {
        +                            "distance": {
        +                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        }
        +                      },
        +                      "required": [
        +                        "optionType",
        +                        "direction",
        +                        "expirationSelector",
        +                        "strikeSelector"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "minItems": 1,
        +                    "type": "array"
        +                  },
        +                  "name": {
        +                    "type": "string"
        +                  },
        +                  "spreadType": {
        +                    "enum": [
        +                      "vertical",
        +                      "calendar",
        +                      "diagonal",
        +                      "ironCondor",
        +                      "straddle",
        +                      "strangle",
        +                      "custom"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "widthConstraint": {
        +                    "additionalProperties": false,
        +                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                    "properties": {
        +                      "minWidthDollars": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minWidthPercent": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "legs"
        +                ],
        +                "type": "object"
        +              },
        +              "minItems": 1,
        +              "type": "array"
        +            },
        +            "universe": {
        +              "additionalProperties": true,
        +              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +              "properties": {
        +                "assets": {
        +                  "items": {
        +                    "additionalProperties": true,
        +                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                    "properties": {
        +                      "name": {
        +                        "type": "string"
        +                      },
        +                      "symbol": {
        +                        "type": "string"
        +                      },
        +                      "type": {
        +                        "enum": [
        +                          "Stock",
        +                          "Cryptocurrency",
        +                          "Option",
        +                          "Other"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "symbol"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "type": "array"
        +                },
        +                "source": {
        +                  "enum": [
        +                    "ALL_US_STOCKS",
        +                    "SP500",
        +                    "NASDAQ100",
        +                    "DJIA",
        +                    "CRYPTO",
        +                    "SPECIFIC_ASSETS"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "source"
        +              ],
        +              "type": "object"
        +            },
        +            "weightIndicator": {
        +              "$ref": "#/$defs/indicator"
        +            }
        +          },
        +          "required": [
        +            "name"
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "structureTemplates": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +          "properties": {
        +            "eligibility": {
        +              "$ref": "#/$defs/condition"
        +            },
        +            "legs": {
        +              "items": {
        +                "additionalProperties": true,
        +                "description": "Single leg of an option builder.",
        +                "properties": {
        +                  "direction": {
        +                    "enum": [
        +                      "long",
        +                      "short"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "expirationRange": {
        +                    "additionalProperties": true,
        +                    "type": "object"
        +                  },
        +                  "expirationSelector": {
        +                    "properties": {
        +                      "maxDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "preference": {
        +                        "enum": [
        +                          "nearest",
        +                          "middle",
        +                          "furthest"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "minDaysToExpiration",
        +                      "maxDaysToExpiration",
        +                      "preference"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "fallbackStrikeSelector": {
        +                    "additionalProperties": false,
        +                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                    "properties": {
        +                      "distance": {
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "enum": [
        +                          "percent",
        +                          "dollars"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "greekFilter": {
        +                    "additionalProperties": true,
        +                    "description": "Optional min/max constraints on Greeks during resolution.",
        +                    "type": "object"
        +                  },
        +                  "liquidityFilter": {
        +                    "additionalProperties": false,
        +                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                    "properties": {
        +                      "maxSpreadAbsolute": {
        +                        "type": "number"
        +                      },
        +                      "maxSpreadPct": {
        +                        "type": "number"
        +                      },
        +                      "minBid": {
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  },
        +                  "optionType": {
        +                    "enum": [
        +                      "call",
        +                      "put"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "ratio": {
        +                    "type": "number"
        +                  },
        +                  "strikeRange": {
        +                    "additionalProperties": true,
        +                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                    "type": "object"
        +                  },
        +                  "strikeSelector": {
        +                    "properties": {
        +                      "distance": {
        +                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "optionType",
        +                  "direction",
        +                  "expirationSelector",
        +                  "strikeSelector"
        +                ],
        +                "type": "object"
        +              },
        +              "minItems": 1,
        +              "type": "array"
        +            },
        +            "name": {
        +              "type": "string"
        +            },
        +            "spreadType": {
        +              "enum": [
        +                "vertical",
        +                "calendar",
        +                "diagonal",
        +                "ironCondor",
        +                "straddle",
        +                "strangle",
        +                "custom"
        +              ],
        +              "type": "string"
        +            },
        +            "widthConstraint": {
        +              "additionalProperties": false,
        +              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +              "properties": {
        +                "minWidthDollars": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                },
        +                "minWidthPercent": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                }
        +              },
        +              "type": "object"
        +            }
        +          },
        +          "required": [
        +            "legs"
        +          ],
        +          "type": "object"
        +        },
        +        "minItems": 1,
        +        "type": "array"
        +      },
        +      "totalBudget": {
        +        "additionalProperties": true,
        +        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        +        "properties": {
        +          "amount": {
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "const": "RebalanceOption",
        +        "type": "string"
        +      },
        +      "universe": {
        +        "additionalProperties": true,
        +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +        "properties": {
        +          "assets": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +              "properties": {
        +                "name": {
        +                  "type": "string"
        +                },
        +                "symbol": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Stock",
        +                    "Cryptocurrency",
        +                    "Option",
        +                    "Other"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "symbol"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "enum": [
        +              "ALL_US_STOCKS",
        +              "SP500",
        +              "NASDAQ100",
        +              "DJIA",
        +              "CRYPTO",
        +              "SPECIFIC_ASSETS"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "weightIndicator": {
        +        "$ref": "#/$defs/indicator"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "universe",
        +      "pipeline",
        +      "weightIndicator",
        +      "structureTemplates"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        +    "properties": {
        +      "closeScope": {
        +        "enum": [
        +          "spread",
        +          "leg"
        +        ],
        +        "type": "string"
        +      },
        +      "direction": {
        +        "enum": [
        +          "long",
        +          "short"
        +        ],
        +        "type": "string"
        +      },
        +      "optionType": {
        +        "enum": [
        +          "call",
        +          "put"
        +        ],
        +        "type": "string"
        +      },
        +      "quantity": {
        +        "additionalProperties": true,
        +        "description": "How many contracts to close. Defaults to all matching when omitted.",
        +        "type": "object"
        +      },
        +      "spreadType": {
        +        "enum": [
        +          "vertical",
        +          "calendar",
        +          "diagonal",
        +          "ironCondor",
        +          "straddle",
        +          "strangle",
        +          "custom"
        +        ],
        +        "type": "string"
        +      },
        +      "triggers": {
        +        "items": {
        +          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxPnlPercent": {
        +                  "type": "number"
        +                },
        +                "minPnlPercent": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "pnl",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxDte": {
        +                  "type": "number"
        +                },
        +                "minDte": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "dte",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxDaysHeld": {
        +                  "type": "number"
        +                },
        +                "minDaysHeld": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "daysHeld",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxIv": {
        +                  "type": "number"
        +                },
        +                "maxSpreadDelta": {
        +                  "type": "number"
        +                },
        +                "maxSpreadTheta": {
        +                  "type": "number"
        +                },
        +                "minIv": {
        +                  "type": "number"
        +                },
        +                "minSpreadDelta": {
        +                  "type": "number"
        +                },
        +                "minSpreadTheta": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "greeks",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "type": {
        +        "const": "CloseOption",
        +        "type": "string"
        +      },
        +      "underlyings": {
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  }
        +]
    • Changedupdate_portfolio9 fields changed
      • changedInput schema / $defs / action / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "description": "Buy or Sell a stock/crypto position.",
        -    "properties": {
        -      "amount": {
        -        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "percent of current positions",
        -              "dollars",
        -              "number of assets"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "targetAsset": {
        -        "additionalProperties": true,
        -        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -        "properties": {
        -          "name": {
        -            "type": "string"
        -          },
        -          "symbol": {
        -            "type": "string"
        -          },
        -          "type": {
        -            "enum": [
        -              "Stock",
        -              "Cryptocurrency",
        -              "Option",
        -              "Other"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "symbol"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "enum": [
        -          "Buy",
        -          "Sell"
        -        ],
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "targetAsset",
        -      "amount"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Send an alert message (no order).",
        -    "properties": {
        -      "message": {
        -        "type": "string"
        -      },
        -      "type": {
        -        "const": "Alert",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "message"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        -    "properties": {
        -      "allocationPolicy": {
        -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "expectedReturnShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "riskAversion": {
        -                "maximum": 1000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MeanVariance",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "riskAversion",
        -              "expectedReturnShrinkage",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "RiskParity",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumDiversification",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "canSell": {
        -        "$ref": "#/$defs/condition",
        -        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        -      },
        -      "deploymentPercent": {
        -        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        -        "maximum": 100,
        -        "minimum": 0,
        -        "type": "number"
        -      },
        -      "exposurePolicy": {
        -        "additionalProperties": false,
        -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        -        "properties": {
        -          "covarianceShrinkage": {
        -            "maximum": 1,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "estimatedTransactionCostBps": {
        -            "maximum": 10000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "lookbackPeriods": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "minimumObservations": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "targetAnnualizedVolatilityPercent": {
        -            "maximum": 1000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "const": "VolatilityTarget",
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "lookbackPeriods",
        -          "minimumObservations",
        -          "covarianceShrinkage",
        -          "targetAnnualizedVolatilityPercent",
        -          "estimatedTransactionCostBps"
        -        ],
        -        "type": "object"
        -      },
        -      "limit": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "perNameAllocation": {
        -        "additionalProperties": true,
        -        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
        -        "properties": {
        -          "amount": {
        -            "exclusiveMinimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "percent of portfolio",
        -              "dollars"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "pipeline": {
        -        "items": {
        -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "condition": {
        -                  "$ref": "#/$defs/condition"
        -                },
        -                "type": {
        -                  "const": "Filter",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "condition"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "limit": {
        -                  "minimum": 1,
        -                  "type": "number"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "type": {
        -                  "const": "SelectTop",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "limit",
        -                "direction"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "percentile": {
        -                  "maximum": 100,
        -                  "minimum": 0,
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "SelectPercentile",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "percentile",
        -                "direction"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "type": {
        -        "const": "DynamicRebalance",
        -        "type": "string"
        -      },
        -      "universe": {
        -        "additionalProperties": true,
        -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -        "properties": {
        -          "assets": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -              "properties": {
        -                "name": {
        -                  "type": "string"
        -                },
        -                "symbol": {
        -                  "type": "string"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "Stock",
        -                    "Cryptocurrency",
        -                    "Option",
        -                    "Other"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "symbol"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "source": {
        -            "enum": [
        -              "ALL_US_STOCKS",
        -              "SP500",
        -              "NASDAQ100",
        -              "DJIA",
        -              "CRYPTO",
        -              "SPECIFIC_ASSETS"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "weightIndicator": {
        -        "$ref": "#/$defs/indicator"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "universe",
        -      "pipeline",
        -      "weightIndicator"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        -    "properties": {
        -      "continueExisting": {
        -        "type": "boolean"
        -      },
        -      "cooldownMinutes": {
        -        "minimum": 0,
        -        "type": "number"
        -      },
        -      "executionModel": {
        -        "type": "string"
        -      },
        -      "includeMarketData": {
        -        "type": "boolean"
        -      },
        -      "initialMessage": {
        -        "type": "string"
        -      },
        -      "maxIterations": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "planningModel": {
        -        "type": "string"
        -      },
        -      "skipPlanning": {
        -        "type": "boolean"
        -      },
        -      "type": {
        -        "const": "LaunchAgent",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "planningModel",
        -      "executionModel",
        -      "initialMessage",
        -      "maxIterations",
        -      "includeMarketData",
        -      "continueExisting",
        -      "skipPlanning"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        -    "properties": {
        -      "against": {
        -        "additionalProperties": true,
        -        "description": "Optional parent-position selector (e.g. for covered calls).",
        -        "type": "object"
        -      },
        -      "allocation": {
        -        "additionalProperties": true,
        -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "contracts"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "builder": {
        -        "additionalProperties": true,
        -        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        -        "properties": {
        -          "dynamicUnderlying": {
        -            "additionalProperties": true,
        -            "properties": {
        -              "limit": {
        -                "minimum": 1,
        -                "type": "number"
        -              },
        -              "pipeline": {
        -                "items": {
        -                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -                  "oneOf": [
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "condition": {
        -                          "$ref": "#/$defs/condition"
        -                        },
        -                        "type": {
        -                          "const": "Filter",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "condition"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "Highest",
        -                            "Lowest"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "limit": {
        -                          "minimum": 1,
        -                          "type": "number"
        -                        },
        -                        "metric": {
        -                          "$ref": "#/$defs/indicator"
        -                        },
        -                        "type": {
        -                          "const": "SelectTop",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "metric",
        -                        "limit",
        -                        "direction"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "Highest",
        -                            "Lowest"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "metric": {
        -                          "$ref": "#/$defs/indicator"
        -                        },
        -                        "percentile": {
        -                          "maximum": 100,
        -                          "minimum": 0,
        -                          "type": "number"
        -                        },
        -                        "type": {
        -                          "const": "SelectPercentile",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "metric",
        -                        "percentile",
        -                        "direction"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ],
        -                  "type": "object"
        -                },
        -                "type": "array"
        -              },
        -              "universe": {
        -                "additionalProperties": true,
        -                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -                "properties": {
        -                  "assets": {
        -                    "items": {
        -                      "additionalProperties": true,
        -                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -                      "properties": {
        -                        "name": {
        -                          "type": "string"
        -                        },
        -                        "symbol": {
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "enum": [
        -                            "Stock",
        -                            "Cryptocurrency",
        -                            "Option",
        -                            "Other"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "symbol"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    "type": "array"
        -                  },
        -                  "source": {
        -                    "enum": [
        -                      "ALL_US_STOCKS",
        -                      "SP500",
        -                      "NASDAQ100",
        -                      "DJIA",
        -                      "CRYPTO",
        -                      "SPECIFIC_ASSETS"
        -                    ],
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "source"
        -                ],
        -                "type": "object"
        -              }
        -            },
        -            "required": [
        -              "universe"
        -            ],
        -            "type": "object"
        -          },
        -          "legs": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Single leg of an option builder.",
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "long",
        -                    "short"
        -                  ],
        -                  "type": "string"
        -                },
        -                "expirationRange": {
        -                  "additionalProperties": true,
        -                  "type": "object"
        -                },
        -                "expirationSelector": {
        -                  "properties": {
        -                    "maxDaysToExpiration": {
        -                      "minimum": 0,
        -                      "type": "number"
        -                    },
        -                    "minDaysToExpiration": {
        -                      "minimum": 0,
        -                      "type": "number"
        -                    },
        -                    "preference": {
        -                      "enum": [
        -                        "nearest",
        -                        "middle",
        -                        "furthest"
        -                      ],
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "minDaysToExpiration",
        -                    "maxDaysToExpiration",
        -                    "preference"
        -                  ],
        -                  "type": "object"
        -                },
        -                "fallbackStrikeSelector": {
        -                  "additionalProperties": false,
        -                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                  "properties": {
        -                    "distance": {
        -                      "type": "number"
        -                    },
        -                    "distanceType": {
        -                      "enum": [
        -                        "percent",
        -                        "dollars"
        -                      ],
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "distanceType",
        -                    "distance"
        -                  ],
        -                  "type": "object"
        -                },
        -                "greekFilter": {
        -                  "additionalProperties": true,
        -                  "description": "Optional min/max constraints on Greeks during resolution.",
        -                  "type": "object"
        -                },
        -                "liquidityFilter": {
        -                  "additionalProperties": false,
        -                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                  "properties": {
        -                    "maxSpreadAbsolute": {
        -                      "type": "number"
        -                    },
        -                    "maxSpreadPct": {
        -                      "type": "number"
        -                    },
        -                    "minBid": {
        -                      "type": "number"
        -                    }
        -                  },
        -                  "type": "object"
        -                },
        -                "optionType": {
        -                  "enum": [
        -                    "call",
        -                    "put"
        -                  ],
        -                  "type": "string"
        -                },
        -                "ratio": {
        -                  "type": "number"
        -                },
        -                "strikeRange": {
        -                  "additionalProperties": true,
        -                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                  "type": "object"
        -                },
        -                "strikeSelector": {
        -                  "properties": {
        -                    "distance": {
        -                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                      "type": "number"
        -                    },
        -                    "distanceType": {
        -                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "distanceType",
        -                    "distance"
        -                  ],
        -                  "type": "object"
        -                }
        -              },
        -              "required": [
        -                "optionType",
        -                "direction",
        -                "expirationSelector",
        -                "strikeSelector"
        -              ],
        -              "type": "object"
        -            },
        -            "minItems": 1,
        -            "type": "array"
        -          },
        -          "spreadType": {
        -            "enum": [
        -              "vertical",
        -              "calendar",
        -              "diagonal",
        -              "ironCondor",
        -              "straddle",
        -              "strangle",
        -              "custom"
        -            ],
        -            "type": "string"
        -          },
        -          "underlyingSymbol": {
        -            "type": "string"
        -          },
        -          "widthConstraint": {
        -            "additionalProperties": false,
        -            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -            "properties": {
        -              "minWidthDollars": {
        -                "exclusiveMinimum": 0,
        -                "type": "number"
        -              },
        -              "minWidthPercent": {
        -                "exclusiveMinimum": 0,
        -                "type": "number"
        -              }
        -            },
        -            "type": "object"
        -          }
        -        },
        -        "required": [
        -          "legs"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "const": "OpenOption",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "builder"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        -    "properties": {
        -      "allocationPolicy": {
        -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "expectedReturnShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "riskAversion": {
        -                "maximum": 1000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MeanVariance",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "riskAversion",
        -              "expectedReturnShrinkage",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "RiskParity",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumDiversification",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "exposurePolicy": {
        -        "additionalProperties": false,
        -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        -        "properties": {
        -          "covarianceShrinkage": {
        -            "maximum": 1,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "estimatedTransactionCostBps": {
        -            "maximum": 10000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "lookbackPeriods": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "minimumObservations": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "targetAnnualizedVolatilityPercent": {
        -            "maximum": 1000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "const": "VolatilityTarget",
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "lookbackPeriods",
        -          "minimumObservations",
        -          "covarianceShrinkage",
        -          "targetAnnualizedVolatilityPercent",
        -          "estimatedTransactionCostBps"
        -        ],
        -        "type": "object"
        -      },
        -      "limit": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "perNameAllocation": {
        -        "additionalProperties": true,
        -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "contracts"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "pipeline": {
        -        "items": {
        -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "condition": {
        -                  "$ref": "#/$defs/condition"
        -                },
        -                "type": {
        -                  "const": "Filter",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "condition"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "limit": {
        -                  "minimum": 1,
        -                  "type": "number"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "type": {
        -                  "const": "SelectTop",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "limit",
        -                "direction"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "percentile": {
        -                  "maximum": 100,
        -                  "minimum": 0,
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "SelectPercentile",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "percentile",
        -                "direction"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "positionScope": {
        -        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        -        "enum": [
        -          "portfolio",
        -          "strategy"
        -        ],
        -        "type": "string"
        -      },
        -      "sleeves": {
        -        "items": {
        -          "additionalProperties": true,
        -          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        -          "properties": {
        -            "limit": {
        -              "minimum": 1,
        -              "type": "number"
        -            },
        -            "name": {
        -              "type": "string"
        -            },
        -            "perNameAllocation": {
        -              "additionalProperties": true,
        -              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -              "properties": {
        -                "amount": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "dollars",
        -                    "percent of portfolio",
        -                    "percent of buying power",
        -                    "contracts"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "amount"
        -              ],
        -              "type": "object"
        -            },
        -            "pipeline": {
        -              "items": {
        -                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -                "oneOf": [
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "condition": {
        -                        "$ref": "#/$defs/condition"
        -                      },
        -                      "type": {
        -                        "const": "Filter",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "condition"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "direction": {
        -                        "enum": [
        -                          "Highest",
        -                          "Lowest"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "limit": {
        -                        "minimum": 1,
        -                        "type": "number"
        -                      },
        -                      "metric": {
        -                        "$ref": "#/$defs/indicator"
        -                      },
        -                      "type": {
        -                        "const": "SelectTop",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "metric",
        -                      "limit",
        -                      "direction"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "direction": {
        -                        "enum": [
        -                          "Highest",
        -                          "Lowest"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "metric": {
        -                        "$ref": "#/$defs/indicator"
        -                      },
        -                      "percentile": {
        -                        "maximum": 100,
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "type": {
        -                        "const": "SelectPercentile",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "metric",
        -                      "percentile",
        -                      "direction"
        -                    ],
        -                    "type": "object"
        -                  }
        -                ],
        -                "type": "object"
        -              },
        -              "type": "array"
        -            },
        -            "structureTemplates": {
        -              "items": {
        -                "additionalProperties": true,
        -                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        -                "properties": {
        -                  "eligibility": {
        -                    "$ref": "#/$defs/condition"
        -                  },
        -                  "legs": {
        -                    "items": {
        -                      "additionalProperties": true,
        -                      "description": "Single leg of an option builder.",
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "long",
        -                            "short"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "expirationRange": {
        -                          "additionalProperties": true,
        -                          "type": "object"
        -                        },
        -                        "expirationSelector": {
        -                          "properties": {
        -                            "maxDaysToExpiration": {
        -                              "minimum": 0,
        -                              "type": "number"
        -                            },
        -                            "minDaysToExpiration": {
        -                              "minimum": 0,
        -                              "type": "number"
        -                            },
        -                            "preference": {
        -                              "enum": [
        -                                "nearest",
        -                                "middle",
        -                                "furthest"
        -                              ],
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "minDaysToExpiration",
        -                            "maxDaysToExpiration",
        -                            "preference"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "fallbackStrikeSelector": {
        -                          "additionalProperties": false,
        -                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                          "properties": {
        -                            "distance": {
        -                              "type": "number"
        -                            },
        -                            "distanceType": {
        -                              "enum": [
        -                                "percent",
        -                                "dollars"
        -                              ],
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "distanceType",
        -                            "distance"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "greekFilter": {
        -                          "additionalProperties": true,
        -                          "description": "Optional min/max constraints on Greeks during resolution.",
        -                          "type": "object"
        -                        },
        -                        "liquidityFilter": {
        -                          "additionalProperties": false,
        -                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                          "properties": {
        -                            "maxSpreadAbsolute": {
        -                              "type": "number"
        -                            },
        -                            "maxSpreadPct": {
        -                              "type": "number"
        -                            },
        -                            "minBid": {
        -                              "type": "number"
        -                            }
        -                          },
        -                          "type": "object"
        -                        },
        -                        "optionType": {
        -                          "enum": [
        -                            "call",
        -                            "put"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "ratio": {
        -                          "type": "number"
        -                        },
        -                        "strikeRange": {
        -                          "additionalProperties": true,
        -                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                          "type": "object"
        -                        },
        -                        "strikeSelector": {
        -                          "properties": {
        -                            "distance": {
        -                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                              "type": "number"
        -                            },
        -                            "distanceType": {
        -                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "distanceType",
        -                            "distance"
        -                          ],
        -                          "type": "object"
        -                        }
        -                      },
        -                      "required": [
        -                        "optionType",
        -                        "direction",
        -                        "expirationSelector",
        -                        "strikeSelector"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    "minItems": 1,
        -                    "type": "array"
        -                  },
        -                  "name": {
        -                    "type": "string"
        -                  },
        -                  "spreadType": {
        -                    "enum": [
        -                      "vertical",
        -                      "calendar",
        -                      "diagonal",
        -                      "ironCondor",
        -                      "straddle",
        -                      "strangle",
        -                      "custom"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "widthConstraint": {
        -                    "additionalProperties": false,
        -                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -                    "properties": {
        -                      "minWidthDollars": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "number"
        -                      },
        -                      "minWidthPercent": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "number"
        -                      }
        -                    },
        -                    "type": "object"
        -                  }
        -                },
        -                "required": [
        -                  "legs"
        -                ],
        -                "type": "object"
        -              },
        -              "minItems": 1,
        -              "type": "array"
        -            },
        -            "universe": {
        -              "additionalProperties": true,
        -              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -              "properties": {
        -                "assets": {
        -                  "items": {
        -                    "additionalProperties": true,
        -                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -                    "properties": {
        -                      "name": {
        -                        "type": "string"
        -                      },
        -                      "symbol": {
        -                        "type": "string"
        -                      },
        -                      "type": {
        -                        "enum": [
        -                          "Stock",
        -                          "Cryptocurrency",
        -                          "Option",
        -                          "Other"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "symbol"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "type": "array"
        -                },
        -                "source": {
        -                  "enum": [
        -                    "ALL_US_STOCKS",
        -                    "SP500",
        -                    "NASDAQ100",
        -                    "DJIA",
        -                    "CRYPTO",
        -                    "SPECIFIC_ASSETS"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "source"
        -              ],
        -              "type": "object"
        -            },
        -            "weightIndicator": {
        -              "$ref": "#/$defs/indicator"
        -            }
        -          },
        -          "required": [
        -            "name"
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "structureTemplates": {
        -        "items": {
        -          "additionalProperties": true,
        -          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        -          "properties": {
        -            "eligibility": {
        -              "$ref": "#/$defs/condition"
        -            },
        -            "legs": {
        -              "items": {
        -                "additionalProperties": true,
        -                "description": "Single leg of an option builder.",
        -                "properties": {
        -                  "direction": {
        -                    "enum": [
        -                      "long",
        -                      "short"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "expirationRange": {
        -                    "additionalProperties": true,
        -                    "type": "object"
        -                  },
        -                  "expirationSelector": {
        -                    "properties": {
        -                      "maxDaysToExpiration": {
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "minDaysToExpiration": {
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "preference": {
        -                        "enum": [
        -                          "nearest",
        -                          "middle",
        -                          "furthest"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "minDaysToExpiration",
        -                      "maxDaysToExpiration",
        -                      "preference"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "fallbackStrikeSelector": {
        -                    "additionalProperties": false,
        -                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                    "properties": {
        -                      "distance": {
        -                        "type": "number"
        -                      },
        -                      "distanceType": {
        -                        "enum": [
        -                          "percent",
        -                          "dollars"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "distanceType",
        -                      "distance"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "greekFilter": {
        -                    "additionalProperties": true,
        -                    "description": "Optional min/max constraints on Greeks during resolution.",
        -                    "type": "object"
        -                  },
        -                  "liquidityFilter": {
        -                    "additionalProperties": false,
        -                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                    "properties": {
        -                      "maxSpreadAbsolute": {
        -                        "type": "number"
        -                      },
        -                      "maxSpreadPct": {
        -                        "type": "number"
        -                      },
        -                      "minBid": {
        -                        "type": "number"
        -                      }
        -                    },
        -                    "type": "object"
        -                  },
        -                  "optionType": {
        -                    "enum": [
        -                      "call",
        -                      "put"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "ratio": {
        -                    "type": "number"
        -                  },
        -                  "strikeRange": {
        -                    "additionalProperties": true,
        -                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                    "type": "object"
        -                  },
        -                  "strikeSelector": {
        -                    "properties": {
        -                      "distance": {
        -                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                        "type": "number"
        -                      },
        -                      "distanceType": {
        -                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "distanceType",
        -                      "distance"
        -                    ],
        -                    "type": "object"
        -                  }
        -                },
        -                "required": [
        -                  "optionType",
        -                  "direction",
        -                  "expirationSelector",
        -                  "strikeSelector"
        -                ],
        -                "type": "object"
        -              },
        -              "minItems": 1,
        -              "type": "array"
        -            },
        -            "name": {
        -              "type": "string"
        -            },
        -            "spreadType": {
        -              "enum": [
        -                "vertical",
        -                "calendar",
        -                "diagonal",
        -                "ironCondor",
        -                "straddle",
        -                "strangle",
        -                "custom"
        -              ],
        -              "type": "string"
        -            },
        -            "widthConstraint": {
        -              "additionalProperties": false,
        -              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -              "properties": {
        -                "minWidthDollars": {
        -                  "exclusiveMinimum": 0,
        -                  "type": "number"
        -                },
        -                "minWidthPercent": {
        -                  "exclusiveMinimum": 0,
        -                  "type": "number"
        -                }
        -              },
        -              "type": "object"
        -            }
        -          },
        -          "required": [
        -            "legs"
        -          ],
        -          "type": "object"
        -        },
        -        "minItems": 1,
        -        "type": "array"
        -      },
        -      "totalBudget": {
        -        "additionalProperties": true,
        -        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        -        "properties": {
        -          "amount": {
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "const": "RebalanceOption",
        -        "type": "string"
        -      },
        -      "universe": {
        -        "additionalProperties": true,
        -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -        "properties": {
        -          "assets": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -              "properties": {
        -                "name": {
        -                  "type": "string"
        -                },
        -                "symbol": {
        -                  "type": "string"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "Stock",
        -                    "Cryptocurrency",
        -                    "Option",
        -                    "Other"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "symbol"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "source": {
        -            "enum": [
        -              "ALL_US_STOCKS",
        -              "SP500",
        -              "NASDAQ100",
        -              "DJIA",
        -              "CRYPTO",
        -              "SPECIFIC_ASSETS"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "weightIndicator": {
        -        "$ref": "#/$defs/indicator"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "universe",
        -      "pipeline",
        -      "weightIndicator",
        -      "structureTemplates"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        -    "properties": {
        -      "closeScope": {
        -        "enum": [
        -          "spread",
        -          "leg"
        -        ],
        -        "type": "string"
        -      },
        -      "direction": {
        -        "enum": [
        -          "long",
        -          "short"
        -        ],
        -        "type": "string"
        -      },
        -      "optionType": {
        -        "enum": [
        -          "call",
        -          "put"
        -        ],
        -        "type": "string"
        -      },
        -      "quantity": {
        -        "additionalProperties": true,
        -        "description": "How many contracts to close. Defaults to all matching when omitted.",
        -        "type": "object"
        -      },
        -      "spreadType": {
        -        "enum": [
        -          "vertical",
        -          "calendar",
        -          "diagonal",
        -          "ironCondor",
        -          "straddle",
        -          "strangle",
        -          "custom"
        -        ],
        -        "type": "string"
        -      },
        -      "triggers": {
        -        "items": {
        -          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxPnlPercent": {
        -                  "type": "number"
        -                },
        -                "minPnlPercent": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "pnl",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxDte": {
        -                  "type": "number"
        -                },
        -                "minDte": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "dte",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxDaysHeld": {
        -                  "type": "number"
        -                },
        -                "minDaysHeld": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "daysHeld",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxIv": {
        -                  "type": "number"
        -                },
        -                "maxSpreadDelta": {
        -                  "type": "number"
        -                },
        -                "maxSpreadTheta": {
        -                  "type": "number"
        -                },
        -                "minIv": {
        -                  "type": "number"
        -                },
        -                "minSpreadDelta": {
        -                  "type": "number"
        -                },
        -                "minSpreadTheta": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "greeks",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "type": {
        -        "const": "CloseOption",
        -        "type": "string"
        -      },
        -      "underlyings": {
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array"
        -      }
        -    },
        -    "required": [
        -      "type"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": true,
        +    "description": "Buy or Sell a stock/crypto position.",
        +    "properties": {
        +      "amount": {
        +        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "percent of current positions",
        +              "dollars",
        +              "number of assets"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "targetAsset": {
        +        "additionalProperties": true,
        +        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +        "properties": {
        +          "name": {
        +            "type": "string"
        +          },
        +          "symbol": {
        +            "type": "string"
        +          },
        +          "type": {
        +            "enum": [
        +              "Stock",
        +              "Cryptocurrency",
        +              "Option",
        +              "Other"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "symbol"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "enum": [
        +          "Buy",
        +          "Sell"
        +        ],
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "targetAsset",
        +      "amount"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Send an alert message (no order).",
        +    "properties": {
        +      "message": {
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "Alert",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "message"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        +    "properties": {
        +      "allocationPolicy": {
        +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "expectedReturnShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "riskAversion": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MeanVariance",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "riskAversion",
        +              "expectedReturnShrinkage",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "RiskParity",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MaximumDiversification",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "canSell": {
        +        "$ref": "#/$defs/condition",
        +        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        +      },
        +      "deploymentPercent": {
        +        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        +        "maximum": 100,
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "exposurePolicy": {
        +        "additionalProperties": false,
        +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +        "properties": {
        +          "covarianceShrinkage": {
        +            "maximum": 1,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "estimatedTransactionCostBps": {
        +            "maximum": 10000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "lookbackPeriods": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "minimumObservations": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "targetAnnualizedVolatilityPercent": {
        +            "maximum": 1000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "const": "VolatilityTarget",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "lookbackPeriods",
        +          "minimumObservations",
        +          "covarianceShrinkage",
        +          "targetAnnualizedVolatilityPercent",
        +          "estimatedTransactionCostBps"
        +        ],
        +        "type": "object"
        +      },
        +      "limit": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "perNameAllocation": {
        +        "additionalProperties": true,
        +        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.",
        +        "properties": {
        +          "amount": {
        +            "exclusiveMinimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "percent of portfolio",
        +              "dollars"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "pipeline": {
        +        "items": {
        +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "condition": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "type": {
        +                  "const": "Filter",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "condition"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "type": {
        +                  "const": "SelectTop",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "limit",
        +                "direction"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "percentile": {
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "SelectPercentile",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "percentile",
        +                "direction"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "type": {
        +        "const": "DynamicRebalance",
        +        "type": "string"
        +      },
        +      "universe": {
        +        "additionalProperties": true,
        +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +        "properties": {
        +          "assets": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +              "properties": {
        +                "name": {
        +                  "type": "string"
        +                },
        +                "symbol": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Stock",
        +                    "Cryptocurrency",
        +                    "Option",
        +                    "Other"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "symbol"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "enum": [
        +              "ALL_US_STOCKS",
        +              "SP500",
        +              "NASDAQ100",
        +              "DJIA",
        +              "CRYPTO",
        +              "SPECIFIC_ASSETS"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "weightIndicator": {
        +        "$ref": "#/$defs/indicator"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "universe",
        +      "pipeline",
        +      "weightIndicator"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        +    "properties": {
        +      "continueExisting": {
        +        "type": "boolean"
        +      },
        +      "cooldownMinutes": {
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "executionModel": {
        +        "type": "string"
        +      },
        +      "includeMarketData": {
        +        "type": "boolean"
        +      },
        +      "initialMessage": {
        +        "type": "string"
        +      },
        +      "maxIterations": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "planningModel": {
        +        "type": "string"
        +      },
        +      "skipPlanning": {
        +        "type": "boolean"
        +      },
        +      "type": {
        +        "const": "LaunchAgent",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "planningModel",
        +      "executionModel",
        +      "initialMessage",
        +      "maxIterations",
        +      "includeMarketData",
        +      "continueExisting",
        +      "skipPlanning"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        +    "properties": {
        +      "against": {
        +        "additionalProperties": true,
        +        "description": "Optional parent-position selector (e.g. for covered calls).",
        +        "type": "object"
        +      },
        +      "allocation": {
        +        "additionalProperties": true,
        +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "contracts",
        +              "percent of realized premium"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "builder": {
        +        "additionalProperties": true,
        +        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        +        "properties": {
        +          "dynamicUnderlying": {
        +            "additionalProperties": true,
        +            "properties": {
        +              "limit": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "pipeline": {
        +                "items": {
        +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                  "oneOf": [
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "condition": {
        +                          "$ref": "#/$defs/condition"
        +                        },
        +                        "type": {
        +                          "const": "Filter",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "condition"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "limit": {
        +                          "minimum": 1,
        +                          "type": "number"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "type": {
        +                          "const": "SelectTop",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "limit",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "percentile": {
        +                          "maximum": 100,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "SelectPercentile",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "percentile",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "universe": {
        +                "additionalProperties": true,
        +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                "properties": {
        +                  "assets": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                      "properties": {
        +                        "name": {
        +                          "type": "string"
        +                        },
        +                        "symbol": {
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "enum": [
        +                            "Stock",
        +                            "Cryptocurrency",
        +                            "Option",
        +                            "Other"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "symbol"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "type": "array"
        +                  },
        +                  "source": {
        +                    "enum": [
        +                      "ALL_US_STOCKS",
        +                      "SP500",
        +                      "NASDAQ100",
        +                      "DJIA",
        +                      "CRYPTO",
        +                      "SPECIFIC_ASSETS"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "source"
        +                ],
        +                "type": "object"
        +              }
        +            },
        +            "required": [
        +              "universe"
        +            ],
        +            "type": "object"
        +          },
        +          "legs": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Single leg of an option builder.",
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "long",
        +                    "short"
        +                  ],
        +                  "type": "string"
        +                },
        +                "expirationRange": {
        +                  "additionalProperties": true,
        +                  "type": "object"
        +                },
        +                "expirationSelector": {
        +                  "properties": {
        +                    "maxDaysToExpiration": {
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "minDaysToExpiration": {
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "preference": {
        +                      "enum": [
        +                        "nearest",
        +                        "middle",
        +                        "furthest"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "minDaysToExpiration",
        +                    "maxDaysToExpiration",
        +                    "preference"
        +                  ],
        +                  "type": "object"
        +                },
        +                "fallbackStrikeSelector": {
        +                  "additionalProperties": false,
        +                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                  "properties": {
        +                    "distance": {
        +                      "type": "number"
        +                    },
        +                    "distanceType": {
        +                      "enum": [
        +                        "percent",
        +                        "dollars"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "distanceType",
        +                    "distance"
        +                  ],
        +                  "type": "object"
        +                },
        +                "greekFilter": {
        +                  "additionalProperties": true,
        +                  "description": "Optional min/max constraints on Greeks during resolution.",
        +                  "type": "object"
        +                },
        +                "liquidityFilter": {
        +                  "additionalProperties": false,
        +                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                  "properties": {
        +                    "maxSpreadAbsolute": {
        +                      "type": "number"
        +                    },
        +                    "maxSpreadPct": {
        +                      "type": "number"
        +                    },
        +                    "minBid": {
        +                      "type": "number"
        +                    }
        +                  },
        +                  "type": "object"
        +                },
        +                "optionType": {
        +                  "enum": [
        +                    "call",
        +                    "put"
        +                  ],
        +                  "type": "string"
        +                },
        +                "ratio": {
        +                  "type": "number"
        +                },
        +                "strikeRange": {
        +                  "additionalProperties": true,
        +                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                  "type": "object"
        +                },
        +                "strikeSelector": {
        +                  "properties": {
        +                    "distance": {
        +                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                      "type": "number"
        +                    },
        +                    "distanceType": {
        +                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "distanceType",
        +                    "distance"
        +                  ],
        +                  "type": "object"
        +                }
        +              },
        +              "required": [
        +                "optionType",
        +                "direction",
        +                "expirationSelector",
        +                "strikeSelector"
        +              ],
        +              "type": "object"
        +            },
        +            "minItems": 1,
        +            "type": "array"
        +          },
        +          "spreadType": {
        +            "enum": [
        +              "vertical",
        +              "calendar",
        +              "diagonal",
        +              "ironCondor",
        +              "straddle",
        +              "strangle",
        +              "custom"
        +            ],
        +            "type": "string"
        +          },
        +          "underlyingSymbol": {
        +            "type": "string"
        +          },
        +          "widthConstraint": {
        +            "additionalProperties": false,
        +            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +            "properties": {
        +              "minWidthDollars": {
        +                "exclusiveMinimum": 0,
        +                "type": "number"
        +              },
        +              "minWidthPercent": {
        +                "exclusiveMinimum": 0,
        +                "type": "number"
        +              }
        +            },
        +            "type": "object"
        +          }
        +        },
        +        "required": [
        +          "legs"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "const": "OpenOption",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "builder"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        +    "properties": {
        +      "allocationPolicy": {
        +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "expectedReturnShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "riskAversion": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MeanVariance",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "riskAversion",
        +              "expectedReturnShrinkage",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "RiskParity",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MaximumDiversification",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "exposurePolicy": {
        +        "additionalProperties": false,
        +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +        "properties": {
        +          "covarianceShrinkage": {
        +            "maximum": 1,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "estimatedTransactionCostBps": {
        +            "maximum": 10000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "lookbackPeriods": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "minimumObservations": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "targetAnnualizedVolatilityPercent": {
        +            "maximum": 1000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "const": "VolatilityTarget",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "lookbackPeriods",
        +          "minimumObservations",
        +          "covarianceShrinkage",
        +          "targetAnnualizedVolatilityPercent",
        +          "estimatedTransactionCostBps"
        +        ],
        +        "type": "object"
        +      },
        +      "limit": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "perNameAllocation": {
        +        "additionalProperties": true,
        +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "contracts",
        +              "percent of realized premium"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "pipeline": {
        +        "items": {
        +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "condition": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "type": {
        +                  "const": "Filter",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "condition"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "type": {
        +                  "const": "SelectTop",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "limit",
        +                "direction"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "percentile": {
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "SelectPercentile",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "percentile",
        +                "direction"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "positionScope": {
        +        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        +        "enum": [
        +          "portfolio",
        +          "strategy"
        +        ],
        +        "type": "string"
        +      },
        +      "sleeves": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        +          "properties": {
        +            "limit": {
        +              "minimum": 1,
        +              "type": "number"
        +            },
        +            "name": {
        +              "type": "string"
        +            },
        +            "perNameAllocation": {
        +              "additionalProperties": true,
        +              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +              "properties": {
        +                "amount": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "dollars",
        +                    "percent of portfolio",
        +                    "percent of buying power",
        +                    "contracts",
        +                    "percent of realized premium"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "amount"
        +              ],
        +              "type": "object"
        +            },
        +            "pipeline": {
        +              "items": {
        +                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                "oneOf": [
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "condition": {
        +                        "$ref": "#/$defs/condition"
        +                      },
        +                      "type": {
        +                        "const": "Filter",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "condition"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "direction": {
        +                        "enum": [
        +                          "Highest",
        +                          "Lowest"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "limit": {
        +                        "minimum": 1,
        +                        "type": "number"
        +                      },
        +                      "metric": {
        +                        "$ref": "#/$defs/indicator"
        +                      },
        +                      "type": {
        +                        "const": "SelectTop",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "metric",
        +                      "limit",
        +                      "direction"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "direction": {
        +                        "enum": [
        +                          "Highest",
        +                          "Lowest"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "metric": {
        +                        "$ref": "#/$defs/indicator"
        +                      },
        +                      "percentile": {
        +                        "maximum": 100,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "SelectPercentile",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "metric",
        +                      "percentile",
        +                      "direction"
        +                    ],
        +                    "type": "object"
        +                  }
        +                ],
        +                "type": "object"
        +              },
        +              "type": "array"
        +            },
        +            "structureTemplates": {
        +              "items": {
        +                "additionalProperties": true,
        +                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +                "properties": {
        +                  "eligibility": {
        +                    "$ref": "#/$defs/condition"
        +                  },
        +                  "legs": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Single leg of an option builder.",
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "long",
        +                            "short"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "expirationRange": {
        +                          "additionalProperties": true,
        +                          "type": "object"
        +                        },
        +                        "expirationSelector": {
        +                          "properties": {
        +                            "maxDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "minDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "preference": {
        +                              "enum": [
        +                                "nearest",
        +                                "middle",
        +                                "furthest"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "minDaysToExpiration",
        +                            "maxDaysToExpiration",
        +                            "preference"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "fallbackStrikeSelector": {
        +                          "additionalProperties": false,
        +                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                          "properties": {
        +                            "distance": {
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "enum": [
        +                                "percent",
        +                                "dollars"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "greekFilter": {
        +                          "additionalProperties": true,
        +                          "description": "Optional min/max constraints on Greeks during resolution.",
        +                          "type": "object"
        +                        },
        +                        "liquidityFilter": {
        +                          "additionalProperties": false,
        +                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                          "properties": {
        +                            "maxSpreadAbsolute": {
        +                              "type": "number"
        +                            },
        +                            "maxSpreadPct": {
        +                              "type": "number"
        +                            },
        +                            "minBid": {
        +                              "type": "number"
        +                            }
        +                          },
        +                          "type": "object"
        +                        },
        +                        "optionType": {
        +                          "enum": [
        +                            "call",
        +                            "put"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "ratio": {
        +                          "type": "number"
        +                        },
        +                        "strikeRange": {
        +                          "additionalProperties": true,
        +                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                          "type": "object"
        +                        },
        +                        "strikeSelector": {
        +                          "properties": {
        +                            "distance": {
        +                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        }
        +                      },
        +                      "required": [
        +                        "optionType",
        +                        "direction",
        +                        "expirationSelector",
        +                        "strikeSelector"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "minItems": 1,
        +                    "type": "array"
        +                  },
        +                  "name": {
        +                    "type": "string"
        +                  },
        +                  "spreadType": {
        +                    "enum": [
        +                      "vertical",
        +                      "calendar",
        +                      "diagonal",
        +                      "ironCondor",
        +                      "straddle",
        +                      "strangle",
        +                      "custom"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "widthConstraint": {
        +                    "additionalProperties": false,
        +                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                    "properties": {
        +                      "minWidthDollars": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minWidthPercent": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "legs"
        +                ],
        +                "type": "object"
        +              },
        +              "minItems": 1,
        +              "type": "array"
        +            },
        +            "universe": {
        +              "additionalProperties": true,
        +              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +              "properties": {
        +                "assets": {
        +                  "items": {
        +                    "additionalProperties": true,
        +                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                    "properties": {
        +                      "name": {
        +                        "type": "string"
        +                      },
        +                      "symbol": {
        +                        "type": "string"
        +                      },
        +                      "type": {
        +                        "enum": [
        +                          "Stock",
        +                          "Cryptocurrency",
        +                          "Option",
        +                          "Other"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "symbol"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "type": "array"
        +                },
        +                "source": {
        +                  "enum": [
        +                    "ALL_US_STOCKS",
        +                    "SP500",
        +                    "NASDAQ100",
        +                    "DJIA",
        +                    "CRYPTO",
        +                    "SPECIFIC_ASSETS"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "source"
        +              ],
        +              "type": "object"
        +            },
        +            "weightIndicator": {
        +              "$ref": "#/$defs/indicator"
        +            }
        +          },
        +          "required": [
        +            "name"
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "structureTemplates": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +          "properties": {
        +            "eligibility": {
        +              "$ref": "#/$defs/condition"
        +            },
        +            "legs": {
        +              "items": {
        +                "additionalProperties": true,
        +                "description": "Single leg of an option builder.",
        +                "properties": {
        +                  "direction": {
        +                    "enum": [
        +                      "long",
        +                      "short"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "expirationRange": {
        +                    "additionalProperties": true,
        +                    "type": "object"
        +                  },
        +                  "expirationSelector": {
        +                    "properties": {
        +                      "maxDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "preference": {
        +                        "enum": [
        +                          "nearest",
        +                          "middle",
        +                          "furthest"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "minDaysToExpiration",
        +                      "maxDaysToExpiration",
        +                      "preference"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "fallbackStrikeSelector": {
        +                    "additionalProperties": false,
        +                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                    "properties": {
        +                      "distance": {
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "enum": [
        +                          "percent",
        +                          "dollars"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "greekFilter": {
        +                    "additionalProperties": true,
        +                    "description": "Optional min/max constraints on Greeks during resolution.",
        +                    "type": "object"
        +                  },
        +                  "liquidityFilter": {
        +                    "additionalProperties": false,
        +                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                    "properties": {
        +                      "maxSpreadAbsolute": {
        +                        "type": "number"
        +                      },
        +                      "maxSpreadPct": {
        +                        "type": "number"
        +                      },
        +                      "minBid": {
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  },
        +                  "optionType": {
        +                    "enum": [
        +                      "call",
        +                      "put"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "ratio": {
        +                    "type": "number"
        +                  },
        +                  "strikeRange": {
        +                    "additionalProperties": true,
        +                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                    "type": "object"
        +                  },
        +                  "strikeSelector": {
        +                    "properties": {
        +                      "distance": {
        +                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "optionType",
        +                  "direction",
        +                  "expirationSelector",
        +                  "strikeSelector"
        +                ],
        +                "type": "object"
        +              },
        +              "minItems": 1,
        +              "type": "array"
        +            },
        +            "name": {
        +              "type": "string"
        +            },
        +            "spreadType": {
        +              "enum": [
        +                "vertical",
        +                "calendar",
        +                "diagonal",
        +                "ironCondor",
        +                "straddle",
        +                "strangle",
        +                "custom"
        +              ],
        +              "type": "string"
        +            },
        +            "widthConstraint": {
        +              "additionalProperties": false,
        +              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +              "properties": {
        +                "minWidthDollars": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                },
        +                "minWidthPercent": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                }
        +              },
        +              "type": "object"
        +            }
        +          },
        +          "required": [
        +            "legs"
        +          ],
        +          "type": "object"
        +        },
        +        "minItems": 1,
        +        "type": "array"
        +      },
        +      "totalBudget": {
        +        "additionalProperties": true,
        +        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        +        "properties": {
        +          "amount": {
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "const": "RebalanceOption",
        +        "type": "string"
        +      },
        +      "universe": {
        +        "additionalProperties": true,
        +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +        "properties": {
        +          "assets": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +              "properties": {
        +                "name": {
        +                  "type": "string"
        +                },
        +                "symbol": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Stock",
        +                    "Cryptocurrency",
        +                    "Option",
        +                    "Other"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "symbol"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "enum": [
        +              "ALL_US_STOCKS",
        +              "SP500",
        +              "NASDAQ100",
        +              "DJIA",
        +              "CRYPTO",
        +              "SPECIFIC_ASSETS"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "weightIndicator": {
        +        "$ref": "#/$defs/indicator"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "universe",
        +      "pipeline",
        +      "weightIndicator",
        +      "structureTemplates"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        +    "properties": {
        +      "closeScope": {
        +        "enum": [
        +          "spread",
        +          "leg"
        +        ],
        +        "type": "string"
        +      },
        +      "direction": {
        +        "enum": [
        +          "long",
        +          "short"
        +        ],
        +        "type": "string"
        +      },
        +      "optionType": {
        +        "enum": [
        +          "call",
        +          "put"
        +        ],
        +        "type": "string"
        +      },
        +      "quantity": {
        +        "additionalProperties": true,
        +        "description": "How many contracts to close. Defaults to all matching when omitted.",
        +        "type": "object"
        +      },
        +      "spreadType": {
        +        "enum": [
        +          "vertical",
        +          "calendar",
        +          "diagonal",
        +          "ironCondor",
        +          "straddle",
        +          "strangle",
        +          "custom"
        +        ],
        +        "type": "string"
        +      },
        +      "triggers": {
        +        "items": {
        +          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxPnlPercent": {
        +                  "type": "number"
        +                },
        +                "minPnlPercent": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "pnl",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxDte": {
        +                  "type": "number"
        +                },
        +                "minDte": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "dte",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxDaysHeld": {
        +                  "type": "number"
        +                },
        +                "minDaysHeld": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "daysHeld",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxIv": {
        +                  "type": "number"
        +                },
        +                "maxSpreadDelta": {
        +                  "type": "number"
        +                },
        +                "maxSpreadTheta": {
        +                  "type": "number"
        +                },
        +                "minIv": {
        +                  "type": "number"
        +                },
        +                "minSpreadDelta": {
        +                  "type": "number"
        +                },
        +                "minSpreadTheta": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "greeks",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "type": {
        +        "const": "CloseOption",
        +        "type": "string"
        +      },
        +      "underlyings": {
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  }
        +]
      • changedInput schema / $defs / indicator / description
        Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), Option* indicators (need underlying + optionType + direction + spreadType), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), OptionPositionValue/OptionPositionCount/OptionPositionPercentChange/OptionPositionMaxDrawdown/OptionDaysToExpiration/OptionDaysHeld/OptionCollateral/OptionSpreadCount/OptionUnrealizedPnL (optional underlying + optionType + direction + spreadType filters), OptionRealizedPnL (net realized P&L on CLOSED option positions; the same optional underlying/optionType/direction/spreadType filters + optional lookbackDays), OptionRealizedPremium (realized premium still available to spend: closed short-option P&L minus premium already spent by 'percent of realized premium' opens; optional underlying + optional lookbackDays ONLY, and it rejects optionType/direction/spreadType), OptionGrossExposurePercent (no fields), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
      • addedInput schema / $defs / indicator / properties / lookbackDays
        Added value: +{
        +  "description": "OptionRealizedPnL / OptionRealizedPremium: only count activity within this many days of the evaluation date. Omit for the whole life of the book.",
        +  "maximum": 36500,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • changedInput schema / $defs / indicator / properties / type / enum
        Previous value: -[
        -  "DaysSinceAgent",
        -  "MinutesSinceAgent",
        -  "DaysSinceAlert",
        -  "MinutesSinceAlert",
        -  "StockReport",
        -  "DaysUntilEarnings",
        -  "DaysSinceEarnings",
        -  "ImpliedVolatility",
        -  "IVRank",
        -  "IVPercentile",
        -  "IVHVRatio",
        -  "LastOrderPrice",
        -  "Fundamental",
        -  "Economic",
        -  "CustomIndicator",
        -  "Index",
        -  "BollingerBand",
        -  "RelativeStrengthIndex",
        -  "PriceMeanAbsoluteDeviation",
        -  "ExponentialMovingAverage",
        -  "SimpleMovingAverage",
        -  "PriceStandardDeviation",
        -  "PriceRateOfChange",
        -  "MaxDrawdown",
        -  "MaxDrawup",
        -  "MinimumPrice",
        -  "MaximumPrice",
        -  "IndicatorMeanAbsoluteDeviation",
        -  "IndicatorExponentialMovingAverage",
        -  "IndicatorSimpleMovingAverage",
        -  "IndicatorStandardDeviation",
        -  "IndicatorRateOfChange",
        -  "DaysSinceOrder",
        -  "DaysSinceOptionOrder",
        -  "DaysSinceStrategyFired",
        -  "DaysSinceLastRebalanceOptionOrder",
        -  "MinutesSinceOptionOrder",
        -  "MinutesSinceOrder",
        -  "DaysSinceTransaction",
        -  "InitialValue",
        -  "BuyingPower",
        -  "PositionValue",
        -  "PositionPercentChange",
        -  "PortfolioValue",
        -  "RebalanceDecisionMetric",
        -  "Value",
        -  "Price",
        -  "Plus",
        -  "Minus",
        -  "Multiply",
        -  "Divide",
        -  "Negative",
        -  "AbsoluteValue",
        -  "SquareRoot",
        -  "Max",
        -  "Min",
        -  "Day",
        -  "Month",
        -  "Date",
        -  "Year",
        -  "CurrentTimeSeconds",
        -  "CurrentTimeMinutes",
        -  "CurrentTimeHours",
        -  "TrailingSum",
        -  "CompoundAnnualGrowthRate",
        -  "Log",
        -  "Exponentiation",
        -  "SumOrderQuantity",
        -  "SumOrderAmount",
        -  "MinutesAfterOpen",
        -  "OpeningPrice",
        -  "PreviousClosingPrice",
        -  "HighOfDay",
        -  "LowOfDay",
        -  "MinutesUntilClose",
        -  "PriceChangeSinceOpen",
        -  "GapSize",
        -  "GapPercentage",
        -  "TrueRange",
        -  "AverageTrueRange",
        -  "Volume",
        -  "VWAP",
        -  "BullishFairValueGap",
        -  "BearishFairValueGap",
        -  "IndicatorAtMinutesAfterOpen",
        -  "IndicatorWindowAgo",
        -  "IndicatorAtEntry",
        -  "IsIndexMember",
        -  "IsIndustry",
        -  "IsAssetType",
        -  "IsAsset",
        -  "IsNotAsset",
        -  "CrossAbove",
        -  "CrossBelow",
        -  "PositionMaxDrawdown",
        -  "PositionMaxDrawup",
        -  "UnderlyingMaxDrawdown",
        -  "ConsecutiveTrue",
        -  "CountTrue",
        -  "OptionPositionValue",
        -  "OptionPositionCount",
        -  "OptionPositionPercentChange",
        -  "OptionPositionMaxDrawdown",
        -  "OptionDaysToExpiration",
        -  "OptionDaysHeld",
        -  "OptionCollateral",
        -  "OptionSpreadCount",
        -  "OptionUnrealizedPnL",
        -  "OptionGrossExposurePercent"
        -]New value: +[
        +  "DaysSinceAgent",
        +  "MinutesSinceAgent",
        +  "DaysSinceAlert",
        +  "MinutesSinceAlert",
        +  "StockReport",
        +  "DaysUntilEarnings",
        +  "DaysSinceEarnings",
        +  "ImpliedVolatility",
        +  "IVRank",
        +  "IVPercentile",
        +  "IVHVRatio",
        +  "LastOrderPrice",
        +  "Fundamental",
        +  "Economic",
        +  "CustomIndicator",
        +  "Index",
        +  "BollingerBand",
        +  "RelativeStrengthIndex",
        +  "PriceMeanAbsoluteDeviation",
        +  "ExponentialMovingAverage",
        +  "SimpleMovingAverage",
        +  "PriceStandardDeviation",
        +  "PriceRateOfChange",
        +  "MaxDrawdown",
        +  "MaxDrawup",
        +  "MinimumPrice",
        +  "MaximumPrice",
        +  "IndicatorMeanAbsoluteDeviation",
        +  "IndicatorExponentialMovingAverage",
        +  "IndicatorSimpleMovingAverage",
        +  "IndicatorStandardDeviation",
        +  "IndicatorRateOfChange",
        +  "DaysSinceOrder",
        +  "DaysSinceOptionOrder",
        +  "DaysSinceStrategyFired",
        +  "DaysSinceLastRebalanceOptionOrder",
        +  "MinutesSinceOptionOrder",
        +  "MinutesSinceOrder",
        +  "DaysSinceTransaction",
        +  "InitialValue",
        +  "BuyingPower",
        +  "PositionValue",
        +  "PositionPercentChange",
        +  "PortfolioValue",
        +  "RebalanceDecisionMetric",
        +  "Value",
        +  "Price",
        +  "Plus",
        +  "Minus",
        +  "Multiply",
        +  "Divide",
        +  "Negative",
        +  "AbsoluteValue",
        +  "SquareRoot",
        +  "Max",
        +  "Min",
        +  "Day",
        +  "Month",
        +  "Date",
        +  "Year",
        +  "CurrentTimeSeconds",
        +  "CurrentTimeMinutes",
        +  "CurrentTimeHours",
        +  "TrailingSum",
        +  "CompoundAnnualGrowthRate",
        +  "Log",
        +  "Exponentiation",
        +  "SumOrderQuantity",
        +  "SumOrderAmount",
        +  "MinutesAfterOpen",
        +  "OpeningPrice",
        +  "PreviousClosingPrice",
        +  "HighOfDay",
        +  "LowOfDay",
        +  "MinutesUntilClose",
        +  "PriceChangeSinceOpen",
        +  "GapSize",
        +  "GapPercentage",
        +  "TrueRange",
        +  "AverageTrueRange",
        +  "Volume",
        +  "VWAP",
        +  "BullishFairValueGap",
        +  "BearishFairValueGap",
        +  "IndicatorAtMinutesAfterOpen",
        +  "IndicatorWindowAgo",
        +  "IndicatorAtEntry",
        +  "IsIndexMember",
        +  "IsIndustry",
        +  "IsAssetType",
        +  "IsAsset",
        +  "IsNotAsset",
        +  "CrossAbove",
        +  "CrossBelow",
        +  "PositionMaxDrawdown",
        +  "PositionMaxDrawup",
        +  "UnderlyingMaxDrawdown",
        +  "ConsecutiveTrue",
        +  "CountTrue",
        +  "OptionPositionValue",
        +  "OptionPositionCount",
        +  "OptionPositionPercentChange",
        +  "OptionPositionMaxDrawdown",
        +  "OptionDaysToExpiration",
        +  "OptionDaysHeld",
        +  "OptionCollateral",
        +  "OptionSpreadCount",
        +  "OptionUnrealizedPnL",
        +  "OptionRealizedPnL",
        +  "OptionRealizedPremium",
        +  "OptionGrossExposurePercent"
        +]
      • changedInput schema / $defs / rebalanceOptionSleeve / properties / perNameAllocation / description
        Previous value: -"Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'."New value: +"Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'."
      • changedInput schema / $defs / rebalanceOptionSleeve / properties / perNameAllocation / properties / type / enum
        Previous value: -[
        -  "dollars",
        -  "percent of portfolio",
        -  "percent of buying power",
        -  "contracts"
        -]New value: +[
        +  "dollars",
        +  "percent of portfolio",
        +  "percent of buying power",
        +  "contracts",
        +  "percent of realized premium"
        +]
      • changedInput schema / $defs / strategy / properties / action / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "description": "Buy or Sell a stock/crypto position.",
        -    "properties": {
        -      "amount": {
        -        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "percent of current positions",
        -              "dollars",
        -              "number of assets"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "targetAsset": {
        -        "additionalProperties": true,
        -        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -        "properties": {
        -          "name": {
        -            "type": "string"
        -          },
        -          "symbol": {
        -            "type": "string"
        -          },
        -          "type": {
        -            "enum": [
        -              "Stock",
        -              "Cryptocurrency",
        -              "Option",
        -              "Other"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "symbol"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "enum": [
        -          "Buy",
        -          "Sell"
        -        ],
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "targetAsset",
        -      "amount"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Send an alert message (no order).",
        -    "properties": {
        -      "message": {
        -        "type": "string"
        -      },
        -      "type": {
        -        "const": "Alert",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "message"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        -    "properties": {
        -      "allocationPolicy": {
        -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "expectedReturnShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "riskAversion": {
        -                "maximum": 1000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MeanVariance",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "riskAversion",
        -              "expectedReturnShrinkage",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "RiskParity",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumDiversification",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "canSell": {
        -        "$ref": "#/$defs/condition",
        -        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        -      },
        -      "deploymentPercent": {
        -        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        -        "maximum": 100,
        -        "minimum": 0,
        -        "type": "number"
        -      },
        -      "exposurePolicy": {
        -        "additionalProperties": false,
        -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        -        "properties": {
        -          "covarianceShrinkage": {
        -            "maximum": 1,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "estimatedTransactionCostBps": {
        -            "maximum": 10000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "lookbackPeriods": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "minimumObservations": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "targetAnnualizedVolatilityPercent": {
        -            "maximum": 1000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "const": "VolatilityTarget",
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "lookbackPeriods",
        -          "minimumObservations",
        -          "covarianceShrinkage",
        -          "targetAnnualizedVolatilityPercent",
        -          "estimatedTransactionCostBps"
        -        ],
        -        "type": "object"
        -      },
        -      "limit": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "perNameAllocation": {
        -        "additionalProperties": true,
        -        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
        -        "properties": {
        -          "amount": {
        -            "exclusiveMinimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "percent of portfolio",
        -              "dollars"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "pipeline": {
        -        "items": {
        -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "condition": {
        -                  "$ref": "#/$defs/condition"
        -                },
        -                "type": {
        -                  "const": "Filter",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "condition"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "limit": {
        -                  "minimum": 1,
        -                  "type": "number"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "type": {
        -                  "const": "SelectTop",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "limit",
        -                "direction"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "percentile": {
        -                  "maximum": 100,
        -                  "minimum": 0,
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "SelectPercentile",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "percentile",
        -                "direction"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "type": {
        -        "const": "DynamicRebalance",
        -        "type": "string"
        -      },
        -      "universe": {
        -        "additionalProperties": true,
        -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -        "properties": {
        -          "assets": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -              "properties": {
        -                "name": {
        -                  "type": "string"
        -                },
        -                "symbol": {
        -                  "type": "string"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "Stock",
        -                    "Cryptocurrency",
        -                    "Option",
        -                    "Other"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "symbol"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "source": {
        -            "enum": [
        -              "ALL_US_STOCKS",
        -              "SP500",
        -              "NASDAQ100",
        -              "DJIA",
        -              "CRYPTO",
        -              "SPECIFIC_ASSETS"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "weightIndicator": {
        -        "$ref": "#/$defs/indicator"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "universe",
        -      "pipeline",
        -      "weightIndicator"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        -    "properties": {
        -      "continueExisting": {
        -        "type": "boolean"
        -      },
        -      "cooldownMinutes": {
        -        "minimum": 0,
        -        "type": "number"
        -      },
        -      "executionModel": {
        -        "type": "string"
        -      },
        -      "includeMarketData": {
        -        "type": "boolean"
        -      },
        -      "initialMessage": {
        -        "type": "string"
        -      },
        -      "maxIterations": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "planningModel": {
        -        "type": "string"
        -      },
        -      "skipPlanning": {
        -        "type": "boolean"
        -      },
        -      "type": {
        -        "const": "LaunchAgent",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "planningModel",
        -      "executionModel",
        -      "initialMessage",
        -      "maxIterations",
        -      "includeMarketData",
        -      "continueExisting",
        -      "skipPlanning"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        -    "properties": {
        -      "against": {
        -        "additionalProperties": true,
        -        "description": "Optional parent-position selector (e.g. for covered calls).",
        -        "type": "object"
        -      },
        -      "allocation": {
        -        "additionalProperties": true,
        -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "contracts"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "builder": {
        -        "additionalProperties": true,
        -        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        -        "properties": {
        -          "dynamicUnderlying": {
        -            "additionalProperties": true,
        -            "properties": {
        -              "limit": {
        -                "minimum": 1,
        -                "type": "number"
        -              },
        -              "pipeline": {
        -                "items": {
        -                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -                  "oneOf": [
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "condition": {
        -                          "$ref": "#/$defs/condition"
        -                        },
        -                        "type": {
        -                          "const": "Filter",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "condition"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "Highest",
        -                            "Lowest"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "limit": {
        -                          "minimum": 1,
        -                          "type": "number"
        -                        },
        -                        "metric": {
        -                          "$ref": "#/$defs/indicator"
        -                        },
        -                        "type": {
        -                          "const": "SelectTop",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "metric",
        -                        "limit",
        -                        "direction"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "Highest",
        -                            "Lowest"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "metric": {
        -                          "$ref": "#/$defs/indicator"
        -                        },
        -                        "percentile": {
        -                          "maximum": 100,
        -                          "minimum": 0,
        -                          "type": "number"
        -                        },
        -                        "type": {
        -                          "const": "SelectPercentile",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "metric",
        -                        "percentile",
        -                        "direction"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ],
        -                  "type": "object"
        -                },
        -                "type": "array"
        -              },
        -              "universe": {
        -                "additionalProperties": true,
        -                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -                "properties": {
        -                  "assets": {
        -                    "items": {
        -                      "additionalProperties": true,
        -                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -                      "properties": {
        -                        "name": {
        -                          "type": "string"
        -                        },
        -                        "symbol": {
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "enum": [
        -                            "Stock",
        -                            "Cryptocurrency",
        -                            "Option",
        -                            "Other"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "symbol"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    "type": "array"
        -                  },
        -                  "source": {
        -                    "enum": [
        -                      "ALL_US_STOCKS",
        -                      "SP500",
        -                      "NASDAQ100",
        -                      "DJIA",
        -                      "CRYPTO",
        -                      "SPECIFIC_ASSETS"
        -                    ],
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "source"
        -                ],
        -                "type": "object"
        -              }
        -            },
        -            "required": [
        -              "universe"
        -            ],
        -            "type": "object"
        -          },
        -          "legs": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Single leg of an option builder.",
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "long",
        -                    "short"
        -                  ],
        -                  "type": "string"
        -                },
        -                "expirationRange": {
        -                  "additionalProperties": true,
        -                  "type": "object"
        -                },
        -                "expirationSelector": {
        -                  "properties": {
        -                    "maxDaysToExpiration": {
        -                      "minimum": 0,
        -                      "type": "number"
        -                    },
        -                    "minDaysToExpiration": {
        -                      "minimum": 0,
        -                      "type": "number"
        -                    },
        -                    "preference": {
        -                      "enum": [
        -                        "nearest",
        -                        "middle",
        -                        "furthest"
        -                      ],
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "minDaysToExpiration",
        -                    "maxDaysToExpiration",
        -                    "preference"
        -                  ],
        -                  "type": "object"
        -                },
        -                "fallbackStrikeSelector": {
        -                  "additionalProperties": false,
        -                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                  "properties": {
        -                    "distance": {
        -                      "type": "number"
        -                    },
        -                    "distanceType": {
        -                      "enum": [
        -                        "percent",
        -                        "dollars"
        -                      ],
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "distanceType",
        -                    "distance"
        -                  ],
        -                  "type": "object"
        -                },
        -                "greekFilter": {
        -                  "additionalProperties": true,
        -                  "description": "Optional min/max constraints on Greeks during resolution.",
        -                  "type": "object"
        -                },
        -                "liquidityFilter": {
        -                  "additionalProperties": false,
        -                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                  "properties": {
        -                    "maxSpreadAbsolute": {
        -                      "type": "number"
        -                    },
        -                    "maxSpreadPct": {
        -                      "type": "number"
        -                    },
        -                    "minBid": {
        -                      "type": "number"
        -                    }
        -                  },
        -                  "type": "object"
        -                },
        -                "optionType": {
        -                  "enum": [
        -                    "call",
        -                    "put"
        -                  ],
        -                  "type": "string"
        -                },
        -                "ratio": {
        -                  "type": "number"
        -                },
        -                "strikeRange": {
        -                  "additionalProperties": true,
        -                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                  "type": "object"
        -                },
        -                "strikeSelector": {
        -                  "properties": {
        -                    "distance": {
        -                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                      "type": "number"
        -                    },
        -                    "distanceType": {
        -                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "distanceType",
        -                    "distance"
        -                  ],
        -                  "type": "object"
        -                }
        -              },
        -              "required": [
        -                "optionType",
        -                "direction",
        -                "expirationSelector",
        -                "strikeSelector"
        -              ],
        -              "type": "object"
        -            },
        -            "minItems": 1,
        -            "type": "array"
        -          },
        -          "spreadType": {
        -            "enum": [
        -              "vertical",
        -              "calendar",
        -              "diagonal",
        -              "ironCondor",
        -              "straddle",
        -              "strangle",
        -              "custom"
        -            ],
        -            "type": "string"
        -          },
        -          "underlyingSymbol": {
        -            "type": "string"
        -          },
        -          "widthConstraint": {
        -            "additionalProperties": false,
        -            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -            "properties": {
        -              "minWidthDollars": {
        -                "exclusiveMinimum": 0,
        -                "type": "number"
        -              },
        -              "minWidthPercent": {
        -                "exclusiveMinimum": 0,
        -                "type": "number"
        -              }
        -            },
        -            "type": "object"
        -          }
        -        },
        -        "required": [
        -          "legs"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "const": "OpenOption",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "builder"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        -    "properties": {
        -      "allocationPolicy": {
        -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "expectedReturnShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "riskAversion": {
        -                "maximum": 1000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MeanVariance",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "riskAversion",
        -              "expectedReturnShrinkage",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "RiskParity",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumDiversification",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "exposurePolicy": {
        -        "additionalProperties": false,
        -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        -        "properties": {
        -          "covarianceShrinkage": {
        -            "maximum": 1,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "estimatedTransactionCostBps": {
        -            "maximum": 10000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "lookbackPeriods": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "minimumObservations": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "targetAnnualizedVolatilityPercent": {
        -            "maximum": 1000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "const": "VolatilityTarget",
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "lookbackPeriods",
        -          "minimumObservations",
        -          "covarianceShrinkage",
        -          "targetAnnualizedVolatilityPercent",
        -          "estimatedTransactionCostBps"
        -        ],
        -        "type": "object"
        -      },
        -      "limit": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "perNameAllocation": {
        -        "additionalProperties": true,
        -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "contracts"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "pipeline": {
        -        "items": {
        -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "condition": {
        -                  "$ref": "#/$defs/condition"
        -                },
        -                "type": {
        -                  "const": "Filter",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "condition"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "limit": {
        -                  "minimum": 1,
        -                  "type": "number"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "type": {
        -                  "const": "SelectTop",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "limit",
        -                "direction"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "percentile": {
        -                  "maximum": 100,
        -                  "minimum": 0,
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "SelectPercentile",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "percentile",
        -                "direction"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "positionScope": {
        -        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        -        "enum": [
        -          "portfolio",
        -          "strategy"
        -        ],
        -        "type": "string"
        -      },
        -      "sleeves": {
        -        "items": {
        -          "additionalProperties": true,
        -          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        -          "properties": {
        -            "limit": {
        -              "minimum": 1,
        -              "type": "number"
        -            },
        -            "name": {
        -              "type": "string"
        -            },
        -            "perNameAllocation": {
        -              "additionalProperties": true,
        -              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -              "properties": {
        -                "amount": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "dollars",
        -                    "percent of portfolio",
        -                    "percent of buying power",
        -                    "contracts"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "amount"
        -              ],
        -              "type": "object"
        -            },
        -            "pipeline": {
        -              "items": {
        -                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -                "oneOf": [
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "condition": {
        -                        "$ref": "#/$defs/condition"
        -                      },
        -                      "type": {
        -                        "const": "Filter",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "condition"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "direction": {
        -                        "enum": [
        -                          "Highest",
        -                          "Lowest"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "limit": {
        -                        "minimum": 1,
        -                        "type": "number"
        -                      },
        -                      "metric": {
        -                        "$ref": "#/$defs/indicator"
        -                      },
        -                      "type": {
        -                        "const": "SelectTop",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "metric",
        -                      "limit",
        -                      "direction"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "direction": {
        -                        "enum": [
        -                          "Highest",
        -                          "Lowest"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "metric": {
        -                        "$ref": "#/$defs/indicator"
        -                      },
        -                      "percentile": {
        -                        "maximum": 100,
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "type": {
        -                        "const": "SelectPercentile",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "metric",
        -                      "percentile",
        -                      "direction"
        -                    ],
        -                    "type": "object"
        -                  }
        -                ],
        -                "type": "object"
        -              },
        -              "type": "array"
        -            },
        -            "structureTemplates": {
        -              "items": {
        -                "additionalProperties": true,
        -                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        -                "properties": {
        -                  "eligibility": {
        -                    "$ref": "#/$defs/condition"
        -                  },
        -                  "legs": {
        -                    "items": {
        -                      "additionalProperties": true,
        -                      "description": "Single leg of an option builder.",
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "long",
        -                            "short"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "expirationRange": {
        -                          "additionalProperties": true,
        -                          "type": "object"
        -                        },
        -                        "expirationSelector": {
        -                          "properties": {
        -                            "maxDaysToExpiration": {
        -                              "minimum": 0,
        -                              "type": "number"
        -                            },
        -                            "minDaysToExpiration": {
        -                              "minimum": 0,
        -                              "type": "number"
        -                            },
        -                            "preference": {
        -                              "enum": [
        -                                "nearest",
        -                                "middle",
        -                                "furthest"
        -                              ],
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "minDaysToExpiration",
        -                            "maxDaysToExpiration",
        -                            "preference"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "fallbackStrikeSelector": {
        -                          "additionalProperties": false,
        -                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                          "properties": {
        -                            "distance": {
        -                              "type": "number"
        -                            },
        -                            "distanceType": {
        -                              "enum": [
        -                                "percent",
        -                                "dollars"
        -                              ],
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "distanceType",
        -                            "distance"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "greekFilter": {
        -                          "additionalProperties": true,
        -                          "description": "Optional min/max constraints on Greeks during resolution.",
        -                          "type": "object"
        -                        },
        -                        "liquidityFilter": {
        -                          "additionalProperties": false,
        -                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                          "properties": {
        -                            "maxSpreadAbsolute": {
        -                              "type": "number"
        -                            },
        -                            "maxSpreadPct": {
        -                              "type": "number"
        -                            },
        -                            "minBid": {
        -                              "type": "number"
        -                            }
        -                          },
        -                          "type": "object"
        -                        },
        -                        "optionType": {
        -                          "enum": [
        -                            "call",
        -                            "put"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "ratio": {
        -                          "type": "number"
        -                        },
        -                        "strikeRange": {
        -                          "additionalProperties": true,
        -                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                          "type": "object"
        -                        },
        -                        "strikeSelector": {
        -                          "properties": {
        -                            "distance": {
        -                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                              "type": "number"
        -                            },
        -                            "distanceType": {
        -                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "distanceType",
        -                            "distance"
        -                          ],
        -                          "type": "object"
        -                        }
        -                      },
        -                      "required": [
        -                        "optionType",
        -                        "direction",
        -                        "expirationSelector",
        -                        "strikeSelector"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    "minItems": 1,
        -                    "type": "array"
        -                  },
        -                  "name": {
        -                    "type": "string"
        -                  },
        -                  "spreadType": {
        -                    "enum": [
        -                      "vertical",
        -                      "calendar",
        -                      "diagonal",
        -                      "ironCondor",
        -                      "straddle",
        -                      "strangle",
        -                      "custom"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "widthConstraint": {
        -                    "additionalProperties": false,
        -                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -                    "properties": {
        -                      "minWidthDollars": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "number"
        -                      },
        -                      "minWidthPercent": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "number"
        -                      }
        -                    },
        -                    "type": "object"
        -                  }
        -                },
        -                "required": [
        -                  "legs"
        -                ],
        -                "type": "object"
        -              },
        -              "minItems": 1,
        -              "type": "array"
        -            },
        -            "universe": {
        -              "additionalProperties": true,
        -              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -              "properties": {
        -                "assets": {
        -                  "items": {
        -                    "additionalProperties": true,
        -                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -                    "properties": {
        -                      "name": {
        -                        "type": "string"
        -                      },
        -                      "symbol": {
        -                        "type": "string"
        -                      },
        -                      "type": {
        -                        "enum": [
        -                          "Stock",
        -                          "Cryptocurrency",
        -                          "Option",
        -                          "Other"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "symbol"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "type": "array"
        -                },
        -                "source": {
        -                  "enum": [
        -                    "ALL_US_STOCKS",
        -                    "SP500",
        -                    "NASDAQ100",
        -                    "DJIA",
        -                    "CRYPTO",
        -                    "SPECIFIC_ASSETS"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "source"
        -              ],
        -              "type": "object"
        -            },
        -            "weightIndicator": {
        -              "$ref": "#/$defs/indicator"
        -            }
        -          },
        -          "required": [
        -            "name"
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "structureTemplates": {
        -        "items": {
        -          "additionalProperties": true,
        -          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        -          "properties": {
        -            "eligibility": {
        -              "$ref": "#/$defs/condition"
        -            },
        -            "legs": {
        -              "items": {
        -                "additionalProperties": true,
        -                "description": "Single leg of an option builder.",
        -                "properties": {
        -                  "direction": {
        -                    "enum": [
        -                      "long",
        -                      "short"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "expirationRange": {
        -                    "additionalProperties": true,
        -                    "type": "object"
        -                  },
        -                  "expirationSelector": {
        -                    "properties": {
        -                      "maxDaysToExpiration": {
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "minDaysToExpiration": {
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "preference": {
        -                        "enum": [
        -                          "nearest",
        -                          "middle",
        -                          "furthest"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "minDaysToExpiration",
        -                      "maxDaysToExpiration",
        -                      "preference"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "fallbackStrikeSelector": {
        -                    "additionalProperties": false,
        -                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                    "properties": {
        -                      "distance": {
        -                        "type": "number"
        -                      },
        -                      "distanceType": {
        -                        "enum": [
        -                          "percent",
        -                          "dollars"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "distanceType",
        -                      "distance"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "greekFilter": {
        -                    "additionalProperties": true,
        -                    "description": "Optional min/max constraints on Greeks during resolution.",
        -                    "type": "object"
        -                  },
        -                  "liquidityFilter": {
        -                    "additionalProperties": false,
        -                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                    "properties": {
        -                      "maxSpreadAbsolute": {
        -                        "type": "number"
        -                      },
        -                      "maxSpreadPct": {
        -                        "type": "number"
        -                      },
        -                      "minBid": {
        -                        "type": "number"
        -                      }
        -                    },
        -                    "type": "object"
        -                  },
        -                  "optionType": {
        -                    "enum": [
        -                      "call",
        -                      "put"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "ratio": {
        -                    "type": "number"
        -                  },
        -                  "strikeRange": {
        -                    "additionalProperties": true,
        -                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                    "type": "object"
        -                  },
        -                  "strikeSelector": {
        -                    "properties": {
        -                      "distance": {
        -                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                        "type": "number"
        -                      },
        -                      "distanceType": {
        -                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "distanceType",
        -                      "distance"
        -                    ],
        -                    "type": "object"
        -                  }
        -                },
        -                "required": [
        -                  "optionType",
        -                  "direction",
        -                  "expirationSelector",
        -                  "strikeSelector"
        -                ],
        -                "type": "object"
        -              },
        -              "minItems": 1,
        -              "type": "array"
        -            },
        -            "name": {
        -              "type": "string"
        -            },
        -            "spreadType": {
        -              "enum": [
        -                "vertical",
        -                "calendar",
        -                "diagonal",
        -                "ironCondor",
        -                "straddle",
        -                "strangle",
        -                "custom"
        -              ],
        -              "type": "string"
        -            },
        -            "widthConstraint": {
        -              "additionalProperties": false,
        -              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -              "properties": {
        -                "minWidthDollars": {
        -                  "exclusiveMinimum": 0,
        -                  "type": "number"
        -                },
        -                "minWidthPercent": {
        -                  "exclusiveMinimum": 0,
        -                  "type": "number"
        -                }
        -              },
        -              "type": "object"
        -            }
        -          },
        -          "required": [
        -            "legs"
        -          ],
        -          "type": "object"
        -        },
        -        "minItems": 1,
        -        "type": "array"
        -      },
        -      "totalBudget": {
        -        "additionalProperties": true,
        -        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        -        "properties": {
        -          "amount": {
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "const": "RebalanceOption",
        -        "type": "string"
        -      },
        -      "universe": {
        -        "additionalProperties": true,
        -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -        "properties": {
        -          "assets": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -              "properties": {
        -                "name": {
        -                  "type": "string"
        -                },
        -                "symbol": {
        -                  "type": "string"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "Stock",
        -                    "Cryptocurrency",
        -                    "Option",
        -                    "Other"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "symbol"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "source": {
        -            "enum": [
        -              "ALL_US_STOCKS",
        -              "SP500",
        -              "NASDAQ100",
        -              "DJIA",
        -              "CRYPTO",
        -              "SPECIFIC_ASSETS"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "weightIndicator": {
        -        "$ref": "#/$defs/indicator"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "universe",
        -      "pipeline",
        -      "weightIndicator",
        -      "structureTemplates"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        -    "properties": {
        -      "closeScope": {
        -        "enum": [
        -          "spread",
        -          "leg"
        -        ],
        -        "type": "string"
        -      },
        -      "direction": {
        -        "enum": [
        -          "long",
        -          "short"
        -        ],
        -        "type": "string"
        -      },
        -      "optionType": {
        -        "enum": [
        -          "call",
        -          "put"
        -        ],
        -        "type": "string"
        -      },
        -      "quantity": {
        -        "additionalProperties": true,
        -        "description": "How many contracts to close. Defaults to all matching when omitted.",
        -        "type": "object"
        -      },
        -      "spreadType": {
        -        "enum": [
        -          "vertical",
        -          "calendar",
        -          "diagonal",
        -          "ironCondor",
        -          "straddle",
        -          "strangle",
        -          "custom"
        -        ],
        -        "type": "string"
        -      },
        -      "triggers": {
        -        "items": {
        -          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxPnlPercent": {
        -                  "type": "number"
        -                },
        -                "minPnlPercent": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "pnl",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxDte": {
        -                  "type": "number"
        -                },
        -                "minDte": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "dte",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxDaysHeld": {
        -                  "type": "number"
        -                },
        -                "minDaysHeld": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "daysHeld",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxIv": {
        -                  "type": "number"
        -                },
        -                "maxSpreadDelta": {
        -                  "type": "number"
        -                },
        -                "maxSpreadTheta": {
        -                  "type": "number"
        -                },
        -                "minIv": {
        -                  "type": "number"
        -                },
        -                "minSpreadDelta": {
        -                  "type": "number"
        -                },
        -                "minSpreadTheta": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "greeks",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "type": {
        -        "const": "CloseOption",
        -        "type": "string"
        -      },
        -      "underlyings": {
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array"
        -      }
        -    },
        -    "required": [
        -      "type"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": true,
        +    "description": "Buy or Sell a stock/crypto position.",
        +    "properties": {
        +      "amount": {
        +        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "percent of current positions",
        +              "dollars",
        +              "number of assets"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "targetAsset": {
        +        "additionalProperties": true,
        +        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +        "properties": {
        +          "name": {
        +            "type": "string"
        +          },
        +          "symbol": {
        +            "type": "string"
        +          },
        +          "type": {
        +            "enum": [
        +              "Stock",
        +              "Cryptocurrency",
        +              "Option",
        +              "Other"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "symbol"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "enum": [
        +          "Buy",
        +          "Sell"
        +        ],
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "targetAsset",
        +      "amount"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Send an alert message (no order).",
        +    "properties": {
        +      "message": {
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "Alert",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "message"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        +    "properties": {
        +      "allocationPolicy": {
        +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "expectedReturnShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "riskAversion": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MeanVariance",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "riskAversion",
        +              "expectedReturnShrinkage",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "RiskParity",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MaximumDiversification",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "canSell": {
        +        "$ref": "#/$defs/condition",
        +        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        +      },
        +      "deploymentPercent": {
        +        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        +        "maximum": 100,
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "exposurePolicy": {
        +        "additionalProperties": false,
        +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +        "properties": {
        +          "covarianceShrinkage": {
        +            "maximum": 1,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "estimatedTransactionCostBps": {
        +            "maximum": 10000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "lookbackPeriods": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "minimumObservations": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "targetAnnualizedVolatilityPercent": {
        +            "maximum": 1000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "const": "VolatilityTarget",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "lookbackPeriods",
        +          "minimumObservations",
        +          "covarianceShrinkage",
        +          "targetAnnualizedVolatilityPercent",
        +          "estimatedTransactionCostBps"
        +        ],
        +        "type": "object"
        +      },
        +      "limit": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "perNameAllocation": {
        +        "additionalProperties": true,
        +        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.",
        +        "properties": {
        +          "amount": {
        +            "exclusiveMinimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "percent of portfolio",
        +              "dollars"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "pipeline": {
        +        "items": {
        +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "condition": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "type": {
        +                  "const": "Filter",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "condition"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "type": {
        +                  "const": "SelectTop",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "limit",
        +                "direction"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "percentile": {
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "SelectPercentile",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "percentile",
        +                "direction"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "type": {
        +        "const": "DynamicRebalance",
        +        "type": "string"
        +      },
        +      "universe": {
        +        "additionalProperties": true,
        +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +        "properties": {
        +          "assets": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +              "properties": {
        +                "name": {
        +                  "type": "string"
        +                },
        +                "symbol": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Stock",
        +                    "Cryptocurrency",
        +                    "Option",
        +                    "Other"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "symbol"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "enum": [
        +              "ALL_US_STOCKS",
        +              "SP500",
        +              "NASDAQ100",
        +              "DJIA",
        +              "CRYPTO",
        +              "SPECIFIC_ASSETS"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "weightIndicator": {
        +        "$ref": "#/$defs/indicator"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "universe",
        +      "pipeline",
        +      "weightIndicator"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        +    "properties": {
        +      "continueExisting": {
        +        "type": "boolean"
        +      },
        +      "cooldownMinutes": {
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "executionModel": {
        +        "type": "string"
        +      },
        +      "includeMarketData": {
        +        "type": "boolean"
        +      },
        +      "initialMessage": {
        +        "type": "string"
        +      },
        +      "maxIterations": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "planningModel": {
        +        "type": "string"
        +      },
        +      "skipPlanning": {
        +        "type": "boolean"
        +      },
        +      "type": {
        +        "const": "LaunchAgent",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "planningModel",
        +      "executionModel",
        +      "initialMessage",
        +      "maxIterations",
        +      "includeMarketData",
        +      "continueExisting",
        +      "skipPlanning"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        +    "properties": {
        +      "against": {
        +        "additionalProperties": true,
        +        "description": "Optional parent-position selector (e.g. for covered calls).",
        +        "type": "object"
        +      },
        +      "allocation": {
        +        "additionalProperties": true,
        +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "contracts",
        +              "percent of realized premium"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "builder": {
        +        "additionalProperties": true,
        +        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        +        "properties": {
        +          "dynamicUnderlying": {
        +            "additionalProperties": true,
        +            "properties": {
        +              "limit": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "pipeline": {
        +                "items": {
        +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                  "oneOf": [
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "condition": {
        +                          "$ref": "#/$defs/condition"
        +                        },
        +                        "type": {
        +                          "const": "Filter",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "condition"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "limit": {
        +                          "minimum": 1,
        +                          "type": "number"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "type": {
        +                          "const": "SelectTop",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "limit",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "percentile": {
        +                          "maximum": 100,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "SelectPercentile",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "percentile",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "universe": {
        +                "additionalProperties": true,
        +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                "properties": {
        +                  "assets": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                      "properties": {
        +                        "name": {
        +                          "type": "string"
        +                        },
        +                        "symbol": {
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "enum": [
        +                            "Stock",
        +                            "Cryptocurrency",
        +                            "Option",
        +                            "Other"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "symbol"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "type": "array"
        +                  },
        +                  "source": {
        +                    "enum": [
        +                      "ALL_US_STOCKS",
        +                      "SP500",
        +                      "NASDAQ100",
        +                      "DJIA",
        +                      "CRYPTO",
        +                      "SPECIFIC_ASSETS"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "source"
        +                ],
        +                "type": "object"
        +              }
        +            },
        +            "required": [
        +              "universe"
        +            ],
        +            "type": "object"
        +          },
        +          "legs": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Single leg of an option builder.",
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "long",
        +                    "short"
        +                  ],
        +                  "type": "string"
        +                },
        +                "expirationRange": {
        +                  "additionalProperties": true,
        +                  "type": "object"
        +                },
        +                "expirationSelector": {
        +                  "properties": {
        +                    "maxDaysToExpiration": {
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "minDaysToExpiration": {
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "preference": {
        +                      "enum": [
        +                        "nearest",
        +                        "middle",
        +                        "furthest"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "minDaysToExpiration",
        +                    "maxDaysToExpiration",
        +                    "preference"
        +                  ],
        +                  "type": "object"
        +                },
        +                "fallbackStrikeSelector": {
        +                  "additionalProperties": false,
        +                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                  "properties": {
        +                    "distance": {
        +                      "type": "number"
        +                    },
        +                    "distanceType": {
        +                      "enum": [
        +                        "percent",
        +                        "dollars"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "distanceType",
        +                    "distance"
        +                  ],
        +                  "type": "object"
        +                },
        +                "greekFilter": {
        +                  "additionalProperties": true,
        +                  "description": "Optional min/max constraints on Greeks during resolution.",
        +                  "type": "object"
        +                },
        +                "liquidityFilter": {
        +                  "additionalProperties": false,
        +                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                  "properties": {
        +                    "maxSpreadAbsolute": {
        +                      "type": "number"
        +                    },
        +                    "maxSpreadPct": {
        +                      "type": "number"
        +                    },
        +                    "minBid": {
        +                      "type": "number"
        +                    }
        +                  },
        +                  "type": "object"
        +                },
        +                "optionType": {
        +                  "enum": [
        +                    "call",
        +                    "put"
        +                  ],
        +                  "type": "string"
        +                },
        +                "ratio": {
        +                  "type": "number"
        +                },
        +                "strikeRange": {
        +                  "additionalProperties": true,
        +                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                  "type": "object"
        +                },
        +                "strikeSelector": {
        +                  "properties": {
        +                    "distance": {
        +                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                      "type": "number"
        +                    },
        +                    "distanceType": {
        +                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "distanceType",
        +                    "distance"
        +                  ],
        +                  "type": "object"
        +                }
        +              },
        +              "required": [
        +                "optionType",
        +                "direction",
        +                "expirationSelector",
        +                "strikeSelector"
        +              ],
        +              "type": "object"
        +            },
        +            "minItems": 1,
        +            "type": "array"
        +          },
        +          "spreadType": {
        +            "enum": [
        +              "vertical",
        +              "calendar",
        +              "diagonal",
        +              "ironCondor",
        +              "straddle",
        +              "strangle",
        +              "custom"
        +            ],
        +            "type": "string"
        +          },
        +          "underlyingSymbol": {
        +            "type": "string"
        +          },
        +          "widthConstraint": {
        +            "additionalProperties": false,
        +            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +            "properties": {
        +              "minWidthDollars": {
        +                "exclusiveMinimum": 0,
        +                "type": "number"
        +              },
        +              "minWidthPercent": {
        +                "exclusiveMinimum": 0,
        +                "type": "number"
        +              }
        +            },
        +            "type": "object"
        +          }
        +        },
        +        "required": [
        +          "legs"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "const": "OpenOption",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "builder"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        +    "properties": {
        +      "allocationPolicy": {
        +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "expectedReturnShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "riskAversion": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MeanVariance",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "riskAversion",
        +              "expectedReturnShrinkage",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "RiskParity",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MaximumDiversification",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "exposurePolicy": {
        +        "additionalProperties": false,
        +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +        "properties": {
        +          "covarianceShrinkage": {
        +            "maximum": 1,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "estimatedTransactionCostBps": {
        +            "maximum": 10000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "lookbackPeriods": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "minimumObservations": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "targetAnnualizedVolatilityPercent": {
        +            "maximum": 1000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "const": "VolatilityTarget",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "lookbackPeriods",
        +          "minimumObservations",
        +          "covarianceShrinkage",
        +          "targetAnnualizedVolatilityPercent",
        +          "estimatedTransactionCostBps"
        +        ],
        +        "type": "object"
        +      },
        +      "limit": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "perNameAllocation": {
        +        "additionalProperties": true,
        +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "contracts",
        +              "percent of realized premium"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "pipeline": {
        +        "items": {
        +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "condition": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "type": {
        +                  "const": "Filter",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "condition"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "type": {
        +                  "const": "SelectTop",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "limit",
        +                "direction"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "percentile": {
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "SelectPercentile",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "percentile",
        +                "direction"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "positionScope": {
        +        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        +        "enum": [
        +          "portfolio",
        +          "strategy"
        +        ],
        +        "type": "string"
        +      },
        +      "sleeves": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        +          "properties": {
        +            "limit": {
        +              "minimum": 1,
        +              "type": "number"
        +            },
        +            "name": {
        +              "type": "string"
        +            },
        +            "perNameAllocation": {
        +              "additionalProperties": true,
        +              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +              "properties": {
        +                "amount": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "dollars",
        +                    "percent of portfolio",
        +                    "percent of buying power",
        +                    "contracts",
        +                    "percent of realized premium"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "amount"
        +              ],
        +              "type": "object"
        +            },
        +            "pipeline": {
        +              "items": {
        +                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                "oneOf": [
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "condition": {
        +                        "$ref": "#/$defs/condition"
        +                      },
        +                      "type": {
        +                        "const": "Filter",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "condition"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "direction": {
        +                        "enum": [
        +                          "Highest",
        +                          "Lowest"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "limit": {
        +                        "minimum": 1,
        +                        "type": "number"
        +                      },
        +                      "metric": {
        +                        "$ref": "#/$defs/indicator"
        +                      },
        +                      "type": {
        +                        "const": "SelectTop",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "metric",
        +                      "limit",
        +                      "direction"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "direction": {
        +                        "enum": [
        +                          "Highest",
        +                          "Lowest"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "metric": {
        +                        "$ref": "#/$defs/indicator"
        +                      },
        +                      "percentile": {
        +                        "maximum": 100,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "SelectPercentile",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "metric",
        +                      "percentile",
        +                      "direction"
        +                    ],
        +                    "type": "object"
        +                  }
        +                ],
        +                "type": "object"
        +              },
        +              "type": "array"
        +            },
        +            "structureTemplates": {
        +              "items": {
        +                "additionalProperties": true,
        +                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +                "properties": {
        +                  "eligibility": {
        +                    "$ref": "#/$defs/condition"
        +                  },
        +                  "legs": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Single leg of an option builder.",
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "long",
        +                            "short"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "expirationRange": {
        +                          "additionalProperties": true,
        +                          "type": "object"
        +                        },
        +                        "expirationSelector": {
        +                          "properties": {
        +                            "maxDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "minDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "preference": {
        +                              "enum": [
        +                                "nearest",
        +                                "middle",
        +                                "furthest"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "minDaysToExpiration",
        +                            "maxDaysToExpiration",
        +                            "preference"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "fallbackStrikeSelector": {
        +                          "additionalProperties": false,
        +                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                          "properties": {
        +                            "distance": {
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "enum": [
        +                                "percent",
        +                                "dollars"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "greekFilter": {
        +                          "additionalProperties": true,
        +                          "description": "Optional min/max constraints on Greeks during resolution.",
        +                          "type": "object"
        +                        },
        +                        "liquidityFilter": {
        +                          "additionalProperties": false,
        +                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                          "properties": {
        +                            "maxSpreadAbsolute": {
        +                              "type": "number"
        +                            },
        +                            "maxSpreadPct": {
        +                              "type": "number"
        +                            },
        +                            "minBid": {
        +                              "type": "number"
        +                            }
        +                          },
        +                          "type": "object"
        +                        },
        +                        "optionType": {
        +                          "enum": [
        +                            "call",
        +                            "put"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "ratio": {
        +                          "type": "number"
        +                        },
        +                        "strikeRange": {
        +                          "additionalProperties": true,
        +                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                          "type": "object"
        +                        },
        +                        "strikeSelector": {
        +                          "properties": {
        +                            "distance": {
        +                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        }
        +                      },
        +                      "required": [
        +                        "optionType",
        +                        "direction",
        +                        "expirationSelector",
        +                        "strikeSelector"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "minItems": 1,
        +                    "type": "array"
        +                  },
        +                  "name": {
        +                    "type": "string"
        +                  },
        +                  "spreadType": {
        +                    "enum": [
        +                      "vertical",
        +                      "calendar",
        +                      "diagonal",
        +                      "ironCondor",
        +                      "straddle",
        +                      "strangle",
        +                      "custom"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "widthConstraint": {
        +                    "additionalProperties": false,
        +                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                    "properties": {
        +                      "minWidthDollars": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minWidthPercent": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "legs"
        +                ],
        +                "type": "object"
        +              },
        +              "minItems": 1,
        +              "type": "array"
        +            },
        +            "universe": {
        +              "additionalProperties": true,
        +              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +              "properties": {
        +                "assets": {
        +                  "items": {
        +                    "additionalProperties": true,
        +                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                    "properties": {
        +                      "name": {
        +                        "type": "string"
        +                      },
        +                      "symbol": {
        +                        "type": "string"
        +                      },
        +                      "type": {
        +                        "enum": [
        +                          "Stock",
        +                          "Cryptocurrency",
        +                          "Option",
        +                          "Other"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "symbol"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "type": "array"
        +                },
        +                "source": {
        +                  "enum": [
        +                    "ALL_US_STOCKS",
        +                    "SP500",
        +                    "NASDAQ100",
        +                    "DJIA",
        +                    "CRYPTO",
        +                    "SPECIFIC_ASSETS"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "source"
        +              ],
        +              "type": "object"
        +            },
        +            "weightIndicator": {
        +              "$ref": "#/$defs/indicator"
        +            }
        +          },
        +          "required": [
        +            "name"
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "structureTemplates": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +          "properties": {
        +            "eligibility": {
        +              "$ref": "#/$defs/condition"
        +            },
        +            "legs": {
        +              "items": {
        +                "additionalProperties": true,
        +                "description": "Single leg of an option builder.",
        +                "properties": {
        +                  "direction": {
        +                    "enum": [
        +                      "long",
        +                      "short"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "expirationRange": {
        +                    "additionalProperties": true,
        +                    "type": "object"
        +                  },
        +                  "expirationSelector": {
        +                    "properties": {
        +                      "maxDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "preference": {
        +                        "enum": [
        +                          "nearest",
        +                          "middle",
        +                          "furthest"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "minDaysToExpiration",
        +                      "maxDaysToExpiration",
        +                      "preference"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "fallbackStrikeSelector": {
        +                    "additionalProperties": false,
        +                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                    "properties": {
        +                      "distance": {
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "enum": [
        +                          "percent",
        +                          "dollars"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "greekFilter": {
        +                    "additionalProperties": true,
        +                    "description": "Optional min/max constraints on Greeks during resolution.",
        +                    "type": "object"
        +                  },
        +                  "liquidityFilter": {
        +                    "additionalProperties": false,
        +                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                    "properties": {
        +                      "maxSpreadAbsolute": {
        +                        "type": "number"
        +                      },
        +                      "maxSpreadPct": {
        +                        "type": "number"
        +                      },
        +                      "minBid": {
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  },
        +                  "optionType": {
        +                    "enum": [
        +                      "call",
        +                      "put"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "ratio": {
        +                    "type": "number"
        +                  },
        +                  "strikeRange": {
        +                    "additionalProperties": true,
        +                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                    "type": "object"
        +                  },
        +                  "strikeSelector": {
        +                    "properties": {
        +                      "distance": {
        +                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "optionType",
        +                  "direction",
        +                  "expirationSelector",
        +                  "strikeSelector"
        +                ],
        +                "type": "object"
        +              },
        +              "minItems": 1,
        +              "type": "array"
        +            },
        +            "name": {
        +              "type": "string"
        +            },
        +            "spreadType": {
        +              "enum": [
        +                "vertical",
        +                "calendar",
        +                "diagonal",
        +                "ironCondor",
        +                "straddle",
        +                "strangle",
        +                "custom"
        +              ],
        +              "type": "string"
        +            },
        +            "widthConstraint": {
        +              "additionalProperties": false,
        +              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +              "properties": {
        +                "minWidthDollars": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                },
        +                "minWidthPercent": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                }
        +              },
        +              "type": "object"
        +            }
        +          },
        +          "required": [
        +            "legs"
        +          ],
        +          "type": "object"
        +        },
        +        "minItems": 1,
        +        "type": "array"
        +      },
        +      "totalBudget": {
        +        "additionalProperties": true,
        +        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        +        "properties": {
        +          "amount": {
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "const": "RebalanceOption",
        +        "type": "string"
        +      },
        +      "universe": {
        +        "additionalProperties": true,
        +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +        "properties": {
        +          "assets": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +              "properties": {
        +                "name": {
        +                  "type": "string"
        +                },
        +                "symbol": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Stock",
        +                    "Cryptocurrency",
        +                    "Option",
        +                    "Other"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "symbol"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "enum": [
        +              "ALL_US_STOCKS",
        +              "SP500",
        +              "NASDAQ100",
        +              "DJIA",
        +              "CRYPTO",
        +              "SPECIFIC_ASSETS"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "weightIndicator": {
        +        "$ref": "#/$defs/indicator"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "universe",
        +      "pipeline",
        +      "weightIndicator",
        +      "structureTemplates"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        +    "properties": {
        +      "closeScope": {
        +        "enum": [
        +          "spread",
        +          "leg"
        +        ],
        +        "type": "string"
        +      },
        +      "direction": {
        +        "enum": [
        +          "long",
        +          "short"
        +        ],
        +        "type": "string"
        +      },
        +      "optionType": {
        +        "enum": [
        +          "call",
        +          "put"
        +        ],
        +        "type": "string"
        +      },
        +      "quantity": {
        +        "additionalProperties": true,
        +        "description": "How many contracts to close. Defaults to all matching when omitted.",
        +        "type": "object"
        +      },
        +      "spreadType": {
        +        "enum": [
        +          "vertical",
        +          "calendar",
        +          "diagonal",
        +          "ironCondor",
        +          "straddle",
        +          "strangle",
        +          "custom"
        +        ],
        +        "type": "string"
        +      },
        +      "triggers": {
        +        "items": {
        +          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxPnlPercent": {
        +                  "type": "number"
        +                },
        +                "minPnlPercent": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "pnl",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxDte": {
        +                  "type": "number"
        +                },
        +                "minDte": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "dte",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxDaysHeld": {
        +                  "type": "number"
        +                },
        +                "minDaysHeld": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "daysHeld",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxIv": {
        +                  "type": "number"
        +                },
        +                "maxSpreadDelta": {
        +                  "type": "number"
        +                },
        +                "maxSpreadTheta": {
        +                  "type": "number"
        +                },
        +                "minIv": {
        +                  "type": "number"
        +                },
        +                "minSpreadDelta": {
        +                  "type": "number"
        +                },
        +                "minSpreadTheta": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "greeks",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "type": {
        +        "const": "CloseOption",
        +        "type": "string"
        +      },
        +      "underlyings": {
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  }
        +]
      • changedInput schema / properties / operations / items / properties / strategyObject / properties / action / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "description": "Buy or Sell a stock/crypto position.",
        -    "properties": {
        -      "amount": {
        -        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "percent of current positions",
        -              "dollars",
        -              "number of assets"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "targetAsset": {
        -        "additionalProperties": true,
        -        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -        "properties": {
        -          "name": {
        -            "type": "string"
        -          },
        -          "symbol": {
        -            "type": "string"
        -          },
        -          "type": {
        -            "enum": [
        -              "Stock",
        -              "Cryptocurrency",
        -              "Option",
        -              "Other"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "symbol"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "enum": [
        -          "Buy",
        -          "Sell"
        -        ],
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "targetAsset",
        -      "amount"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Send an alert message (no order).",
        -    "properties": {
        -      "message": {
        -        "type": "string"
        -      },
        -      "type": {
        -        "const": "Alert",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "message"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        -    "properties": {
        -      "allocationPolicy": {
        -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "expectedReturnShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "riskAversion": {
        -                "maximum": 1000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MeanVariance",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "riskAversion",
        -              "expectedReturnShrinkage",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "RiskParity",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumDiversification",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "canSell": {
        -        "$ref": "#/$defs/condition",
        -        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        -      },
        -      "deploymentPercent": {
        -        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        -        "maximum": 100,
        -        "minimum": 0,
        -        "type": "number"
        -      },
        -      "exposurePolicy": {
        -        "additionalProperties": false,
        -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        -        "properties": {
        -          "covarianceShrinkage": {
        -            "maximum": 1,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "estimatedTransactionCostBps": {
        -            "maximum": 10000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "lookbackPeriods": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "minimumObservations": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "targetAnnualizedVolatilityPercent": {
        -            "maximum": 1000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "const": "VolatilityTarget",
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "lookbackPeriods",
        -          "minimumObservations",
        -          "covarianceShrinkage",
        -          "targetAnnualizedVolatilityPercent",
        -          "estimatedTransactionCostBps"
        -        ],
        -        "type": "object"
        -      },
        -      "limit": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "perNameAllocation": {
        -        "additionalProperties": true,
        -        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
        -        "properties": {
        -          "amount": {
        -            "exclusiveMinimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "percent of portfolio",
        -              "dollars"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "pipeline": {
        -        "items": {
        -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "condition": {
        -                  "$ref": "#/$defs/condition"
        -                },
        -                "type": {
        -                  "const": "Filter",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "condition"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "limit": {
        -                  "minimum": 1,
        -                  "type": "number"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "type": {
        -                  "const": "SelectTop",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "limit",
        -                "direction"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "percentile": {
        -                  "maximum": 100,
        -                  "minimum": 0,
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "SelectPercentile",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "percentile",
        -                "direction"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "type": {
        -        "const": "DynamicRebalance",
        -        "type": "string"
        -      },
        -      "universe": {
        -        "additionalProperties": true,
        -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -        "properties": {
        -          "assets": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -              "properties": {
        -                "name": {
        -                  "type": "string"
        -                },
        -                "symbol": {
        -                  "type": "string"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "Stock",
        -                    "Cryptocurrency",
        -                    "Option",
        -                    "Other"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "symbol"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "source": {
        -            "enum": [
        -              "ALL_US_STOCKS",
        -              "SP500",
        -              "NASDAQ100",
        -              "DJIA",
        -              "CRYPTO",
        -              "SPECIFIC_ASSETS"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "weightIndicator": {
        -        "$ref": "#/$defs/indicator"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "universe",
        -      "pipeline",
        -      "weightIndicator"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        -    "properties": {
        -      "continueExisting": {
        -        "type": "boolean"
        -      },
        -      "cooldownMinutes": {
        -        "minimum": 0,
        -        "type": "number"
        -      },
        -      "executionModel": {
        -        "type": "string"
        -      },
        -      "includeMarketData": {
        -        "type": "boolean"
        -      },
        -      "initialMessage": {
        -        "type": "string"
        -      },
        -      "maxIterations": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "planningModel": {
        -        "type": "string"
        -      },
        -      "skipPlanning": {
        -        "type": "boolean"
        -      },
        -      "type": {
        -        "const": "LaunchAgent",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "planningModel",
        -      "executionModel",
        -      "initialMessage",
        -      "maxIterations",
        -      "includeMarketData",
        -      "continueExisting",
        -      "skipPlanning"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        -    "properties": {
        -      "against": {
        -        "additionalProperties": true,
        -        "description": "Optional parent-position selector (e.g. for covered calls).",
        -        "type": "object"
        -      },
        -      "allocation": {
        -        "additionalProperties": true,
        -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "contracts"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "builder": {
        -        "additionalProperties": true,
        -        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        -        "properties": {
        -          "dynamicUnderlying": {
        -            "additionalProperties": true,
        -            "properties": {
        -              "limit": {
        -                "minimum": 1,
        -                "type": "number"
        -              },
        -              "pipeline": {
        -                "items": {
        -                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -                  "oneOf": [
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "condition": {
        -                          "$ref": "#/$defs/condition"
        -                        },
        -                        "type": {
        -                          "const": "Filter",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "condition"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "Highest",
        -                            "Lowest"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "limit": {
        -                          "minimum": 1,
        -                          "type": "number"
        -                        },
        -                        "metric": {
        -                          "$ref": "#/$defs/indicator"
        -                        },
        -                        "type": {
        -                          "const": "SelectTop",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "metric",
        -                        "limit",
        -                        "direction"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "Highest",
        -                            "Lowest"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "metric": {
        -                          "$ref": "#/$defs/indicator"
        -                        },
        -                        "percentile": {
        -                          "maximum": 100,
        -                          "minimum": 0,
        -                          "type": "number"
        -                        },
        -                        "type": {
        -                          "const": "SelectPercentile",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "metric",
        -                        "percentile",
        -                        "direction"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ],
        -                  "type": "object"
        -                },
        -                "type": "array"
        -              },
        -              "universe": {
        -                "additionalProperties": true,
        -                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -                "properties": {
        -                  "assets": {
        -                    "items": {
        -                      "additionalProperties": true,
        -                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -                      "properties": {
        -                        "name": {
        -                          "type": "string"
        -                        },
        -                        "symbol": {
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "enum": [
        -                            "Stock",
        -                            "Cryptocurrency",
        -                            "Option",
        -                            "Other"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "symbol"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    "type": "array"
        -                  },
        -                  "source": {
        -                    "enum": [
        -                      "ALL_US_STOCKS",
        -                      "SP500",
        -                      "NASDAQ100",
        -                      "DJIA",
        -                      "CRYPTO",
        -                      "SPECIFIC_ASSETS"
        -                    ],
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "source"
        -                ],
        -                "type": "object"
        -              }
        -            },
        -            "required": [
        -              "universe"
        -            ],
        -            "type": "object"
        -          },
        -          "legs": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Single leg of an option builder.",
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "long",
        -                    "short"
        -                  ],
        -                  "type": "string"
        -                },
        -                "expirationRange": {
        -                  "additionalProperties": true,
        -                  "type": "object"
        -                },
        -                "expirationSelector": {
        -                  "properties": {
        -                    "maxDaysToExpiration": {
        -                      "minimum": 0,
        -                      "type": "number"
        -                    },
        -                    "minDaysToExpiration": {
        -                      "minimum": 0,
        -                      "type": "number"
        -                    },
        -                    "preference": {
        -                      "enum": [
        -                        "nearest",
        -                        "middle",
        -                        "furthest"
        -                      ],
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "minDaysToExpiration",
        -                    "maxDaysToExpiration",
        -                    "preference"
        -                  ],
        -                  "type": "object"
        -                },
        -                "fallbackStrikeSelector": {
        -                  "additionalProperties": false,
        -                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                  "properties": {
        -                    "distance": {
        -                      "type": "number"
        -                    },
        -                    "distanceType": {
        -                      "enum": [
        -                        "percent",
        -                        "dollars"
        -                      ],
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "distanceType",
        -                    "distance"
        -                  ],
        -                  "type": "object"
        -                },
        -                "greekFilter": {
        -                  "additionalProperties": true,
        -                  "description": "Optional min/max constraints on Greeks during resolution.",
        -                  "type": "object"
        -                },
        -                "liquidityFilter": {
        -                  "additionalProperties": false,
        -                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                  "properties": {
        -                    "maxSpreadAbsolute": {
        -                      "type": "number"
        -                    },
        -                    "maxSpreadPct": {
        -                      "type": "number"
        -                    },
        -                    "minBid": {
        -                      "type": "number"
        -                    }
        -                  },
        -                  "type": "object"
        -                },
        -                "optionType": {
        -                  "enum": [
        -                    "call",
        -                    "put"
        -                  ],
        -                  "type": "string"
        -                },
        -                "ratio": {
        -                  "type": "number"
        -                },
        -                "strikeRange": {
        -                  "additionalProperties": true,
        -                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                  "type": "object"
        -                },
        -                "strikeSelector": {
        -                  "properties": {
        -                    "distance": {
        -                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                      "type": "number"
        -                    },
        -                    "distanceType": {
        -                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "distanceType",
        -                    "distance"
        -                  ],
        -                  "type": "object"
        -                }
        -              },
        -              "required": [
        -                "optionType",
        -                "direction",
        -                "expirationSelector",
        -                "strikeSelector"
        -              ],
        -              "type": "object"
        -            },
        -            "minItems": 1,
        -            "type": "array"
        -          },
        -          "spreadType": {
        -            "enum": [
        -              "vertical",
        -              "calendar",
        -              "diagonal",
        -              "ironCondor",
        -              "straddle",
        -              "strangle",
        -              "custom"
        -            ],
        -            "type": "string"
        -          },
        -          "underlyingSymbol": {
        -            "type": "string"
        -          },
        -          "widthConstraint": {
        -            "additionalProperties": false,
        -            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -            "properties": {
        -              "minWidthDollars": {
        -                "exclusiveMinimum": 0,
        -                "type": "number"
        -              },
        -              "minWidthPercent": {
        -                "exclusiveMinimum": 0,
        -                "type": "number"
        -              }
        -            },
        -            "type": "object"
        -          }
        -        },
        -        "required": [
        -          "legs"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "const": "OpenOption",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "builder"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        -    "properties": {
        -      "allocationPolicy": {
        -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "expectedReturnShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "riskAversion": {
        -                "maximum": 1000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MeanVariance",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "riskAversion",
        -              "expectedReturnShrinkage",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "RiskParity",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumDiversification",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "exposurePolicy": {
        -        "additionalProperties": false,
        -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        -        "properties": {
        -          "covarianceShrinkage": {
        -            "maximum": 1,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "estimatedTransactionCostBps": {
        -            "maximum": 10000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "lookbackPeriods": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "minimumObservations": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "targetAnnualizedVolatilityPercent": {
        -            "maximum": 1000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "const": "VolatilityTarget",
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "lookbackPeriods",
        -          "minimumObservations",
        -          "covarianceShrinkage",
        -          "targetAnnualizedVolatilityPercent",
        -          "estimatedTransactionCostBps"
        -        ],
        -        "type": "object"
        -      },
        -      "limit": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "perNameAllocation": {
        -        "additionalProperties": true,
        -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "contracts"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "pipeline": {
        -        "items": {
        -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "condition": {
        -                  "$ref": "#/$defs/condition"
        -                },
        -                "type": {
        -                  "const": "Filter",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "condition"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "limit": {
        -                  "minimum": 1,
        -                  "type": "number"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "type": {
        -                  "const": "SelectTop",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "limit",
        -                "direction"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "percentile": {
        -                  "maximum": 100,
        -                  "minimum": 0,
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "SelectPercentile",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "percentile",
        -                "direction"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "positionScope": {
        -        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        -        "enum": [
        -          "portfolio",
        -          "strategy"
        -        ],
        -        "type": "string"
        -      },
        -      "sleeves": {
        -        "items": {
        -          "additionalProperties": true,
        -          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        -          "properties": {
        -            "limit": {
        -              "minimum": 1,
        -              "type": "number"
        -            },
        -            "name": {
        -              "type": "string"
        -            },
        -            "perNameAllocation": {
        -              "additionalProperties": true,
        -              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -              "properties": {
        -                "amount": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "dollars",
        -                    "percent of portfolio",
        -                    "percent of buying power",
        -                    "contracts"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "amount"
        -              ],
        -              "type": "object"
        -            },
        -            "pipeline": {
        -              "items": {
        -                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -                "oneOf": [
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "condition": {
        -                        "$ref": "#/$defs/condition"
        -                      },
        -                      "type": {
        -                        "const": "Filter",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "condition"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "direction": {
        -                        "enum": [
        -                          "Highest",
        -                          "Lowest"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "limit": {
        -                        "minimum": 1,
        -                        "type": "number"
        -                      },
        -                      "metric": {
        -                        "$ref": "#/$defs/indicator"
        -                      },
        -                      "type": {
        -                        "const": "SelectTop",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "metric",
        -                      "limit",
        -                      "direction"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "direction": {
        -                        "enum": [
        -                          "Highest",
        -                          "Lowest"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "metric": {
        -                        "$ref": "#/$defs/indicator"
        -                      },
        -                      "percentile": {
        -                        "maximum": 100,
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "type": {
        -                        "const": "SelectPercentile",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "metric",
        -                      "percentile",
        -                      "direction"
        -                    ],
        -                    "type": "object"
        -                  }
        -                ],
        -                "type": "object"
        -              },
        -              "type": "array"
        -            },
        -            "structureTemplates": {
        -              "items": {
        -                "additionalProperties": true,
        -                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        -                "properties": {
        -                  "eligibility": {
        -                    "$ref": "#/$defs/condition"
        -                  },
        -                  "legs": {
        -                    "items": {
        -                      "additionalProperties": true,
        -                      "description": "Single leg of an option builder.",
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "long",
        -                            "short"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "expirationRange": {
        -                          "additionalProperties": true,
        -                          "type": "object"
        -                        },
        -                        "expirationSelector": {
        -                          "properties": {
        -                            "maxDaysToExpiration": {
        -                              "minimum": 0,
        -                              "type": "number"
        -                            },
        -                            "minDaysToExpiration": {
        -                              "minimum": 0,
        -                              "type": "number"
        -                            },
        -                            "preference": {
        -                              "enum": [
        -                                "nearest",
        -                                "middle",
        -                                "furthest"
        -                              ],
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "minDaysToExpiration",
        -                            "maxDaysToExpiration",
        -                            "preference"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "fallbackStrikeSelector": {
        -                          "additionalProperties": false,
        -                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                          "properties": {
        -                            "distance": {
        -                              "type": "number"
        -                            },
        -                            "distanceType": {
        -                              "enum": [
        -                                "percent",
        -                                "dollars"
        -                              ],
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "distanceType",
        -                            "distance"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "greekFilter": {
        -                          "additionalProperties": true,
        -                          "description": "Optional min/max constraints on Greeks during resolution.",
        -                          "type": "object"
        -                        },
        -                        "liquidityFilter": {
        -                          "additionalProperties": false,
        -                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                          "properties": {
        -                            "maxSpreadAbsolute": {
        -                              "type": "number"
        -                            },
        -                            "maxSpreadPct": {
        -                              "type": "number"
        -                            },
        -                            "minBid": {
        -                              "type": "number"
        -                            }
        -                          },
        -                          "type": "object"
        -                        },
        -                        "optionType": {
        -                          "enum": [
        -                            "call",
        -                            "put"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "ratio": {
        -                          "type": "number"
        -                        },
        -                        "strikeRange": {
        -                          "additionalProperties": true,
        -                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                          "type": "object"
        -                        },
        -                        "strikeSelector": {
        -                          "properties": {
        -                            "distance": {
        -                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                              "type": "number"
        -                            },
        -                            "distanceType": {
        -                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "distanceType",
        -                            "distance"
        -                          ],
        -                          "type": "object"
        -                        }
        -                      },
        -                      "required": [
        -                        "optionType",
        -                        "direction",
        -                        "expirationSelector",
        -                        "strikeSelector"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    "minItems": 1,
        -                    "type": "array"
        -                  },
        -                  "name": {
        -                    "type": "string"
        -                  },
        -                  "spreadType": {
        -                    "enum": [
        -                      "vertical",
        -                      "calendar",
        -                      "diagonal",
        -                      "ironCondor",
        -                      "straddle",
        -                      "strangle",
        -                      "custom"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "widthConstraint": {
        -                    "additionalProperties": false,
        -                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -                    "properties": {
        -                      "minWidthDollars": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "number"
        -                      },
        -                      "minWidthPercent": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "number"
        -                      }
        -                    },
        -                    "type": "object"
        -                  }
        -                },
        -                "required": [
        -                  "legs"
        -                ],
        -                "type": "object"
        -              },
        -              "minItems": 1,
        -              "type": "array"
        -            },
        -            "universe": {
        -              "additionalProperties": true,
        -              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -              "properties": {
        -                "assets": {
        -                  "items": {
        -                    "additionalProperties": true,
        -                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -                    "properties": {
        -                      "name": {
        -                        "type": "string"
        -                      },
        -                      "symbol": {
        -                        "type": "string"
        -                      },
        -                      "type": {
        -                        "enum": [
        -                          "Stock",
        -                          "Cryptocurrency",
        -                          "Option",
        -                          "Other"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "symbol"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "type": "array"
        -                },
        -                "source": {
        -                  "enum": [
        -                    "ALL_US_STOCKS",
        -                    "SP500",
        -                    "NASDAQ100",
        -                    "DJIA",
        -                    "CRYPTO",
        -                    "SPECIFIC_ASSETS"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "source"
        -              ],
        -              "type": "object"
        -            },
        -            "weightIndicator": {
        -              "$ref": "#/$defs/indicator"
        -            }
        -          },
        -          "required": [
        -            "name"
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "structureTemplates": {
        -        "items": {
        -          "additionalProperties": true,
        -          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        -          "properties": {
        -            "eligibility": {
        -              "$ref": "#/$defs/condition"
        -            },
        -            "legs": {
        -              "items": {
        -                "additionalProperties": true,
        -                "description": "Single leg of an option builder.",
        -                "properties": {
        -                  "direction": {
        -                    "enum": [
        -                      "long",
        -                      "short"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "expirationRange": {
        -                    "additionalProperties": true,
        -                    "type": "object"
        -                  },
        -                  "expirationSelector": {
        -                    "properties": {
        -                      "maxDaysToExpiration": {
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "minDaysToExpiration": {
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "preference": {
        -                        "enum": [
        -                          "nearest",
        -                          "middle",
        -                          "furthest"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "minDaysToExpiration",
        -                      "maxDaysToExpiration",
        -                      "preference"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "fallbackStrikeSelector": {
        -                    "additionalProperties": false,
        -                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                    "properties": {
        -                      "distance": {
        -                        "type": "number"
        -                      },
        -                      "distanceType": {
        -                        "enum": [
        -                          "percent",
        -                          "dollars"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "distanceType",
        -                      "distance"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "greekFilter": {
        -                    "additionalProperties": true,
        -                    "description": "Optional min/max constraints on Greeks during resolution.",
        -                    "type": "object"
        -                  },
        -                  "liquidityFilter": {
        -                    "additionalProperties": false,
        -                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                    "properties": {
        -                      "maxSpreadAbsolute": {
        -                        "type": "number"
        -                      },
        -                      "maxSpreadPct": {
        -                        "type": "number"
        -                      },
        -                      "minBid": {
        -                        "type": "number"
        -                      }
        -                    },
        -                    "type": "object"
        -                  },
        -                  "optionType": {
        -                    "enum": [
        -                      "call",
        -                      "put"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "ratio": {
        -                    "type": "number"
        -                  },
        -                  "strikeRange": {
        -                    "additionalProperties": true,
        -                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                    "type": "object"
        -                  },
        -                  "strikeSelector": {
        -                    "properties": {
        -                      "distance": {
        -                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                        "type": "number"
        -                      },
        -                      "distanceType": {
        -                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "distanceType",
        -                      "distance"
        -                    ],
        -                    "type": "object"
        -                  }
        -                },
        -                "required": [
        -                  "optionType",
        -                  "direction",
        -                  "expirationSelector",
        -                  "strikeSelector"
        -                ],
        -                "type": "object"
        -              },
        -              "minItems": 1,
        -              "type": "array"
        -            },
        -            "name": {
        -              "type": "string"
        -            },
        -            "spreadType": {
        -              "enum": [
        -                "vertical",
        -                "calendar",
        -                "diagonal",
        -                "ironCondor",
        -                "straddle",
        -                "strangle",
        -                "custom"
        -              ],
        -              "type": "string"
        -            },
        -            "widthConstraint": {
        -              "additionalProperties": false,
        -              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -              "properties": {
        -                "minWidthDollars": {
        -                  "exclusiveMinimum": 0,
        -                  "type": "number"
        -                },
        -                "minWidthPercent": {
        -                  "exclusiveMinimum": 0,
        -                  "type": "number"
        -                }
        -              },
        -              "type": "object"
        -            }
        -          },
        -          "required": [
        -            "legs"
        -          ],
        -          "type": "object"
        -        },
        -        "minItems": 1,
        -        "type": "array"
        -      },
        -      "totalBudget": {
        -        "additionalProperties": true,
        -        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        -        "properties": {
        -          "amount": {
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "const": "RebalanceOption",
        -        "type": "string"
        -      },
        -      "universe": {
        -        "additionalProperties": true,
        -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -        "properties": {
        -          "assets": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -              "properties": {
        -                "name": {
        -                  "type": "string"
        -                },
        -                "symbol": {
        -                  "type": "string"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "Stock",
        -                    "Cryptocurrency",
        -                    "Option",
        -                    "Other"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "symbol"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "source": {
        -            "enum": [
        -              "ALL_US_STOCKS",
        -              "SP500",
        -              "NASDAQ100",
        -              "DJIA",
        -              "CRYPTO",
        -              "SPECIFIC_ASSETS"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "weightIndicator": {
        -        "$ref": "#/$defs/indicator"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "universe",
        -      "pipeline",
        -      "weightIndicator",
        -      "structureTemplates"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        -    "properties": {
        -      "closeScope": {
        -        "enum": [
        -          "spread",
        -          "leg"
        -        ],
        -        "type": "string"
        -      },
        -      "direction": {
        -        "enum": [
        -          "long",
        -          "short"
        -        ],
        -        "type": "string"
        -      },
        -      "optionType": {
        -        "enum": [
        -          "call",
        -          "put"
        -        ],
        -        "type": "string"
        -      },
        -      "quantity": {
        -        "additionalProperties": true,
        -        "description": "How many contracts to close. Defaults to all matching when omitted.",
        -        "type": "object"
        -      },
        -      "spreadType": {
        -        "enum": [
        -          "vertical",
        -          "calendar",
        -          "diagonal",
        -          "ironCondor",
        -          "straddle",
        -          "strangle",
        -          "custom"
        -        ],
        -        "type": "string"
        -      },
        -      "triggers": {
        -        "items": {
        -          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxPnlPercent": {
        -                  "type": "number"
        -                },
        -                "minPnlPercent": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "pnl",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxDte": {
        -                  "type": "number"
        -                },
        -                "minDte": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "dte",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxDaysHeld": {
        -                  "type": "number"
        -                },
        -                "minDaysHeld": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "daysHeld",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxIv": {
        -                  "type": "number"
        -                },
        -                "maxSpreadDelta": {
        -                  "type": "number"
        -                },
        -                "maxSpreadTheta": {
        -                  "type": "number"
        -                },
        -                "minIv": {
        -                  "type": "number"
        -                },
        -                "minSpreadDelta": {
        -                  "type": "number"
        -                },
        -                "minSpreadTheta": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "greeks",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "type": {
        -        "const": "CloseOption",
        -        "type": "string"
        -      },
        -      "underlyings": {
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array"
        -      }
        -    },
        -    "required": [
        -      "type"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": true,
        +    "description": "Buy or Sell a stock/crypto position.",
        +    "properties": {
        +      "amount": {
        +        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "percent of current positions",
        +              "dollars",
        +              "number of assets"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "targetAsset": {
        +        "additionalProperties": true,
        +        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +        "properties": {
        +          "name": {
        +            "type": "string"
        +          },
        +          "symbol": {
        +            "type": "string"
        +          },
        +          "type": {
        +            "enum": [
        +              "Stock",
        +              "Cryptocurrency",
        +              "Option",
        +              "Other"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "symbol"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "enum": [
        +          "Buy",
        +          "Sell"
        +        ],
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "targetAsset",
        +      "amount"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Send an alert message (no order).",
        +    "properties": {
        +      "message": {
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "Alert",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "message"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        +    "properties": {
        +      "allocationPolicy": {
        +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "expectedReturnShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "riskAversion": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MeanVariance",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "riskAversion",
        +              "expectedReturnShrinkage",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "RiskParity",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MaximumDiversification",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "canSell": {
        +        "$ref": "#/$defs/condition",
        +        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        +      },
        +      "deploymentPercent": {
        +        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        +        "maximum": 100,
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "exposurePolicy": {
        +        "additionalProperties": false,
        +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +        "properties": {
        +          "covarianceShrinkage": {
        +            "maximum": 1,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "estimatedTransactionCostBps": {
        +            "maximum": 10000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "lookbackPeriods": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "minimumObservations": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "targetAnnualizedVolatilityPercent": {
        +            "maximum": 1000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "const": "VolatilityTarget",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "lookbackPeriods",
        +          "minimumObservations",
        +          "covarianceShrinkage",
        +          "targetAnnualizedVolatilityPercent",
        +          "estimatedTransactionCostBps"
        +        ],
        +        "type": "object"
        +      },
        +      "limit": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "perNameAllocation": {
        +        "additionalProperties": true,
        +        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.",
        +        "properties": {
        +          "amount": {
        +            "exclusiveMinimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "percent of portfolio",
        +              "dollars"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "pipeline": {
        +        "items": {
        +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "condition": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "type": {
        +                  "const": "Filter",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "condition"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "type": {
        +                  "const": "SelectTop",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "limit",
        +                "direction"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "percentile": {
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "SelectPercentile",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "percentile",
        +                "direction"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "type": {
        +        "const": "DynamicRebalance",
        +        "type": "string"
        +      },
        +      "universe": {
        +        "additionalProperties": true,
        +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +        "properties": {
        +          "assets": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +              "properties": {
        +                "name": {
        +                  "type": "string"
        +                },
        +                "symbol": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Stock",
        +                    "Cryptocurrency",
        +                    "Option",
        +                    "Other"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "symbol"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "enum": [
        +              "ALL_US_STOCKS",
        +              "SP500",
        +              "NASDAQ100",
        +              "DJIA",
        +              "CRYPTO",
        +              "SPECIFIC_ASSETS"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "weightIndicator": {
        +        "$ref": "#/$defs/indicator"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "universe",
        +      "pipeline",
        +      "weightIndicator"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        +    "properties": {
        +      "continueExisting": {
        +        "type": "boolean"
        +      },
        +      "cooldownMinutes": {
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "executionModel": {
        +        "type": "string"
        +      },
        +      "includeMarketData": {
        +        "type": "boolean"
        +      },
        +      "initialMessage": {
        +        "type": "string"
        +      },
        +      "maxIterations": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "planningModel": {
        +        "type": "string"
        +      },
        +      "skipPlanning": {
        +        "type": "boolean"
        +      },
        +      "type": {
        +        "const": "LaunchAgent",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "planningModel",
        +      "executionModel",
        +      "initialMessage",
        +      "maxIterations",
        +      "includeMarketData",
        +      "continueExisting",
        +      "skipPlanning"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        +    "properties": {
        +      "against": {
        +        "additionalProperties": true,
        +        "description": "Optional parent-position selector (e.g. for covered calls).",
        +        "type": "object"
        +      },
        +      "allocation": {
        +        "additionalProperties": true,
        +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "contracts",
        +              "percent of realized premium"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "builder": {
        +        "additionalProperties": true,
        +        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        +        "properties": {
        +          "dynamicUnderlying": {
        +            "additionalProperties": true,
        +            "properties": {
        +              "limit": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "pipeline": {
        +                "items": {
        +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                  "oneOf": [
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "condition": {
        +                          "$ref": "#/$defs/condition"
        +                        },
        +                        "type": {
        +                          "const": "Filter",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "condition"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "limit": {
        +                          "minimum": 1,
        +                          "type": "number"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "type": {
        +                          "const": "SelectTop",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "limit",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "percentile": {
        +                          "maximum": 100,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "SelectPercentile",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "percentile",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "universe": {
        +                "additionalProperties": true,
        +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                "properties": {
        +                  "assets": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                      "properties": {
        +                        "name": {
        +                          "type": "string"
        +                        },
        +                        "symbol": {
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "enum": [
        +                            "Stock",
        +                            "Cryptocurrency",
        +                            "Option",
        +                            "Other"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "symbol"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "type": "array"
        +                  },
        +                  "source": {
        +                    "enum": [
        +                      "ALL_US_STOCKS",
        +                      "SP500",
        +                      "NASDAQ100",
        +                      "DJIA",
        +                      "CRYPTO",
        +                      "SPECIFIC_ASSETS"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "source"
        +                ],
        +                "type": "object"
        +              }
        +            },
        +            "required": [
        +              "universe"
        +            ],
        +            "type": "object"
        +          },
        +          "legs": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Single leg of an option builder.",
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "long",
        +                    "short"
        +                  ],
        +                  "type": "string"
        +                },
        +                "expirationRange": {
        +                  "additionalProperties": true,
        +                  "type": "object"
        +                },
        +                "expirationSelector": {
        +                  "properties": {
        +                    "maxDaysToExpiration": {
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "minDaysToExpiration": {
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "preference": {
        +                      "enum": [
        +                        "nearest",
        +                        "middle",
        +                        "furthest"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "minDaysToExpiration",
        +                    "maxDaysToExpiration",
        +                    "preference"
        +                  ],
        +                  "type": "object"
        +                },
        +                "fallbackStrikeSelector": {
        +                  "additionalProperties": false,
        +                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                  "properties": {
        +                    "distance": {
        +                      "type": "number"
        +                    },
        +                    "distanceType": {
        +                      "enum": [
        +                        "percent",
        +                        "dollars"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "distanceType",
        +                    "distance"
        +                  ],
        +                  "type": "object"
        +                },
        +                "greekFilter": {
        +                  "additionalProperties": true,
        +                  "description": "Optional min/max constraints on Greeks during resolution.",
        +                  "type": "object"
        +                },
        +                "liquidityFilter": {
        +                  "additionalProperties": false,
        +                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                  "properties": {
        +                    "maxSpreadAbsolute": {
        +                      "type": "number"
        +                    },
        +                    "maxSpreadPct": {
        +                      "type": "number"
        +                    },
        +                    "minBid": {
        +                      "type": "number"
        +                    }
        +                  },
        +                  "type": "object"
        +                },
        +                "optionType": {
        +                  "enum": [
        +                    "call",
        +                    "put"
        +                  ],
        +                  "type": "string"
        +                },
        +                "ratio": {
        +                  "type": "number"
        +                },
        +                "strikeRange": {
        +                  "additionalProperties": true,
        +                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                  "type": "object"
        +                },
        +                "strikeSelector": {
        +                  "properties": {
        +                    "distance": {
        +                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                      "type": "number"
        +                    },
        +                    "distanceType": {
        +                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "distanceType",
        +                    "distance"
        +                  ],
        +                  "type": "object"
        +                }
        +              },
        +              "required": [
        +                "optionType",
        +                "direction",
        +                "expirationSelector",
        +                "strikeSelector"
        +              ],
        +              "type": "object"
        +            },
        +            "minItems": 1,
        +            "type": "array"
        +          },
        +          "spreadType": {
        +            "enum": [
        +              "vertical",
        +              "calendar",
        +              "diagonal",
        +              "ironCondor",
        +              "straddle",
        +              "strangle",
        +              "custom"
        +            ],
        +            "type": "string"
        +          },
        +          "underlyingSymbol": {
        +            "type": "string"
        +          },
        +          "widthConstraint": {
        +            "additionalProperties": false,
        +            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +            "properties": {
        +              "minWidthDollars": {
        +                "exclusiveMinimum": 0,
        +                "type": "number"
        +              },
        +              "minWidthPercent": {
        +                "exclusiveMinimum": 0,
        +                "type": "number"
        +              }
        +            },
        +            "type": "object"
        +          }
        +        },
        +        "required": [
        +          "legs"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "const": "OpenOption",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "builder"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        +    "properties": {
        +      "allocationPolicy": {
        +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "expectedReturnShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "riskAversion": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MeanVariance",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "riskAversion",
        +              "expectedReturnShrinkage",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "RiskParity",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MaximumDiversification",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "exposurePolicy": {
        +        "additionalProperties": false,
        +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +        "properties": {
        +          "covarianceShrinkage": {
        +            "maximum": 1,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "estimatedTransactionCostBps": {
        +            "maximum": 10000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "lookbackPeriods": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "minimumObservations": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "targetAnnualizedVolatilityPercent": {
        +            "maximum": 1000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "const": "VolatilityTarget",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "lookbackPeriods",
        +          "minimumObservations",
        +          "covarianceShrinkage",
        +          "targetAnnualizedVolatilityPercent",
        +          "estimatedTransactionCostBps"
        +        ],
        +        "type": "object"
        +      },
        +      "limit": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "perNameAllocation": {
        +        "additionalProperties": true,
        +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "contracts",
        +              "percent of realized premium"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "pipeline": {
        +        "items": {
        +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "condition": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "type": {
        +                  "const": "Filter",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "condition"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "type": {
        +                  "const": "SelectTop",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "limit",
        +                "direction"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "percentile": {
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "SelectPercentile",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "percentile",
        +                "direction"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "positionScope": {
        +        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        +        "enum": [
        +          "portfolio",
        +          "strategy"
        +        ],
        +        "type": "string"
        +      },
        +      "sleeves": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        +          "properties": {
        +            "limit": {
        +              "minimum": 1,
        +              "type": "number"
        +            },
        +            "name": {
        +              "type": "string"
        +            },
        +            "perNameAllocation": {
        +              "additionalProperties": true,
        +              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +              "properties": {
        +                "amount": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "dollars",
        +                    "percent of portfolio",
        +                    "percent of buying power",
        +                    "contracts",
        +                    "percent of realized premium"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "amount"
        +              ],
        +              "type": "object"
        +            },
        +            "pipeline": {
        +              "items": {
        +                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                "oneOf": [
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "condition": {
        +                        "$ref": "#/$defs/condition"
        +                      },
        +                      "type": {
        +                        "const": "Filter",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "condition"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "direction": {
        +                        "enum": [
        +                          "Highest",
        +                          "Lowest"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "limit": {
        +                        "minimum": 1,
        +                        "type": "number"
        +                      },
        +                      "metric": {
        +                        "$ref": "#/$defs/indicator"
        +                      },
        +                      "type": {
        +                        "const": "SelectTop",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "metric",
        +                      "limit",
        +                      "direction"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "direction": {
        +                        "enum": [
        +                          "Highest",
        +                          "Lowest"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "metric": {
        +                        "$ref": "#/$defs/indicator"
        +                      },
        +                      "percentile": {
        +                        "maximum": 100,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "SelectPercentile",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "metric",
        +                      "percentile",
        +                      "direction"
        +                    ],
        +                    "type": "object"
        +                  }
        +                ],
        +                "type": "object"
        +              },
        +              "type": "array"
        +            },
        +            "structureTemplates": {
        +              "items": {
        +                "additionalProperties": true,
        +                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +                "properties": {
        +                  "eligibility": {
        +                    "$ref": "#/$defs/condition"
        +                  },
        +                  "legs": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Single leg of an option builder.",
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "long",
        +                            "short"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "expirationRange": {
        +                          "additionalProperties": true,
        +                          "type": "object"
        +                        },
        +                        "expirationSelector": {
        +                          "properties": {
        +                            "maxDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "minDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "preference": {
        +                              "enum": [
        +                                "nearest",
        +                                "middle",
        +                                "furthest"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "minDaysToExpiration",
        +                            "maxDaysToExpiration",
        +                            "preference"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "fallbackStrikeSelector": {
        +                          "additionalProperties": false,
        +                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                          "properties": {
        +                            "distance": {
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "enum": [
        +                                "percent",
        +                                "dollars"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "greekFilter": {
        +                          "additionalProperties": true,
        +                          "description": "Optional min/max constraints on Greeks during resolution.",
        +                          "type": "object"
        +                        },
        +                        "liquidityFilter": {
        +                          "additionalProperties": false,
        +                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                          "properties": {
        +                            "maxSpreadAbsolute": {
        +                              "type": "number"
        +                            },
        +                            "maxSpreadPct": {
        +                              "type": "number"
        +                            },
        +                            "minBid": {
        +                              "type": "number"
        +                            }
        +                          },
        +                          "type": "object"
        +                        },
        +                        "optionType": {
        +                          "enum": [
        +                            "call",
        +                            "put"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "ratio": {
        +                          "type": "number"
        +                        },
        +                        "strikeRange": {
        +                          "additionalProperties": true,
        +                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                          "type": "object"
        +                        },
        +                        "strikeSelector": {
        +                          "properties": {
        +                            "distance": {
        +                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        }
        +                      },
        +                      "required": [
        +                        "optionType",
        +                        "direction",
        +                        "expirationSelector",
        +                        "strikeSelector"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "minItems": 1,
        +                    "type": "array"
        +                  },
        +                  "name": {
        +                    "type": "string"
        +                  },
        +                  "spreadType": {
        +                    "enum": [
        +                      "vertical",
        +                      "calendar",
        +                      "diagonal",
        +                      "ironCondor",
        +                      "straddle",
        +                      "strangle",
        +                      "custom"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "widthConstraint": {
        +                    "additionalProperties": false,
        +                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                    "properties": {
        +                      "minWidthDollars": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minWidthPercent": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "legs"
        +                ],
        +                "type": "object"
        +              },
        +              "minItems": 1,
        +              "type": "array"
        +            },
        +            "universe": {
        +              "additionalProperties": true,
        +              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +              "properties": {
        +                "assets": {
        +                  "items": {
        +                    "additionalProperties": true,
        +                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                    "properties": {
        +                      "name": {
        +                        "type": "string"
        +                      },
        +                      "symbol": {
        +                        "type": "string"
        +                      },
        +                      "type": {
        +                        "enum": [
        +                          "Stock",
        +                          "Cryptocurrency",
        +                          "Option",
        +                          "Other"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "symbol"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "type": "array"
        +                },
        +                "source": {
        +                  "enum": [
        +                    "ALL_US_STOCKS",
        +                    "SP500",
        +                    "NASDAQ100",
        +                    "DJIA",
        +                    "CRYPTO",
        +                    "SPECIFIC_ASSETS"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "source"
        +              ],
        +              "type": "object"
        +            },
        +            "weightIndicator": {
        +              "$ref": "#/$defs/indicator"
        +            }
        +          },
        +          "required": [
        +            "name"
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "structureTemplates": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +          "properties": {
        +            "eligibility": {
        +              "$ref": "#/$defs/condition"
        +            },
        +            "legs": {
        +              "items": {
        +                "additionalProperties": true,
        +                "description": "Single leg of an option builder.",
        +                "properties": {
        +                  "direction": {
        +                    "enum": [
        +                      "long",
        +                      "short"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "expirationRange": {
        +                    "additionalProperties": true,
        +                    "type": "object"
        +                  },
        +                  "expirationSelector": {
        +                    "properties": {
        +                      "maxDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "preference": {
        +                        "enum": [
        +                          "nearest",
        +                          "middle",
        +                          "furthest"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "minDaysToExpiration",
        +                      "maxDaysToExpiration",
        +                      "preference"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "fallbackStrikeSelector": {
        +                    "additionalProperties": false,
        +                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                    "properties": {
        +                      "distance": {
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "enum": [
        +                          "percent",
        +                          "dollars"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "greekFilter": {
        +                    "additionalProperties": true,
        +                    "description": "Optional min/max constraints on Greeks during resolution.",
        +                    "type": "object"
        +                  },
        +                  "liquidityFilter": {
        +                    "additionalProperties": false,
        +                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                    "properties": {
        +                      "maxSpreadAbsolute": {
        +                        "type": "number"
        +                      },
        +                      "maxSpreadPct": {
        +                        "type": "number"
        +                      },
        +                      "minBid": {
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  },
        +                  "optionType": {
        +                    "enum": [
        +                      "call",
        +                      "put"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "ratio": {
        +                    "type": "number"
        +                  },
        +                  "strikeRange": {
        +                    "additionalProperties": true,
        +                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                    "type": "object"
        +                  },
        +                  "strikeSelector": {
        +                    "properties": {
        +                      "distance": {
        +                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "optionType",
        +                  "direction",
        +                  "expirationSelector",
        +                  "strikeSelector"
        +                ],
        +                "type": "object"
        +              },
        +              "minItems": 1,
        +              "type": "array"
        +            },
        +            "name": {
        +              "type": "string"
        +            },
        +            "spreadType": {
        +              "enum": [
        +                "vertical",
        +                "calendar",
        +                "diagonal",
        +                "ironCondor",
        +                "straddle",
        +                "strangle",
        +                "custom"
        +              ],
        +              "type": "string"
        +            },
        +            "widthConstraint": {
        +              "additionalProperties": false,
        +              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +              "properties": {
        +                "minWidthDollars": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                },
        +                "minWidthPercent": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                }
        +              },
        +              "type": "object"
        +            }
        +          },
        +          "required": [
        +            "legs"
        +          ],
        +          "type": "object"
        +        },
        +        "minItems": 1,
        +        "type": "array"
        +      },
        +      "totalBudget": {
        +        "additionalProperties": true,
        +        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        +        "properties": {
        +          "amount": {
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "const": "RebalanceOption",
        +        "type": "string"
        +      },
        +      "universe": {
        +        "additionalProperties": true,
        +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +        "properties": {
        +          "assets": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +              "properties": {
        +                "name": {
        +                  "type": "string"
        +                },
        +                "symbol": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Stock",
        +                    "Cryptocurrency",
        +                    "Option",
        +                    "Other"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "symbol"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "enum": [
        +              "ALL_US_STOCKS",
        +              "SP500",
        +              "NASDAQ100",
        +              "DJIA",
        +              "CRYPTO",
        +              "SPECIFIC_ASSETS"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "weightIndicator": {
        +        "$ref": "#/$defs/indicator"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "universe",
        +      "pipeline",
        +      "weightIndicator",
        +      "structureTemplates"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        +    "properties": {
        +      "closeScope": {
        +        "enum": [
        +          "spread",
        +          "leg"
        +        ],
        +        "type": "string"
        +      },
        +      "direction": {
        +        "enum": [
        +          "long",
        +          "short"
        +        ],
        +        "type": "string"
        +      },
        +      "optionType": {
        +        "enum": [
        +          "call",
        +          "put"
        +        ],
        +        "type": "string"
        +      },
        +      "quantity": {
        +        "additionalProperties": true,
        +        "description": "How many contracts to close. Defaults to all matching when omitted.",
        +        "type": "object"
        +      },
        +      "spreadType": {
        +        "enum": [
        +          "vertical",
        +          "calendar",
        +          "diagonal",
        +          "ironCondor",
        +          "straddle",
        +          "strangle",
        +          "custom"
        +        ],
        +        "type": "string"
        +      },
        +      "triggers": {
        +        "items": {
        +          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxPnlPercent": {
        +                  "type": "number"
        +                },
        +                "minPnlPercent": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "pnl",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxDte": {
        +                  "type": "number"
        +                },
        +                "minDte": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "dte",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxDaysHeld": {
        +                  "type": "number"
        +                },
        +                "minDaysHeld": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "daysHeld",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxIv": {
        +                  "type": "number"
        +                },
        +                "maxSpreadDelta": {
        +                  "type": "number"
        +                },
        +                "maxSpreadTheta": {
        +                  "type": "number"
        +                },
        +                "minIv": {
        +                  "type": "number"
        +                },
        +                "minSpreadDelta": {
        +                  "type": "number"
        +                },
        +                "minSpreadTheta": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "greeks",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "type": {
        +        "const": "CloseOption",
        +        "type": "string"
        +      },
        +      "underlyings": {
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  }
        +]
      • changedInput schema / properties / operations / items / properties / strategyObjects / items / properties / action / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "description": "Buy or Sell a stock/crypto position.",
        -    "properties": {
        -      "amount": {
        -        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "percent of current positions",
        -              "dollars",
        -              "number of assets"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "targetAsset": {
        -        "additionalProperties": true,
        -        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -        "properties": {
        -          "name": {
        -            "type": "string"
        -          },
        -          "symbol": {
        -            "type": "string"
        -          },
        -          "type": {
        -            "enum": [
        -              "Stock",
        -              "Cryptocurrency",
        -              "Option",
        -              "Other"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "symbol"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "enum": [
        -          "Buy",
        -          "Sell"
        -        ],
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "targetAsset",
        -      "amount"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Send an alert message (no order).",
        -    "properties": {
        -      "message": {
        -        "type": "string"
        -      },
        -      "type": {
        -        "const": "Alert",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "message"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        -    "properties": {
        -      "allocationPolicy": {
        -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "expectedReturnShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "riskAversion": {
        -                "maximum": 1000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MeanVariance",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "riskAversion",
        -              "expectedReturnShrinkage",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "RiskParity",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumDiversification",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "canSell": {
        -        "$ref": "#/$defs/condition",
        -        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        -      },
        -      "deploymentPercent": {
        -        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        -        "maximum": 100,
        -        "minimum": 0,
        -        "type": "number"
        -      },
        -      "exposurePolicy": {
        -        "additionalProperties": false,
        -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        -        "properties": {
        -          "covarianceShrinkage": {
        -            "maximum": 1,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "estimatedTransactionCostBps": {
        -            "maximum": 10000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "lookbackPeriods": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "minimumObservations": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "targetAnnualizedVolatilityPercent": {
        -            "maximum": 1000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "const": "VolatilityTarget",
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "lookbackPeriods",
        -          "minimumObservations",
        -          "covarianceShrinkage",
        -          "targetAnnualizedVolatilityPercent",
        -          "estimatedTransactionCostBps"
        -        ],
        -        "type": "object"
        -      },
        -      "limit": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "perNameAllocation": {
        -        "additionalProperties": true,
        -        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
        -        "properties": {
        -          "amount": {
        -            "exclusiveMinimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "percent of portfolio",
        -              "dollars"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "pipeline": {
        -        "items": {
        -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "condition": {
        -                  "$ref": "#/$defs/condition"
        -                },
        -                "type": {
        -                  "const": "Filter",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "condition"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "limit": {
        -                  "minimum": 1,
        -                  "type": "number"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "type": {
        -                  "const": "SelectTop",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "limit",
        -                "direction"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "percentile": {
        -                  "maximum": 100,
        -                  "minimum": 0,
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "SelectPercentile",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "percentile",
        -                "direction"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "type": {
        -        "const": "DynamicRebalance",
        -        "type": "string"
        -      },
        -      "universe": {
        -        "additionalProperties": true,
        -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -        "properties": {
        -          "assets": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -              "properties": {
        -                "name": {
        -                  "type": "string"
        -                },
        -                "symbol": {
        -                  "type": "string"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "Stock",
        -                    "Cryptocurrency",
        -                    "Option",
        -                    "Other"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "symbol"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "source": {
        -            "enum": [
        -              "ALL_US_STOCKS",
        -              "SP500",
        -              "NASDAQ100",
        -              "DJIA",
        -              "CRYPTO",
        -              "SPECIFIC_ASSETS"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "weightIndicator": {
        -        "$ref": "#/$defs/indicator"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "universe",
        -      "pipeline",
        -      "weightIndicator"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        -    "properties": {
        -      "continueExisting": {
        -        "type": "boolean"
        -      },
        -      "cooldownMinutes": {
        -        "minimum": 0,
        -        "type": "number"
        -      },
        -      "executionModel": {
        -        "type": "string"
        -      },
        -      "includeMarketData": {
        -        "type": "boolean"
        -      },
        -      "initialMessage": {
        -        "type": "string"
        -      },
        -      "maxIterations": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "planningModel": {
        -        "type": "string"
        -      },
        -      "skipPlanning": {
        -        "type": "boolean"
        -      },
        -      "type": {
        -        "const": "LaunchAgent",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "planningModel",
        -      "executionModel",
        -      "initialMessage",
        -      "maxIterations",
        -      "includeMarketData",
        -      "continueExisting",
        -      "skipPlanning"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        -    "properties": {
        -      "against": {
        -        "additionalProperties": true,
        -        "description": "Optional parent-position selector (e.g. for covered calls).",
        -        "type": "object"
        -      },
        -      "allocation": {
        -        "additionalProperties": true,
        -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "contracts"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "builder": {
        -        "additionalProperties": true,
        -        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        -        "properties": {
        -          "dynamicUnderlying": {
        -            "additionalProperties": true,
        -            "properties": {
        -              "limit": {
        -                "minimum": 1,
        -                "type": "number"
        -              },
        -              "pipeline": {
        -                "items": {
        -                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -                  "oneOf": [
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "condition": {
        -                          "$ref": "#/$defs/condition"
        -                        },
        -                        "type": {
        -                          "const": "Filter",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "condition"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "Highest",
        -                            "Lowest"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "limit": {
        -                          "minimum": 1,
        -                          "type": "number"
        -                        },
        -                        "metric": {
        -                          "$ref": "#/$defs/indicator"
        -                        },
        -                        "type": {
        -                          "const": "SelectTop",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "metric",
        -                        "limit",
        -                        "direction"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "additionalProperties": true,
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "Highest",
        -                            "Lowest"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "metric": {
        -                          "$ref": "#/$defs/indicator"
        -                        },
        -                        "percentile": {
        -                          "maximum": 100,
        -                          "minimum": 0,
        -                          "type": "number"
        -                        },
        -                        "type": {
        -                          "const": "SelectPercentile",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "metric",
        -                        "percentile",
        -                        "direction"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ],
        -                  "type": "object"
        -                },
        -                "type": "array"
        -              },
        -              "universe": {
        -                "additionalProperties": true,
        -                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -                "properties": {
        -                  "assets": {
        -                    "items": {
        -                      "additionalProperties": true,
        -                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -                      "properties": {
        -                        "name": {
        -                          "type": "string"
        -                        },
        -                        "symbol": {
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "enum": [
        -                            "Stock",
        -                            "Cryptocurrency",
        -                            "Option",
        -                            "Other"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "symbol"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    "type": "array"
        -                  },
        -                  "source": {
        -                    "enum": [
        -                      "ALL_US_STOCKS",
        -                      "SP500",
        -                      "NASDAQ100",
        -                      "DJIA",
        -                      "CRYPTO",
        -                      "SPECIFIC_ASSETS"
        -                    ],
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "source"
        -                ],
        -                "type": "object"
        -              }
        -            },
        -            "required": [
        -              "universe"
        -            ],
        -            "type": "object"
        -          },
        -          "legs": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Single leg of an option builder.",
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "long",
        -                    "short"
        -                  ],
        -                  "type": "string"
        -                },
        -                "expirationRange": {
        -                  "additionalProperties": true,
        -                  "type": "object"
        -                },
        -                "expirationSelector": {
        -                  "properties": {
        -                    "maxDaysToExpiration": {
        -                      "minimum": 0,
        -                      "type": "number"
        -                    },
        -                    "minDaysToExpiration": {
        -                      "minimum": 0,
        -                      "type": "number"
        -                    },
        -                    "preference": {
        -                      "enum": [
        -                        "nearest",
        -                        "middle",
        -                        "furthest"
        -                      ],
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "minDaysToExpiration",
        -                    "maxDaysToExpiration",
        -                    "preference"
        -                  ],
        -                  "type": "object"
        -                },
        -                "fallbackStrikeSelector": {
        -                  "additionalProperties": false,
        -                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                  "properties": {
        -                    "distance": {
        -                      "type": "number"
        -                    },
        -                    "distanceType": {
        -                      "enum": [
        -                        "percent",
        -                        "dollars"
        -                      ],
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "distanceType",
        -                    "distance"
        -                  ],
        -                  "type": "object"
        -                },
        -                "greekFilter": {
        -                  "additionalProperties": true,
        -                  "description": "Optional min/max constraints on Greeks during resolution.",
        -                  "type": "object"
        -                },
        -                "liquidityFilter": {
        -                  "additionalProperties": false,
        -                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                  "properties": {
        -                    "maxSpreadAbsolute": {
        -                      "type": "number"
        -                    },
        -                    "maxSpreadPct": {
        -                      "type": "number"
        -                    },
        -                    "minBid": {
        -                      "type": "number"
        -                    }
        -                  },
        -                  "type": "object"
        -                },
        -                "optionType": {
        -                  "enum": [
        -                    "call",
        -                    "put"
        -                  ],
        -                  "type": "string"
        -                },
        -                "ratio": {
        -                  "type": "number"
        -                },
        -                "strikeRange": {
        -                  "additionalProperties": true,
        -                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                  "type": "object"
        -                },
        -                "strikeSelector": {
        -                  "properties": {
        -                    "distance": {
        -                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                      "type": "number"
        -                    },
        -                    "distanceType": {
        -                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "distanceType",
        -                    "distance"
        -                  ],
        -                  "type": "object"
        -                }
        -              },
        -              "required": [
        -                "optionType",
        -                "direction",
        -                "expirationSelector",
        -                "strikeSelector"
        -              ],
        -              "type": "object"
        -            },
        -            "minItems": 1,
        -            "type": "array"
        -          },
        -          "spreadType": {
        -            "enum": [
        -              "vertical",
        -              "calendar",
        -              "diagonal",
        -              "ironCondor",
        -              "straddle",
        -              "strangle",
        -              "custom"
        -            ],
        -            "type": "string"
        -          },
        -          "underlyingSymbol": {
        -            "type": "string"
        -          },
        -          "widthConstraint": {
        -            "additionalProperties": false,
        -            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -            "properties": {
        -              "minWidthDollars": {
        -                "exclusiveMinimum": 0,
        -                "type": "number"
        -              },
        -              "minWidthPercent": {
        -                "exclusiveMinimum": 0,
        -                "type": "number"
        -              }
        -            },
        -            "type": "object"
        -          }
        -        },
        -        "required": [
        -          "legs"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "const": "OpenOption",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "builder"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        -    "properties": {
        -      "allocationPolicy": {
        -        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        -        "oneOf": [
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "expectedReturnShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "riskAversion": {
        -                "maximum": 1000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MeanVariance",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "riskAversion",
        -              "expectedReturnShrinkage",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "RiskParity",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          },
        -          {
        -            "additionalProperties": false,
        -            "properties": {
        -              "covarianceShrinkage": {
        -                "maximum": 1,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "estimatedTransactionCostBps": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "lookbackPeriods": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "minimumObservations": {
        -                "maximum": 5000,
        -                "minimum": 2,
        -                "type": "integer"
        -              },
        -              "turnoverPenalty": {
        -                "maximum": 10000,
        -                "minimum": 0,
        -                "type": "number"
        -              },
        -              "type": {
        -                "const": "MaximumDiversification",
        -                "type": "string"
        -              }
        -            },
        -            "required": [
        -              "type",
        -              "lookbackPeriods",
        -              "minimumObservations",
        -              "covarianceShrinkage",
        -              "turnoverPenalty",
        -              "estimatedTransactionCostBps"
        -            ],
        -            "type": "object"
        -          }
        -        ]
        -      },
        -      "exposurePolicy": {
        -        "additionalProperties": false,
        -        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        -        "properties": {
        -          "covarianceShrinkage": {
        -            "maximum": 1,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "estimatedTransactionCostBps": {
        -            "maximum": 10000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "lookbackPeriods": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "minimumObservations": {
        -            "maximum": 5000,
        -            "minimum": 2,
        -            "type": "integer"
        -          },
        -          "targetAnnualizedVolatilityPercent": {
        -            "maximum": 1000,
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "const": "VolatilityTarget",
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "lookbackPeriods",
        -          "minimumObservations",
        -          "covarianceShrinkage",
        -          "targetAnnualizedVolatilityPercent",
        -          "estimatedTransactionCostBps"
        -        ],
        -        "type": "object"
        -      },
        -      "limit": {
        -        "minimum": 1,
        -        "type": "number"
        -      },
        -      "perNameAllocation": {
        -        "additionalProperties": true,
        -        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -        "properties": {
        -          "amount": {
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio",
        -              "percent of buying power",
        -              "contracts"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "pipeline": {
        -        "items": {
        -          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "condition": {
        -                  "$ref": "#/$defs/condition"
        -                },
        -                "type": {
        -                  "const": "Filter",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "condition"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "limit": {
        -                  "minimum": 1,
        -                  "type": "number"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "type": {
        -                  "const": "SelectTop",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "limit",
        -                "direction"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "direction": {
        -                  "enum": [
        -                    "Highest",
        -                    "Lowest"
        -                  ],
        -                  "type": "string"
        -                },
        -                "metric": {
        -                  "$ref": "#/$defs/indicator"
        -                },
        -                "percentile": {
        -                  "maximum": 100,
        -                  "minimum": 0,
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "SelectPercentile",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "metric",
        -                "percentile",
        -                "direction"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "positionScope": {
        -        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        -        "enum": [
        -          "portfolio",
        -          "strategy"
        -        ],
        -        "type": "string"
        -      },
        -      "sleeves": {
        -        "items": {
        -          "additionalProperties": true,
        -          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        -          "properties": {
        -            "limit": {
        -              "minimum": 1,
        -              "type": "number"
        -            },
        -            "name": {
        -              "type": "string"
        -            },
        -            "perNameAllocation": {
        -              "additionalProperties": true,
        -              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        -              "properties": {
        -                "amount": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "dollars",
        -                    "percent of portfolio",
        -                    "percent of buying power",
        -                    "contracts"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "amount"
        -              ],
        -              "type": "object"
        -            },
        -            "pipeline": {
        -              "items": {
        -                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        -                "oneOf": [
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "condition": {
        -                        "$ref": "#/$defs/condition"
        -                      },
        -                      "type": {
        -                        "const": "Filter",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "condition"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "direction": {
        -                        "enum": [
        -                          "Highest",
        -                          "Lowest"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "limit": {
        -                        "minimum": 1,
        -                        "type": "number"
        -                      },
        -                      "metric": {
        -                        "$ref": "#/$defs/indicator"
        -                      },
        -                      "type": {
        -                        "const": "SelectTop",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "metric",
        -                      "limit",
        -                      "direction"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  {
        -                    "additionalProperties": true,
        -                    "properties": {
        -                      "direction": {
        -                        "enum": [
        -                          "Highest",
        -                          "Lowest"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "metric": {
        -                        "$ref": "#/$defs/indicator"
        -                      },
        -                      "percentile": {
        -                        "maximum": 100,
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "type": {
        -                        "const": "SelectPercentile",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "metric",
        -                      "percentile",
        -                      "direction"
        -                    ],
        -                    "type": "object"
        -                  }
        -                ],
        -                "type": "object"
        -              },
        -              "type": "array"
        -            },
        -            "structureTemplates": {
        -              "items": {
        -                "additionalProperties": true,
        -                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        -                "properties": {
        -                  "eligibility": {
        -                    "$ref": "#/$defs/condition"
        -                  },
        -                  "legs": {
        -                    "items": {
        -                      "additionalProperties": true,
        -                      "description": "Single leg of an option builder.",
        -                      "properties": {
        -                        "direction": {
        -                          "enum": [
        -                            "long",
        -                            "short"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "expirationRange": {
        -                          "additionalProperties": true,
        -                          "type": "object"
        -                        },
        -                        "expirationSelector": {
        -                          "properties": {
        -                            "maxDaysToExpiration": {
        -                              "minimum": 0,
        -                              "type": "number"
        -                            },
        -                            "minDaysToExpiration": {
        -                              "minimum": 0,
        -                              "type": "number"
        -                            },
        -                            "preference": {
        -                              "enum": [
        -                                "nearest",
        -                                "middle",
        -                                "furthest"
        -                              ],
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "minDaysToExpiration",
        -                            "maxDaysToExpiration",
        -                            "preference"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "fallbackStrikeSelector": {
        -                          "additionalProperties": false,
        -                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                          "properties": {
        -                            "distance": {
        -                              "type": "number"
        -                            },
        -                            "distanceType": {
        -                              "enum": [
        -                                "percent",
        -                                "dollars"
        -                              ],
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "distanceType",
        -                            "distance"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "greekFilter": {
        -                          "additionalProperties": true,
        -                          "description": "Optional min/max constraints on Greeks during resolution.",
        -                          "type": "object"
        -                        },
        -                        "liquidityFilter": {
        -                          "additionalProperties": false,
        -                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                          "properties": {
        -                            "maxSpreadAbsolute": {
        -                              "type": "number"
        -                            },
        -                            "maxSpreadPct": {
        -                              "type": "number"
        -                            },
        -                            "minBid": {
        -                              "type": "number"
        -                            }
        -                          },
        -                          "type": "object"
        -                        },
        -                        "optionType": {
        -                          "enum": [
        -                            "call",
        -                            "put"
        -                          ],
        -                          "type": "string"
        -                        },
        -                        "ratio": {
        -                          "type": "number"
        -                        },
        -                        "strikeRange": {
        -                          "additionalProperties": true,
        -                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                          "type": "object"
        -                        },
        -                        "strikeSelector": {
        -                          "properties": {
        -                            "distance": {
        -                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                              "type": "number"
        -                            },
        -                            "distanceType": {
        -                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                              "type": "string"
        -                            }
        -                          },
        -                          "required": [
        -                            "distanceType",
        -                            "distance"
        -                          ],
        -                          "type": "object"
        -                        }
        -                      },
        -                      "required": [
        -                        "optionType",
        -                        "direction",
        -                        "expirationSelector",
        -                        "strikeSelector"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    "minItems": 1,
        -                    "type": "array"
        -                  },
        -                  "name": {
        -                    "type": "string"
        -                  },
        -                  "spreadType": {
        -                    "enum": [
        -                      "vertical",
        -                      "calendar",
        -                      "diagonal",
        -                      "ironCondor",
        -                      "straddle",
        -                      "strangle",
        -                      "custom"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "widthConstraint": {
        -                    "additionalProperties": false,
        -                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -                    "properties": {
        -                      "minWidthDollars": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "number"
        -                      },
        -                      "minWidthPercent": {
        -                        "exclusiveMinimum": 0,
        -                        "type": "number"
        -                      }
        -                    },
        -                    "type": "object"
        -                  }
        -                },
        -                "required": [
        -                  "legs"
        -                ],
        -                "type": "object"
        -              },
        -              "minItems": 1,
        -              "type": "array"
        -            },
        -            "universe": {
        -              "additionalProperties": true,
        -              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -              "properties": {
        -                "assets": {
        -                  "items": {
        -                    "additionalProperties": true,
        -                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -                    "properties": {
        -                      "name": {
        -                        "type": "string"
        -                      },
        -                      "symbol": {
        -                        "type": "string"
        -                      },
        -                      "type": {
        -                        "enum": [
        -                          "Stock",
        -                          "Cryptocurrency",
        -                          "Option",
        -                          "Other"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "type",
        -                      "symbol"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "type": "array"
        -                },
        -                "source": {
        -                  "enum": [
        -                    "ALL_US_STOCKS",
        -                    "SP500",
        -                    "NASDAQ100",
        -                    "DJIA",
        -                    "CRYPTO",
        -                    "SPECIFIC_ASSETS"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "source"
        -              ],
        -              "type": "object"
        -            },
        -            "weightIndicator": {
        -              "$ref": "#/$defs/indicator"
        -            }
        -          },
        -          "required": [
        -            "name"
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "structureTemplates": {
        -        "items": {
        -          "additionalProperties": true,
        -          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        -          "properties": {
        -            "eligibility": {
        -              "$ref": "#/$defs/condition"
        -            },
        -            "legs": {
        -              "items": {
        -                "additionalProperties": true,
        -                "description": "Single leg of an option builder.",
        -                "properties": {
        -                  "direction": {
        -                    "enum": [
        -                      "long",
        -                      "short"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "expirationRange": {
        -                    "additionalProperties": true,
        -                    "type": "object"
        -                  },
        -                  "expirationSelector": {
        -                    "properties": {
        -                      "maxDaysToExpiration": {
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "minDaysToExpiration": {
        -                        "minimum": 0,
        -                        "type": "number"
        -                      },
        -                      "preference": {
        -                        "enum": [
        -                          "nearest",
        -                          "middle",
        -                          "furthest"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "minDaysToExpiration",
        -                      "maxDaysToExpiration",
        -                      "preference"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "fallbackStrikeSelector": {
        -                    "additionalProperties": false,
        -                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        -                    "properties": {
        -                      "distance": {
        -                        "type": "number"
        -                      },
        -                      "distanceType": {
        -                        "enum": [
        -                          "percent",
        -                          "dollars"
        -                        ],
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "distanceType",
        -                      "distance"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "greekFilter": {
        -                    "additionalProperties": true,
        -                    "description": "Optional min/max constraints on Greeks during resolution.",
        -                    "type": "object"
        -                  },
        -                  "liquidityFilter": {
        -                    "additionalProperties": false,
        -                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        -                    "properties": {
        -                      "maxSpreadAbsolute": {
        -                        "type": "number"
        -                      },
        -                      "maxSpreadPct": {
        -                        "type": "number"
        -                      },
        -                      "minBid": {
        -                        "type": "number"
        -                      }
        -                    },
        -                    "type": "object"
        -                  },
        -                  "optionType": {
        -                    "enum": [
        -                      "call",
        -                      "put"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "ratio": {
        -                    "type": "number"
        -                  },
        -                  "strikeRange": {
        -                    "additionalProperties": true,
        -                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        -                    "type": "object"
        -                  },
        -                  "strikeSelector": {
        -                    "properties": {
        -                      "distance": {
        -                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        -                        "type": "number"
        -                      },
        -                      "distanceType": {
        -                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "distanceType",
        -                      "distance"
        -                    ],
        -                    "type": "object"
        -                  }
        -                },
        -                "required": [
        -                  "optionType",
        -                  "direction",
        -                  "expirationSelector",
        -                  "strikeSelector"
        -                ],
        -                "type": "object"
        -              },
        -              "minItems": 1,
        -              "type": "array"
        -            },
        -            "name": {
        -              "type": "string"
        -            },
        -            "spreadType": {
        -              "enum": [
        -                "vertical",
        -                "calendar",
        -                "diagonal",
        -                "ironCondor",
        -                "straddle",
        -                "strangle",
        -                "custom"
        -              ],
        -              "type": "string"
        -            },
        -            "widthConstraint": {
        -              "additionalProperties": false,
        -              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        -              "properties": {
        -                "minWidthDollars": {
        -                  "exclusiveMinimum": 0,
        -                  "type": "number"
        -                },
        -                "minWidthPercent": {
        -                  "exclusiveMinimum": 0,
        -                  "type": "number"
        -                }
        -              },
        -              "type": "object"
        -            }
        -          },
        -          "required": [
        -            "legs"
        -          ],
        -          "type": "object"
        -        },
        -        "minItems": 1,
        -        "type": "array"
        -      },
        -      "totalBudget": {
        -        "additionalProperties": true,
        -        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        -        "properties": {
        -          "amount": {
        -            "minimum": 0,
        -            "type": "number"
        -          },
        -          "type": {
        -            "enum": [
        -              "dollars",
        -              "percent of portfolio"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "type",
        -          "amount"
        -        ],
        -        "type": "object"
        -      },
        -      "type": {
        -        "const": "RebalanceOption",
        -        "type": "string"
        -      },
        -      "universe": {
        -        "additionalProperties": true,
        -        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        -        "properties": {
        -          "assets": {
        -            "items": {
        -              "additionalProperties": true,
        -              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        -              "properties": {
        -                "name": {
        -                  "type": "string"
        -                },
        -                "symbol": {
        -                  "type": "string"
        -                },
        -                "type": {
        -                  "enum": [
        -                    "Stock",
        -                    "Cryptocurrency",
        -                    "Option",
        -                    "Other"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "symbol"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "source": {
        -            "enum": [
        -              "ALL_US_STOCKS",
        -              "SP500",
        -              "NASDAQ100",
        -              "DJIA",
        -              "CRYPTO",
        -              "SPECIFIC_ASSETS"
        -            ],
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "weightIndicator": {
        -        "$ref": "#/$defs/indicator"
        -      }
        -    },
        -    "required": [
        -      "type",
        -      "universe",
        -      "pipeline",
        -      "weightIndicator",
        -      "structureTemplates"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": true,
        -    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        -    "properties": {
        -      "closeScope": {
        -        "enum": [
        -          "spread",
        -          "leg"
        -        ],
        -        "type": "string"
        -      },
        -      "direction": {
        -        "enum": [
        -          "long",
        -          "short"
        -        ],
        -        "type": "string"
        -      },
        -      "optionType": {
        -        "enum": [
        -          "call",
        -          "put"
        -        ],
        -        "type": "string"
        -      },
        -      "quantity": {
        -        "additionalProperties": true,
        -        "description": "How many contracts to close. Defaults to all matching when omitted.",
        -        "type": "object"
        -      },
        -      "spreadType": {
        -        "enum": [
        -          "vertical",
        -          "calendar",
        -          "diagonal",
        -          "ironCondor",
        -          "straddle",
        -          "strangle",
        -          "custom"
        -        ],
        -        "type": "string"
        -      },
        -      "triggers": {
        -        "items": {
        -          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        -          "oneOf": [
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxPnlPercent": {
        -                  "type": "number"
        -                },
        -                "minPnlPercent": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "pnl",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxDte": {
        -                  "type": "number"
        -                },
        -                "minDte": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "dte",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxDaysHeld": {
        -                  "type": "number"
        -                },
        -                "minDaysHeld": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "daysHeld",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "properties": {
        -                "maxIv": {
        -                  "type": "number"
        -                },
        -                "maxSpreadDelta": {
        -                  "type": "number"
        -                },
        -                "maxSpreadTheta": {
        -                  "type": "number"
        -                },
        -                "minIv": {
        -                  "type": "number"
        -                },
        -                "minSpreadDelta": {
        -                  "type": "number"
        -                },
        -                "minSpreadTheta": {
        -                  "type": "number"
        -                },
        -                "type": {
        -                  "const": "greeks",
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "type"
        -              ],
        -              "type": "object"
        -            }
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "type": {
        -        "const": "CloseOption",
        -        "type": "string"
        -      },
        -      "underlyings": {
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array"
        -      }
        -    },
        -    "required": [
        -      "type"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": true,
        +    "description": "Buy or Sell a stock/crypto position.",
        +    "properties": {
        +      "amount": {
        +        "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "percent of current positions",
        +              "dollars",
        +              "number of assets"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "targetAsset": {
        +        "additionalProperties": true,
        +        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +        "properties": {
        +          "name": {
        +            "type": "string"
        +          },
        +          "symbol": {
        +            "type": "string"
        +          },
        +          "type": {
        +            "enum": [
        +              "Stock",
        +              "Cryptocurrency",
        +              "Option",
        +              "Other"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "symbol"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "enum": [
        +          "Buy",
        +          "Sell"
        +        ],
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "targetAsset",
        +      "amount"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Send an alert message (no order).",
        +    "properties": {
        +      "message": {
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "Alert",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "message"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        +    "properties": {
        +      "allocationPolicy": {
        +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "expectedReturnShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "riskAversion": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MeanVariance",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "riskAversion",
        +              "expectedReturnShrinkage",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "RiskParity",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MaximumDiversification",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "canSell": {
        +        "$ref": "#/$defs/condition",
        +        "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        +      },
        +      "deploymentPercent": {
        +        "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        +        "maximum": 100,
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "exposurePolicy": {
        +        "additionalProperties": false,
        +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +        "properties": {
        +          "covarianceShrinkage": {
        +            "maximum": 1,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "estimatedTransactionCostBps": {
        +            "maximum": 10000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "lookbackPeriods": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "minimumObservations": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "targetAnnualizedVolatilityPercent": {
        +            "maximum": 1000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "const": "VolatilityTarget",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "lookbackPeriods",
        +          "minimumObservations",
        +          "covarianceShrinkage",
        +          "targetAnnualizedVolatilityPercent",
        +          "estimatedTransactionCostBps"
        +        ],
        +        "type": "object"
        +      },
        +      "limit": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "perNameAllocation": {
        +        "additionalProperties": true,
        +        "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts, percent of buying power and percent of realized premium are rejected.",
        +        "properties": {
        +          "amount": {
        +            "exclusiveMinimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "percent of portfolio",
        +              "dollars"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "pipeline": {
        +        "items": {
        +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "condition": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "type": {
        +                  "const": "Filter",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "condition"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "type": {
        +                  "const": "SelectTop",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "limit",
        +                "direction"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "percentile": {
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "SelectPercentile",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "percentile",
        +                "direction"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "type": {
        +        "const": "DynamicRebalance",
        +        "type": "string"
        +      },
        +      "universe": {
        +        "additionalProperties": true,
        +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +        "properties": {
        +          "assets": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +              "properties": {
        +                "name": {
        +                  "type": "string"
        +                },
        +                "symbol": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Stock",
        +                    "Cryptocurrency",
        +                    "Option",
        +                    "Other"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "symbol"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "enum": [
        +              "ALL_US_STOCKS",
        +              "SP500",
        +              "NASDAQ100",
        +              "DJIA",
        +              "CRYPTO",
        +              "SPECIFIC_ASSETS"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "weightIndicator": {
        +        "$ref": "#/$defs/indicator"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "universe",
        +      "pipeline",
        +      "weightIndicator"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        +    "properties": {
        +      "continueExisting": {
        +        "type": "boolean"
        +      },
        +      "cooldownMinutes": {
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "executionModel": {
        +        "type": "string"
        +      },
        +      "includeMarketData": {
        +        "type": "boolean"
        +      },
        +      "initialMessage": {
        +        "type": "string"
        +      },
        +      "maxIterations": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "planningModel": {
        +        "type": "string"
        +      },
        +      "skipPlanning": {
        +        "type": "boolean"
        +      },
        +      "type": {
        +        "const": "LaunchAgent",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "planningModel",
        +      "executionModel",
        +      "initialMessage",
        +      "maxIterations",
        +      "includeMarketData",
        +      "continueExisting",
        +      "skipPlanning"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        +    "properties": {
        +      "against": {
        +        "additionalProperties": true,
        +        "description": "Optional parent-position selector (e.g. for covered calls).",
        +        "type": "object"
        +      },
        +      "allocation": {
        +        "additionalProperties": true,
        +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "contracts",
        +              "percent of realized premium"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "builder": {
        +        "additionalProperties": true,
        +        "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        +        "properties": {
        +          "dynamicUnderlying": {
        +            "additionalProperties": true,
        +            "properties": {
        +              "limit": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "pipeline": {
        +                "items": {
        +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                  "oneOf": [
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "condition": {
        +                          "$ref": "#/$defs/condition"
        +                        },
        +                        "type": {
        +                          "const": "Filter",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "condition"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "limit": {
        +                          "minimum": 1,
        +                          "type": "number"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "type": {
        +                          "const": "SelectTop",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "limit",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "percentile": {
        +                          "maximum": 100,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "SelectPercentile",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "percentile",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "universe": {
        +                "additionalProperties": true,
        +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                "properties": {
        +                  "assets": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                      "properties": {
        +                        "name": {
        +                          "type": "string"
        +                        },
        +                        "symbol": {
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "enum": [
        +                            "Stock",
        +                            "Cryptocurrency",
        +                            "Option",
        +                            "Other"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "symbol"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "type": "array"
        +                  },
        +                  "source": {
        +                    "enum": [
        +                      "ALL_US_STOCKS",
        +                      "SP500",
        +                      "NASDAQ100",
        +                      "DJIA",
        +                      "CRYPTO",
        +                      "SPECIFIC_ASSETS"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "source"
        +                ],
        +                "type": "object"
        +              }
        +            },
        +            "required": [
        +              "universe"
        +            ],
        +            "type": "object"
        +          },
        +          "legs": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Single leg of an option builder.",
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "long",
        +                    "short"
        +                  ],
        +                  "type": "string"
        +                },
        +                "expirationRange": {
        +                  "additionalProperties": true,
        +                  "type": "object"
        +                },
        +                "expirationSelector": {
        +                  "properties": {
        +                    "maxDaysToExpiration": {
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "minDaysToExpiration": {
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "preference": {
        +                      "enum": [
        +                        "nearest",
        +                        "middle",
        +                        "furthest"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "minDaysToExpiration",
        +                    "maxDaysToExpiration",
        +                    "preference"
        +                  ],
        +                  "type": "object"
        +                },
        +                "fallbackStrikeSelector": {
        +                  "additionalProperties": false,
        +                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                  "properties": {
        +                    "distance": {
        +                      "type": "number"
        +                    },
        +                    "distanceType": {
        +                      "enum": [
        +                        "percent",
        +                        "dollars"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "distanceType",
        +                    "distance"
        +                  ],
        +                  "type": "object"
        +                },
        +                "greekFilter": {
        +                  "additionalProperties": true,
        +                  "description": "Optional min/max constraints on Greeks during resolution.",
        +                  "type": "object"
        +                },
        +                "liquidityFilter": {
        +                  "additionalProperties": false,
        +                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                  "properties": {
        +                    "maxSpreadAbsolute": {
        +                      "type": "number"
        +                    },
        +                    "maxSpreadPct": {
        +                      "type": "number"
        +                    },
        +                    "minBid": {
        +                      "type": "number"
        +                    }
        +                  },
        +                  "type": "object"
        +                },
        +                "optionType": {
        +                  "enum": [
        +                    "call",
        +                    "put"
        +                  ],
        +                  "type": "string"
        +                },
        +                "ratio": {
        +                  "type": "number"
        +                },
        +                "strikeRange": {
        +                  "additionalProperties": true,
        +                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                  "type": "object"
        +                },
        +                "strikeSelector": {
        +                  "properties": {
        +                    "distance": {
        +                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                      "type": "number"
        +                    },
        +                    "distanceType": {
        +                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "distanceType",
        +                    "distance"
        +                  ],
        +                  "type": "object"
        +                }
        +              },
        +              "required": [
        +                "optionType",
        +                "direction",
        +                "expirationSelector",
        +                "strikeSelector"
        +              ],
        +              "type": "object"
        +            },
        +            "minItems": 1,
        +            "type": "array"
        +          },
        +          "spreadType": {
        +            "enum": [
        +              "vertical",
        +              "calendar",
        +              "diagonal",
        +              "ironCondor",
        +              "straddle",
        +              "strangle",
        +              "custom"
        +            ],
        +            "type": "string"
        +          },
        +          "underlyingSymbol": {
        +            "type": "string"
        +          },
        +          "widthConstraint": {
        +            "additionalProperties": false,
        +            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +            "properties": {
        +              "minWidthDollars": {
        +                "exclusiveMinimum": 0,
        +                "type": "number"
        +              },
        +              "minWidthPercent": {
        +                "exclusiveMinimum": 0,
        +                "type": "number"
        +              }
        +            },
        +            "type": "object"
        +          }
        +        },
        +        "required": [
        +          "legs"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "const": "OpenOption",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "builder"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        +    "properties": {
        +      "allocationPolicy": {
        +        "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "expectedReturnShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "riskAversion": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MeanVariance",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "riskAversion",
        +              "expectedReturnShrinkage",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "RiskParity",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "turnoverPenalty": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "MaximumDiversification",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "turnoverPenalty",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "exposurePolicy": {
        +        "additionalProperties": false,
        +        "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +        "properties": {
        +          "covarianceShrinkage": {
        +            "maximum": 1,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "estimatedTransactionCostBps": {
        +            "maximum": 10000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "lookbackPeriods": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "minimumObservations": {
        +            "maximum": 5000,
        +            "minimum": 2,
        +            "type": "integer"
        +          },
        +          "targetAnnualizedVolatilityPercent": {
        +            "maximum": 1000,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "const": "VolatilityTarget",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "lookbackPeriods",
        +          "minimumObservations",
        +          "covarianceShrinkage",
        +          "targetAnnualizedVolatilityPercent",
        +          "estimatedTransactionCostBps"
        +        ],
        +        "type": "object"
        +      },
        +      "limit": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "perNameAllocation": {
        +        "additionalProperties": true,
        +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "contracts",
        +              "percent of realized premium"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "pipeline": {
        +        "items": {
        +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "condition": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "type": {
        +                  "const": "Filter",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "condition"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "type": {
        +                  "const": "SelectTop",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "limit",
        +                "direction"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "percentile": {
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "SelectPercentile",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "percentile",
        +                "direction"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "positionScope": {
        +        "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        +        "enum": [
        +          "portfolio",
        +          "strategy"
        +        ],
        +        "type": "string"
        +      },
        +      "sleeves": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        +          "properties": {
        +            "limit": {
        +              "minimum": 1,
        +              "type": "number"
        +            },
        +            "name": {
        +              "type": "string"
        +            },
        +            "perNameAllocation": {
        +              "additionalProperties": true,
        +              "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). On OpenOption.allocation, type 'percent of realized premium' spends a percent of the OptionRealizedPremium balance (closed short-option P&L minus premium already spent this way, never gross premium collected) and resolves to 0 while that balance is not positive, so it needs no separate balance condition. Its amount must be at most 100, because more would spend more than the realized balance. DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +              "properties": {
        +                "amount": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "dollars",
        +                    "percent of portfolio",
        +                    "percent of buying power",
        +                    "contracts",
        +                    "percent of realized premium"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "amount"
        +              ],
        +              "type": "object"
        +            },
        +            "pipeline": {
        +              "items": {
        +                "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                "oneOf": [
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "condition": {
        +                        "$ref": "#/$defs/condition"
        +                      },
        +                      "type": {
        +                        "const": "Filter",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "condition"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "direction": {
        +                        "enum": [
        +                          "Highest",
        +                          "Lowest"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "limit": {
        +                        "minimum": 1,
        +                        "type": "number"
        +                      },
        +                      "metric": {
        +                        "$ref": "#/$defs/indicator"
        +                      },
        +                      "type": {
        +                        "const": "SelectTop",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "metric",
        +                      "limit",
        +                      "direction"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "direction": {
        +                        "enum": [
        +                          "Highest",
        +                          "Lowest"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "metric": {
        +                        "$ref": "#/$defs/indicator"
        +                      },
        +                      "percentile": {
        +                        "maximum": 100,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "SelectPercentile",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "metric",
        +                      "percentile",
        +                      "direction"
        +                    ],
        +                    "type": "object"
        +                  }
        +                ],
        +                "type": "object"
        +              },
        +              "type": "array"
        +            },
        +            "structureTemplates": {
        +              "items": {
        +                "additionalProperties": true,
        +                "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +                "properties": {
        +                  "eligibility": {
        +                    "$ref": "#/$defs/condition"
        +                  },
        +                  "legs": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Single leg of an option builder.",
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "long",
        +                            "short"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "expirationRange": {
        +                          "additionalProperties": true,
        +                          "type": "object"
        +                        },
        +                        "expirationSelector": {
        +                          "properties": {
        +                            "maxDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "minDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "preference": {
        +                              "enum": [
        +                                "nearest",
        +                                "middle",
        +                                "furthest"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "minDaysToExpiration",
        +                            "maxDaysToExpiration",
        +                            "preference"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "fallbackStrikeSelector": {
        +                          "additionalProperties": false,
        +                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                          "properties": {
        +                            "distance": {
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "enum": [
        +                                "percent",
        +                                "dollars"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "greekFilter": {
        +                          "additionalProperties": true,
        +                          "description": "Optional min/max constraints on Greeks during resolution.",
        +                          "type": "object"
        +                        },
        +                        "liquidityFilter": {
        +                          "additionalProperties": false,
        +                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                          "properties": {
        +                            "maxSpreadAbsolute": {
        +                              "type": "number"
        +                            },
        +                            "maxSpreadPct": {
        +                              "type": "number"
        +                            },
        +                            "minBid": {
        +                              "type": "number"
        +                            }
        +                          },
        +                          "type": "object"
        +                        },
        +                        "optionType": {
        +                          "enum": [
        +                            "call",
        +                            "put"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "ratio": {
        +                          "type": "number"
        +                        },
        +                        "strikeRange": {
        +                          "additionalProperties": true,
        +                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                          "type": "object"
        +                        },
        +                        "strikeSelector": {
        +                          "properties": {
        +                            "distance": {
        +                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        }
        +                      },
        +                      "required": [
        +                        "optionType",
        +                        "direction",
        +                        "expirationSelector",
        +                        "strikeSelector"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "minItems": 1,
        +                    "type": "array"
        +                  },
        +                  "name": {
        +                    "type": "string"
        +                  },
        +                  "spreadType": {
        +                    "enum": [
        +                      "vertical",
        +                      "calendar",
        +                      "diagonal",
        +                      "ironCondor",
        +                      "straddle",
        +                      "strangle",
        +                      "custom"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "widthConstraint": {
        +                    "additionalProperties": false,
        +                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                    "properties": {
        +                      "minWidthDollars": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minWidthPercent": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "legs"
        +                ],
        +                "type": "object"
        +              },
        +              "minItems": 1,
        +              "type": "array"
        +            },
        +            "universe": {
        +              "additionalProperties": true,
        +              "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +              "properties": {
        +                "assets": {
        +                  "items": {
        +                    "additionalProperties": true,
        +                    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                    "properties": {
        +                      "name": {
        +                        "type": "string"
        +                      },
        +                      "symbol": {
        +                        "type": "string"
        +                      },
        +                      "type": {
        +                        "enum": [
        +                          "Stock",
        +                          "Cryptocurrency",
        +                          "Option",
        +                          "Other"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "symbol"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "type": "array"
        +                },
        +                "source": {
        +                  "enum": [
        +                    "ALL_US_STOCKS",
        +                    "SP500",
        +                    "NASDAQ100",
        +                    "DJIA",
        +                    "CRYPTO",
        +                    "SPECIFIC_ASSETS"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "source"
        +              ],
        +              "type": "object"
        +            },
        +            "weightIndicator": {
        +              "$ref": "#/$defs/indicator"
        +            }
        +          },
        +          "required": [
        +            "name"
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "structureTemplates": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +          "properties": {
        +            "eligibility": {
        +              "$ref": "#/$defs/condition"
        +            },
        +            "legs": {
        +              "items": {
        +                "additionalProperties": true,
        +                "description": "Single leg of an option builder.",
        +                "properties": {
        +                  "direction": {
        +                    "enum": [
        +                      "long",
        +                      "short"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "expirationRange": {
        +                    "additionalProperties": true,
        +                    "type": "object"
        +                  },
        +                  "expirationSelector": {
        +                    "properties": {
        +                      "maxDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "preference": {
        +                        "enum": [
        +                          "nearest",
        +                          "middle",
        +                          "furthest"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "minDaysToExpiration",
        +                      "maxDaysToExpiration",
        +                      "preference"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "fallbackStrikeSelector": {
        +                    "additionalProperties": false,
        +                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                    "properties": {
        +                      "distance": {
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "enum": [
        +                          "percent",
        +                          "dollars"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "greekFilter": {
        +                    "additionalProperties": true,
        +                    "description": "Optional min/max constraints on Greeks during resolution.",
        +                    "type": "object"
        +                  },
        +                  "liquidityFilter": {
        +                    "additionalProperties": false,
        +                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                    "properties": {
        +                      "maxSpreadAbsolute": {
        +                        "type": "number"
        +                      },
        +                      "maxSpreadPct": {
        +                        "type": "number"
        +                      },
        +                      "minBid": {
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  },
        +                  "optionType": {
        +                    "enum": [
        +                      "call",
        +                      "put"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "ratio": {
        +                    "type": "number"
        +                  },
        +                  "strikeRange": {
        +                    "additionalProperties": true,
        +                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                    "type": "object"
        +                  },
        +                  "strikeSelector": {
        +                    "properties": {
        +                      "distance": {
        +                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "optionType",
        +                  "direction",
        +                  "expirationSelector",
        +                  "strikeSelector"
        +                ],
        +                "type": "object"
        +              },
        +              "minItems": 1,
        +              "type": "array"
        +            },
        +            "name": {
        +              "type": "string"
        +            },
        +            "spreadType": {
        +              "enum": [
        +                "vertical",
        +                "calendar",
        +                "diagonal",
        +                "ironCondor",
        +                "straddle",
        +                "strangle",
        +                "custom"
        +              ],
        +              "type": "string"
        +            },
        +            "widthConstraint": {
        +              "additionalProperties": false,
        +              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +              "properties": {
        +                "minWidthDollars": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                },
        +                "minWidthPercent": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                }
        +              },
        +              "type": "object"
        +            }
        +          },
        +          "required": [
        +            "legs"
        +          ],
        +          "type": "object"
        +        },
        +        "minItems": 1,
        +        "type": "array"
        +      },
        +      "totalBudget": {
        +        "additionalProperties": true,
        +        "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        +        "properties": {
        +          "amount": {
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "type": {
        +        "const": "RebalanceOption",
        +        "type": "string"
        +      },
        +      "universe": {
        +        "additionalProperties": true,
        +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +        "properties": {
        +          "assets": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +              "properties": {
        +                "name": {
        +                  "type": "string"
        +                },
        +                "symbol": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Stock",
        +                    "Cryptocurrency",
        +                    "Option",
        +                    "Other"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "symbol"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "enum": [
        +              "ALL_US_STOCKS",
        +              "SP500",
        +              "NASDAQ100",
        +              "DJIA",
        +              "CRYPTO",
        +              "SPECIFIC_ASSETS"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "weightIndicator": {
        +        "$ref": "#/$defs/indicator"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "universe",
        +      "pipeline",
        +      "weightIndicator",
        +      "structureTemplates"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        +    "properties": {
        +      "closeScope": {
        +        "enum": [
        +          "spread",
        +          "leg"
        +        ],
        +        "type": "string"
        +      },
        +      "direction": {
        +        "enum": [
        +          "long",
        +          "short"
        +        ],
        +        "type": "string"
        +      },
        +      "optionType": {
        +        "enum": [
        +          "call",
        +          "put"
        +        ],
        +        "type": "string"
        +      },
        +      "quantity": {
        +        "additionalProperties": true,
        +        "description": "How many contracts to close. Defaults to all matching when omitted.",
        +        "type": "object"
        +      },
        +      "spreadType": {
        +        "enum": [
        +          "vertical",
        +          "calendar",
        +          "diagonal",
        +          "ironCondor",
        +          "straddle",
        +          "strangle",
        +          "custom"
        +        ],
        +        "type": "string"
        +      },
        +      "triggers": {
        +        "items": {
        +          "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxPnlPercent": {
        +                  "type": "number"
        +                },
        +                "minPnlPercent": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "pnl",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxDte": {
        +                  "type": "number"
        +                },
        +                "minDte": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "dte",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxDaysHeld": {
        +                  "type": "number"
        +                },
        +                "minDaysHeld": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "daysHeld",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "maxIv": {
        +                  "type": "number"
        +                },
        +                "maxSpreadDelta": {
        +                  "type": "number"
        +                },
        +                "maxSpreadTheta": {
        +                  "type": "number"
        +                },
        +                "minIv": {
        +                  "type": "number"
        +                },
        +                "minSpreadDelta": {
        +                  "type": "number"
        +                },
        +                "minSpreadTheta": {
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "greeks",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "type": {
        +        "const": "CloseOption",
        +        "type": "string"
        +      },
        +      "underlyings": {
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  }
        +]
  6. 1 tool update
    • Changedbacktest_portfolio3 fields changed
      • changedInput schema / properties / end_date / description
        Previous value: -"Backtest end date (ISO format, e.g. 2024-12-31). Minute hard max is 365 days from start_date; extend a survivor in a later run instead of splitting into yearly Minute jobs."New value: +"Backtest end date (ISO format, e.g. 2024-12-31). Minute allows up to 730 days of minute data from start_date, counting minute-indicator warmup; never split a longer span into yearly Minute jobs."
      • changedInput schema / properties / interval / description
        Previous value: -"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 365 days is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year is a normal second backtest, not an escalation."New value: +"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 730 days of minute data (selected range plus warmup) is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year or two is a normal second backtest, not an escalation."
      • changedInput schema / properties / start_date / description
        Previous value: -"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range cannot exceed 365 days. Do not use 2010-01-01 or a multi-year span on Minute."New value: +"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range plus minute-indicator warmup cannot exceed 730 days of minute data. Do not use 2010-01-01 on Minute."
  7. 1 tool update
    • Changedbacktest_portfolio3 fields changed
      • changedInput schema / properties / end_date / description
        Previous value: -"Backtest end date (ISO format, e.g. 2024-12-31). Minute allows up to 730 days of minute data from start_date, counting minute-indicator warmup; never split a longer span into yearly Minute jobs."New value: +"Backtest end date (ISO format, e.g. 2024-12-31). Minute hard max is 365 days from start_date; extend a survivor in a later run instead of splitting into yearly Minute jobs."
      • changedInput schema / properties / interval / description
        Previous value: -"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 730 days of minute data (selected range plus warmup) is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year or two is a normal second backtest, not an escalation."New value: +"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 365 days is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year is a normal second backtest, not an escalation."
      • changedInput schema / properties / start_date / description
        Previous value: -"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range plus minute-indicator warmup cannot exceed 730 days of minute data. Do not use 2010-01-01 on Minute."New value: +"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range cannot exceed 365 days. Do not use 2010-01-01 or a multi-year span on Minute."
  8. 1 tool update
    • Changedbacktest_portfolio3 fields changed
      • changedInput schema / properties / end_date / description
        Previous value: -"Backtest end date (ISO format, e.g. 2024-12-31). Minute hard max is 365 days from start_date; extend a survivor in a later run instead of splitting into yearly Minute jobs."New value: +"Backtest end date (ISO format, e.g. 2024-12-31). Minute allows up to 730 days of minute data from start_date, counting minute-indicator warmup; never split a longer span into yearly Minute jobs."
      • changedInput schema / properties / interval / description
        Previous value: -"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 365 days is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year is a normal second backtest, not an escalation."New value: +"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 730 days of minute data (selected range plus warmup) is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year or two is a normal second backtest, not an escalation."
      • changedInput schema / properties / start_date / description
        Previous value: -"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range cannot exceed 365 days. Do not use 2010-01-01 or a multi-year span on Minute."New value: +"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range plus minute-indicator warmup cannot exceed 730 days of minute data. Do not use 2010-01-01 on Minute."
  9. 1 tool update
    • Changedbacktest_portfolio3 fields changed
      • changedInput schema / properties / end_date / description
        Previous value: -"Backtest end date (ISO format, e.g. 2024-12-31). Minute allows up to 730 days of minute data from start_date, counting minute-indicator warmup; never split a longer span into yearly Minute jobs."New value: +"Backtest end date (ISO format, e.g. 2024-12-31). Minute hard max is 365 days from start_date; extend a survivor in a later run instead of splitting into yearly Minute jobs."
      • changedInput schema / properties / interval / description
        Previous value: -"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 730 days of minute data (selected range plus warmup) is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year or two is a normal second backtest, not an escalation."New value: +"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 365 days is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year is a normal second backtest, not an escalation."
      • changedInput schema / properties / start_date / description
        Previous value: -"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range plus minute-indicator warmup cannot exceed 730 days of minute data. Do not use 2010-01-01 on Minute."New value: +"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range cannot exceed 365 days. Do not use 2010-01-01 or a multi-year span on Minute."
  10. 1 tool update
    • Changedbacktest_portfolio3 fields changed
      • changedInput schema / properties / end_date / description
        Previous value: -"Backtest end date (ISO format, e.g. 2024-12-31). Minute hard max is 365 days from start_date; extend a survivor in a later run instead of splitting into yearly Minute jobs."New value: +"Backtest end date (ISO format, e.g. 2024-12-31). Minute allows up to 730 days of minute data from start_date, counting minute-indicator warmup; never split a longer span into yearly Minute jobs."
      • changedInput schema / properties / interval / description
        Previous value: -"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 365 days is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year is a normal second backtest, not an escalation."New value: +"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 730 days of minute data (selected range plus warmup) is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year or two is a normal second backtest, not an escalation."
      • changedInput schema / properties / start_date / description
        Previous value: -"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range cannot exceed 365 days. Do not use 2010-01-01 or a multi-year span on Minute."New value: +"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range plus minute-indicator warmup cannot exceed 730 days of minute data. Do not use 2010-01-01 on Minute."
  11. 1 tool update
    • Changedbacktest_portfolio3 fields changed
      • changedInput schema / properties / end_date / description
        Previous value: -"Backtest end date (ISO format, e.g. 2024-12-31). Minute allows up to 730 days of minute data from start_date, counting minute-indicator warmup; never split a longer span into yearly Minute jobs."New value: +"Backtest end date (ISO format, e.g. 2024-12-31). Minute hard max is 365 days from start_date; extend a survivor in a later run instead of splitting into yearly Minute jobs."
      • changedInput schema / properties / interval / description
        Previous value: -"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 730 days of minute data (selected range plus warmup) is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year or two is a normal second backtest, not an escalation."New value: +"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 365 days is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year is a normal second backtest, not an escalation."
      • changedInput schema / properties / start_date / description
        Previous value: -"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range plus minute-indicator warmup cannot exceed 730 days of minute data. Do not use 2010-01-01 on Minute."New value: +"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range cannot exceed 365 days. Do not use 2010-01-01 or a multi-year span on Minute."
  12. 1 tool update
    • Changedbacktest_portfolio3 fields changed
      • changedInput schema / properties / end_date / description
        Previous value: -"Backtest end date (ISO format, e.g. 2024-12-31). Minute hard max is 365 days from start_date; extend a survivor in a later run instead of splitting into yearly Minute jobs."New value: +"Backtest end date (ISO format, e.g. 2024-12-31). Minute allows up to 730 days of minute data from start_date, counting minute-indicator warmup; never split a longer span into yearly Minute jobs."
      • changedInput schema / properties / interval / description
        Previous value: -"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 365 days is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year is a normal second backtest, not an escalation."New value: +"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 730 days of minute data (selected range plus warmup) is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year or two is a normal second backtest, not an escalation."
      • changedInput schema / properties / start_date / description
        Previous value: -"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range cannot exceed 365 days. Do not use 2010-01-01 or a multi-year span on Minute."New value: +"Backtest start date (ISO format, e.g. 2024-01-01). For interval=Minute, default first-look is the last 90 inclusive calendar days and the selected range plus minute-indicator warmup cannot exceed 730 days of minute data. Do not use 2010-01-01 on Minute."
  13. 4 tool updates
    • Changedbacktest_portfolio1 field changed
      • changedInput schema / properties / interval / description
        Previous value: -"Time interval: Day or Minute (default Day). Minute is a daytrade tape — first-look 90 days, hard max 365 days."New value: +"Time interval: Day or Minute (default Day). Minute is a daytrade tape. 365 days is the HARD CAP; 90 days is only the DEFAULT when you name no dates. Name the dates you actually want — certifying a candidate on a full year is a normal second backtest, not an escalation."
    • Changedbuild_portfolio6 fields changed
      • addedInput schema / $defs / orderExecution
        Added value: +{
        +  "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.",
        +  "oneOf": [
        +    {
        +      "additionalProperties": false,
        +      "properties": {
        +        "type": {
        +          "const": "Market",
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "type"
        +      ],
        +      "type": "object"
        +    },
        +    {
        +      "additionalProperties": false,
        +      "properties": {
        +        "price": {
        +          "oneOf": [
        +            {
        +              "additionalProperties": false,
        +              "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        +              "properties": {
        +                "amount": {
        +                  "minimum": 1e-8,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "UnitPrice",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "amount"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": false,
        +              "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        +              "properties": {
        +                "amount": {
        +                  "minimum": 1e-8,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "MinimumNetCredit",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "amount"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": false,
        +              "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        +              "properties": {
        +                "amount": {
        +                  "minimum": 1e-8,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "MaximumNetDebit",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "amount"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": false,
        +              "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        +              "properties": {
        +                "reference": {
        +                  "const": "Current",
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "const": "QuoteRelative",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "reference"
        +              ],
        +              "type": "object"
        +            }
        +          ]
        +        },
        +        "type": {
        +          "const": "Limit",
        +          "type": "string"
        +        },
        +        "workingTime": {
        +          "oneOf": [
        +            {
        +              "additionalProperties": false,
        +              "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        +              "properties": {
        +                "type": {
        +                  "const": "Day",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": false,
        +              "properties": {
        +                "minutes": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "Minutes",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "minutes"
        +              ],
        +              "type": "object"
        +            }
        +          ]
        +        }
        +      },
        +      "required": [
        +        "type",
        +        "price"
        +      ],
        +      "type": "object"
        +    }
        +  ],
        +  "type": "object"
        +}
      • changedInput schema / $defs / strategy / description
        Previous value: -"A trading strategy: a trigger condition + an action to take when the condition is true."New value: +"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
      • addedInput schema / $defs / strategy / properties / orderExecution
        Added value: +{
        +  "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.",
        +  "oneOf": [
        +    {
        +      "additionalProperties": false,
        +      "properties": {
        +        "type": {
        +          "const": "Market",
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "type"
        +      ],
        +      "type": "object"
        +    },
        +    {
        +      "additionalProperties": false,
        +      "properties": {
        +        "price": {
        +          "oneOf": [
        +            {
        +              "additionalProperties": false,
        +              "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        +              "properties": {
        +                "amount": {
        +                  "minimum": 1e-8,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "UnitPrice",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "amount"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": false,
        +              "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        +              "properties": {
        +                "amount": {
        +                  "minimum": 1e-8,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "MinimumNetCredit",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "amount"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": false,
        +              "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        +              "properties": {
        +                "amount": {
        +                  "minimum": 1e-8,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "MaximumNetDebit",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "amount"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": false,
        +              "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        +              "properties": {
        +                "reference": {
        +                  "const": "Current",
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "const": "QuoteRelative",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "reference"
        +              ],
        +              "type": "object"
        +            }
        +          ]
        +        },
        +        "type": {
        +          "const": "Limit",
        +          "type": "string"
        +        },
        +        "workingTime": {
        +          "oneOf": [
        +            {
        +              "additionalProperties": false,
        +              "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        +              "properties": {
        +                "type": {
        +                  "const": "Day",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": false,
        +              "properties": {
        +                "minutes": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "Minutes",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "minutes"
        +              ],
        +              "type": "object"
        +            }
        +          ]
        +        }
        +      },
        +      "required": [
        +        "type",
        +        "price"
        +      ],
        +      "type": "object"
        +    }
        +  ],
        +  "type": "object"
        +}
      • changedInput schema / properties / strategies / description
        Previous value: -"Array of strategies. Each strategy is { name, condition, action }. RebalanceOption actions may include action.positionScope (portfolio | strategy). See $defs.strategy / $defs.condition / $defs.indicator."New value: +"Array of strategies. Each strategy is { name, condition, action, orderExecution? }. RebalanceOption actions may include action.positionScope (portfolio | strategy). Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. See $defs.strategy / $defs.condition / $defs/indicator."
      • changedInput schema / properties / strategies / items / description
        Previous value: -"A trading strategy: a trigger condition + an action to take when the condition is true."New value: +"A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price."
      • addedInput schema / properties / strategies / items / properties / orderExecution
        Added value: +{
        +  "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.",
        +  "oneOf": [
        +    {
        +      "additionalProperties": false,
        +      "properties": {
        +        "type": {
        +          "const": "Market",
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "type"
        +      ],
        +      "type": "object"
        +    },
        +    {
        +      "additionalProperties": false,
        +      "properties": {
        +        "price": {
        +          "oneOf": [
        +            {
        +              "additionalProperties": false,
        +              "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        +              "properties": {
        +                "amount": {
        +                  "minimum": 1e-8,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "UnitPrice",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "amount"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": false,
        +              "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        +              "properties": {
        +                "amount": {
        +                  "minimum": 1e-8,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "MinimumNetCredit",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "amount"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": false,
        +              "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        +              "properties": {
        +                "amount": {
        +                  "minimum": 1e-8,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "MaximumNetDebit",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "amount"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": false,
        +              "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        +              "properties": {
        +                "reference": {
        +                  "const": "Current",
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "const": "QuoteRelative",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "reference"
        +              ],
        +              "type": "object"
        +            }
        +          ]
        +        },
        +        "type": {
        +          "const": "Limit",
        +          "type": "string"
        +        },
        +        "workingTime": {
        +          "oneOf": [
        +            {
        +              "additionalProperties": false,
        +              "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        +              "properties": {
        +                "type": {
        +                  "const": "Day",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": false,
        +              "properties": {
        +                "minutes": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "Minutes",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "minutes"
        +              ],
        +              "type": "object"
        +            }
        +          ]
        +        }
        +      },
        +      "required": [
        +        "type",
        +        "price"
        +      ],
        +      "type": "object"
        +    }
        +  ],
        +  "type": "object"
        +}
    • Addedcreate_portfolio
    • Changedupdate_portfolio5 fields changed
      • addedInput schema / $defs
        Added value: +{
        +  "action": {
        +    "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).",
        +    "oneOf": [
        +      {
        +        "additionalProperties": true,
        +        "description": "Buy or Sell a stock/crypto position.",
        +        "properties": {
        +          "amount": {
        +            "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        +            "properties": {
        +              "amount": {
        +                "type": "number"
        +              },
        +              "type": {
        +                "enum": [
        +                  "percent of portfolio",
        +                  "percent of buying power",
        +                  "percent of current positions",
        +                  "dollars",
        +                  "number of assets"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          "targetAsset": {
        +            "additionalProperties": true,
        +            "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +            "properties": {
        +              "name": {
        +                "type": "string"
        +              },
        +              "symbol": {
        +                "type": "string"
        +              },
        +              "type": {
        +                "enum": [
        +                  "Stock",
        +                  "Cryptocurrency",
        +                  "Option",
        +                  "Other"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "symbol"
        +            ],
        +            "type": "object"
        +          },
        +          "type": {
        +            "enum": [
        +              "Buy",
        +              "Sell"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "targetAsset",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "additionalProperties": true,
        +        "description": "Send an alert message (no order).",
        +        "properties": {
        +          "message": {
        +            "type": "string"
        +          },
        +          "type": {
        +            "const": "Alert",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "message"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "additionalProperties": true,
        +        "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        +        "properties": {
        +          "allocationPolicy": {
        +            "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +            "oneOf": [
        +              {
        +                "additionalProperties": false,
        +                "properties": {
        +                  "covarianceShrinkage": {
        +                    "maximum": 1,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "estimatedTransactionCostBps": {
        +                    "maximum": 10000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "expectedReturnShrinkage": {
        +                    "maximum": 1,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "lookbackPeriods": {
        +                    "maximum": 5000,
        +                    "minimum": 2,
        +                    "type": "integer"
        +                  },
        +                  "minimumObservations": {
        +                    "maximum": 5000,
        +                    "minimum": 2,
        +                    "type": "integer"
        +                  },
        +                  "riskAversion": {
        +                    "maximum": 1000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "turnoverPenalty": {
        +                    "maximum": 10000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "const": "MeanVariance",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "lookbackPeriods",
        +                  "minimumObservations",
        +                  "riskAversion",
        +                  "expectedReturnShrinkage",
        +                  "covarianceShrinkage",
        +                  "turnoverPenalty",
        +                  "estimatedTransactionCostBps"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "additionalProperties": false,
        +                "properties": {
        +                  "covarianceShrinkage": {
        +                    "maximum": 1,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "estimatedTransactionCostBps": {
        +                    "maximum": 10000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "lookbackPeriods": {
        +                    "maximum": 5000,
        +                    "minimum": 2,
        +                    "type": "integer"
        +                  },
        +                  "minimumObservations": {
        +                    "maximum": 5000,
        +                    "minimum": 2,
        +                    "type": "integer"
        +                  },
        +                  "turnoverPenalty": {
        +                    "maximum": 10000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "const": "RiskParity",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "lookbackPeriods",
        +                  "minimumObservations",
        +                  "covarianceShrinkage",
        +                  "turnoverPenalty",
        +                  "estimatedTransactionCostBps"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "additionalProperties": false,
        +                "properties": {
        +                  "covarianceShrinkage": {
        +                    "maximum": 1,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "estimatedTransactionCostBps": {
        +                    "maximum": 10000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "lookbackPeriods": {
        +                    "maximum": 5000,
        +                    "minimum": 2,
        +                    "type": "integer"
        +                  },
        +                  "minimumObservations": {
        +                    "maximum": 5000,
        +                    "minimum": 2,
        +                    "type": "integer"
        +                  },
        +                  "turnoverPenalty": {
        +                    "maximum": 10000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "const": "MaximumDiversification",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "lookbackPeriods",
        +                  "minimumObservations",
        +                  "covarianceShrinkage",
        +                  "turnoverPenalty",
        +                  "estimatedTransactionCostBps"
        +                ],
        +                "type": "object"
        +              }
        +            ]
        +          },
        +          "canSell": {
        +            "$ref": "#/$defs/condition",
        +            "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        +          },
        +          "deploymentPercent": {
        +            "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        +            "maximum": 100,
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "exposurePolicy": {
        +            "additionalProperties": false,
        +            "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "targetAnnualizedVolatilityPercent": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "VolatilityTarget",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "targetAnnualizedVolatilityPercent",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          "limit": {
        +            "minimum": 1,
        +            "type": "number"
        +          },
        +          "perNameAllocation": {
        +            "additionalProperties": true,
        +            "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
        +            "properties": {
        +              "amount": {
        +                "exclusiveMinimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "enum": [
        +                  "percent of portfolio",
        +                  "dollars"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          "pipeline": {
        +            "items": {
        +              "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +              "oneOf": [
        +                {
        +                  "additionalProperties": true,
        +                  "properties": {
        +                    "condition": {
        +                      "$ref": "#/$defs/condition"
        +                    },
        +                    "type": {
        +                      "const": "Filter",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "type",
        +                    "condition"
        +                  ],
        +                  "type": "object"
        +                },
        +                {
        +                  "additionalProperties": true,
        +                  "properties": {
        +                    "direction": {
        +                      "enum": [
        +                        "Highest",
        +                        "Lowest"
        +                      ],
        +                      "type": "string"
        +                    },
        +                    "limit": {
        +                      "minimum": 1,
        +                      "type": "number"
        +                    },
        +                    "metric": {
        +                      "$ref": "#/$defs/indicator"
        +                    },
        +                    "type": {
        +                      "const": "SelectTop",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "type",
        +                    "metric",
        +                    "limit",
        +                    "direction"
        +                  ],
        +                  "type": "object"
        +                },
        +                {
        +                  "additionalProperties": true,
        +                  "properties": {
        +                    "direction": {
        +                      "enum": [
        +                        "Highest",
        +                        "Lowest"
        +                      ],
        +                      "type": "string"
        +                    },
        +                    "metric": {
        +                      "$ref": "#/$defs/indicator"
        +                    },
        +                    "percentile": {
        +                      "maximum": 100,
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "type": {
        +                      "const": "SelectPercentile",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "type",
        +                    "metric",
        +                    "percentile",
        +                    "direction"
        +                  ],
        +                  "type": "object"
        +                }
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "type": {
        +            "const": "DynamicRebalance",
        +            "type": "string"
        +          },
        +          "universe": {
        +            "additionalProperties": true,
        +            "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +            "properties": {
        +              "assets": {
        +                "items": {
        +                  "additionalProperties": true,
        +                  "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                  "properties": {
        +                    "name": {
        +                      "type": "string"
        +                    },
        +                    "symbol": {
        +                      "type": "string"
        +                    },
        +                    "type": {
        +                      "enum": [
        +                        "Stock",
        +                        "Cryptocurrency",
        +                        "Option",
        +                        "Other"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "type",
        +                    "symbol"
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "source": {
        +                "enum": [
        +                  "ALL_US_STOCKS",
        +                  "SP500",
        +                  "NASDAQ100",
        +                  "DJIA",
        +                  "CRYPTO",
        +                  "SPECIFIC_ASSETS"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "source"
        +            ],
        +            "type": "object"
        +          },
        +          "weightIndicator": {
        +            "$ref": "#/$defs/indicator"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "universe",
        +          "pipeline",
        +          "weightIndicator"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "additionalProperties": true,
        +        "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        +        "properties": {
        +          "continueExisting": {
        +            "type": "boolean"
        +          },
        +          "cooldownMinutes": {
        +            "minimum": 0,
        +            "type": "number"
        +          },
        +          "executionModel": {
        +            "type": "string"
        +          },
        +          "includeMarketData": {
        +            "type": "boolean"
        +          },
        +          "initialMessage": {
        +            "type": "string"
        +          },
        +          "maxIterations": {
        +            "minimum": 1,
        +            "type": "number"
        +          },
        +          "planningModel": {
        +            "type": "string"
        +          },
        +          "skipPlanning": {
        +            "type": "boolean"
        +          },
        +          "type": {
        +            "const": "LaunchAgent",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "planningModel",
        +          "executionModel",
        +          "initialMessage",
        +          "maxIterations",
        +          "includeMarketData",
        +          "continueExisting",
        +          "skipPlanning"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "additionalProperties": true,
        +        "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        +        "properties": {
        +          "against": {
        +            "additionalProperties": true,
        +            "description": "Optional parent-position selector (e.g. for covered calls).",
        +            "type": "object"
        +          },
        +          "allocation": {
        +            "additionalProperties": true,
        +            "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +            "properties": {
        +              "amount": {
        +                "type": "number"
        +              },
        +              "type": {
        +                "enum": [
        +                  "dollars",
        +                  "percent of portfolio",
        +                  "percent of buying power",
        +                  "contracts"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          "builder": {
        +            "additionalProperties": true,
        +            "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        +            "properties": {
        +              "dynamicUnderlying": {
        +                "additionalProperties": true,
        +                "properties": {
        +                  "limit": {
        +                    "minimum": 1,
        +                    "type": "number"
        +                  },
        +                  "pipeline": {
        +                    "items": {
        +                      "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                      "oneOf": [
        +                        {
        +                          "additionalProperties": true,
        +                          "properties": {
        +                            "condition": {
        +                              "$ref": "#/$defs/condition"
        +                            },
        +                            "type": {
        +                              "const": "Filter",
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "type",
        +                            "condition"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        {
        +                          "additionalProperties": true,
        +                          "properties": {
        +                            "direction": {
        +                              "enum": [
        +                                "Highest",
        +                                "Lowest"
        +                              ],
        +                              "type": "string"
        +                            },
        +                            "limit": {
        +                              "minimum": 1,
        +                              "type": "number"
        +                            },
        +                            "metric": {
        +                              "$ref": "#/$defs/indicator"
        +                            },
        +                            "type": {
        +                              "const": "SelectTop",
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "type",
        +                            "metric",
        +                            "limit",
        +                            "direction"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        {
        +                          "additionalProperties": true,
        +                          "properties": {
        +                            "direction": {
        +                              "enum": [
        +                                "Highest",
        +                                "Lowest"
        +                              ],
        +                              "type": "string"
        +                            },
        +                            "metric": {
        +                              "$ref": "#/$defs/indicator"
        +                            },
        +                            "percentile": {
        +                              "maximum": 100,
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "type": {
        +                              "const": "SelectPercentile",
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "type",
        +                            "metric",
        +                            "percentile",
        +                            "direction"
        +                          ],
        +                          "type": "object"
        +                        }
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "type": "array"
        +                  },
        +                  "universe": {
        +                    "additionalProperties": true,
        +                    "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                    "properties": {
        +                      "assets": {
        +                        "items": {
        +                          "additionalProperties": true,
        +                          "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                          "properties": {
        +                            "name": {
        +                              "type": "string"
        +                            },
        +                            "symbol": {
        +                              "type": "string"
        +                            },
        +                            "type": {
        +                              "enum": [
        +                                "Stock",
        +                                "Cryptocurrency",
        +                                "Option",
        +                                "Other"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "type",
        +                            "symbol"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "type": "array"
        +                      },
        +                      "source": {
        +                        "enum": [
        +                          "ALL_US_STOCKS",
        +                          "SP500",
        +                          "NASDAQ100",
        +                          "DJIA",
        +                          "CRYPTO",
        +                          "SPECIFIC_ASSETS"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "source"
        +                    ],
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "universe"
        +                ],
        +                "type": "object"
        +              },
        +              "legs": {
        +                "items": {
        +                  "additionalProperties": true,
        +                  "description": "Single leg of an option builder.",
        +                  "properties": {
        +                    "direction": {
        +                      "enum": [
        +                        "long",
        +                        "short"
        +                      ],
        +                      "type": "string"
        +                    },
        +                    "expirationRange": {
        +                      "additionalProperties": true,
        +                      "type": "object"
        +                    },
        +                    "expirationSelector": {
        +                      "properties": {
        +                        "maxDaysToExpiration": {
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "minDaysToExpiration": {
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "preference": {
        +                          "enum": [
        +                            "nearest",
        +                            "middle",
        +                            "furthest"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "minDaysToExpiration",
        +                        "maxDaysToExpiration",
        +                        "preference"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "fallbackStrikeSelector": {
        +                      "additionalProperties": false,
        +                      "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                      "properties": {
        +                        "distance": {
        +                          "type": "number"
        +                        },
        +                        "distanceType": {
        +                          "enum": [
        +                            "percent",
        +                            "dollars"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "distanceType",
        +                        "distance"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "greekFilter": {
        +                      "additionalProperties": true,
        +                      "description": "Optional min/max constraints on Greeks during resolution.",
        +                      "type": "object"
        +                    },
        +                    "liquidityFilter": {
        +                      "additionalProperties": false,
        +                      "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                      "properties": {
        +                        "maxSpreadAbsolute": {
        +                          "type": "number"
        +                        },
        +                        "maxSpreadPct": {
        +                          "type": "number"
        +                        },
        +                        "minBid": {
        +                          "type": "number"
        +                        }
        +                      },
        +                      "type": "object"
        +                    },
        +                    "optionType": {
        +                      "enum": [
        +                        "call",
        +                        "put"
        +                      ],
        +                      "type": "string"
        +                    },
        +                    "ratio": {
        +                      "type": "number"
        +                    },
        +                    "strikeRange": {
        +                      "additionalProperties": true,
        +                      "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                      "type": "object"
        +                    },
        +                    "strikeSelector": {
        +                      "properties": {
        +                        "distance": {
        +                          "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                          "type": "number"
        +                        },
        +                        "distanceType": {
        +                          "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "distanceType",
        +                        "distance"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  },
        +                  "required": [
        +                    "optionType",
        +                    "direction",
        +                    "expirationSelector",
        +                    "strikeSelector"
        +                  ],
        +                  "type": "object"
        +                },
        +                "minItems": 1,
        +                "type": "array"
        +              },
        +              "spreadType": {
        +                "enum": [
        +                  "vertical",
        +                  "calendar",
        +                  "diagonal",
        +                  "ironCondor",
        +                  "straddle",
        +                  "strangle",
        +                  "custom"
        +                ],
        +                "type": "string"
        +              },
        +              "underlyingSymbol": {
        +                "type": "string"
        +              },
        +              "widthConstraint": {
        +                "additionalProperties": false,
        +                "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                "properties": {
        +                  "minWidthDollars": {
        +                    "exclusiveMinimum": 0,
        +                    "type": "number"
        +                  },
        +                  "minWidthPercent": {
        +                    "exclusiveMinimum": 0,
        +                    "type": "number"
        +                  }
        +                },
        +                "type": "object"
        +              }
        +            },
        +            "required": [
        +              "legs"
        +            ],
        +            "type": "object"
        +          },
        +          "type": {
        +            "const": "OpenOption",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "builder"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "additionalProperties": true,
        +        "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        +        "properties": {
        +          "allocationPolicy": {
        +            "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +            "oneOf": [
        +              {
        +                "additionalProperties": false,
        +                "properties": {
        +                  "covarianceShrinkage": {
        +                    "maximum": 1,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "estimatedTransactionCostBps": {
        +                    "maximum": 10000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "expectedReturnShrinkage": {
        +                    "maximum": 1,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "lookbackPeriods": {
        +                    "maximum": 5000,
        +                    "minimum": 2,
        +                    "type": "integer"
        +                  },
        +                  "minimumObservations": {
        +                    "maximum": 5000,
        +                    "minimum": 2,
        +                    "type": "integer"
        +                  },
        +                  "riskAversion": {
        +                    "maximum": 1000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "turnoverPenalty": {
        +                    "maximum": 10000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "const": "MeanVariance",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "lookbackPeriods",
        +                  "minimumObservations",
        +                  "riskAversion",
        +                  "expectedReturnShrinkage",
        +                  "covarianceShrinkage",
        +                  "turnoverPenalty",
        +                  "estimatedTransactionCostBps"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "additionalProperties": false,
        +                "properties": {
        +                  "covarianceShrinkage": {
        +                    "maximum": 1,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "estimatedTransactionCostBps": {
        +                    "maximum": 10000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "lookbackPeriods": {
        +                    "maximum": 5000,
        +                    "minimum": 2,
        +                    "type": "integer"
        +                  },
        +                  "minimumObservations": {
        +                    "maximum": 5000,
        +                    "minimum": 2,
        +                    "type": "integer"
        +                  },
        +                  "turnoverPenalty": {
        +                    "maximum": 10000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "const": "RiskParity",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "lookbackPeriods",
        +                  "minimumObservations",
        +                  "covarianceShrinkage",
        +                  "turnoverPenalty",
        +                  "estimatedTransactionCostBps"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "additionalProperties": false,
        +                "properties": {
        +                  "covarianceShrinkage": {
        +                    "maximum": 1,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "estimatedTransactionCostBps": {
        +                    "maximum": 10000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "lookbackPeriods": {
        +                    "maximum": 5000,
        +                    "minimum": 2,
        +                    "type": "integer"
        +                  },
        +                  "minimumObservations": {
        +                    "maximum": 5000,
        +                    "minimum": 2,
        +                    "type": "integer"
        +                  },
        +                  "turnoverPenalty": {
        +                    "maximum": 10000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "const": "MaximumDiversification",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "lookbackPeriods",
        +                  "minimumObservations",
        +                  "covarianceShrinkage",
        +                  "turnoverPenalty",
        +                  "estimatedTransactionCostBps"
        +                ],
        +                "type": "object"
        +              }
        +            ]
        +          },
        +          "exposurePolicy": {
        +            "additionalProperties": false,
        +            "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +            "properties": {
        +              "covarianceShrinkage": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "estimatedTransactionCostBps": {
        +                "maximum": 10000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "lookbackPeriods": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "minimumObservations": {
        +                "maximum": 5000,
        +                "minimum": 2,
        +                "type": "integer"
        +              },
        +              "targetAnnualizedVolatilityPercent": {
        +                "maximum": 1000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "const": "VolatilityTarget",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "lookbackPeriods",
        +              "minimumObservations",
        +              "covarianceShrinkage",
        +              "targetAnnualizedVolatilityPercent",
        +              "estimatedTransactionCostBps"
        +            ],
        +            "type": "object"
        +          },
        +          "limit": {
        +            "minimum": 1,
        +            "type": "number"
        +          },
        +          "perNameAllocation": {
        +            "additionalProperties": true,
        +            "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +            "properties": {
        +              "amount": {
        +                "type": "number"
        +              },
        +              "type": {
        +                "enum": [
        +                  "dollars",
        +                  "percent of portfolio",
        +                  "percent of buying power",
        +                  "contracts"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          "pipeline": {
        +            "items": {
        +              "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +              "oneOf": [
        +                {
        +                  "additionalProperties": true,
        +                  "properties": {
        +                    "condition": {
        +                      "$ref": "#/$defs/condition"
        +                    },
        +                    "type": {
        +                      "const": "Filter",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "type",
        +                    "condition"
        +                  ],
        +                  "type": "object"
        +                },
        +                {
        +                  "additionalProperties": true,
        +                  "properties": {
        +                    "direction": {
        +                      "enum": [
        +                        "Highest",
        +                        "Lowest"
        +                      ],
        +                      "type": "string"
        +                    },
        +                    "limit": {
        +                      "minimum": 1,
        +                      "type": "number"
        +                    },
        +                    "metric": {
        +                      "$ref": "#/$defs/indicator"
        +                    },
        +                    "type": {
        +                      "const": "SelectTop",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "type",
        +                    "metric",
        +                    "limit",
        +                    "direction"
        +                  ],
        +                  "type": "object"
        +                },
        +                {
        +                  "additionalProperties": true,
        +                  "properties": {
        +                    "direction": {
        +                      "enum": [
        +                        "Highest",
        +                        "Lowest"
        +                      ],
        +                      "type": "string"
        +                    },
        +                    "metric": {
        +                      "$ref": "#/$defs/indicator"
        +                    },
        +                    "percentile": {
        +                      "maximum": 100,
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "type": {
        +                      "const": "SelectPercentile",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "type",
        +                    "metric",
        +                    "percentile",
        +                    "direction"
        +                  ],
        +                  "type": "object"
        +                }
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "positionScope": {
        +            "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        +            "enum": [
        +              "portfolio",
        +              "strategy"
        +            ],
        +            "type": "string"
        +          },
        +          "sleeves": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        +              "properties": {
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "name": {
        +                  "type": "string"
        +                },
        +                "perNameAllocation": {
        +                  "additionalProperties": true,
        +                  "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +                  "properties": {
        +                    "amount": {
        +                      "type": "number"
        +                    },
        +                    "type": {
        +                      "enum": [
        +                        "dollars",
        +                        "percent of portfolio",
        +                        "percent of buying power",
        +                        "contracts"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "type",
        +                    "amount"
        +                  ],
        +                  "type": "object"
        +                },
        +                "pipeline": {
        +                  "items": {
        +                    "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                    "oneOf": [
        +                      {
        +                        "additionalProperties": true,
        +                        "properties": {
        +                          "condition": {
        +                            "$ref": "#/$defs/condition"
        +                          },
        +                          "type": {
        +                            "const": "Filter",
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "type",
        +                          "condition"
        +                        ],
        +                        "type": "object"
        +                      },
        +                      {
        +                        "additionalProperties": true,
        +                        "properties": {
        +                          "direction": {
        +                            "enum": [
        +                              "Highest",
        +                              "Lowest"
        +                            ],
        +                            "type": "string"
        +                          },
        +                          "limit": {
        +                            "minimum": 1,
        +                            "type": "number"
        +                          },
        +                          "metric": {
        +                            "$ref": "#/$defs/indicator"
        +                          },
        +                          "type": {
        +                            "const": "SelectTop",
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "type",
        +                          "metric",
        +                          "limit",
        +                          "direction"
        +                        ],
        +                        "type": "object"
        +                      },
        +                      {
        +                        "additionalProperties": true,
        +                        "properties": {
        +                          "direction": {
        +                            "enum": [
        +                              "Highest",
        +                              "Lowest"
        +                            ],
        +                            "type": "string"
        +                          },
        +                          "metric": {
        +                            "$ref": "#/$defs/indicator"
        +                          },
        +                          "percentile": {
        +                            "maximum": 100,
        +                            "minimum": 0,
        +                            "type": "number"
        +                          },
        +                          "type": {
        +                            "const": "SelectPercentile",
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "type",
        +                          "metric",
        +                          "percentile",
        +                          "direction"
        +                        ],
        +                        "type": "object"
        +                      }
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "type": "array"
        +                },
        +                "structureTemplates": {
        +                  "items": {
        +                    "additionalProperties": true,
        +                    "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +                    "properties": {
        +                      "eligibility": {
        +                        "$ref": "#/$defs/condition"
        +                      },
        +                      "legs": {
        +                        "items": {
        +                          "additionalProperties": true,
        +                          "description": "Single leg of an option builder.",
        +                          "properties": {
        +                            "direction": {
        +                              "enum": [
        +                                "long",
        +                                "short"
        +                              ],
        +                              "type": "string"
        +                            },
        +                            "expirationRange": {
        +                              "additionalProperties": true,
        +                              "type": "object"
        +                            },
        +                            "expirationSelector": {
        +                              "properties": {
        +                                "maxDaysToExpiration": {
        +                                  "minimum": 0,
        +                                  "type": "number"
        +                                },
        +                                "minDaysToExpiration": {
        +                                  "minimum": 0,
        +                                  "type": "number"
        +                                },
        +                                "preference": {
        +                                  "enum": [
        +                                    "nearest",
        +                                    "middle",
        +                                    "furthest"
        +                                  ],
        +                                  "type": "string"
        +                                }
        +                              },
        +                              "required": [
        +                                "minDaysToExpiration",
        +                                "maxDaysToExpiration",
        +                                "preference"
        +                              ],
        +                              "type": "object"
        +                            },
        +                            "fallbackStrikeSelector": {
        +                              "additionalProperties": false,
        +                              "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                              "properties": {
        +                                "distance": {
        +                                  "type": "number"
        +                                },
        +                                "distanceType": {
        +                                  "enum": [
        +                                    "percent",
        +                                    "dollars"
        +                                  ],
        +                                  "type": "string"
        +                                }
        +                              },
        +                              "required": [
        +                                "distanceType",
        +                                "distance"
        +                              ],
        +                              "type": "object"
        +                            },
        +                            "greekFilter": {
        +                              "additionalProperties": true,
        +                              "description": "Optional min/max constraints on Greeks during resolution.",
        +                              "type": "object"
        +                            },
        +                            "liquidityFilter": {
        +                              "additionalProperties": false,
        +                              "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                              "properties": {
        +                                "maxSpreadAbsolute": {
        +                                  "type": "number"
        +                                },
        +                                "maxSpreadPct": {
        +                                  "type": "number"
        +                                },
        +                                "minBid": {
        +                                  "type": "number"
        +                                }
        +                              },
        +                              "type": "object"
        +                            },
        +                            "optionType": {
        +                              "enum": [
        +                                "call",
        +                                "put"
        +                              ],
        +                              "type": "string"
        +                            },
        +                            "ratio": {
        +                              "type": "number"
        +                            },
        +                            "strikeRange": {
        +                              "additionalProperties": true,
        +                              "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                              "type": "object"
        +                            },
        +                            "strikeSelector": {
        +                              "properties": {
        +                                "distance": {
        +                                  "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                                  "type": "number"
        +                                },
        +                                "distanceType": {
        +                                  "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                                  "type": "string"
        +                                }
        +                              },
        +                              "required": [
        +                                "distanceType",
        +                                "distance"
        +                              ],
        +                              "type": "object"
        +                            }
        +                          },
        +                          "required": [
        +                            "optionType",
        +                            "direction",
        +                            "expirationSelector",
        +                            "strikeSelector"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "minItems": 1,
        +                        "type": "array"
        +                      },
        +                      "name": {
        +                        "type": "string"
        +                      },
        +                      "spreadType": {
        +                        "enum": [
        +                          "vertical",
        +                          "calendar",
        +                          "diagonal",
        +                          "ironCondor",
        +                          "straddle",
        +                          "strangle",
        +                          "custom"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "widthConstraint": {
        +                        "additionalProperties": false,
        +                        "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                        "properties": {
        +                          "minWidthDollars": {
        +                            "exclusiveMinimum": 0,
        +                            "type": "number"
        +                          },
        +                          "minWidthPercent": {
        +                            "exclusiveMinimum": 0,
        +                            "type": "number"
        +                          }
        +                        },
        +                        "type": "object"
        +                      }
        +                    },
        +                    "required": [
        +                      "legs"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "minItems": 1,
        +                  "type": "array"
        +                },
        +                "universe": {
        +                  "additionalProperties": true,
        +                  "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                  "properties": {
        +                    "assets": {
        +                      "items": {
        +                        "additionalProperties": true,
        +                        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                        "properties": {
        +                          "name": {
        +                            "type": "string"
        +                          },
        +                          "symbol": {
        +                            "type": "string"
        +                          },
        +                          "type": {
        +                            "enum": [
        +                              "Stock",
        +                              "Cryptocurrency",
        +                              "Option",
        +                              "Other"
        +                            ],
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "type",
        +                          "symbol"
        +                        ],
        +                        "type": "object"
        +                      },
        +                      "type": "array"
        +                    },
        +                    "source": {
        +                      "enum": [
        +                        "ALL_US_STOCKS",
        +                        "SP500",
        +                        "NASDAQ100",
        +                        "DJIA",
        +                        "CRYPTO",
        +                        "SPECIFIC_ASSETS"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "source"
        +                  ],
        +                  "type": "object"
        +                },
        +                "weightIndicator": {
        +                  "$ref": "#/$defs/indicator"
        +                }
        +              },
        +              "required": [
        +                "name"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "structureTemplates": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +              "properties": {
        +                "eligibility": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "legs": {
        +                  "items": {
        +                    "additionalProperties": true,
        +                    "description": "Single leg of an option builder.",
        +                    "properties": {
        +                      "direction": {
        +                        "enum": [
        +                          "long",
        +                          "short"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "expirationRange": {
        +                        "additionalProperties": true,
        +                        "type": "object"
        +                      },
        +                      "expirationSelector": {
        +                        "properties": {
        +                          "maxDaysToExpiration": {
        +                            "minimum": 0,
        +                            "type": "number"
        +                          },
        +                          "minDaysToExpiration": {
        +                            "minimum": 0,
        +                            "type": "number"
        +                          },
        +                          "preference": {
        +                            "enum": [
        +                              "nearest",
        +                              "middle",
        +                              "furthest"
        +                            ],
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "minDaysToExpiration",
        +                          "maxDaysToExpiration",
        +                          "preference"
        +                        ],
        +                        "type": "object"
        +                      },
        +                      "fallbackStrikeSelector": {
        +                        "additionalProperties": false,
        +                        "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                        "properties": {
        +                          "distance": {
        +                            "type": "number"
        +                          },
        +                          "distanceType": {
        +                            "enum": [
        +                              "percent",
        +                              "dollars"
        +                            ],
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "distanceType",
        +                          "distance"
        +                        ],
        +                        "type": "object"
        +                      },
        +                      "greekFilter": {
        +                        "additionalProperties": true,
        +                        "description": "Optional min/max constraints on Greeks during resolution.",
        +                        "type": "object"
        +                      },
        +                      "liquidityFilter": {
        +                        "additionalProperties": false,
        +                        "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                        "properties": {
        +                          "maxSpreadAbsolute": {
        +                            "type": "number"
        +                          },
        +                          "maxSpreadPct": {
        +                            "type": "number"
        +                          },
        +                          "minBid": {
        +                            "type": "number"
        +                          }
        +                        },
        +                        "type": "object"
        +                      },
        +                      "optionType": {
        +                        "enum": [
        +                          "call",
        +                          "put"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "ratio": {
        +                        "type": "number"
        +                      },
        +                      "strikeRange": {
        +                        "additionalProperties": true,
        +                        "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                        "type": "object"
        +                      },
        +                      "strikeSelector": {
        +                        "properties": {
        +                          "distance": {
        +                            "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                            "type": "number"
        +                          },
        +                          "distanceType": {
        +                            "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "distanceType",
        +                          "distance"
        +                        ],
        +                        "type": "object"
        +                      }
        +                    },
        +                    "required": [
        +                      "optionType",
        +                      "direction",
        +                      "expirationSelector",
        +                      "strikeSelector"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "minItems": 1,
        +                  "type": "array"
        +                },
        +                "name": {
        +                  "type": "string"
        +                },
        +                "spreadType": {
        +                  "enum": [
        +                    "vertical",
        +                    "calendar",
        +                    "diagonal",
        +                    "ironCondor",
        +                    "straddle",
        +                    "strangle",
        +                    "custom"
        +                  ],
        +                  "type": "string"
        +                },
        +                "widthConstraint": {
        +                  "additionalProperties": false,
        +                  "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                  "properties": {
        +                    "minWidthDollars": {
        +                      "exclusiveMinimum": 0,
        +                      "type": "number"
        +                    },
        +                    "minWidthPercent": {
        +                      "exclusiveMinimum": 0,
        +                      "type": "number"
        +                    }
        +                  },
        +                  "type": "object"
        +                }
        +              },
        +              "required": [
        +                "legs"
        +              ],
        +              "type": "object"
        +            },
        +            "minItems": 1,
        +            "type": "array"
        +          },
        +          "totalBudget": {
        +            "additionalProperties": true,
        +            "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        +            "properties": {
        +              "amount": {
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "type": {
        +                "enum": [
        +                  "dollars",
        +                  "percent of portfolio"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          "type": {
        +            "const": "RebalanceOption",
        +            "type": "string"
        +          },
        +          "universe": {
        +            "additionalProperties": true,
        +            "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +            "properties": {
        +              "assets": {
        +                "items": {
        +                  "additionalProperties": true,
        +                  "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                  "properties": {
        +                    "name": {
        +                      "type": "string"
        +                    },
        +                    "symbol": {
        +                      "type": "string"
        +                    },
        +                    "type": {
        +                      "enum": [
        +                        "Stock",
        +                        "Cryptocurrency",
        +                        "Option",
        +                        "Other"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "type",
        +                    "symbol"
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "source": {
        +                "enum": [
        +                  "ALL_US_STOCKS",
        +                  "SP500",
        +                  "NASDAQ100",
        +                  "DJIA",
        +                  "CRYPTO",
        +                  "SPECIFIC_ASSETS"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "source"
        +            ],
        +            "type": "object"
        +          },
        +          "weightIndicator": {
        +            "$ref": "#/$defs/indicator"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "universe",
        +          "pipeline",
        +          "weightIndicator",
        +          "structureTemplates"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "additionalProperties": true,
        +        "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        +        "properties": {
        +          "closeScope": {
        +            "enum": [
        +              "spread",
        +              "leg"
        +            ],
        +            "type": "string"
        +          },
        +          "direction": {
        +            "enum": [
        +              "long",
        +              "short"
        +            ],
        +            "type": "string"
        +          },
        +          "optionType": {
        +            "enum": [
        +              "call",
        +              "put"
        +            ],
        +            "type": "string"
        +          },
        +          "quantity": {
        +            "additionalProperties": true,
        +            "description": "How many contracts to close. Defaults to all matching when omitted.",
        +            "type": "object"
        +          },
        +          "spreadType": {
        +            "enum": [
        +              "vertical",
        +              "calendar",
        +              "diagonal",
        +              "ironCondor",
        +              "straddle",
        +              "strangle",
        +              "custom"
        +            ],
        +            "type": "string"
        +          },
        +          "triggers": {
        +            "items": {
        +              "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        +              "oneOf": [
        +                {
        +                  "additionalProperties": true,
        +                  "properties": {
        +                    "maxPnlPercent": {
        +                      "type": "number"
        +                    },
        +                    "minPnlPercent": {
        +                      "type": "number"
        +                    },
        +                    "type": {
        +                      "const": "pnl",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "type"
        +                  ],
        +                  "type": "object"
        +                },
        +                {
        +                  "additionalProperties": true,
        +                  "properties": {
        +                    "maxDte": {
        +                      "type": "number"
        +                    },
        +                    "minDte": {
        +                      "type": "number"
        +                    },
        +                    "type": {
        +                      "const": "dte",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "type"
        +                  ],
        +                  "type": "object"
        +                },
        +                {
        +                  "additionalProperties": true,
        +                  "properties": {
        +                    "maxDaysHeld": {
        +                      "type": "number"
        +                    },
        +                    "minDaysHeld": {
        +                      "type": "number"
        +                    },
        +                    "type": {
        +                      "const": "daysHeld",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "type"
        +                  ],
        +                  "type": "object"
        +                },
        +                {
        +                  "additionalProperties": true,
        +                  "properties": {
        +                    "maxIv": {
        +                      "type": "number"
        +                    },
        +                    "maxSpreadDelta": {
        +                      "type": "number"
        +                    },
        +                    "maxSpreadTheta": {
        +                      "type": "number"
        +                    },
        +                    "minIv": {
        +                      "type": "number"
        +                    },
        +                    "minSpreadDelta": {
        +                      "type": "number"
        +                    },
        +                    "minSpreadTheta": {
        +                      "type": "number"
        +                    },
        +                    "type": {
        +                      "const": "greeks",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "type"
        +                  ],
        +                  "type": "object"
        +                }
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "type": {
        +            "const": "CloseOption",
        +            "type": "string"
        +          },
        +          "underlyings": {
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          }
        +        },
        +        "required": [
        +          "type"
        +        ],
        +        "type": "object"
        +      }
        +    ],
        +    "type": "object"
        +  },
        +  "asset": {
        +    "additionalProperties": true,
        +    "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +    "properties": {
        +      "name": {
        +        "type": "string"
        +      },
        +      "symbol": {
        +        "type": "string"
        +      },
        +      "type": {
        +        "enum": [
        +          "Stock",
        +          "Cryptocurrency",
        +          "Option",
        +          "Other"
        +        ],
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "symbol"
        +    ],
        +    "type": "object"
        +  },
        +  "condition": {
        +    "additionalProperties": true,
        +    "description": "A condition tree (Bridge pattern). type='Base' compares lhs vs rhs with a comparator; type='And'/'Or' combine an array of nested conditions; type='Multi' fires when N nested conditions are true (count vs threshold); type='Then' is sequential — it fires when the last nested condition is true now and each earlier one was true at a strictly earlier tick within 'window' of the next, so it needs at least 2 conditions and a window with length > 0.",
        +    "properties": {
        +      "comparison": {
        +        "description": "Base / Multi only: how to compare.",
        +        "enum": [
        +          "lessThan",
        +          "greaterThan",
        +          "lessThanOrEqual",
        +          "greaterThanOrEqual",
        +          "equal",
        +          "notEqual"
        +        ],
        +        "type": "string"
        +      },
        +      "conditions": {
        +        "description": "And / Or / Multi / Then only: nested conditions. Then reads them in order (at least 2).",
        +        "items": {
        +          "$ref": "#/$defs/condition"
        +        },
        +        "type": "array"
        +      },
        +      "lhs": {
        +        "$ref": "#/$defs/indicator",
        +        "description": "Base only: left-hand indicator."
        +      },
        +      "name": {
        +        "description": "Optional name; auto-derived if omitted.",
        +        "type": "string"
        +      },
        +      "rhs": {
        +        "$ref": "#/$defs/indicator",
        +        "description": "Base only: right-hand indicator."
        +      },
        +      "type": {
        +        "enum": [
        +          "And",
        +          "Or",
        +          "Base",
        +          "Multi",
        +          "Then"
        +        ],
        +        "type": "string"
        +      },
        +      "value": {
        +        "description": "Multi only: threshold count (>=1).",
        +        "type": "number"
        +      },
        +      "window": {
        +        "description": "Then only: how long each step has to be followed by the next one, e.g. {length: 30, interval: 'Minute'}. length must be > 0.",
        +        "properties": {
        +          "interval": {
        +            "enum": [
        +              "Day",
        +              "Hour",
        +              "Minute"
        +            ],
        +            "type": "string"
        +          },
        +          "length": {
        +            "type": "number"
        +          }
        +        },
        +        "required": [
        +          "length",
        +          "interval"
        +        ],
        +        "type": "object"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  "deploymentBudget": {
        +    "additionalProperties": true,
        +    "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        +    "properties": {
        +      "amount": {
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "type": {
        +        "enum": [
        +          "dollars",
        +          "percent of portfolio"
        +        ],
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "amount"
        +    ],
        +    "type": "object"
        +  },
        +  "indicator": {
        +    "additionalProperties": true,
        +    "description": "An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), Option* indicators (need underlying + optionType + direction + spreadType), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown.",
        +    "properties": {
        +      "assetType": {
        +        "description": "IsAssetType: e.g. 'Stock', 'Cryptocurrency'.",
        +        "type": "string"
        +      },
        +      "base": {
        +        "description": "Log: logarithm base (>0, ≠1).",
        +        "type": "number"
        +      },
        +      "compound": {
        +        "type": "boolean"
        +      },
        +      "condition": {
        +        "$ref": "#/$defs/condition",
        +        "description": "ConsecutiveTrue / CountTrue: the condition to evaluate over the window."
        +      },
        +      "customIndicatorId": {
        +        "description": "REQUIRED when type is CustomIndicator. Mongo ObjectId hex string for the owned custom data source (see list_custom_indicators or MCP session instructions). Never omit — display name alone is rejected.",
        +        "type": "string"
        +      },
        +      "customIndicatorName": {
        +        "description": "Optional display label for CustomIndicator. Ignored for lookup; customIndicatorId is authoritative.",
        +        "type": "string"
        +      },
        +      "direction": {
        +        "description": "Option* indicators: long or short.",
        +        "enum": [
        +          "long",
        +          "short"
        +        ],
        +        "type": "string"
        +      },
        +      "exponent": {
        +        "description": "Exponentiation: power exponent.",
        +        "type": "number"
        +      },
        +      "form": {
        +        "additionalProperties": true,
        +        "description": "Optional auto-generated form metadata. Usually omit; the server fills this.",
        +        "type": "object"
        +      },
        +      "index": {
        +        "description": "IsIndexMember: point-in-time index id ('SP500', 'NASDAQ100', or 'DJIA').",
        +        "enum": [
        +          "SP500",
        +          "NASDAQ100",
        +          "DJIA"
        +        ],
        +        "type": "string"
        +      },
        +      "indicators": {
        +        "description": "Sub-indicators for compound types (Plus, CrossAbove, etc.).",
        +        "items": {
        +          "$ref": "#/$defs/indicator"
        +        },
        +        "type": "array"
        +      },
        +      "industry": {
        +        "description": "IsIndustry: industry tag.",
        +        "type": "string"
        +      },
        +      "length": {
        +        "description": "TrailingSum and similar — window length in days.",
        +        "type": "number"
        +      },
        +      "matchAsset": {
        +        "additionalProperties": true,
        +        "description": "IsAsset / IsNotAsset: the asset to match against.",
        +        "properties": {
        +          "name": {
        +            "type": "string"
        +          },
        +          "symbol": {
        +            "type": "string"
        +          },
        +          "type": {
        +            "enum": [
        +              "Stock",
        +              "Cryptocurrency",
        +              "Option",
        +              "Other"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "symbol"
        +        ],
        +        "type": "object"
        +      },
        +      "maxDte": {
        +        "description": "Option* indicators: max days to expiration.",
        +        "type": "number"
        +      },
        +      "message": {
        +        "description": "DaysSinceAlert / MinutesSinceAlert: alert message to match.",
        +        "type": "string"
        +      },
        +      "metric": {
        +        "description": "Fundamental/CompoundAnnualGrowthRate: financial metric (e.g. 'peRatio'). Economic: economic indicator (e.g. 'UNRATE'). Index: index symbol (e.g. 'VIX', 'SPX'). RebalanceDecisionMetric: allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit.",
        +        "type": "string"
        +      },
        +      "minDte": {
        +        "description": "Option* indicators: min days to expiration.",
        +        "type": "number"
        +      },
        +      "minOrMax": {
        +        "description": "OptionDaysToExpiration / OptionDaysHeld: aggregate selector.",
        +        "enum": [
        +          "min",
        +          "max"
        +        ],
        +        "type": "string"
        +      },
        +      "minutesAfterOpen": {
        +        "description": "IndicatorAtMinutesAfterOpen: 0–390.",
        +        "maximum": 390,
        +        "minimum": 0,
        +        "type": "number"
        +      },
        +      "name": {
        +        "description": "Optional human-readable name. Auto-derived if omitted.",
        +        "type": "string"
        +      },
        +      "numStandardDeviations": {
        +        "description": "BollingerBand: e.g. 2.",
        +        "type": "number"
        +      },
        +      "optionType": {
        +        "description": "Option* indicators: call or put.",
        +        "enum": [
        +          "call",
        +          "put"
        +        ],
        +        "type": "string"
        +      },
        +      "orderStatus": {
        +        "description": "Order-side indicators: filter by status.",
        +        "enum": [
        +          "Pending",
        +          "Accepted",
        +          "Pending User Approval",
        +          "Canceled",
        +          "Filled",
        +          "Partially Filled"
        +        ],
        +        "type": "string"
        +      },
        +      "positionEffect": {
        +        "description": "Option* indicators: open or close.",
        +        "type": "string"
        +      },
        +      "side": {
        +        "description": "Order-side indicators: Buy or Sell.",
        +        "enum": [
        +          "Buy",
        +          "Sell"
        +        ],
        +        "type": "string"
        +      },
        +      "spreadType": {
        +        "description": "Option* indicators: vertical, ironCondor, etc.",
        +        "enum": [
        +          "vertical",
        +          "calendar",
        +          "diagonal",
        +          "ironCondor",
        +          "straddle",
        +          "strangle",
        +          "custom"
        +        ],
        +        "type": "string"
        +      },
        +      "targetAsset": {
        +        "additionalProperties": true,
        +        "description": "The asset this indicator measures (most price/option indicators).",
        +        "properties": {
        +          "name": {
        +            "type": "string"
        +          },
        +          "symbol": {
        +            "type": "string"
        +          },
        +          "type": {
        +            "enum": [
        +              "Stock",
        +              "Cryptocurrency",
        +              "Option",
        +              "Other"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "symbol"
        +        ],
        +        "type": "object"
        +      },
        +      "targetAssets": {
        +        "description": "Multi-asset variant (position / order indicators).",
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +          "properties": {
        +            "name": {
        +              "type": "string"
        +            },
        +            "symbol": {
        +              "type": "string"
        +            },
        +            "type": {
        +              "enum": [
        +                "Stock",
        +                "Cryptocurrency",
        +                "Option",
        +                "Other"
        +              ],
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "type",
        +            "symbol"
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "transactionStatus": {
        +        "description": "DaysSinceTransaction: transaction status.",
        +        "enum": [
        +          "Pending",
        +          "Canceled",
        +          "Completed"
        +        ],
        +        "type": "string"
        +      },
        +      "transactionType": {
        +        "description": "DaysSinceTransaction: Deposit or Withdraw.",
        +        "enum": [
        +          "Deposit",
        +          "Withdraw"
        +        ],
        +        "type": "string"
        +      },
        +      "type": {
        +        "enum": [
        +          "DaysSinceAgent",
        +          "MinutesSinceAgent",
        +          "DaysSinceAlert",
        +          "MinutesSinceAlert",
        +          "StockReport",
        +          "DaysUntilEarnings",
        +          "DaysSinceEarnings",
        +          "ImpliedVolatility",
        +          "IVRank",
        +          "IVPercentile",
        +          "IVHVRatio",
        +          "LastOrderPrice",
        +          "Fundamental",
        +          "Economic",
        +          "CustomIndicator",
        +          "Index",
        +          "BollingerBand",
        +          "RelativeStrengthIndex",
        +          "PriceMeanAbsoluteDeviation",
        +          "ExponentialMovingAverage",
        +          "SimpleMovingAverage",
        +          "PriceStandardDeviation",
        +          "PriceRateOfChange",
        +          "MaxDrawdown",
        +          "MaxDrawup",
        +          "MinimumPrice",
        +          "MaximumPrice",
        +          "IndicatorMeanAbsoluteDeviation",
        +          "IndicatorExponentialMovingAverage",
        +          "IndicatorSimpleMovingAverage",
        +          "IndicatorStandardDeviation",
        +          "IndicatorRateOfChange",
        +          "DaysSinceOrder",
        +          "DaysSinceOptionOrder",
        +          "DaysSinceStrategyFired",
        +          "DaysSinceLastRebalanceOptionOrder",
        +          "MinutesSinceOptionOrder",
        +          "MinutesSinceOrder",
        +          "DaysSinceTransaction",
        +          "InitialValue",
        +          "BuyingPower",
        +          "PositionValue",
        +          "PositionPercentChange",
        +          "PortfolioValue",
        +          "RebalanceDecisionMetric",
        +          "Value",
        +          "Price",
        +          "Plus",
        +          "Minus",
        +          "Multiply",
        +          "Divide",
        +          "Negative",
        +          "AbsoluteValue",
        +          "SquareRoot",
        +          "Max",
        +          "Min",
        +          "Day",
        +          "Month",
        +          "Date",
        +          "Year",
        +          "CurrentTimeSeconds",
        +          "CurrentTimeMinutes",
        +          "CurrentTimeHours",
        +          "TrailingSum",
        +          "CompoundAnnualGrowthRate",
        +          "Log",
        +          "Exponentiation",
        +          "SumOrderQuantity",
        +          "SumOrderAmount",
        +          "MinutesAfterOpen",
        +          "OpeningPrice",
        +          "PreviousClosingPrice",
        +          "HighOfDay",
        +          "LowOfDay",
        +          "MinutesUntilClose",
        +          "PriceChangeSinceOpen",
        +          "GapSize",
        +          "GapPercentage",
        +          "TrueRange",
        +          "AverageTrueRange",
        +          "Volume",
        +          "VWAP",
        +          "BullishFairValueGap",
        +          "BearishFairValueGap",
        +          "IndicatorAtMinutesAfterOpen",
        +          "IndicatorWindowAgo",
        +          "IndicatorAtEntry",
        +          "IsIndexMember",
        +          "IsIndustry",
        +          "IsAssetType",
        +          "IsAsset",
        +          "IsNotAsset",
        +          "CrossAbove",
        +          "CrossBelow",
        +          "PositionMaxDrawdown",
        +          "PositionMaxDrawup",
        +          "UnderlyingMaxDrawdown",
        +          "ConsecutiveTrue",
        +          "CountTrue",
        +          "OptionPositionValue",
        +          "OptionPositionCount",
        +          "OptionPositionPercentChange",
        +          "OptionPositionMaxDrawdown",
        +          "OptionDaysToExpiration",
        +          "OptionDaysHeld",
        +          "OptionCollateral",
        +          "OptionSpreadCount",
        +          "OptionUnrealizedPnL",
        +          "OptionGrossExposurePercent"
        +        ],
        +        "type": "string"
        +      },
        +      "underlying": {
        +        "description": "Option* indicators: underlying ticker (e.g. 'SPY').",
        +        "type": "string"
        +      },
        +      "value": {
        +        "description": "Required for Value indicators (numeric constant).",
        +        "type": "number"
        +      },
        +      "window": {
        +        "description": "Rolling time window. e.g. {length:14, interval:'Day'} = trailing 14 trading days.",
        +        "properties": {
        +          "interval": {
        +            "enum": [
        +              "Day",
        +              "Hour",
        +              "Minute"
        +            ],
        +            "type": "string"
        +          },
        +          "length": {
        +            "minimum": 1,
        +            "type": "number"
        +          }
        +        },
        +        "required": [
        +          "length",
        +          "interval"
        +        ],
        +        "type": "object"
        +      },
        +      "years": {
        +        "description": "CompoundAnnualGrowthRate: years over which to compute CAGR.",
        +        "type": "number"
        +      }
        +    },
        +    "required": [
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  "optionStructureTemplate": {
        +    "additionalProperties": true,
        +    "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +    "properties": {
        +      "eligibility": {
        +        "$ref": "#/$defs/condition"
        +      },
        +      "legs": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "Single leg of an option builder.",
        +          "properties": {
        +            "direction": {
        +              "enum": [
        +                "long",
        +                "short"
        +              ],
        +              "type": "string"
        +            },
        +            "expirationRange": {
        +              "additionalProperties": true,
        +              "type": "object"
        +            },
        +            "expirationSelector": {
        +              "properties": {
        +                "maxDaysToExpiration": {
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "minDaysToExpiration": {
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "preference": {
        +                  "enum": [
        +                    "nearest",
        +                    "middle",
        +                    "furthest"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "minDaysToExpiration",
        +                "maxDaysToExpiration",
        +                "preference"
        +              ],
        +              "type": "object"
        +            },
        +            "fallbackStrikeSelector": {
        +              "additionalProperties": false,
        +              "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +              "properties": {
        +                "distance": {
        +                  "type": "number"
        +                },
        +                "distanceType": {
        +                  "enum": [
        +                    "percent",
        +                    "dollars"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "distanceType",
        +                "distance"
        +              ],
        +              "type": "object"
        +            },
        +            "greekFilter": {
        +              "additionalProperties": true,
        +              "description": "Optional min/max constraints on Greeks during resolution.",
        +              "type": "object"
        +            },
        +            "liquidityFilter": {
        +              "additionalProperties": false,
        +              "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +              "properties": {
        +                "maxSpreadAbsolute": {
        +                  "type": "number"
        +                },
        +                "maxSpreadPct": {
        +                  "type": "number"
        +                },
        +                "minBid": {
        +                  "type": "number"
        +                }
        +              },
        +              "type": "object"
        +            },
        +            "optionType": {
        +              "enum": [
        +                "call",
        +                "put"
        +              ],
        +              "type": "string"
        +            },
        +            "ratio": {
        +              "type": "number"
        +            },
        +            "strikeRange": {
        +              "additionalProperties": true,
        +              "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +              "type": "object"
        +            },
        +            "strikeSelector": {
        +              "properties": {
        +                "distance": {
        +                  "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                  "type": "number"
        +                },
        +                "distanceType": {
        +                  "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "distanceType",
        +                "distance"
        +              ],
        +              "type": "object"
        +            }
        +          },
        +          "required": [
        +            "optionType",
        +            "direction",
        +            "expirationSelector",
        +            "strikeSelector"
        +          ],
        +          "type": "object"
        +        },
        +        "minItems": 1,
        +        "type": "array"
        +      },
        +      "name": {
        +        "type": "string"
        +      },
        +      "spreadType": {
        +        "enum": [
        +          "vertical",
        +          "calendar",
        +          "diagonal",
        +          "ironCondor",
        +          "straddle",
        +          "strangle",
        +          "custom"
        +        ],
        +        "type": "string"
        +      },
        +      "widthConstraint": {
        +        "additionalProperties": false,
        +        "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +        "properties": {
        +          "minWidthDollars": {
        +            "exclusiveMinimum": 0,
        +            "type": "number"
        +          },
        +          "minWidthPercent": {
        +            "exclusiveMinimum": 0,
        +            "type": "number"
        +          }
        +        },
        +        "type": "object"
        +      }
        +    },
        +    "required": [
        +      "legs"
        +    ],
        +    "type": "object"
        +  },
        +  "orderExecution": {
        +    "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.",
        +    "oneOf": [
        +      {
        +        "additionalProperties": false,
        +        "properties": {
        +          "type": {
        +            "const": "Market",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "additionalProperties": false,
        +        "properties": {
        +          "price": {
        +            "oneOf": [
        +              {
        +                "additionalProperties": false,
        +                "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        +                "properties": {
        +                  "amount": {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "const": "UnitPrice",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "amount"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "additionalProperties": false,
        +                "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        +                "properties": {
        +                  "amount": {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "const": "MinimumNetCredit",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "amount"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "additionalProperties": false,
        +                "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        +                "properties": {
        +                  "amount": {
        +                    "minimum": 1e-8,
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "const": "MaximumNetDebit",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "amount"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "additionalProperties": false,
        +                "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        +                "properties": {
        +                  "reference": {
        +                    "const": "Current",
        +                    "type": "string"
        +                  },
        +                  "type": {
        +                    "const": "QuoteRelative",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "reference"
        +                ],
        +                "type": "object"
        +              }
        +            ]
        +          },
        +          "type": {
        +            "const": "Limit",
        +            "type": "string"
        +          },
        +          "workingTime": {
        +            "oneOf": [
        +              {
        +                "additionalProperties": false,
        +                "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        +                "properties": {
        +                  "type": {
        +                    "const": "Day",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "additionalProperties": false,
        +                "properties": {
        +                  "minutes": {
        +                    "minimum": 1,
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "const": "Minutes",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "minutes"
        +                ],
        +                "type": "object"
        +              }
        +            ]
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "price"
        +        ],
        +        "type": "object"
        +      }
        +    ],
        +    "type": "object"
        +  },
        +  "rebalanceOptionSleeve": {
        +    "additionalProperties": true,
        +    "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        +    "properties": {
        +      "limit": {
        +        "minimum": 1,
        +        "type": "number"
        +      },
        +      "name": {
        +        "type": "string"
        +      },
        +      "perNameAllocation": {
        +        "additionalProperties": true,
        +        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +        "properties": {
        +          "amount": {
        +            "type": "number"
        +          },
        +          "type": {
        +            "enum": [
        +              "dollars",
        +              "percent of portfolio",
        +              "percent of buying power",
        +              "contracts"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "type",
        +          "amount"
        +        ],
        +        "type": "object"
        +      },
        +      "pipeline": {
        +        "items": {
        +          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "condition": {
        +                  "$ref": "#/$defs/condition"
        +                },
        +                "type": {
        +                  "const": "Filter",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "condition"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "type": {
        +                  "const": "SelectTop",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "limit",
        +                "direction"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "properties": {
        +                "direction": {
        +                  "enum": [
        +                    "Highest",
        +                    "Lowest"
        +                  ],
        +                  "type": "string"
        +                },
        +                "metric": {
        +                  "$ref": "#/$defs/indicator"
        +                },
        +                "percentile": {
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "type": {
        +                  "const": "SelectPercentile",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "metric",
        +                "percentile",
        +                "direction"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "structureTemplates": {
        +        "items": {
        +          "additionalProperties": true,
        +          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +          "properties": {
        +            "eligibility": {
        +              "$ref": "#/$defs/condition"
        +            },
        +            "legs": {
        +              "items": {
        +                "additionalProperties": true,
        +                "description": "Single leg of an option builder.",
        +                "properties": {
        +                  "direction": {
        +                    "enum": [
        +                      "long",
        +                      "short"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "expirationRange": {
        +                    "additionalProperties": true,
        +                    "type": "object"
        +                  },
        +                  "expirationSelector": {
        +                    "properties": {
        +                      "maxDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minDaysToExpiration": {
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "preference": {
        +                        "enum": [
        +                          "nearest",
        +                          "middle",
        +                          "furthest"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "minDaysToExpiration",
        +                      "maxDaysToExpiration",
        +                      "preference"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "fallbackStrikeSelector": {
        +                    "additionalProperties": false,
        +                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                    "properties": {
        +                      "distance": {
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "enum": [
        +                          "percent",
        +                          "dollars"
        +                        ],
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "greekFilter": {
        +                    "additionalProperties": true,
        +                    "description": "Optional min/max constraints on Greeks during resolution.",
        +                    "type": "object"
        +                  },
        +                  "liquidityFilter": {
        +                    "additionalProperties": false,
        +                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                    "properties": {
        +                      "maxSpreadAbsolute": {
        +                        "type": "number"
        +                      },
        +                      "maxSpreadPct": {
        +                        "type": "number"
        +                      },
        +                      "minBid": {
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  },
        +                  "optionType": {
        +                    "enum": [
        +                      "call",
        +                      "put"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "ratio": {
        +                    "type": "number"
        +                  },
        +                  "strikeRange": {
        +                    "additionalProperties": true,
        +                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                    "type": "object"
        +                  },
        +                  "strikeSelector": {
        +                    "properties": {
        +                      "distance": {
        +                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                        "type": "number"
        +                      },
        +                      "distanceType": {
        +                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "distanceType",
        +                      "distance"
        +                    ],
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "optionType",
        +                  "direction",
        +                  "expirationSelector",
        +                  "strikeSelector"
        +                ],
        +                "type": "object"
        +              },
        +              "minItems": 1,
        +              "type": "array"
        +            },
        +            "name": {
        +              "type": "string"
        +            },
        +            "spreadType": {
        +              "enum": [
        +                "vertical",
        +                "calendar",
        +                "diagonal",
        +                "ironCondor",
        +                "straddle",
        +                "strangle",
        +                "custom"
        +              ],
        +              "type": "string"
        +            },
        +            "widthConstraint": {
        +              "additionalProperties": false,
        +              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +              "properties": {
        +                "minWidthDollars": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                },
        +                "minWidthPercent": {
        +                  "exclusiveMinimum": 0,
        +                  "type": "number"
        +                }
        +              },
        +              "type": "object"
        +            }
        +          },
        +          "required": [
        +            "legs"
        +          ],
        +          "type": "object"
        +        },
        +        "minItems": 1,
        +        "type": "array"
        +      },
        +      "universe": {
        +        "additionalProperties": true,
        +        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +        "properties": {
        +          "assets": {
        +            "items": {
        +              "additionalProperties": true,
        +              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +              "properties": {
        +                "name": {
        +                  "type": "string"
        +                },
        +                "symbol": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Stock",
        +                    "Cryptocurrency",
        +                    "Option",
        +                    "Other"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "symbol"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "enum": [
        +              "ALL_US_STOCKS",
        +              "SP500",
        +              "NASDAQ100",
        +              "DJIA",
        +              "CRYPTO",
        +              "SPECIFIC_ASSETS"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "weightIndicator": {
        +        "$ref": "#/$defs/indicator"
        +      }
        +    },
        +    "required": [
        +      "name"
        +    ],
        +    "type": "object"
        +  },
        +  "strategy": {
        +    "additionalProperties": true,
        +    "description": "A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.",
        +    "properties": {
        +      "action": {
        +        "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).",
        +        "oneOf": [
        +          {
        +            "additionalProperties": true,
        +            "description": "Buy or Sell a stock/crypto position.",
        +            "properties": {
        +              "amount": {
        +                "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        +                "properties": {
        +                  "amount": {
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "enum": [
        +                      "percent of portfolio",
        +                      "percent of buying power",
        +                      "percent of current positions",
        +                      "dollars",
        +                      "number of assets"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "amount"
        +                ],
        +                "type": "object"
        +              },
        +              "targetAsset": {
        +                "additionalProperties": true,
        +                "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                "properties": {
        +                  "name": {
        +                    "type": "string"
        +                  },
        +                  "symbol": {
        +                    "type": "string"
        +                  },
        +                  "type": {
        +                    "enum": [
        +                      "Stock",
        +                      "Cryptocurrency",
        +                      "Option",
        +                      "Other"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "symbol"
        +                ],
        +                "type": "object"
        +              },
        +              "type": {
        +                "enum": [
        +                  "Buy",
        +                  "Sell"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "targetAsset",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": true,
        +            "description": "Send an alert message (no order).",
        +            "properties": {
        +              "message": {
        +                "type": "string"
        +              },
        +              "type": {
        +                "const": "Alert",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "message"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": true,
        +            "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        +            "properties": {
        +              "allocationPolicy": {
        +                "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +                "oneOf": [
        +                  {
        +                    "additionalProperties": false,
        +                    "properties": {
        +                      "covarianceShrinkage": {
        +                        "maximum": 1,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "estimatedTransactionCostBps": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "expectedReturnShrinkage": {
        +                        "maximum": 1,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "lookbackPeriods": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "minimumObservations": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "riskAversion": {
        +                        "maximum": 1000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "turnoverPenalty": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "MeanVariance",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "lookbackPeriods",
        +                      "minimumObservations",
        +                      "riskAversion",
        +                      "expectedReturnShrinkage",
        +                      "covarianceShrinkage",
        +                      "turnoverPenalty",
        +                      "estimatedTransactionCostBps"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": false,
        +                    "properties": {
        +                      "covarianceShrinkage": {
        +                        "maximum": 1,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "estimatedTransactionCostBps": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "lookbackPeriods": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "minimumObservations": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "turnoverPenalty": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "RiskParity",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "lookbackPeriods",
        +                      "minimumObservations",
        +                      "covarianceShrinkage",
        +                      "turnoverPenalty",
        +                      "estimatedTransactionCostBps"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": false,
        +                    "properties": {
        +                      "covarianceShrinkage": {
        +                        "maximum": 1,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "estimatedTransactionCostBps": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "lookbackPeriods": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "minimumObservations": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "turnoverPenalty": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "MaximumDiversification",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "lookbackPeriods",
        +                      "minimumObservations",
        +                      "covarianceShrinkage",
        +                      "turnoverPenalty",
        +                      "estimatedTransactionCostBps"
        +                    ],
        +                    "type": "object"
        +                  }
        +                ]
        +              },
        +              "canSell": {
        +                "$ref": "#/$defs/condition",
        +                "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        +              },
        +              "deploymentPercent": {
        +                "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        +                "maximum": 100,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "exposurePolicy": {
        +                "additionalProperties": false,
        +                "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +                "properties": {
        +                  "covarianceShrinkage": {
        +                    "maximum": 1,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "estimatedTransactionCostBps": {
        +                    "maximum": 10000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "lookbackPeriods": {
        +                    "maximum": 5000,
        +                    "minimum": 2,
        +                    "type": "integer"
        +                  },
        +                  "minimumObservations": {
        +                    "maximum": 5000,
        +                    "minimum": 2,
        +                    "type": "integer"
        +                  },
        +                  "targetAnnualizedVolatilityPercent": {
        +                    "maximum": 1000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "const": "VolatilityTarget",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "lookbackPeriods",
        +                  "minimumObservations",
        +                  "covarianceShrinkage",
        +                  "targetAnnualizedVolatilityPercent",
        +                  "estimatedTransactionCostBps"
        +                ],
        +                "type": "object"
        +              },
        +              "limit": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "perNameAllocation": {
        +                "additionalProperties": true,
        +                "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
        +                "properties": {
        +                  "amount": {
        +                    "exclusiveMinimum": 0,
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "enum": [
        +                      "percent of portfolio",
        +                      "dollars"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "amount"
        +                ],
        +                "type": "object"
        +              },
        +              "pipeline": {
        +                "items": {
        +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                  "oneOf": [
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "condition": {
        +                          "$ref": "#/$defs/condition"
        +                        },
        +                        "type": {
        +                          "const": "Filter",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "condition"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "limit": {
        +                          "minimum": 1,
        +                          "type": "number"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "type": {
        +                          "const": "SelectTop",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "limit",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "percentile": {
        +                          "maximum": 100,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "SelectPercentile",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "percentile",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "type": {
        +                "const": "DynamicRebalance",
        +                "type": "string"
        +              },
        +              "universe": {
        +                "additionalProperties": true,
        +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                "properties": {
        +                  "assets": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                      "properties": {
        +                        "name": {
        +                          "type": "string"
        +                        },
        +                        "symbol": {
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "enum": [
        +                            "Stock",
        +                            "Cryptocurrency",
        +                            "Option",
        +                            "Other"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "symbol"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "type": "array"
        +                  },
        +                  "source": {
        +                    "enum": [
        +                      "ALL_US_STOCKS",
        +                      "SP500",
        +                      "NASDAQ100",
        +                      "DJIA",
        +                      "CRYPTO",
        +                      "SPECIFIC_ASSETS"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "source"
        +                ],
        +                "type": "object"
        +              },
        +              "weightIndicator": {
        +                "$ref": "#/$defs/indicator"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "universe",
        +              "pipeline",
        +              "weightIndicator"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": true,
        +            "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        +            "properties": {
        +              "continueExisting": {
        +                "type": "boolean"
        +              },
        +              "cooldownMinutes": {
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "executionModel": {
        +                "type": "string"
        +              },
        +              "includeMarketData": {
        +                "type": "boolean"
        +              },
        +              "initialMessage": {
        +                "type": "string"
        +              },
        +              "maxIterations": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "planningModel": {
        +                "type": "string"
        +              },
        +              "skipPlanning": {
        +                "type": "boolean"
        +              },
        +              "type": {
        +                "const": "LaunchAgent",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "planningModel",
        +              "executionModel",
        +              "initialMessage",
        +              "maxIterations",
        +              "includeMarketData",
        +              "continueExisting",
        +              "skipPlanning"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": true,
        +            "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        +            "properties": {
        +              "against": {
        +                "additionalProperties": true,
        +                "description": "Optional parent-position selector (e.g. for covered calls).",
        +                "type": "object"
        +              },
        +              "allocation": {
        +                "additionalProperties": true,
        +                "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +                "properties": {
        +                  "amount": {
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "enum": [
        +                      "dollars",
        +                      "percent of portfolio",
        +                      "percent of buying power",
        +                      "contracts"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "amount"
        +                ],
        +                "type": "object"
        +              },
        +              "builder": {
        +                "additionalProperties": true,
        +                "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        +                "properties": {
        +                  "dynamicUnderlying": {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "limit": {
        +                        "minimum": 1,
        +                        "type": "number"
        +                      },
        +                      "pipeline": {
        +                        "items": {
        +                          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                          "oneOf": [
        +                            {
        +                              "additionalProperties": true,
        +                              "properties": {
        +                                "condition": {
        +                                  "$ref": "#/$defs/condition"
        +                                },
        +                                "type": {
        +                                  "const": "Filter",
        +                                  "type": "string"
        +                                }
        +                              },
        +                              "required": [
        +                                "type",
        +                                "condition"
        +                              ],
        +                              "type": "object"
        +                            },
        +                            {
        +                              "additionalProperties": true,
        +                              "properties": {
        +                                "direction": {
        +                                  "enum": [
        +                                    "Highest",
        +                                    "Lowest"
        +                                  ],
        +                                  "type": "string"
        +                                },
        +                                "limit": {
        +                                  "minimum": 1,
        +                                  "type": "number"
        +                                },
        +                                "metric": {
        +                                  "$ref": "#/$defs/indicator"
        +                                },
        +                                "type": {
        +                                  "const": "SelectTop",
        +                                  "type": "string"
        +                                }
        +                              },
        +                              "required": [
        +                                "type",
        +                                "metric",
        +                                "limit",
        +                                "direction"
        +                              ],
        +                              "type": "object"
        +                            },
        +                            {
        +                              "additionalProperties": true,
        +                              "properties": {
        +                                "direction": {
        +                                  "enum": [
        +                                    "Highest",
        +                                    "Lowest"
        +                                  ],
        +                                  "type": "string"
        +                                },
        +                                "metric": {
        +                                  "$ref": "#/$defs/indicator"
        +                                },
        +                                "percentile": {
        +                                  "maximum": 100,
        +                                  "minimum": 0,
        +                                  "type": "number"
        +                                },
        +                                "type": {
        +                                  "const": "SelectPercentile",
        +                                  "type": "string"
        +                                }
        +                              },
        +                              "required": [
        +                                "type",
        +                                "metric",
        +                                "percentile",
        +                                "direction"
        +                              ],
        +                              "type": "object"
        +                            }
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "type": "array"
        +                      },
        +                      "universe": {
        +                        "additionalProperties": true,
        +                        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                        "properties": {
        +                          "assets": {
        +                            "items": {
        +                              "additionalProperties": true,
        +                              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                              "properties": {
        +                                "name": {
        +                                  "type": "string"
        +                                },
        +                                "symbol": {
        +                                  "type": "string"
        +                                },
        +                                "type": {
        +                                  "enum": [
        +                                    "Stock",
        +                                    "Cryptocurrency",
        +                                    "Option",
        +                                    "Other"
        +                                  ],
        +                                  "type": "string"
        +                                }
        +                              },
        +                              "required": [
        +                                "type",
        +                                "symbol"
        +                              ],
        +                              "type": "object"
        +                            },
        +                            "type": "array"
        +                          },
        +                          "source": {
        +                            "enum": [
        +                              "ALL_US_STOCKS",
        +                              "SP500",
        +                              "NASDAQ100",
        +                              "DJIA",
        +                              "CRYPTO",
        +                              "SPECIFIC_ASSETS"
        +                            ],
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "source"
        +                        ],
        +                        "type": "object"
        +                      }
        +                    },
        +                    "required": [
        +                      "universe"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "legs": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Single leg of an option builder.",
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "long",
        +                            "short"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "expirationRange": {
        +                          "additionalProperties": true,
        +                          "type": "object"
        +                        },
        +                        "expirationSelector": {
        +                          "properties": {
        +                            "maxDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "minDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "preference": {
        +                              "enum": [
        +                                "nearest",
        +                                "middle",
        +                                "furthest"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "minDaysToExpiration",
        +                            "maxDaysToExpiration",
        +                            "preference"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "fallbackStrikeSelector": {
        +                          "additionalProperties": false,
        +                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                          "properties": {
        +                            "distance": {
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "enum": [
        +                                "percent",
        +                                "dollars"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "greekFilter": {
        +                          "additionalProperties": true,
        +                          "description": "Optional min/max constraints on Greeks during resolution.",
        +                          "type": "object"
        +                        },
        +                        "liquidityFilter": {
        +                          "additionalProperties": false,
        +                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                          "properties": {
        +                            "maxSpreadAbsolute": {
        +                              "type": "number"
        +                            },
        +                            "maxSpreadPct": {
        +                              "type": "number"
        +                            },
        +                            "minBid": {
        +                              "type": "number"
        +                            }
        +                          },
        +                          "type": "object"
        +                        },
        +                        "optionType": {
        +                          "enum": [
        +                            "call",
        +                            "put"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "ratio": {
        +                          "type": "number"
        +                        },
        +                        "strikeRange": {
        +                          "additionalProperties": true,
        +                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                          "type": "object"
        +                        },
        +                        "strikeSelector": {
        +                          "properties": {
        +                            "distance": {
        +                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        }
        +                      },
        +                      "required": [
        +                        "optionType",
        +                        "direction",
        +                        "expirationSelector",
        +                        "strikeSelector"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "minItems": 1,
        +                    "type": "array"
        +                  },
        +                  "spreadType": {
        +                    "enum": [
        +                      "vertical",
        +                      "calendar",
        +                      "diagonal",
        +                      "ironCondor",
        +                      "straddle",
        +                      "strangle",
        +                      "custom"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "underlyingSymbol": {
        +                    "type": "string"
        +                  },
        +                  "widthConstraint": {
        +                    "additionalProperties": false,
        +                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                    "properties": {
        +                      "minWidthDollars": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minWidthPercent": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "legs"
        +                ],
        +                "type": "object"
        +              },
        +              "type": {
        +                "const": "OpenOption",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "builder"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": true,
        +            "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        +            "properties": {
        +              "allocationPolicy": {
        +                "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +                "oneOf": [
        +                  {
        +                    "additionalProperties": false,
        +                    "properties": {
        +                      "covarianceShrinkage": {
        +                        "maximum": 1,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "estimatedTransactionCostBps": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "expectedReturnShrinkage": {
        +                        "maximum": 1,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "lookbackPeriods": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "minimumObservations": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "riskAversion": {
        +                        "maximum": 1000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "turnoverPenalty": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "MeanVariance",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "lookbackPeriods",
        +                      "minimumObservations",
        +                      "riskAversion",
        +                      "expectedReturnShrinkage",
        +                      "covarianceShrinkage",
        +                      "turnoverPenalty",
        +                      "estimatedTransactionCostBps"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": false,
        +                    "properties": {
        +                      "covarianceShrinkage": {
        +                        "maximum": 1,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "estimatedTransactionCostBps": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "lookbackPeriods": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "minimumObservations": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "turnoverPenalty": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "RiskParity",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "lookbackPeriods",
        +                      "minimumObservations",
        +                      "covarianceShrinkage",
        +                      "turnoverPenalty",
        +                      "estimatedTransactionCostBps"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": false,
        +                    "properties": {
        +                      "covarianceShrinkage": {
        +                        "maximum": 1,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "estimatedTransactionCostBps": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "lookbackPeriods": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "minimumObservations": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "turnoverPenalty": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "MaximumDiversification",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "lookbackPeriods",
        +                      "minimumObservations",
        +                      "covarianceShrinkage",
        +                      "turnoverPenalty",
        +                      "estimatedTransactionCostBps"
        +                    ],
        +                    "type": "object"
        +                  }
        +                ]
        +              },
        +              "exposurePolicy": {
        +                "additionalProperties": false,
        +                "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +                "properties": {
        +                  "covarianceShrinkage": {
        +                    "maximum": 1,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "estimatedTransactionCostBps": {
        +                    "maximum": 10000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "lookbackPeriods": {
        +                    "maximum": 5000,
        +                    "minimum": 2,
        +                    "type": "integer"
        +                  },
        +                  "minimumObservations": {
        +                    "maximum": 5000,
        +                    "minimum": 2,
        +                    "type": "integer"
        +                  },
        +                  "targetAnnualizedVolatilityPercent": {
        +                    "maximum": 1000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "const": "VolatilityTarget",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "lookbackPeriods",
        +                  "minimumObservations",
        +                  "covarianceShrinkage",
        +                  "targetAnnualizedVolatilityPercent",
        +                  "estimatedTransactionCostBps"
        +                ],
        +                "type": "object"
        +              },
        +              "limit": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "perNameAllocation": {
        +                "additionalProperties": true,
        +                "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +                "properties": {
        +                  "amount": {
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "enum": [
        +                      "dollars",
        +                      "percent of portfolio",
        +                      "percent of buying power",
        +                      "contracts"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "amount"
        +                ],
        +                "type": "object"
        +              },
        +              "pipeline": {
        +                "items": {
        +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                  "oneOf": [
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "condition": {
        +                          "$ref": "#/$defs/condition"
        +                        },
        +                        "type": {
        +                          "const": "Filter",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "condition"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "limit": {
        +                          "minimum": 1,
        +                          "type": "number"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "type": {
        +                          "const": "SelectTop",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "limit",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "percentile": {
        +                          "maximum": 100,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "SelectPercentile",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "percentile",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "positionScope": {
        +                "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        +                "enum": [
        +                  "portfolio",
        +                  "strategy"
        +                ],
        +                "type": "string"
        +              },
        +              "sleeves": {
        +                "items": {
        +                  "additionalProperties": true,
        +                  "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        +                  "properties": {
        +                    "limit": {
        +                      "minimum": 1,
        +                      "type": "number"
        +                    },
        +                    "name": {
        +                      "type": "string"
        +                    },
        +                    "perNameAllocation": {
        +                      "additionalProperties": true,
        +                      "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +                      "properties": {
        +                        "amount": {
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "enum": [
        +                            "dollars",
        +                            "percent of portfolio",
        +                            "percent of buying power",
        +                            "contracts"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "amount"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "pipeline": {
        +                      "items": {
        +                        "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                        "oneOf": [
        +                          {
        +                            "additionalProperties": true,
        +                            "properties": {
        +                              "condition": {
        +                                "$ref": "#/$defs/condition"
        +                              },
        +                              "type": {
        +                                "const": "Filter",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "condition"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "additionalProperties": true,
        +                            "properties": {
        +                              "direction": {
        +                                "enum": [
        +                                  "Highest",
        +                                  "Lowest"
        +                                ],
        +                                "type": "string"
        +                              },
        +                              "limit": {
        +                                "minimum": 1,
        +                                "type": "number"
        +                              },
        +                              "metric": {
        +                                "$ref": "#/$defs/indicator"
        +                              },
        +                              "type": {
        +                                "const": "SelectTop",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "metric",
        +                              "limit",
        +                              "direction"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "additionalProperties": true,
        +                            "properties": {
        +                              "direction": {
        +                                "enum": [
        +                                  "Highest",
        +                                  "Lowest"
        +                                ],
        +                                "type": "string"
        +                              },
        +                              "metric": {
        +                                "$ref": "#/$defs/indicator"
        +                              },
        +                              "percentile": {
        +                                "maximum": 100,
        +                                "minimum": 0,
        +                                "type": "number"
        +                              },
        +                              "type": {
        +                                "const": "SelectPercentile",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "metric",
        +                              "percentile",
        +                              "direction"
        +                            ],
        +                            "type": "object"
        +                          }
        +                        ],
        +                        "type": "object"
        +                      },
        +                      "type": "array"
        +                    },
        +                    "structureTemplates": {
        +                      "items": {
        +                        "additionalProperties": true,
        +                        "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +                        "properties": {
        +                          "eligibility": {
        +                            "$ref": "#/$defs/condition"
        +                          },
        +                          "legs": {
        +                            "items": {
        +                              "additionalProperties": true,
        +                              "description": "Single leg of an option builder.",
        +                              "properties": {
        +                                "direction": {
        +                                  "enum": [
        +                                    "long",
        +                                    "short"
        +                                  ],
        +                                  "type": "string"
        +                                },
        +                                "expirationRange": {
        +                                  "additionalProperties": true,
        +                                  "type": "object"
        +                                },
        +                                "expirationSelector": {
        +                                  "properties": {
        +                                    "maxDaysToExpiration": {
        +                                      "minimum": 0,
        +                                      "type": "number"
        +                                    },
        +                                    "minDaysToExpiration": {
        +                                      "minimum": 0,
        +                                      "type": "number"
        +                                    },
        +                                    "preference": {
        +                                      "enum": [
        +                                        "nearest",
        +                                        "middle",
        +                                        "furthest"
        +                                      ],
        +                                      "type": "string"
        +                                    }
        +                                  },
        +                                  "required": [
        +                                    "minDaysToExpiration",
        +                                    "maxDaysToExpiration",
        +                                    "preference"
        +                                  ],
        +                                  "type": "object"
        +                                },
        +                                "fallbackStrikeSelector": {
        +                                  "additionalProperties": false,
        +                                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                                  "properties": {
        +                                    "distance": {
        +                                      "type": "number"
        +                                    },
        +                                    "distanceType": {
        +                                      "enum": [
        +                                        "percent",
        +                                        "dollars"
        +                                      ],
        +                                      "type": "string"
        +                                    }
        +                                  },
        +                                  "required": [
        +                                    "distanceType",
        +                                    "distance"
        +                                  ],
        +                                  "type": "object"
        +                                },
        +                                "greekFilter": {
        +                                  "additionalProperties": true,
        +                                  "description": "Optional min/max constraints on Greeks during resolution.",
        +                                  "type": "object"
        +                                },
        +                                "liquidityFilter": {
        +                                  "additionalProperties": false,
        +                                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                                  "properties": {
        +                                    "maxSpreadAbsolute": {
        +                                      "type": "number"
        +                                    },
        +                                    "maxSpreadPct": {
        +                                      "type": "number"
        +                                    },
        +                                    "minBid": {
        +                                      "type": "number"
        +                                    }
        +                                  },
        +                                  "type": "object"
        +                                },
        +                                "optionType": {
        +                                  "enum": [
        +                                    "call",
        +                                    "put"
        +                                  ],
        +                                  "type": "string"
        +                                },
        +                                "ratio": {
        +                                  "type": "number"
        +                                },
        +                                "strikeRange": {
        +                                  "additionalProperties": true,
        +                                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                                  "type": "object"
        +                                },
        +                                "strikeSelector": {
        +                                  "properties": {
        +                                    "distance": {
        +                                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                                      "type": "number"
        +                                    },
        +                                    "distanceType": {
        +                                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                                      "type": "string"
        +                                    }
        +                                  },
        +                                  "required": [
        +                                    "distanceType",
        +                                    "distance"
        +                                  ],
        +                                  "type": "object"
        +                                }
        +                              },
        +                              "required": [
        +                                "optionType",
        +                                "direction",
        +                                "expirationSelector",
        +                                "strikeSelector"
        +                              ],
        +                              "type": "object"
        +                            },
        +                            "minItems": 1,
        +                            "type": "array"
        +                          },
        +                          "name": {
        +                            "type": "string"
        +                          },
        +                          "spreadType": {
        +                            "enum": [
        +                              "vertical",
        +                              "calendar",
        +                              "diagonal",
        +                              "ironCondor",
        +                              "straddle",
        +                              "strangle",
        +                              "custom"
        +                            ],
        +                            "type": "string"
        +                          },
        +                          "widthConstraint": {
        +                            "additionalProperties": false,
        +                            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                            "properties": {
        +                              "minWidthDollars": {
        +                                "exclusiveMinimum": 0,
        +                                "type": "number"
        +                              },
        +                              "minWidthPercent": {
        +                                "exclusiveMinimum": 0,
        +                                "type": "number"
        +                              }
        +                            },
        +                            "type": "object"
        +                          }
        +                        },
        +                        "required": [
        +                          "legs"
        +                        ],
        +                        "type": "object"
        +                      },
        +                      "minItems": 1,
        +                      "type": "array"
        +                    },
        +                    "universe": {
        +                      "additionalProperties": true,
        +                      "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                      "properties": {
        +                        "assets": {
        +                          "items": {
        +                            "additionalProperties": true,
        +                            "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                            "properties": {
        +                              "name": {
        +                                "type": "string"
        +                              },
        +                              "symbol": {
        +                                "type": "string"
        +                              },
        +                              "type": {
        +                                "enum": [
        +                                  "Stock",
        +                                  "Cryptocurrency",
        +                                  "Option",
        +                                  "Other"
        +                                ],
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "symbol"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          "type": "array"
        +                        },
        +                        "source": {
        +                          "enum": [
        +                            "ALL_US_STOCKS",
        +                            "SP500",
        +                            "NASDAQ100",
        +                            "DJIA",
        +                            "CRYPTO",
        +                            "SPECIFIC_ASSETS"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "source"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "weightIndicator": {
        +                      "$ref": "#/$defs/indicator"
        +                    }
        +                  },
        +                  "required": [
        +                    "name"
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "structureTemplates": {
        +                "items": {
        +                  "additionalProperties": true,
        +                  "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +                  "properties": {
        +                    "eligibility": {
        +                      "$ref": "#/$defs/condition"
        +                    },
        +                    "legs": {
        +                      "items": {
        +                        "additionalProperties": true,
        +                        "description": "Single leg of an option builder.",
        +                        "properties": {
        +                          "direction": {
        +                            "enum": [
        +                              "long",
        +                              "short"
        +                            ],
        +                            "type": "string"
        +                          },
        +                          "expirationRange": {
        +                            "additionalProperties": true,
        +                            "type": "object"
        +                          },
        +                          "expirationSelector": {
        +                            "properties": {
        +                              "maxDaysToExpiration": {
        +                                "minimum": 0,
        +                                "type": "number"
        +                              },
        +                              "minDaysToExpiration": {
        +                                "minimum": 0,
        +                                "type": "number"
        +                              },
        +                              "preference": {
        +                                "enum": [
        +                                  "nearest",
        +                                  "middle",
        +                                  "furthest"
        +                                ],
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "minDaysToExpiration",
        +                              "maxDaysToExpiration",
        +                              "preference"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          "fallbackStrikeSelector": {
        +                            "additionalProperties": false,
        +                            "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                            "properties": {
        +                              "distance": {
        +                                "type": "number"
        +                              },
        +                              "distanceType": {
        +                                "enum": [
        +                                  "percent",
        +                                  "dollars"
        +                                ],
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "distanceType",
        +                              "distance"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          "greekFilter": {
        +                            "additionalProperties": true,
        +                            "description": "Optional min/max constraints on Greeks during resolution.",
        +                            "type": "object"
        +                          },
        +                          "liquidityFilter": {
        +                            "additionalProperties": false,
        +                            "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                            "properties": {
        +                              "maxSpreadAbsolute": {
        +                                "type": "number"
        +                              },
        +                              "maxSpreadPct": {
        +                                "type": "number"
        +                              },
        +                              "minBid": {
        +                                "type": "number"
        +                              }
        +                            },
        +                            "type": "object"
        +                          },
        +                          "optionType": {
        +                            "enum": [
        +                              "call",
        +                              "put"
        +                            ],
        +                            "type": "string"
        +                          },
        +                          "ratio": {
        +                            "type": "number"
        +                          },
        +                          "strikeRange": {
        +                            "additionalProperties": true,
        +                            "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                            "type": "object"
        +                          },
        +                          "strikeSelector": {
        +                            "properties": {
        +                              "distance": {
        +                                "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                                "type": "number"
        +                              },
        +                              "distanceType": {
        +                                "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "distanceType",
        +                              "distance"
        +                            ],
        +                            "type": "object"
        +                          }
        +                        },
        +                        "required": [
        +                          "optionType",
        +                          "direction",
        +                          "expirationSelector",
        +                          "strikeSelector"
        +                        ],
        +                        "type": "object"
        +                      },
        +                      "minItems": 1,
        +                      "type": "array"
        +                    },
        +                    "name": {
        +                      "type": "string"
        +                    },
        +                    "spreadType": {
        +                      "enum": [
        +                        "vertical",
        +                        "calendar",
        +                        "diagonal",
        +                        "ironCondor",
        +                        "straddle",
        +                        "strangle",
        +                        "custom"
        +                      ],
        +                      "type": "string"
        +                    },
        +                    "widthConstraint": {
        +                      "additionalProperties": false,
        +                      "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                      "properties": {
        +                        "minWidthDollars": {
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "minWidthPercent": {
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        }
        +                      },
        +                      "type": "object"
        +                    }
        +                  },
        +                  "required": [
        +                    "legs"
        +                  ],
        +                  "type": "object"
        +                },
        +                "minItems": 1,
        +                "type": "array"
        +              },
        +              "totalBudget": {
        +                "additionalProperties": true,
        +                "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        +                "properties": {
        +                  "amount": {
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "enum": [
        +                      "dollars",
        +                      "percent of portfolio"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "amount"
        +                ],
        +                "type": "object"
        +              },
        +              "type": {
        +                "const": "RebalanceOption",
        +                "type": "string"
        +              },
        +              "universe": {
        +                "additionalProperties": true,
        +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                "properties": {
        +                  "assets": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                      "properties": {
        +                        "name": {
        +                          "type": "string"
        +                        },
        +                        "symbol": {
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "enum": [
        +                            "Stock",
        +                            "Cryptocurrency",
        +                            "Option",
        +                            "Other"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "symbol"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "type": "array"
        +                  },
        +                  "source": {
        +                    "enum": [
        +                      "ALL_US_STOCKS",
        +                      "SP500",
        +                      "NASDAQ100",
        +                      "DJIA",
        +                      "CRYPTO",
        +                      "SPECIFIC_ASSETS"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "source"
        +                ],
        +                "type": "object"
        +              },
        +              "weightIndicator": {
        +                "$ref": "#/$defs/indicator"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "universe",
        +              "pipeline",
        +              "weightIndicator",
        +              "structureTemplates"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": true,
        +            "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        +            "properties": {
        +              "closeScope": {
        +                "enum": [
        +                  "spread",
        +                  "leg"
        +                ],
        +                "type": "string"
        +              },
        +              "direction": {
        +                "enum": [
        +                  "long",
        +                  "short"
        +                ],
        +                "type": "string"
        +              },
        +              "optionType": {
        +                "enum": [
        +                  "call",
        +                  "put"
        +                ],
        +                "type": "string"
        +              },
        +              "quantity": {
        +                "additionalProperties": true,
        +                "description": "How many contracts to close. Defaults to all matching when omitted.",
        +                "type": "object"
        +              },
        +              "spreadType": {
        +                "enum": [
        +                  "vertical",
        +                  "calendar",
        +                  "diagonal",
        +                  "ironCondor",
        +                  "straddle",
        +                  "strangle",
        +                  "custom"
        +                ],
        +                "type": "string"
        +              },
        +              "triggers": {
        +                "items": {
        +                  "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        +                  "oneOf": [
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "maxPnlPercent": {
        +                          "type": "number"
        +                        },
        +                        "minPnlPercent": {
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "pnl",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "maxDte": {
        +                          "type": "number"
        +                        },
        +                        "minDte": {
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "dte",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "maxDaysHeld": {
        +                          "type": "number"
        +                        },
        +                        "minDaysHeld": {
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "daysHeld",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "maxIv": {
        +                          "type": "number"
        +                        },
        +                        "maxSpreadDelta": {
        +                          "type": "number"
        +                        },
        +                        "maxSpreadTheta": {
        +                          "type": "number"
        +                        },
        +                        "minIv": {
        +                          "type": "number"
        +                        },
        +                        "minSpreadDelta": {
        +                          "type": "number"
        +                        },
        +                        "minSpreadTheta": {
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "greeks",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "type": {
        +                "const": "CloseOption",
        +                "type": "string"
        +              },
        +              "underlyings": {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              }
        +            },
        +            "required": [
        +              "type"
        +            ],
        +            "type": "object"
        +          }
        +        ],
        +        "type": "object"
        +      },
        +      "active": {
        +        "description": "Whether the strategy is active (default true).",
        +        "type": "boolean"
        +      },
        +      "condition": {
        +        "$ref": "#/$defs/condition"
        +      },
        +      "name": {
        +        "description": "Human-readable strategy name.",
        +        "type": "string"
        +      },
        +      "orderExecution": {
        +        "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "type": {
        +                "const": "Market",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "price": {
        +                "oneOf": [
        +                  {
        +                    "additionalProperties": false,
        +                    "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        +                    "properties": {
        +                      "amount": {
        +                        "minimum": 1e-8,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "UnitPrice",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "amount"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": false,
        +                    "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        +                    "properties": {
        +                      "amount": {
        +                        "minimum": 1e-8,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "MinimumNetCredit",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "amount"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": false,
        +                    "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        +                    "properties": {
        +                      "amount": {
        +                        "minimum": 1e-8,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "MaximumNetDebit",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "amount"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": false,
        +                    "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        +                    "properties": {
        +                      "reference": {
        +                        "const": "Current",
        +                        "type": "string"
        +                      },
        +                      "type": {
        +                        "const": "QuoteRelative",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "reference"
        +                    ],
        +                    "type": "object"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "Limit",
        +                "type": "string"
        +              },
        +              "workingTime": {
        +                "oneOf": [
        +                  {
        +                    "additionalProperties": false,
        +                    "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        +                    "properties": {
        +                      "type": {
        +                        "const": "Day",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": false,
        +                    "properties": {
        +                      "minutes": {
        +                        "minimum": 1,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "Minutes",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "minutes"
        +                    ],
        +                    "type": "object"
        +                  }
        +                ]
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "price"
        +            ],
        +            "type": "object"
        +          }
        +        ],
        +        "type": "object"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "condition",
        +      "action"
        +    ],
        +    "type": "object"
        +  },
        +  "window": {
        +    "description": "Rolling time window. e.g. {length:14, interval:'Day'} = trailing 14 trading days.",
        +    "properties": {
        +      "interval": {
        +        "enum": [
        +          "Day",
        +          "Hour",
        +          "Minute"
        +        ],
        +        "type": "string"
        +      },
        +      "length": {
        +        "minimum": 1,
        +        "type": "number"
        +      }
        +    },
        +    "required": [
        +      "length",
        +      "interval"
        +    ],
        +    "type": "object"
        +  }
        +}
      • changedInput schema / properties / operations / description
        Previous value: -"Array of edit operations. Each operation needs \"portfolioId\" (live, paper, or chat — server resolves automatically). Supported types include \"rename\" (requires non-empty \"name\"), \"delete\" (permanently remove a chat/paper/live portfolio; archives deployed books; pass confirmLive:true only after explicit user confirmation when deleting an active live portfolio). DEPLOY SAFETY: deploying a chat portfolio ID creates a NEW PAPER-TRADING portfolio (simulated money, no broker order ever placed). It cannot place real-money trades. A LIVE/real-brokerage deployment only happens when the target is an EXISTING real-brokerage portfolio (re-activating it, or addStrategies/replaceStrategies on a portfolio already connected to a live broker). You cannot create a live brokerage account from a chat portfolio through this tool. Fetch the portfolio first and use strategy IDs from the returned \"strategies\" array for removals. To add/replace strategies, pass FINISHED strategy objects ({name, condition, action} — same shape as create_portfolio.strategies) via \"strategyObjects\" (or \"strategyObject\" for replaceStrategy). These are ingested deterministically with zero LLM cost; prefer them. RebalanceOption `action.positionScope`: `\"portfolio\"` (default for single-book portfolios — rotation-close and open-skip span all option spreads in the portfolio) or `\"strategy\"` (only spreads this strategy opened; use when multiple RebalanceOption strategies share one portfolio). Set on `create_portfolio` strategies[].action or on `update_portfolio` replaceStrategy/replaceStrategies `strategyObject.action`. Examples: [{\"type\":\"deploy\",\"portfolioId\":\"id\"}, {\"type\":\"undeploy\",\"portfolioId\":\"id\"}, {\"type\":\"delete\",\"portfolioId\":\"id\"}, {\"type\":\"addStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...}}]}, {\"type\":\"removeStrategies\",\"portfolioId\":\"id\",\"strategyIds\":[\"strategyId\"]}, {\"type\":\"replaceStrategy\",\"portfolioId\":\"id\",\"targetStrategyId\":\"strategyId\",\"strategyObject\":{\"name\":\"...\",\"condition\":{...},\"action\":{\"type\":\"RebalanceOption\",\"positionScope\":\"portfolio\",...}}}, {\"type\":\"replaceStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...}}]}, {\"type\":\"setDeploymentFrequency\",\"portfolioId\":\"id\",\"deploymentFrequency\":\"Constant\"}, {\"type\":\"rename\",\"portfolioId\":\"id\",\"name\":\"New Portfolio Name\"}]"New value: +"Array of edit operations. Each operation needs \"portfolioId\" (live, paper, or chat — server resolves automatically). Supported types include \"rename\" (requires non-empty \"name\"), \"delete\" (permanently remove a chat/paper/live portfolio; archives deployed books; pass confirmLive:true only after explicit user confirmation when deleting an active live portfolio). DEPLOY SAFETY: deploying a chat portfolio ID creates a NEW PAPER-TRADING portfolio (simulated money, no broker order ever placed). It cannot place real-money trades. A LIVE/real-brokerage deployment only happens when the target is an EXISTING real-brokerage portfolio (re-activating it, or addStrategies/replaceStrategies on a portfolio already connected to a live broker). You cannot create a live brokerage account from a chat portfolio through this tool. Fetch the portfolio first and use strategy IDs from the returned \"strategies\" array for removals. To add/replace strategies, pass FINISHED strategy objects ({name, condition, action, orderExecution?} — same shape as create_portfolio.strategies) via \"strategyObjects\" (or \"strategyObject\" for replaceStrategy). These are ingested deterministically with zero LLM cost; prefer them. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price. RebalanceOption `action.positionScope`: `\"portfolio\"` (default for single-book portfolios — rotation-close and open-skip span all option spreads in the portfolio) or `\"strategy\"` (only spreads this strategy opened; use when multiple RebalanceOption strategies share one portfolio). Set on `create_portfolio` strategies[].action or on `update_portfolio` replaceStrategy/replaceStrategies `strategyObject.action`. Examples: [{\"type\":\"deploy\",\"portfolioId\":\"id\"}, {\"type\":\"undeploy\",\"portfolioId\":\"id\"}, {\"type\":\"delete\",\"portfolioId\":\"id\"}, {\"type\":\"addStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...},\"orderExecution\":{\"type\":\"Limit\",\"price\":{\"type\":\"UnitPrice\",\"amount\":150},\"workingTime\":{\"type\":\"Day\"}}}]}, {\"type\":\"removeStrategies\",\"portfolioId\":\"id\",\"strategyIds\":[\"strategyId\"]}, {\"type\":\"replaceStrategy\",\"portfolioId\":\"id\",\"targetStrategyId\":\"strategyId\",\"strategyObject\":{\"name\":\"...\",\"condition\":{...},\"action\":{\"type\":\"RebalanceOption\",\"positionScope\":\"portfolio\",...}}}, {\"type\":\"replaceStrategies\",\"portfolioId\":\"id\",\"strategyObjects\":[{\"name\":\"...\",\"condition\":{...},\"action\":{...}}]}, {\"type\":\"setDeploymentFrequency\",\"portfolioId\":\"id\",\"deploymentFrequency\":\"Constant\"}, {\"type\":\"rename\",\"portfolioId\":\"id\",\"name\":\"New Portfolio Name\"}]"
      • addedInput schema / properties / operations / items / additionalProperties
        Added value: +false
      • addedInput schema / properties / operations / items / properties
        Added value: +{
        +  "confirmLive": {
        +    "type": "boolean"
        +  },
        +  "deploymentFrequency": {
        +    "enum": [
        +      "Constant",
        +      "OpenClose"
        +    ],
        +    "type": "string"
        +  },
        +  "name": {
        +    "type": "string"
        +  },
        +  "portfolioId": {
        +    "type": "string"
        +  },
        +  "strategyIds": {
        +    "items": {
        +      "type": "string"
        +    },
        +    "type": "array"
        +  },
        +  "strategyObject": {
        +    "additionalProperties": true,
        +    "description": "A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.",
        +    "properties": {
        +      "action": {
        +        "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).",
        +        "oneOf": [
        +          {
        +            "additionalProperties": true,
        +            "description": "Buy or Sell a stock/crypto position.",
        +            "properties": {
        +              "amount": {
        +                "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        +                "properties": {
        +                  "amount": {
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "enum": [
        +                      "percent of portfolio",
        +                      "percent of buying power",
        +                      "percent of current positions",
        +                      "dollars",
        +                      "number of assets"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "amount"
        +                ],
        +                "type": "object"
        +              },
        +              "targetAsset": {
        +                "additionalProperties": true,
        +                "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                "properties": {
        +                  "name": {
        +                    "type": "string"
        +                  },
        +                  "symbol": {
        +                    "type": "string"
        +                  },
        +                  "type": {
        +                    "enum": [
        +                      "Stock",
        +                      "Cryptocurrency",
        +                      "Option",
        +                      "Other"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "symbol"
        +                ],
        +                "type": "object"
        +              },
        +              "type": {
        +                "enum": [
        +                  "Buy",
        +                  "Sell"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "targetAsset",
        +              "amount"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": true,
        +            "description": "Send an alert message (no order).",
        +            "properties": {
        +              "message": {
        +                "type": "string"
        +              },
        +              "type": {
        +                "const": "Alert",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "message"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": true,
        +            "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        +            "properties": {
        +              "allocationPolicy": {
        +                "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +                "oneOf": [
        +                  {
        +                    "additionalProperties": false,
        +                    "properties": {
        +                      "covarianceShrinkage": {
        +                        "maximum": 1,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "estimatedTransactionCostBps": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "expectedReturnShrinkage": {
        +                        "maximum": 1,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "lookbackPeriods": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "minimumObservations": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "riskAversion": {
        +                        "maximum": 1000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "turnoverPenalty": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "MeanVariance",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "lookbackPeriods",
        +                      "minimumObservations",
        +                      "riskAversion",
        +                      "expectedReturnShrinkage",
        +                      "covarianceShrinkage",
        +                      "turnoverPenalty",
        +                      "estimatedTransactionCostBps"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": false,
        +                    "properties": {
        +                      "covarianceShrinkage": {
        +                        "maximum": 1,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "estimatedTransactionCostBps": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "lookbackPeriods": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "minimumObservations": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "turnoverPenalty": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "RiskParity",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "lookbackPeriods",
        +                      "minimumObservations",
        +                      "covarianceShrinkage",
        +                      "turnoverPenalty",
        +                      "estimatedTransactionCostBps"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": false,
        +                    "properties": {
        +                      "covarianceShrinkage": {
        +                        "maximum": 1,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "estimatedTransactionCostBps": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "lookbackPeriods": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "minimumObservations": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "turnoverPenalty": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "MaximumDiversification",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "lookbackPeriods",
        +                      "minimumObservations",
        +                      "covarianceShrinkage",
        +                      "turnoverPenalty",
        +                      "estimatedTransactionCostBps"
        +                    ],
        +                    "type": "object"
        +                  }
        +                ]
        +              },
        +              "canSell": {
        +                "$ref": "#/$defs/condition",
        +                "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        +              },
        +              "deploymentPercent": {
        +                "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        +                "maximum": 100,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "exposurePolicy": {
        +                "additionalProperties": false,
        +                "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +                "properties": {
        +                  "covarianceShrinkage": {
        +                    "maximum": 1,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "estimatedTransactionCostBps": {
        +                    "maximum": 10000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "lookbackPeriods": {
        +                    "maximum": 5000,
        +                    "minimum": 2,
        +                    "type": "integer"
        +                  },
        +                  "minimumObservations": {
        +                    "maximum": 5000,
        +                    "minimum": 2,
        +                    "type": "integer"
        +                  },
        +                  "targetAnnualizedVolatilityPercent": {
        +                    "maximum": 1000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "const": "VolatilityTarget",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "lookbackPeriods",
        +                  "minimumObservations",
        +                  "covarianceShrinkage",
        +                  "targetAnnualizedVolatilityPercent",
        +                  "estimatedTransactionCostBps"
        +                ],
        +                "type": "object"
        +              },
        +              "limit": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "perNameAllocation": {
        +                "additionalProperties": true,
        +                "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
        +                "properties": {
        +                  "amount": {
        +                    "exclusiveMinimum": 0,
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "enum": [
        +                      "percent of portfolio",
        +                      "dollars"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "amount"
        +                ],
        +                "type": "object"
        +              },
        +              "pipeline": {
        +                "items": {
        +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                  "oneOf": [
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "condition": {
        +                          "$ref": "#/$defs/condition"
        +                        },
        +                        "type": {
        +                          "const": "Filter",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "condition"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "limit": {
        +                          "minimum": 1,
        +                          "type": "number"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "type": {
        +                          "const": "SelectTop",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "limit",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "percentile": {
        +                          "maximum": 100,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "SelectPercentile",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "percentile",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "type": {
        +                "const": "DynamicRebalance",
        +                "type": "string"
        +              },
        +              "universe": {
        +                "additionalProperties": true,
        +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                "properties": {
        +                  "assets": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                      "properties": {
        +                        "name": {
        +                          "type": "string"
        +                        },
        +                        "symbol": {
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "enum": [
        +                            "Stock",
        +                            "Cryptocurrency",
        +                            "Option",
        +                            "Other"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "symbol"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "type": "array"
        +                  },
        +                  "source": {
        +                    "enum": [
        +                      "ALL_US_STOCKS",
        +                      "SP500",
        +                      "NASDAQ100",
        +                      "DJIA",
        +                      "CRYPTO",
        +                      "SPECIFIC_ASSETS"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "source"
        +                ],
        +                "type": "object"
        +              },
        +              "weightIndicator": {
        +                "$ref": "#/$defs/indicator"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "universe",
        +              "pipeline",
        +              "weightIndicator"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": true,
        +            "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        +            "properties": {
        +              "continueExisting": {
        +                "type": "boolean"
        +              },
        +              "cooldownMinutes": {
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "executionModel": {
        +                "type": "string"
        +              },
        +              "includeMarketData": {
        +                "type": "boolean"
        +              },
        +              "initialMessage": {
        +                "type": "string"
        +              },
        +              "maxIterations": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "planningModel": {
        +                "type": "string"
        +              },
        +              "skipPlanning": {
        +                "type": "boolean"
        +              },
        +              "type": {
        +                "const": "LaunchAgent",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "planningModel",
        +              "executionModel",
        +              "initialMessage",
        +              "maxIterations",
        +              "includeMarketData",
        +              "continueExisting",
        +              "skipPlanning"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": true,
        +            "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        +            "properties": {
        +              "against": {
        +                "additionalProperties": true,
        +                "description": "Optional parent-position selector (e.g. for covered calls).",
        +                "type": "object"
        +              },
        +              "allocation": {
        +                "additionalProperties": true,
        +                "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +                "properties": {
        +                  "amount": {
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "enum": [
        +                      "dollars",
        +                      "percent of portfolio",
        +                      "percent of buying power",
        +                      "contracts"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "amount"
        +                ],
        +                "type": "object"
        +              },
        +              "builder": {
        +                "additionalProperties": true,
        +                "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        +                "properties": {
        +                  "dynamicUnderlying": {
        +                    "additionalProperties": true,
        +                    "properties": {
        +                      "limit": {
        +                        "minimum": 1,
        +                        "type": "number"
        +                      },
        +                      "pipeline": {
        +                        "items": {
        +                          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                          "oneOf": [
        +                            {
        +                              "additionalProperties": true,
        +                              "properties": {
        +                                "condition": {
        +                                  "$ref": "#/$defs/condition"
        +                                },
        +                                "type": {
        +                                  "const": "Filter",
        +                                  "type": "string"
        +                                }
        +                              },
        +                              "required": [
        +                                "type",
        +                                "condition"
        +                              ],
        +                              "type": "object"
        +                            },
        +                            {
        +                              "additionalProperties": true,
        +                              "properties": {
        +                                "direction": {
        +                                  "enum": [
        +                                    "Highest",
        +                                    "Lowest"
        +                                  ],
        +                                  "type": "string"
        +                                },
        +                                "limit": {
        +                                  "minimum": 1,
        +                                  "type": "number"
        +                                },
        +                                "metric": {
        +                                  "$ref": "#/$defs/indicator"
        +                                },
        +                                "type": {
        +                                  "const": "SelectTop",
        +                                  "type": "string"
        +                                }
        +                              },
        +                              "required": [
        +                                "type",
        +                                "metric",
        +                                "limit",
        +                                "direction"
        +                              ],
        +                              "type": "object"
        +                            },
        +                            {
        +                              "additionalProperties": true,
        +                              "properties": {
        +                                "direction": {
        +                                  "enum": [
        +                                    "Highest",
        +                                    "Lowest"
        +                                  ],
        +                                  "type": "string"
        +                                },
        +                                "metric": {
        +                                  "$ref": "#/$defs/indicator"
        +                                },
        +                                "percentile": {
        +                                  "maximum": 100,
        +                                  "minimum": 0,
        +                                  "type": "number"
        +                                },
        +                                "type": {
        +                                  "const": "SelectPercentile",
        +                                  "type": "string"
        +                                }
        +                              },
        +                              "required": [
        +                                "type",
        +                                "metric",
        +                                "percentile",
        +                                "direction"
        +                              ],
        +                              "type": "object"
        +                            }
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "type": "array"
        +                      },
        +                      "universe": {
        +                        "additionalProperties": true,
        +                        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                        "properties": {
        +                          "assets": {
        +                            "items": {
        +                              "additionalProperties": true,
        +                              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                              "properties": {
        +                                "name": {
        +                                  "type": "string"
        +                                },
        +                                "symbol": {
        +                                  "type": "string"
        +                                },
        +                                "type": {
        +                                  "enum": [
        +                                    "Stock",
        +                                    "Cryptocurrency",
        +                                    "Option",
        +                                    "Other"
        +                                  ],
        +                                  "type": "string"
        +                                }
        +                              },
        +                              "required": [
        +                                "type",
        +                                "symbol"
        +                              ],
        +                              "type": "object"
        +                            },
        +                            "type": "array"
        +                          },
        +                          "source": {
        +                            "enum": [
        +                              "ALL_US_STOCKS",
        +                              "SP500",
        +                              "NASDAQ100",
        +                              "DJIA",
        +                              "CRYPTO",
        +                              "SPECIFIC_ASSETS"
        +                            ],
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "source"
        +                        ],
        +                        "type": "object"
        +                      }
        +                    },
        +                    "required": [
        +                      "universe"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "legs": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Single leg of an option builder.",
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "long",
        +                            "short"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "expirationRange": {
        +                          "additionalProperties": true,
        +                          "type": "object"
        +                        },
        +                        "expirationSelector": {
        +                          "properties": {
        +                            "maxDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "minDaysToExpiration": {
        +                              "minimum": 0,
        +                              "type": "number"
        +                            },
        +                            "preference": {
        +                              "enum": [
        +                                "nearest",
        +                                "middle",
        +                                "furthest"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "minDaysToExpiration",
        +                            "maxDaysToExpiration",
        +                            "preference"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "fallbackStrikeSelector": {
        +                          "additionalProperties": false,
        +                          "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                          "properties": {
        +                            "distance": {
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "enum": [
        +                                "percent",
        +                                "dollars"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "greekFilter": {
        +                          "additionalProperties": true,
        +                          "description": "Optional min/max constraints on Greeks during resolution.",
        +                          "type": "object"
        +                        },
        +                        "liquidityFilter": {
        +                          "additionalProperties": false,
        +                          "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                          "properties": {
        +                            "maxSpreadAbsolute": {
        +                              "type": "number"
        +                            },
        +                            "maxSpreadPct": {
        +                              "type": "number"
        +                            },
        +                            "minBid": {
        +                              "type": "number"
        +                            }
        +                          },
        +                          "type": "object"
        +                        },
        +                        "optionType": {
        +                          "enum": [
        +                            "call",
        +                            "put"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "ratio": {
        +                          "type": "number"
        +                        },
        +                        "strikeRange": {
        +                          "additionalProperties": true,
        +                          "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                          "type": "object"
        +                        },
        +                        "strikeSelector": {
        +                          "properties": {
        +                            "distance": {
        +                              "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                              "type": "number"
        +                            },
        +                            "distanceType": {
        +                              "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "distanceType",
        +                            "distance"
        +                          ],
        +                          "type": "object"
        +                        }
        +                      },
        +                      "required": [
        +                        "optionType",
        +                        "direction",
        +                        "expirationSelector",
        +                        "strikeSelector"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "minItems": 1,
        +                    "type": "array"
        +                  },
        +                  "spreadType": {
        +                    "enum": [
        +                      "vertical",
        +                      "calendar",
        +                      "diagonal",
        +                      "ironCondor",
        +                      "straddle",
        +                      "strangle",
        +                      "custom"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "underlyingSymbol": {
        +                    "type": "string"
        +                  },
        +                  "widthConstraint": {
        +                    "additionalProperties": false,
        +                    "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                    "properties": {
        +                      "minWidthDollars": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      },
        +                      "minWidthPercent": {
        +                        "exclusiveMinimum": 0,
        +                        "type": "number"
        +                      }
        +                    },
        +                    "type": "object"
        +                  }
        +                },
        +                "required": [
        +                  "legs"
        +                ],
        +                "type": "object"
        +              },
        +              "type": {
        +                "const": "OpenOption",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "builder"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": true,
        +            "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        +            "properties": {
        +              "allocationPolicy": {
        +                "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +                "oneOf": [
        +                  {
        +                    "additionalProperties": false,
        +                    "properties": {
        +                      "covarianceShrinkage": {
        +                        "maximum": 1,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "estimatedTransactionCostBps": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "expectedReturnShrinkage": {
        +                        "maximum": 1,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "lookbackPeriods": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "minimumObservations": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "riskAversion": {
        +                        "maximum": 1000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "turnoverPenalty": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "MeanVariance",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "lookbackPeriods",
        +                      "minimumObservations",
        +                      "riskAversion",
        +                      "expectedReturnShrinkage",
        +                      "covarianceShrinkage",
        +                      "turnoverPenalty",
        +                      "estimatedTransactionCostBps"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": false,
        +                    "properties": {
        +                      "covarianceShrinkage": {
        +                        "maximum": 1,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "estimatedTransactionCostBps": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "lookbackPeriods": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "minimumObservations": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "turnoverPenalty": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "RiskParity",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "lookbackPeriods",
        +                      "minimumObservations",
        +                      "covarianceShrinkage",
        +                      "turnoverPenalty",
        +                      "estimatedTransactionCostBps"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": false,
        +                    "properties": {
        +                      "covarianceShrinkage": {
        +                        "maximum": 1,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "estimatedTransactionCostBps": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "lookbackPeriods": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "minimumObservations": {
        +                        "maximum": 5000,
        +                        "minimum": 2,
        +                        "type": "integer"
        +                      },
        +                      "turnoverPenalty": {
        +                        "maximum": 10000,
        +                        "minimum": 0,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "MaximumDiversification",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "lookbackPeriods",
        +                      "minimumObservations",
        +                      "covarianceShrinkage",
        +                      "turnoverPenalty",
        +                      "estimatedTransactionCostBps"
        +                    ],
        +                    "type": "object"
        +                  }
        +                ]
        +              },
        +              "exposurePolicy": {
        +                "additionalProperties": false,
        +                "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +                "properties": {
        +                  "covarianceShrinkage": {
        +                    "maximum": 1,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "estimatedTransactionCostBps": {
        +                    "maximum": 10000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "lookbackPeriods": {
        +                    "maximum": 5000,
        +                    "minimum": 2,
        +                    "type": "integer"
        +                  },
        +                  "minimumObservations": {
        +                    "maximum": 5000,
        +                    "minimum": 2,
        +                    "type": "integer"
        +                  },
        +                  "targetAnnualizedVolatilityPercent": {
        +                    "maximum": 1000,
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "const": "VolatilityTarget",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "lookbackPeriods",
        +                  "minimumObservations",
        +                  "covarianceShrinkage",
        +                  "targetAnnualizedVolatilityPercent",
        +                  "estimatedTransactionCostBps"
        +                ],
        +                "type": "object"
        +              },
        +              "limit": {
        +                "minimum": 1,
        +                "type": "number"
        +              },
        +              "perNameAllocation": {
        +                "additionalProperties": true,
        +                "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +                "properties": {
        +                  "amount": {
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "enum": [
        +                      "dollars",
        +                      "percent of portfolio",
        +                      "percent of buying power",
        +                      "contracts"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "amount"
        +                ],
        +                "type": "object"
        +              },
        +              "pipeline": {
        +                "items": {
        +                  "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                  "oneOf": [
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "condition": {
        +                          "$ref": "#/$defs/condition"
        +                        },
        +                        "type": {
        +                          "const": "Filter",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "condition"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "limit": {
        +                          "minimum": 1,
        +                          "type": "number"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "type": {
        +                          "const": "SelectTop",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "limit",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "direction": {
        +                          "enum": [
        +                            "Highest",
        +                            "Lowest"
        +                          ],
        +                          "type": "string"
        +                        },
        +                        "metric": {
        +                          "$ref": "#/$defs/indicator"
        +                        },
        +                        "percentile": {
        +                          "maximum": 100,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "SelectPercentile",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "metric",
        +                        "percentile",
        +                        "direction"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "positionScope": {
        +                "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        +                "enum": [
        +                  "portfolio",
        +                  "strategy"
        +                ],
        +                "type": "string"
        +              },
        +              "sleeves": {
        +                "items": {
        +                  "additionalProperties": true,
        +                  "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        +                  "properties": {
        +                    "limit": {
        +                      "minimum": 1,
        +                      "type": "number"
        +                    },
        +                    "name": {
        +                      "type": "string"
        +                    },
        +                    "perNameAllocation": {
        +                      "additionalProperties": true,
        +                      "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +                      "properties": {
        +                        "amount": {
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "enum": [
        +                            "dollars",
        +                            "percent of portfolio",
        +                            "percent of buying power",
        +                            "contracts"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "amount"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "pipeline": {
        +                      "items": {
        +                        "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                        "oneOf": [
        +                          {
        +                            "additionalProperties": true,
        +                            "properties": {
        +                              "condition": {
        +                                "$ref": "#/$defs/condition"
        +                              },
        +                              "type": {
        +                                "const": "Filter",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "condition"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "additionalProperties": true,
        +                            "properties": {
        +                              "direction": {
        +                                "enum": [
        +                                  "Highest",
        +                                  "Lowest"
        +                                ],
        +                                "type": "string"
        +                              },
        +                              "limit": {
        +                                "minimum": 1,
        +                                "type": "number"
        +                              },
        +                              "metric": {
        +                                "$ref": "#/$defs/indicator"
        +                              },
        +                              "type": {
        +                                "const": "SelectTop",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "metric",
        +                              "limit",
        +                              "direction"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "additionalProperties": true,
        +                            "properties": {
        +                              "direction": {
        +                                "enum": [
        +                                  "Highest",
        +                                  "Lowest"
        +                                ],
        +                                "type": "string"
        +                              },
        +                              "metric": {
        +                                "$ref": "#/$defs/indicator"
        +                              },
        +                              "percentile": {
        +                                "maximum": 100,
        +                                "minimum": 0,
        +                                "type": "number"
        +                              },
        +                              "type": {
        +                                "const": "SelectPercentile",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "metric",
        +                              "percentile",
        +                              "direction"
        +                            ],
        +                            "type": "object"
        +                          }
        +                        ],
        +                        "type": "object"
        +                      },
        +                      "type": "array"
        +                    },
        +                    "structureTemplates": {
        +                      "items": {
        +                        "additionalProperties": true,
        +                        "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +                        "properties": {
        +                          "eligibility": {
        +                            "$ref": "#/$defs/condition"
        +                          },
        +                          "legs": {
        +                            "items": {
        +                              "additionalProperties": true,
        +                              "description": "Single leg of an option builder.",
        +                              "properties": {
        +                                "direction": {
        +                                  "enum": [
        +                                    "long",
        +                                    "short"
        +                                  ],
        +                                  "type": "string"
        +                                },
        +                                "expirationRange": {
        +                                  "additionalProperties": true,
        +                                  "type": "object"
        +                                },
        +                                "expirationSelector": {
        +                                  "properties": {
        +                                    "maxDaysToExpiration": {
        +                                      "minimum": 0,
        +                                      "type": "number"
        +                                    },
        +                                    "minDaysToExpiration": {
        +                                      "minimum": 0,
        +                                      "type": "number"
        +                                    },
        +                                    "preference": {
        +                                      "enum": [
        +                                        "nearest",
        +                                        "middle",
        +                                        "furthest"
        +                                      ],
        +                                      "type": "string"
        +                                    }
        +                                  },
        +                                  "required": [
        +                                    "minDaysToExpiration",
        +                                    "maxDaysToExpiration",
        +                                    "preference"
        +                                  ],
        +                                  "type": "object"
        +                                },
        +                                "fallbackStrikeSelector": {
        +                                  "additionalProperties": false,
        +                                  "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                                  "properties": {
        +                                    "distance": {
        +                                      "type": "number"
        +                                    },
        +                                    "distanceType": {
        +                                      "enum": [
        +                                        "percent",
        +                                        "dollars"
        +                                      ],
        +                                      "type": "string"
        +                                    }
        +                                  },
        +                                  "required": [
        +                                    "distanceType",
        +                                    "distance"
        +                                  ],
        +                                  "type": "object"
        +                                },
        +                                "greekFilter": {
        +                                  "additionalProperties": true,
        +                                  "description": "Optional min/max constraints on Greeks during resolution.",
        +                                  "type": "object"
        +                                },
        +                                "liquidityFilter": {
        +                                  "additionalProperties": false,
        +                                  "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                                  "properties": {
        +                                    "maxSpreadAbsolute": {
        +                                      "type": "number"
        +                                    },
        +                                    "maxSpreadPct": {
        +                                      "type": "number"
        +                                    },
        +                                    "minBid": {
        +                                      "type": "number"
        +                                    }
        +                                  },
        +                                  "type": "object"
        +                                },
        +                                "optionType": {
        +                                  "enum": [
        +                                    "call",
        +                                    "put"
        +                                  ],
        +                                  "type": "string"
        +                                },
        +                                "ratio": {
        +                                  "type": "number"
        +                                },
        +                                "strikeRange": {
        +                                  "additionalProperties": true,
        +                                  "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                                  "type": "object"
        +                                },
        +                                "strikeSelector": {
        +                                  "properties": {
        +                                    "distance": {
        +                                      "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                                      "type": "number"
        +                                    },
        +                                    "distanceType": {
        +                                      "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                                      "type": "string"
        +                                    }
        +                                  },
        +                                  "required": [
        +                                    "distanceType",
        +                                    "distance"
        +                                  ],
        +                                  "type": "object"
        +                                }
        +                              },
        +                              "required": [
        +                                "optionType",
        +                                "direction",
        +                                "expirationSelector",
        +                                "strikeSelector"
        +                              ],
        +                              "type": "object"
        +                            },
        +                            "minItems": 1,
        +                            "type": "array"
        +                          },
        +                          "name": {
        +                            "type": "string"
        +                          },
        +                          "spreadType": {
        +                            "enum": [
        +                              "vertical",
        +                              "calendar",
        +                              "diagonal",
        +                              "ironCondor",
        +                              "straddle",
        +                              "strangle",
        +                              "custom"
        +                            ],
        +                            "type": "string"
        +                          },
        +                          "widthConstraint": {
        +                            "additionalProperties": false,
        +                            "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                            "properties": {
        +                              "minWidthDollars": {
        +                                "exclusiveMinimum": 0,
        +                                "type": "number"
        +                              },
        +                              "minWidthPercent": {
        +                                "exclusiveMinimum": 0,
        +                                "type": "number"
        +                              }
        +                            },
        +                            "type": "object"
        +                          }
        +                        },
        +                        "required": [
        +                          "legs"
        +                        ],
        +                        "type": "object"
        +                      },
        +                      "minItems": 1,
        +                      "type": "array"
        +                    },
        +                    "universe": {
        +                      "additionalProperties": true,
        +                      "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                      "properties": {
        +                        "assets": {
        +                          "items": {
        +                            "additionalProperties": true,
        +                            "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                            "properties": {
        +                              "name": {
        +                                "type": "string"
        +                              },
        +                              "symbol": {
        +                                "type": "string"
        +                              },
        +                              "type": {
        +                                "enum": [
        +                                  "Stock",
        +                                  "Cryptocurrency",
        +                                  "Option",
        +                                  "Other"
        +                                ],
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "symbol"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          "type": "array"
        +                        },
        +                        "source": {
        +                          "enum": [
        +                            "ALL_US_STOCKS",
        +                            "SP500",
        +                            "NASDAQ100",
        +                            "DJIA",
        +                            "CRYPTO",
        +                            "SPECIFIC_ASSETS"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "source"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "weightIndicator": {
        +                      "$ref": "#/$defs/indicator"
        +                    }
        +                  },
        +                  "required": [
        +                    "name"
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "structureTemplates": {
        +                "items": {
        +                  "additionalProperties": true,
        +                  "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +                  "properties": {
        +                    "eligibility": {
        +                      "$ref": "#/$defs/condition"
        +                    },
        +                    "legs": {
        +                      "items": {
        +                        "additionalProperties": true,
        +                        "description": "Single leg of an option builder.",
        +                        "properties": {
        +                          "direction": {
        +                            "enum": [
        +                              "long",
        +                              "short"
        +                            ],
        +                            "type": "string"
        +                          },
        +                          "expirationRange": {
        +                            "additionalProperties": true,
        +                            "type": "object"
        +                          },
        +                          "expirationSelector": {
        +                            "properties": {
        +                              "maxDaysToExpiration": {
        +                                "minimum": 0,
        +                                "type": "number"
        +                              },
        +                              "minDaysToExpiration": {
        +                                "minimum": 0,
        +                                "type": "number"
        +                              },
        +                              "preference": {
        +                                "enum": [
        +                                  "nearest",
        +                                  "middle",
        +                                  "furthest"
        +                                ],
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "minDaysToExpiration",
        +                              "maxDaysToExpiration",
        +                              "preference"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          "fallbackStrikeSelector": {
        +                            "additionalProperties": false,
        +                            "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                            "properties": {
        +                              "distance": {
        +                                "type": "number"
        +                              },
        +                              "distanceType": {
        +                                "enum": [
        +                                  "percent",
        +                                  "dollars"
        +                                ],
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "distanceType",
        +                              "distance"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          "greekFilter": {
        +                            "additionalProperties": true,
        +                            "description": "Optional min/max constraints on Greeks during resolution.",
        +                            "type": "object"
        +                          },
        +                          "liquidityFilter": {
        +                            "additionalProperties": false,
        +                            "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                            "properties": {
        +                              "maxSpreadAbsolute": {
        +                                "type": "number"
        +                              },
        +                              "maxSpreadPct": {
        +                                "type": "number"
        +                              },
        +                              "minBid": {
        +                                "type": "number"
        +                              }
        +                            },
        +                            "type": "object"
        +                          },
        +                          "optionType": {
        +                            "enum": [
        +                              "call",
        +                              "put"
        +                            ],
        +                            "type": "string"
        +                          },
        +                          "ratio": {
        +                            "type": "number"
        +                          },
        +                          "strikeRange": {
        +                            "additionalProperties": true,
        +                            "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                            "type": "object"
        +                          },
        +                          "strikeSelector": {
        +                            "properties": {
        +                              "distance": {
        +                                "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                                "type": "number"
        +                              },
        +                              "distanceType": {
        +                                "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "distanceType",
        +                              "distance"
        +                            ],
        +                            "type": "object"
        +                          }
        +                        },
        +                        "required": [
        +                          "optionType",
        +                          "direction",
        +                          "expirationSelector",
        +                          "strikeSelector"
        +                        ],
        +                        "type": "object"
        +                      },
        +                      "minItems": 1,
        +                      "type": "array"
        +                    },
        +                    "name": {
        +                      "type": "string"
        +                    },
        +                    "spreadType": {
        +                      "enum": [
        +                        "vertical",
        +                        "calendar",
        +                        "diagonal",
        +                        "ironCondor",
        +                        "straddle",
        +                        "strangle",
        +                        "custom"
        +                      ],
        +                      "type": "string"
        +                    },
        +                    "widthConstraint": {
        +                      "additionalProperties": false,
        +                      "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                      "properties": {
        +                        "minWidthDollars": {
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "minWidthPercent": {
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        }
        +                      },
        +                      "type": "object"
        +                    }
        +                  },
        +                  "required": [
        +                    "legs"
        +                  ],
        +                  "type": "object"
        +                },
        +                "minItems": 1,
        +                "type": "array"
        +              },
        +              "totalBudget": {
        +                "additionalProperties": true,
        +                "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        +                "properties": {
        +                  "amount": {
        +                    "minimum": 0,
        +                    "type": "number"
        +                  },
        +                  "type": {
        +                    "enum": [
        +                      "dollars",
        +                      "percent of portfolio"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "amount"
        +                ],
        +                "type": "object"
        +              },
        +              "type": {
        +                "const": "RebalanceOption",
        +                "type": "string"
        +              },
        +              "universe": {
        +                "additionalProperties": true,
        +                "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                "properties": {
        +                  "assets": {
        +                    "items": {
        +                      "additionalProperties": true,
        +                      "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                      "properties": {
        +                        "name": {
        +                          "type": "string"
        +                        },
        +                        "symbol": {
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "enum": [
        +                            "Stock",
        +                            "Cryptocurrency",
        +                            "Option",
        +                            "Other"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "symbol"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "type": "array"
        +                  },
        +                  "source": {
        +                    "enum": [
        +                      "ALL_US_STOCKS",
        +                      "SP500",
        +                      "NASDAQ100",
        +                      "DJIA",
        +                      "CRYPTO",
        +                      "SPECIFIC_ASSETS"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "source"
        +                ],
        +                "type": "object"
        +              },
        +              "weightIndicator": {
        +                "$ref": "#/$defs/indicator"
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "universe",
        +              "pipeline",
        +              "weightIndicator",
        +              "structureTemplates"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": true,
        +            "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        +            "properties": {
        +              "closeScope": {
        +                "enum": [
        +                  "spread",
        +                  "leg"
        +                ],
        +                "type": "string"
        +              },
        +              "direction": {
        +                "enum": [
        +                  "long",
        +                  "short"
        +                ],
        +                "type": "string"
        +              },
        +              "optionType": {
        +                "enum": [
        +                  "call",
        +                  "put"
        +                ],
        +                "type": "string"
        +              },
        +              "quantity": {
        +                "additionalProperties": true,
        +                "description": "How many contracts to close. Defaults to all matching when omitted.",
        +                "type": "object"
        +              },
        +              "spreadType": {
        +                "enum": [
        +                  "vertical",
        +                  "calendar",
        +                  "diagonal",
        +                  "ironCondor",
        +                  "straddle",
        +                  "strangle",
        +                  "custom"
        +                ],
        +                "type": "string"
        +              },
        +              "triggers": {
        +                "items": {
        +                  "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        +                  "oneOf": [
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "maxPnlPercent": {
        +                          "type": "number"
        +                        },
        +                        "minPnlPercent": {
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "pnl",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "maxDte": {
        +                          "type": "number"
        +                        },
        +                        "minDte": {
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "dte",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "maxDaysHeld": {
        +                          "type": "number"
        +                        },
        +                        "minDaysHeld": {
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "daysHeld",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "maxIv": {
        +                          "type": "number"
        +                        },
        +                        "maxSpreadDelta": {
        +                          "type": "number"
        +                        },
        +                        "maxSpreadTheta": {
        +                          "type": "number"
        +                        },
        +                        "minIv": {
        +                          "type": "number"
        +                        },
        +                        "minSpreadDelta": {
        +                          "type": "number"
        +                        },
        +                        "minSpreadTheta": {
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "greeks",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "type": {
        +                "const": "CloseOption",
        +                "type": "string"
        +              },
        +              "underlyings": {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              }
        +            },
        +            "required": [
        +              "type"
        +            ],
        +            "type": "object"
        +          }
        +        ],
        +        "type": "object"
        +      },
        +      "active": {
        +        "description": "Whether the strategy is active (default true).",
        +        "type": "boolean"
        +      },
        +      "condition": {
        +        "$ref": "#/$defs/condition"
        +      },
        +      "name": {
        +        "description": "Human-readable strategy name.",
        +        "type": "string"
        +      },
        +      "orderExecution": {
        +        "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.",
        +        "oneOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "type": {
        +                "const": "Market",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "type"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "price": {
        +                "oneOf": [
        +                  {
        +                    "additionalProperties": false,
        +                    "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        +                    "properties": {
        +                      "amount": {
        +                        "minimum": 1e-8,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "UnitPrice",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "amount"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": false,
        +                    "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        +                    "properties": {
        +                      "amount": {
        +                        "minimum": 1e-8,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "MinimumNetCredit",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "amount"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": false,
        +                    "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        +                    "properties": {
        +                      "amount": {
        +                        "minimum": 1e-8,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "MaximumNetDebit",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "amount"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": false,
        +                    "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        +                    "properties": {
        +                      "reference": {
        +                        "const": "Current",
        +                        "type": "string"
        +                      },
        +                      "type": {
        +                        "const": "QuoteRelative",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "reference"
        +                    ],
        +                    "type": "object"
        +                  }
        +                ]
        +              },
        +              "type": {
        +                "const": "Limit",
        +                "type": "string"
        +              },
        +              "workingTime": {
        +                "oneOf": [
        +                  {
        +                    "additionalProperties": false,
        +                    "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        +                    "properties": {
        +                      "type": {
        +                        "const": "Day",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  {
        +                    "additionalProperties": false,
        +                    "properties": {
        +                      "minutes": {
        +                        "minimum": 1,
        +                        "type": "number"
        +                      },
        +                      "type": {
        +                        "const": "Minutes",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "type",
        +                      "minutes"
        +                    ],
        +                    "type": "object"
        +                  }
        +                ]
        +              }
        +            },
        +            "required": [
        +              "type",
        +              "price"
        +            ],
        +            "type": "object"
        +          }
        +        ],
        +        "type": "object"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "condition",
        +      "action"
        +    ],
        +    "type": "object"
        +  },
        +  "strategyObjects": {
        +    "items": {
        +      "additionalProperties": true,
        +      "description": "A trading strategy: a trigger condition + an action to take when the condition is true. Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.",
        +      "properties": {
        +        "action": {
        +          "description": "The action to execute when the strategy's condition triggers. One of: Buy/Sell (stock or crypto with targetAsset+amount), Deposit/Withdraw (cash flow), Alert (send a message), DynamicRebalance (universe→pipeline→weightIndicator), LaunchAgent (spin up an Aurora agent), RebalanceOption (rank universe, rotate option book via structureTemplates; pair with CloseOption lifecycle exits), OpenOption (open via OptionsBuilder), CloseOption (close positions filtered by triggers).",
        +          "oneOf": [
        +            {
        +              "additionalProperties": true,
        +              "description": "Buy or Sell a stock/crypto position.",
        +              "properties": {
        +                "amount": {
        +                  "description": "Buy/Sell allocation. type: 'percent of portfolio', 'percent of buying power', 'percent of current positions', 'dollars', or 'number of assets'. amount: the value (e.g. amount:25, type:'percent of buying power').",
        +                  "properties": {
        +                    "amount": {
        +                      "type": "number"
        +                    },
        +                    "type": {
        +                      "enum": [
        +                        "percent of portfolio",
        +                        "percent of buying power",
        +                        "percent of current positions",
        +                        "dollars",
        +                        "number of assets"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "type",
        +                    "amount"
        +                  ],
        +                  "type": "object"
        +                },
        +                "targetAsset": {
        +                  "additionalProperties": true,
        +                  "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                  "properties": {
        +                    "name": {
        +                      "type": "string"
        +                    },
        +                    "symbol": {
        +                      "type": "string"
        +                    },
        +                    "type": {
        +                      "enum": [
        +                        "Stock",
        +                        "Cryptocurrency",
        +                        "Option",
        +                        "Other"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "type",
        +                    "symbol"
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": {
        +                  "enum": [
        +                    "Buy",
        +                    "Sell"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "targetAsset",
        +                "amount"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "description": "Send an alert message (no order).",
        +              "properties": {
        +                "message": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "const": "Alert",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "message"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "description": "Dynamic rebalance: filter/rank a universe by a pipeline, then allocate the selected equities. Without allocationPolicy, weightIndicator supplies score weights. With allocationPolicy, weightIndicator remains required for deterministic ranking and warmup fallback while the joint policy sizes selected names. exposurePolicy may independently scale total risky exposure. Book-level cash/deploy is deploymentPercent (0–100 number) — NOT totalBudget (RebalanceOption-only). perNameAllocation caps any single name. canSell optionally gates non-target full equity exits; target-weight trims remain enabled. A strategy condition may compare RebalanceDecisionMetric values because the prospective plan is computed before condition evaluation.",
        +              "properties": {
        +                "allocationPolicy": {
        +                  "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +                  "oneOf": [
        +                    {
        +                      "additionalProperties": false,
        +                      "properties": {
        +                        "covarianceShrinkage": {
        +                          "maximum": 1,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "estimatedTransactionCostBps": {
        +                          "maximum": 10000,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "expectedReturnShrinkage": {
        +                          "maximum": 1,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "lookbackPeriods": {
        +                          "maximum": 5000,
        +                          "minimum": 2,
        +                          "type": "integer"
        +                        },
        +                        "minimumObservations": {
        +                          "maximum": 5000,
        +                          "minimum": 2,
        +                          "type": "integer"
        +                        },
        +                        "riskAversion": {
        +                          "maximum": 1000,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "turnoverPenalty": {
        +                          "maximum": 10000,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "MeanVariance",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "lookbackPeriods",
        +                        "minimumObservations",
        +                        "riskAversion",
        +                        "expectedReturnShrinkage",
        +                        "covarianceShrinkage",
        +                        "turnoverPenalty",
        +                        "estimatedTransactionCostBps"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": false,
        +                      "properties": {
        +                        "covarianceShrinkage": {
        +                          "maximum": 1,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "estimatedTransactionCostBps": {
        +                          "maximum": 10000,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "lookbackPeriods": {
        +                          "maximum": 5000,
        +                          "minimum": 2,
        +                          "type": "integer"
        +                        },
        +                        "minimumObservations": {
        +                          "maximum": 5000,
        +                          "minimum": 2,
        +                          "type": "integer"
        +                        },
        +                        "turnoverPenalty": {
        +                          "maximum": 10000,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "RiskParity",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "lookbackPeriods",
        +                        "minimumObservations",
        +                        "covarianceShrinkage",
        +                        "turnoverPenalty",
        +                        "estimatedTransactionCostBps"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": false,
        +                      "properties": {
        +                        "covarianceShrinkage": {
        +                          "maximum": 1,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "estimatedTransactionCostBps": {
        +                          "maximum": 10000,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "lookbackPeriods": {
        +                          "maximum": 5000,
        +                          "minimum": 2,
        +                          "type": "integer"
        +                        },
        +                        "minimumObservations": {
        +                          "maximum": 5000,
        +                          "minimum": 2,
        +                          "type": "integer"
        +                        },
        +                        "turnoverPenalty": {
        +                          "maximum": 10000,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "MaximumDiversification",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "lookbackPeriods",
        +                        "minimumObservations",
        +                        "covarianceShrinkage",
        +                        "turnoverPenalty",
        +                        "estimatedTransactionCostBps"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ]
        +                },
        +                "canSell": {
        +                  "$ref": "#/$defs/condition",
        +                  "description": "Candidate-bound condition evaluated for each held equity leaving the selected set. False or unavailable retains the position. Example: PositionPercentChange(candidate) >= 0 implements rotate winners only. Does not gate trims of still-selected names; deploymentPercent=0 overrides it for a full cash-out."
        +                },
        +                "deploymentPercent": {
        +                  "description": "Percent of portfolio NAV to deploy (remainder cash). Do not use totalBudget here.",
        +                  "maximum": 100,
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "exposurePolicy": {
        +                  "additionalProperties": false,
        +                  "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +                  "properties": {
        +                    "covarianceShrinkage": {
        +                      "maximum": 1,
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "estimatedTransactionCostBps": {
        +                      "maximum": 10000,
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "lookbackPeriods": {
        +                      "maximum": 5000,
        +                      "minimum": 2,
        +                      "type": "integer"
        +                    },
        +                    "minimumObservations": {
        +                      "maximum": 5000,
        +                      "minimum": 2,
        +                      "type": "integer"
        +                    },
        +                    "targetAnnualizedVolatilityPercent": {
        +                      "maximum": 1000,
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "type": {
        +                      "const": "VolatilityTarget",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "type",
        +                    "lookbackPeriods",
        +                    "minimumObservations",
        +                    "covarianceShrinkage",
        +                    "targetAnnualizedVolatilityPercent",
        +                    "estimatedTransactionCostBps"
        +                  ],
        +                  "type": "object"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "perNameAllocation": {
        +                  "additionalProperties": true,
        +                  "description": "Per-name cap for DynamicRebalance. type: 'percent of portfolio' or 'dollars' only — contracts and percent of buying power are rejected.",
        +                  "properties": {
        +                    "amount": {
        +                      "exclusiveMinimum": 0,
        +                      "type": "number"
        +                    },
        +                    "type": {
        +                      "enum": [
        +                        "percent of portfolio",
        +                        "dollars"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "type",
        +                    "amount"
        +                  ],
        +                  "type": "object"
        +                },
        +                "pipeline": {
        +                  "items": {
        +                    "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                    "oneOf": [
        +                      {
        +                        "additionalProperties": true,
        +                        "properties": {
        +                          "condition": {
        +                            "$ref": "#/$defs/condition"
        +                          },
        +                          "type": {
        +                            "const": "Filter",
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "type",
        +                          "condition"
        +                        ],
        +                        "type": "object"
        +                      },
        +                      {
        +                        "additionalProperties": true,
        +                        "properties": {
        +                          "direction": {
        +                            "enum": [
        +                              "Highest",
        +                              "Lowest"
        +                            ],
        +                            "type": "string"
        +                          },
        +                          "limit": {
        +                            "minimum": 1,
        +                            "type": "number"
        +                          },
        +                          "metric": {
        +                            "$ref": "#/$defs/indicator"
        +                          },
        +                          "type": {
        +                            "const": "SelectTop",
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "type",
        +                          "metric",
        +                          "limit",
        +                          "direction"
        +                        ],
        +                        "type": "object"
        +                      },
        +                      {
        +                        "additionalProperties": true,
        +                        "properties": {
        +                          "direction": {
        +                            "enum": [
        +                              "Highest",
        +                              "Lowest"
        +                            ],
        +                            "type": "string"
        +                          },
        +                          "metric": {
        +                            "$ref": "#/$defs/indicator"
        +                          },
        +                          "percentile": {
        +                            "maximum": 100,
        +                            "minimum": 0,
        +                            "type": "number"
        +                          },
        +                          "type": {
        +                            "const": "SelectPercentile",
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "type",
        +                          "metric",
        +                          "percentile",
        +                          "direction"
        +                        ],
        +                        "type": "object"
        +                      }
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "type": "array"
        +                },
        +                "type": {
        +                  "const": "DynamicRebalance",
        +                  "type": "string"
        +                },
        +                "universe": {
        +                  "additionalProperties": true,
        +                  "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                  "properties": {
        +                    "assets": {
        +                      "items": {
        +                        "additionalProperties": true,
        +                        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                        "properties": {
        +                          "name": {
        +                            "type": "string"
        +                          },
        +                          "symbol": {
        +                            "type": "string"
        +                          },
        +                          "type": {
        +                            "enum": [
        +                              "Stock",
        +                              "Cryptocurrency",
        +                              "Option",
        +                              "Other"
        +                            ],
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "type",
        +                          "symbol"
        +                        ],
        +                        "type": "object"
        +                      },
        +                      "type": "array"
        +                    },
        +                    "source": {
        +                      "enum": [
        +                        "ALL_US_STOCKS",
        +                        "SP500",
        +                        "NASDAQ100",
        +                        "DJIA",
        +                        "CRYPTO",
        +                        "SPECIFIC_ASSETS"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "source"
        +                  ],
        +                  "type": "object"
        +                },
        +                "weightIndicator": {
        +                  "$ref": "#/$defs/indicator"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "universe",
        +                "pipeline",
        +                "weightIndicator"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "description": "Launch an Aurora agent (paid LLM action — costs research tokens per run; ensure cooldownMinutes is sensible).",
        +              "properties": {
        +                "continueExisting": {
        +                  "type": "boolean"
        +                },
        +                "cooldownMinutes": {
        +                  "minimum": 0,
        +                  "type": "number"
        +                },
        +                "executionModel": {
        +                  "type": "string"
        +                },
        +                "includeMarketData": {
        +                  "type": "boolean"
        +                },
        +                "initialMessage": {
        +                  "type": "string"
        +                },
        +                "maxIterations": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "planningModel": {
        +                  "type": "string"
        +                },
        +                "skipPlanning": {
        +                  "type": "boolean"
        +                },
        +                "type": {
        +                  "const": "LaunchAgent",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "planningModel",
        +                "executionModel",
        +                "initialMessage",
        +                "maxIterations",
        +                "includeMarketData",
        +                "continueExisting",
        +                "skipPlanning"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "description": "Open a new options position via the OptionsBuilder. Use 'against' to write a leg against an existing parent option position.",
        +              "properties": {
        +                "against": {
        +                  "additionalProperties": true,
        +                  "description": "Optional parent-position selector (e.g. for covered calls).",
        +                  "type": "object"
        +                },
        +                "allocation": {
        +                  "additionalProperties": true,
        +                  "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +                  "properties": {
        +                    "amount": {
        +                      "type": "number"
        +                    },
        +                    "type": {
        +                      "enum": [
        +                        "dollars",
        +                        "percent of portfolio",
        +                        "percent of buying power",
        +                        "contracts"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "type",
        +                    "amount"
        +                  ],
        +                  "type": "object"
        +                },
        +                "builder": {
        +                  "additionalProperties": true,
        +                  "description": "OpenOption builder: resolve contracts at execution time. Use underlyingSymbol for a fixed ticker, OR dynamicUnderlying for per-strategy universe selection. For coordinated multi-name option rotation with shared totalBudget and ranked selection, use action type RebalanceOption instead.",
        +                  "properties": {
        +                    "dynamicUnderlying": {
        +                      "additionalProperties": true,
        +                      "properties": {
        +                        "limit": {
        +                          "minimum": 1,
        +                          "type": "number"
        +                        },
        +                        "pipeline": {
        +                          "items": {
        +                            "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                            "oneOf": [
        +                              {
        +                                "additionalProperties": true,
        +                                "properties": {
        +                                  "condition": {
        +                                    "$ref": "#/$defs/condition"
        +                                  },
        +                                  "type": {
        +                                    "const": "Filter",
        +                                    "type": "string"
        +                                  }
        +                                },
        +                                "required": [
        +                                  "type",
        +                                  "condition"
        +                                ],
        +                                "type": "object"
        +                              },
        +                              {
        +                                "additionalProperties": true,
        +                                "properties": {
        +                                  "direction": {
        +                                    "enum": [
        +                                      "Highest",
        +                                      "Lowest"
        +                                    ],
        +                                    "type": "string"
        +                                  },
        +                                  "limit": {
        +                                    "minimum": 1,
        +                                    "type": "number"
        +                                  },
        +                                  "metric": {
        +                                    "$ref": "#/$defs/indicator"
        +                                  },
        +                                  "type": {
        +                                    "const": "SelectTop",
        +                                    "type": "string"
        +                                  }
        +                                },
        +                                "required": [
        +                                  "type",
        +                                  "metric",
        +                                  "limit",
        +                                  "direction"
        +                                ],
        +                                "type": "object"
        +                              },
        +                              {
        +                                "additionalProperties": true,
        +                                "properties": {
        +                                  "direction": {
        +                                    "enum": [
        +                                      "Highest",
        +                                      "Lowest"
        +                                    ],
        +                                    "type": "string"
        +                                  },
        +                                  "metric": {
        +                                    "$ref": "#/$defs/indicator"
        +                                  },
        +                                  "percentile": {
        +                                    "maximum": 100,
        +                                    "minimum": 0,
        +                                    "type": "number"
        +                                  },
        +                                  "type": {
        +                                    "const": "SelectPercentile",
        +                                    "type": "string"
        +                                  }
        +                                },
        +                                "required": [
        +                                  "type",
        +                                  "metric",
        +                                  "percentile",
        +                                  "direction"
        +                                ],
        +                                "type": "object"
        +                              }
        +                            ],
        +                            "type": "object"
        +                          },
        +                          "type": "array"
        +                        },
        +                        "universe": {
        +                          "additionalProperties": true,
        +                          "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                          "properties": {
        +                            "assets": {
        +                              "items": {
        +                                "additionalProperties": true,
        +                                "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                                "properties": {
        +                                  "name": {
        +                                    "type": "string"
        +                                  },
        +                                  "symbol": {
        +                                    "type": "string"
        +                                  },
        +                                  "type": {
        +                                    "enum": [
        +                                      "Stock",
        +                                      "Cryptocurrency",
        +                                      "Option",
        +                                      "Other"
        +                                    ],
        +                                    "type": "string"
        +                                  }
        +                                },
        +                                "required": [
        +                                  "type",
        +                                  "symbol"
        +                                ],
        +                                "type": "object"
        +                              },
        +                              "type": "array"
        +                            },
        +                            "source": {
        +                              "enum": [
        +                                "ALL_US_STOCKS",
        +                                "SP500",
        +                                "NASDAQ100",
        +                                "DJIA",
        +                                "CRYPTO",
        +                                "SPECIFIC_ASSETS"
        +                              ],
        +                              "type": "string"
        +                            }
        +                          },
        +                          "required": [
        +                            "source"
        +                          ],
        +                          "type": "object"
        +                        }
        +                      },
        +                      "required": [
        +                        "universe"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "legs": {
        +                      "items": {
        +                        "additionalProperties": true,
        +                        "description": "Single leg of an option builder.",
        +                        "properties": {
        +                          "direction": {
        +                            "enum": [
        +                              "long",
        +                              "short"
        +                            ],
        +                            "type": "string"
        +                          },
        +                          "expirationRange": {
        +                            "additionalProperties": true,
        +                            "type": "object"
        +                          },
        +                          "expirationSelector": {
        +                            "properties": {
        +                              "maxDaysToExpiration": {
        +                                "minimum": 0,
        +                                "type": "number"
        +                              },
        +                              "minDaysToExpiration": {
        +                                "minimum": 0,
        +                                "type": "number"
        +                              },
        +                              "preference": {
        +                                "enum": [
        +                                  "nearest",
        +                                  "middle",
        +                                  "furthest"
        +                                ],
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "minDaysToExpiration",
        +                              "maxDaysToExpiration",
        +                              "preference"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          "fallbackStrikeSelector": {
        +                            "additionalProperties": false,
        +                            "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                            "properties": {
        +                              "distance": {
        +                                "type": "number"
        +                              },
        +                              "distanceType": {
        +                                "enum": [
        +                                  "percent",
        +                                  "dollars"
        +                                ],
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "distanceType",
        +                              "distance"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          "greekFilter": {
        +                            "additionalProperties": true,
        +                            "description": "Optional min/max constraints on Greeks during resolution.",
        +                            "type": "object"
        +                          },
        +                          "liquidityFilter": {
        +                            "additionalProperties": false,
        +                            "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                            "properties": {
        +                              "maxSpreadAbsolute": {
        +                                "type": "number"
        +                              },
        +                              "maxSpreadPct": {
        +                                "type": "number"
        +                              },
        +                              "minBid": {
        +                                "type": "number"
        +                              }
        +                            },
        +                            "type": "object"
        +                          },
        +                          "optionType": {
        +                            "enum": [
        +                              "call",
        +                              "put"
        +                            ],
        +                            "type": "string"
        +                          },
        +                          "ratio": {
        +                            "type": "number"
        +                          },
        +                          "strikeRange": {
        +                            "additionalProperties": true,
        +                            "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                            "type": "object"
        +                          },
        +                          "strikeSelector": {
        +                            "properties": {
        +                              "distance": {
        +                                "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                                "type": "number"
        +                              },
        +                              "distanceType": {
        +                                "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "distanceType",
        +                              "distance"
        +                            ],
        +                            "type": "object"
        +                          }
        +                        },
        +                        "required": [
        +                          "optionType",
        +                          "direction",
        +                          "expirationSelector",
        +                          "strikeSelector"
        +                        ],
        +                        "type": "object"
        +                      },
        +                      "minItems": 1,
        +                      "type": "array"
        +                    },
        +                    "spreadType": {
        +                      "enum": [
        +                        "vertical",
        +                        "calendar",
        +                        "diagonal",
        +                        "ironCondor",
        +                        "straddle",
        +                        "strangle",
        +                        "custom"
        +                      ],
        +                      "type": "string"
        +                    },
        +                    "underlyingSymbol": {
        +                      "type": "string"
        +                    },
        +                    "widthConstraint": {
        +                      "additionalProperties": false,
        +                      "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                      "properties": {
        +                        "minWidthDollars": {
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "minWidthPercent": {
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        }
        +                      },
        +                      "type": "object"
        +                    }
        +                  },
        +                  "required": [
        +                    "legs"
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": {
        +                  "const": "OpenOption",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "builder"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "description": "RebalanceOption: filter/rank a universe, select top-N by weightIndicator (ranking score, not sizing weight), then allocate per-underlying premium budgets. allocationPolicy may jointly size the selected underlyings; exposurePolicy may independently scale the total premium budget using selected-underlying volatility (not option-P&L volatility). Use DaysSinceLastRebalanceOptionOrder in strategy conditions for shared rebalance cadence. A condition may also compare RebalanceDecisionMetric values because the prospective plan is computed first. Keep take-profit/stop-loss/DTE/short-leg exits in separate CloseOption strategies — not inside RebalanceOption. For unequal per-name sizing without a policy, use sleeves (each with its own perNameAllocation) under one totalBudget.",
        +              "properties": {
        +                "allocationPolicy": {
        +                  "description": "Optional joint allocator applied after universe filtering/ranking. Supports MeanVariance, RiskParity, and MaximumDiversification using point-in-time completed daily returns. Selection remains the pipeline/weightIndicator responsibility; this policy sizes the selected names. If warmup history is insufficient, the existing score-weighted allocator is used deterministically.",
        +                  "oneOf": [
        +                    {
        +                      "additionalProperties": false,
        +                      "properties": {
        +                        "covarianceShrinkage": {
        +                          "maximum": 1,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "estimatedTransactionCostBps": {
        +                          "maximum": 10000,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "expectedReturnShrinkage": {
        +                          "maximum": 1,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "lookbackPeriods": {
        +                          "maximum": 5000,
        +                          "minimum": 2,
        +                          "type": "integer"
        +                        },
        +                        "minimumObservations": {
        +                          "maximum": 5000,
        +                          "minimum": 2,
        +                          "type": "integer"
        +                        },
        +                        "riskAversion": {
        +                          "maximum": 1000,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "turnoverPenalty": {
        +                          "maximum": 10000,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "MeanVariance",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "lookbackPeriods",
        +                        "minimumObservations",
        +                        "riskAversion",
        +                        "expectedReturnShrinkage",
        +                        "covarianceShrinkage",
        +                        "turnoverPenalty",
        +                        "estimatedTransactionCostBps"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": false,
        +                      "properties": {
        +                        "covarianceShrinkage": {
        +                          "maximum": 1,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "estimatedTransactionCostBps": {
        +                          "maximum": 10000,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "lookbackPeriods": {
        +                          "maximum": 5000,
        +                          "minimum": 2,
        +                          "type": "integer"
        +                        },
        +                        "minimumObservations": {
        +                          "maximum": 5000,
        +                          "minimum": 2,
        +                          "type": "integer"
        +                        },
        +                        "turnoverPenalty": {
        +                          "maximum": 10000,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "RiskParity",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "lookbackPeriods",
        +                        "minimumObservations",
        +                        "covarianceShrinkage",
        +                        "turnoverPenalty",
        +                        "estimatedTransactionCostBps"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": false,
        +                      "properties": {
        +                        "covarianceShrinkage": {
        +                          "maximum": 1,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "estimatedTransactionCostBps": {
        +                          "maximum": 10000,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "lookbackPeriods": {
        +                          "maximum": 5000,
        +                          "minimum": 2,
        +                          "type": "integer"
        +                        },
        +                        "minimumObservations": {
        +                          "maximum": 5000,
        +                          "minimum": 2,
        +                          "type": "integer"
        +                        },
        +                        "turnoverPenalty": {
        +                          "maximum": 10000,
        +                          "minimum": 0,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "MaximumDiversification",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "lookbackPeriods",
        +                        "minimumObservations",
        +                        "covarianceShrinkage",
        +                        "turnoverPenalty",
        +                        "estimatedTransactionCostBps"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ]
        +                },
        +                "exposurePolicy": {
        +                  "additionalProperties": false,
        +                  "description": "Optional volatility-target exposure overlay, independent from allocationPolicy. Scales risky weights or option premium budgets down using selected-underlying historical volatility; never adds leverage beyond the action cap. For RebalanceOption this targets underlying volatility and scales premium budget, not option-P&L volatility.",
        +                  "properties": {
        +                    "covarianceShrinkage": {
        +                      "maximum": 1,
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "estimatedTransactionCostBps": {
        +                      "maximum": 10000,
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "lookbackPeriods": {
        +                      "maximum": 5000,
        +                      "minimum": 2,
        +                      "type": "integer"
        +                    },
        +                    "minimumObservations": {
        +                      "maximum": 5000,
        +                      "minimum": 2,
        +                      "type": "integer"
        +                    },
        +                    "targetAnnualizedVolatilityPercent": {
        +                      "maximum": 1000,
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "type": {
        +                      "const": "VolatilityTarget",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "type",
        +                    "lookbackPeriods",
        +                    "minimumObservations",
        +                    "covarianceShrinkage",
        +                    "targetAnnualizedVolatilityPercent",
        +                    "estimatedTransactionCostBps"
        +                  ],
        +                  "type": "object"
        +                },
        +                "limit": {
        +                  "minimum": 1,
        +                  "type": "number"
        +                },
        +                "perNameAllocation": {
        +                  "additionalProperties": true,
        +                  "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +                  "properties": {
        +                    "amount": {
        +                      "type": "number"
        +                    },
        +                    "type": {
        +                      "enum": [
        +                        "dollars",
        +                        "percent of portfolio",
        +                        "percent of buying power",
        +                        "contracts"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "type",
        +                    "amount"
        +                  ],
        +                  "type": "object"
        +                },
        +                "pipeline": {
        +                  "items": {
        +                    "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                    "oneOf": [
        +                      {
        +                        "additionalProperties": true,
        +                        "properties": {
        +                          "condition": {
        +                            "$ref": "#/$defs/condition"
        +                          },
        +                          "type": {
        +                            "const": "Filter",
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "type",
        +                          "condition"
        +                        ],
        +                        "type": "object"
        +                      },
        +                      {
        +                        "additionalProperties": true,
        +                        "properties": {
        +                          "direction": {
        +                            "enum": [
        +                              "Highest",
        +                              "Lowest"
        +                            ],
        +                            "type": "string"
        +                          },
        +                          "limit": {
        +                            "minimum": 1,
        +                            "type": "number"
        +                          },
        +                          "metric": {
        +                            "$ref": "#/$defs/indicator"
        +                          },
        +                          "type": {
        +                            "const": "SelectTop",
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "type",
        +                          "metric",
        +                          "limit",
        +                          "direction"
        +                        ],
        +                        "type": "object"
        +                      },
        +                      {
        +                        "additionalProperties": true,
        +                        "properties": {
        +                          "direction": {
        +                            "enum": [
        +                              "Highest",
        +                              "Lowest"
        +                            ],
        +                            "type": "string"
        +                          },
        +                          "metric": {
        +                            "$ref": "#/$defs/indicator"
        +                          },
        +                          "percentile": {
        +                            "maximum": 100,
        +                            "minimum": 0,
        +                            "type": "number"
        +                          },
        +                          "type": {
        +                            "const": "SelectPercentile",
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "type",
        +                          "metric",
        +                          "percentile",
        +                          "direction"
        +                        ],
        +                        "type": "object"
        +                      }
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "type": "array"
        +                },
        +                "positionScope": {
        +                  "description": "Which option spreads this rebalance manages. portfolio: rotation-close and open-skip apply portfolio-wide (recommended for single-book portfolios). strategy: only spreads opened by this strategy (multi-strategy books). Omit on new strategies → portfolio in TS/UI; legacy persisted docs without this field deserialize to strategy in Rust until backfilled.",
        +                  "enum": [
        +                    "portfolio",
        +                    "strategy"
        +                  ],
        +                  "type": "string"
        +                },
        +                "sleeves": {
        +                  "items": {
        +                    "additionalProperties": true,
        +                    "description": "RebalanceOption sleeve for heterogeneous universe/ranking/sizing groups sharing one action-level totalBudget (sleeves cannot define totalBudget).",
        +                    "properties": {
        +                      "limit": {
        +                        "minimum": 1,
        +                        "type": "number"
        +                      },
        +                      "name": {
        +                        "type": "string"
        +                      },
        +                      "perNameAllocation": {
        +                        "additionalProperties": true,
        +                        "description": "Allocation for an options position (OpenOption.allocation) or per-name cap (RebalanceOption.perNameAllocation). DynamicRebalance also takes a `perNameAllocation`, but only accepts type 'percent of portfolio' or 'dollars'.",
        +                        "properties": {
        +                          "amount": {
        +                            "type": "number"
        +                          },
        +                          "type": {
        +                            "enum": [
        +                              "dollars",
        +                              "percent of portfolio",
        +                              "percent of buying power",
        +                              "contracts"
        +                            ],
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "type",
        +                          "amount"
        +                        ],
        +                        "type": "object"
        +                      },
        +                      "pipeline": {
        +                        "items": {
        +                          "description": "Universe pipeline stage (DynamicRebalance and RebalanceOption). Filter: applies a condition. SelectTop: keeps top-N ranked by an indicator. SelectPercentile: keeps assets at/above a percentile.",
        +                          "oneOf": [
        +                            {
        +                              "additionalProperties": true,
        +                              "properties": {
        +                                "condition": {
        +                                  "$ref": "#/$defs/condition"
        +                                },
        +                                "type": {
        +                                  "const": "Filter",
        +                                  "type": "string"
        +                                }
        +                              },
        +                              "required": [
        +                                "type",
        +                                "condition"
        +                              ],
        +                              "type": "object"
        +                            },
        +                            {
        +                              "additionalProperties": true,
        +                              "properties": {
        +                                "direction": {
        +                                  "enum": [
        +                                    "Highest",
        +                                    "Lowest"
        +                                  ],
        +                                  "type": "string"
        +                                },
        +                                "limit": {
        +                                  "minimum": 1,
        +                                  "type": "number"
        +                                },
        +                                "metric": {
        +                                  "$ref": "#/$defs/indicator"
        +                                },
        +                                "type": {
        +                                  "const": "SelectTop",
        +                                  "type": "string"
        +                                }
        +                              },
        +                              "required": [
        +                                "type",
        +                                "metric",
        +                                "limit",
        +                                "direction"
        +                              ],
        +                              "type": "object"
        +                            },
        +                            {
        +                              "additionalProperties": true,
        +                              "properties": {
        +                                "direction": {
        +                                  "enum": [
        +                                    "Highest",
        +                                    "Lowest"
        +                                  ],
        +                                  "type": "string"
        +                                },
        +                                "metric": {
        +                                  "$ref": "#/$defs/indicator"
        +                                },
        +                                "percentile": {
        +                                  "maximum": 100,
        +                                  "minimum": 0,
        +                                  "type": "number"
        +                                },
        +                                "type": {
        +                                  "const": "SelectPercentile",
        +                                  "type": "string"
        +                                }
        +                              },
        +                              "required": [
        +                                "type",
        +                                "metric",
        +                                "percentile",
        +                                "direction"
        +                              ],
        +                              "type": "object"
        +                            }
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "type": "array"
        +                      },
        +                      "structureTemplates": {
        +                        "items": {
        +                          "additionalProperties": true,
        +                          "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +                          "properties": {
        +                            "eligibility": {
        +                              "$ref": "#/$defs/condition"
        +                            },
        +                            "legs": {
        +                              "items": {
        +                                "additionalProperties": true,
        +                                "description": "Single leg of an option builder.",
        +                                "properties": {
        +                                  "direction": {
        +                                    "enum": [
        +                                      "long",
        +                                      "short"
        +                                    ],
        +                                    "type": "string"
        +                                  },
        +                                  "expirationRange": {
        +                                    "additionalProperties": true,
        +                                    "type": "object"
        +                                  },
        +                                  "expirationSelector": {
        +                                    "properties": {
        +                                      "maxDaysToExpiration": {
        +                                        "minimum": 0,
        +                                        "type": "number"
        +                                      },
        +                                      "minDaysToExpiration": {
        +                                        "minimum": 0,
        +                                        "type": "number"
        +                                      },
        +                                      "preference": {
        +                                        "enum": [
        +                                          "nearest",
        +                                          "middle",
        +                                          "furthest"
        +                                        ],
        +                                        "type": "string"
        +                                      }
        +                                    },
        +                                    "required": [
        +                                      "minDaysToExpiration",
        +                                      "maxDaysToExpiration",
        +                                      "preference"
        +                                    ],
        +                                    "type": "object"
        +                                  },
        +                                  "fallbackStrikeSelector": {
        +                                    "additionalProperties": false,
        +                                    "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                                    "properties": {
        +                                      "distance": {
        +                                        "type": "number"
        +                                      },
        +                                      "distanceType": {
        +                                        "enum": [
        +                                          "percent",
        +                                          "dollars"
        +                                        ],
        +                                        "type": "string"
        +                                      }
        +                                    },
        +                                    "required": [
        +                                      "distanceType",
        +                                      "distance"
        +                                    ],
        +                                    "type": "object"
        +                                  },
        +                                  "greekFilter": {
        +                                    "additionalProperties": true,
        +                                    "description": "Optional min/max constraints on Greeks during resolution.",
        +                                    "type": "object"
        +                                  },
        +                                  "liquidityFilter": {
        +                                    "additionalProperties": false,
        +                                    "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                                    "properties": {
        +                                      "maxSpreadAbsolute": {
        +                                        "type": "number"
        +                                      },
        +                                      "maxSpreadPct": {
        +                                        "type": "number"
        +                                      },
        +                                      "minBid": {
        +                                        "type": "number"
        +                                      }
        +                                    },
        +                                    "type": "object"
        +                                  },
        +                                  "optionType": {
        +                                    "enum": [
        +                                      "call",
        +                                      "put"
        +                                    ],
        +                                    "type": "string"
        +                                  },
        +                                  "ratio": {
        +                                    "type": "number"
        +                                  },
        +                                  "strikeRange": {
        +                                    "additionalProperties": true,
        +                                    "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                                    "type": "object"
        +                                  },
        +                                  "strikeSelector": {
        +                                    "properties": {
        +                                      "distance": {
        +                                        "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                                        "type": "number"
        +                                      },
        +                                      "distanceType": {
        +                                        "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                                        "type": "string"
        +                                      }
        +                                    },
        +                                    "required": [
        +                                      "distanceType",
        +                                      "distance"
        +                                    ],
        +                                    "type": "object"
        +                                  }
        +                                },
        +                                "required": [
        +                                  "optionType",
        +                                  "direction",
        +                                  "expirationSelector",
        +                                  "strikeSelector"
        +                                ],
        +                                "type": "object"
        +                              },
        +                              "minItems": 1,
        +                              "type": "array"
        +                            },
        +                            "name": {
        +                              "type": "string"
        +                            },
        +                            "spreadType": {
        +                              "enum": [
        +                                "vertical",
        +                                "calendar",
        +                                "diagonal",
        +                                "ironCondor",
        +                                "straddle",
        +                                "strangle",
        +                                "custom"
        +                              ],
        +                              "type": "string"
        +                            },
        +                            "widthConstraint": {
        +                              "additionalProperties": false,
        +                              "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                              "properties": {
        +                                "minWidthDollars": {
        +                                  "exclusiveMinimum": 0,
        +                                  "type": "number"
        +                                },
        +                                "minWidthPercent": {
        +                                  "exclusiveMinimum": 0,
        +                                  "type": "number"
        +                                }
        +                              },
        +                              "type": "object"
        +                            }
        +                          },
        +                          "required": [
        +                            "legs"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "minItems": 1,
        +                        "type": "array"
        +                      },
        +                      "universe": {
        +                        "additionalProperties": true,
        +                        "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                        "properties": {
        +                          "assets": {
        +                            "items": {
        +                              "additionalProperties": true,
        +                              "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                              "properties": {
        +                                "name": {
        +                                  "type": "string"
        +                                },
        +                                "symbol": {
        +                                  "type": "string"
        +                                },
        +                                "type": {
        +                                  "enum": [
        +                                    "Stock",
        +                                    "Cryptocurrency",
        +                                    "Option",
        +                                    "Other"
        +                                  ],
        +                                  "type": "string"
        +                                }
        +                              },
        +                              "required": [
        +                                "type",
        +                                "symbol"
        +                              ],
        +                              "type": "object"
        +                            },
        +                            "type": "array"
        +                          },
        +                          "source": {
        +                            "enum": [
        +                              "ALL_US_STOCKS",
        +                              "SP500",
        +                              "NASDAQ100",
        +                              "DJIA",
        +                              "CRYPTO",
        +                              "SPECIFIC_ASSETS"
        +                            ],
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "source"
        +                        ],
        +                        "type": "object"
        +                      },
        +                      "weightIndicator": {
        +                        "$ref": "#/$defs/indicator"
        +                      }
        +                    },
        +                    "required": [
        +                      "name"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "type": "array"
        +                },
        +                "structureTemplates": {
        +                  "items": {
        +                    "additionalProperties": true,
        +                    "description": "RebalanceOption structure template. Optional eligibility gates the template; legs define the spread; templates are tried in order — at most one open per underlying per rebalance pass.",
        +                    "properties": {
        +                      "eligibility": {
        +                        "$ref": "#/$defs/condition"
        +                      },
        +                      "legs": {
        +                        "items": {
        +                          "additionalProperties": true,
        +                          "description": "Single leg of an option builder.",
        +                          "properties": {
        +                            "direction": {
        +                              "enum": [
        +                                "long",
        +                                "short"
        +                              ],
        +                              "type": "string"
        +                            },
        +                            "expirationRange": {
        +                              "additionalProperties": true,
        +                              "type": "object"
        +                            },
        +                            "expirationSelector": {
        +                              "properties": {
        +                                "maxDaysToExpiration": {
        +                                  "minimum": 0,
        +                                  "type": "number"
        +                                },
        +                                "minDaysToExpiration": {
        +                                  "minimum": 0,
        +                                  "type": "number"
        +                                },
        +                                "preference": {
        +                                  "enum": [
        +                                    "nearest",
        +                                    "middle",
        +                                    "furthest"
        +                                  ],
        +                                  "type": "string"
        +                                }
        +                              },
        +                              "required": [
        +                                "minDaysToExpiration",
        +                                "maxDaysToExpiration",
        +                                "preference"
        +                              ],
        +                              "type": "object"
        +                            },
        +                            "fallbackStrikeSelector": {
        +                              "additionalProperties": false,
        +                              "description": "Non-delta fallback used when distanceType is 'delta' and no contract resolves close enough to the requested delta. The resolver's own rejection names this field: \"Set a fallbackStrikeSelector (percent or dollars) to keep thin chains tradeable.\" Without it a thin chain fails the leg outright. distanceType here must be 'percent' or 'dollars' — a delta fallback is rejected.",
        +                              "properties": {
        +                                "distance": {
        +                                  "type": "number"
        +                                },
        +                                "distanceType": {
        +                                  "enum": [
        +                                    "percent",
        +                                    "dollars"
        +                                  ],
        +                                  "type": "string"
        +                                }
        +                              },
        +                              "required": [
        +                                "distanceType",
        +                                "distance"
        +                              ],
        +                              "type": "object"
        +                            },
        +                            "greekFilter": {
        +                              "additionalProperties": true,
        +                              "description": "Optional min/max constraints on Greeks during resolution.",
        +                              "type": "object"
        +                            },
        +                            "liquidityFilter": {
        +                              "additionalProperties": false,
        +                              "description": "Optional bid/ask constraints during resolution. maxSpreadPct is (ask-bid)/mid and is preferred over maxSpreadAbsolute, since $0.50 is 50% of a $1.00 contract and 1.7% of a $30.00 one; when both are set both must pass. minBid excludes contracts that cannot be sold into. Contracts with no real NBBO quote are always rejected.",
        +                              "properties": {
        +                                "maxSpreadAbsolute": {
        +                                  "type": "number"
        +                                },
        +                                "maxSpreadPct": {
        +                                  "type": "number"
        +                                },
        +                                "minBid": {
        +                                  "type": "number"
        +                                }
        +                              },
        +                              "type": "object"
        +                            },
        +                            "optionType": {
        +                              "enum": [
        +                                "call",
        +                                "put"
        +                              ],
        +                              "type": "string"
        +                            },
        +                            "ratio": {
        +                              "type": "number"
        +                            },
        +                            "strikeRange": {
        +                              "additionalProperties": true,
        +                              "description": "Optional fallback search window used when the target strike is unaffordable. startDistance/endDistance are %-OTM offsets measured from ATM, in the same units and sign as strikeSelector.distance (positive = OTM for calls and puts alike) — NOT offsets from the target strike.",
        +                              "type": "object"
        +                            },
        +                            "strikeSelector": {
        +                              "properties": {
        +                                "distance": {
        +                                  "description": "Distance from ATM. Calls: positive = OTM (higher strike). Puts: positive = OTM (lower strike). 0 = ATM. For 'percent' this is a WHOLE-NUMBER percent — 15 means 15% OTM; 0.15 is rejected, not read as 15%. For 'delta' it is the absolute target delta (0-1, exclusive).",
        +                                  "type": "number"
        +                                },
        +                                "distanceType": {
        +                                  "description": "'percent', 'dollars', or 'delta' — how strike distance is measured from ATM.",
        +                                  "type": "string"
        +                                }
        +                              },
        +                              "required": [
        +                                "distanceType",
        +                                "distance"
        +                              ],
        +                              "type": "object"
        +                            }
        +                          },
        +                          "required": [
        +                            "optionType",
        +                            "direction",
        +                            "expirationSelector",
        +                            "strikeSelector"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "minItems": 1,
        +                        "type": "array"
        +                      },
        +                      "name": {
        +                        "type": "string"
        +                      },
        +                      "spreadType": {
        +                        "enum": [
        +                          "vertical",
        +                          "calendar",
        +                          "diagonal",
        +                          "ironCondor",
        +                          "straddle",
        +                          "strangle",
        +                          "custom"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "widthConstraint": {
        +                        "additionalProperties": false,
        +                        "description": "Minimum realised strike width, checked AFTER contracts resolve. Each leg snaps independently to the nearest listed strike, so the authored offsets and the width you actually get differ by up to a full strike-grid step in either direction — a 3% short-leg offset on LLY's $20 Mar-2027 grid resolved to one $20 step, 1.76% of spot. minWidthPercent is a WHOLE-NUMBER percent of spot (4 = 4%). When both bounds are set, both must pass. A structure below the floor is rejected and the next structureTemplate in the ladder is tried; single-leg structures have no width and are exempt.",
        +                        "properties": {
        +                          "minWidthDollars": {
        +                            "exclusiveMinimum": 0,
        +                            "type": "number"
        +                          },
        +                          "minWidthPercent": {
        +                            "exclusiveMinimum": 0,
        +                            "type": "number"
        +                          }
        +                        },
        +                        "type": "object"
        +                      }
        +                    },
        +                    "required": [
        +                      "legs"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "minItems": 1,
        +                  "type": "array"
        +                },
        +                "totalBudget": {
        +                  "additionalProperties": true,
        +                  "description": "Book-level deployment cap for RebalanceOption (totalBudget). percent of portfolio: fraction of NAV; dollars: fixed dollars.",
        +                  "properties": {
        +                    "amount": {
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "type": {
        +                      "enum": [
        +                        "dollars",
        +                        "percent of portfolio"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "type",
        +                    "amount"
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": {
        +                  "const": "RebalanceOption",
        +                  "type": "string"
        +                },
        +                "universe": {
        +                  "additionalProperties": true,
        +                  "description": "Universe of candidate assets. source ALL_US_STOCKS or CRYPTO needs no other field. SPECIFIC_ASSETS requires assets[].",
        +                  "properties": {
        +                    "assets": {
        +                      "items": {
        +                        "additionalProperties": true,
        +                        "description": "Asset reference. Stock/Crypto/Option/Other. Stocks use {type:'Stock', symbol:'AAPL', name:'Apple Inc.'}.",
        +                        "properties": {
        +                          "name": {
        +                            "type": "string"
        +                          },
        +                          "symbol": {
        +                            "type": "string"
        +                          },
        +                          "type": {
        +                            "enum": [
        +                              "Stock",
        +                              "Cryptocurrency",
        +                              "Option",
        +                              "Other"
        +                            ],
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "type",
        +                          "symbol"
        +                        ],
        +                        "type": "object"
        +                      },
        +                      "type": "array"
        +                    },
        +                    "source": {
        +                      "enum": [
        +                        "ALL_US_STOCKS",
        +                        "SP500",
        +                        "NASDAQ100",
        +                        "DJIA",
        +                        "CRYPTO",
        +                        "SPECIFIC_ASSETS"
        +                      ],
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "source"
        +                  ],
        +                  "type": "object"
        +                },
        +                "weightIndicator": {
        +                  "$ref": "#/$defs/indicator"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "universe",
        +                "pipeline",
        +                "weightIndicator",
        +                "structureTemplates"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": true,
        +              "description": "Close existing options positions. Position selectors (underlyings, optionType, direction, spreadType) are AND gates; triggers[] groups are OR gates.",
        +              "properties": {
        +                "closeScope": {
        +                  "enum": [
        +                    "spread",
        +                    "leg"
        +                  ],
        +                  "type": "string"
        +                },
        +                "direction": {
        +                  "enum": [
        +                    "long",
        +                    "short"
        +                  ],
        +                  "type": "string"
        +                },
        +                "optionType": {
        +                  "enum": [
        +                    "call",
        +                    "put"
        +                  ],
        +                  "type": "string"
        +                },
        +                "quantity": {
        +                  "additionalProperties": true,
        +                  "description": "How many contracts to close. Defaults to all matching when omitted.",
        +                  "type": "object"
        +                },
        +                "spreadType": {
        +                  "enum": [
        +                    "vertical",
        +                    "calendar",
        +                    "diagonal",
        +                    "ironCondor",
        +                    "straddle",
        +                    "strangle",
        +                    "custom"
        +                  ],
        +                  "type": "string"
        +                },
        +                "triggers": {
        +                  "items": {
        +                    "description": "Close trigger for an options exit. Triggers within an array are OR-gated.",
        +                    "oneOf": [
        +                      {
        +                        "additionalProperties": true,
        +                        "properties": {
        +                          "maxPnlPercent": {
        +                            "type": "number"
        +                          },
        +                          "minPnlPercent": {
        +                            "type": "number"
        +                          },
        +                          "type": {
        +                            "const": "pnl",
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "type"
        +                        ],
        +                        "type": "object"
        +                      },
        +                      {
        +                        "additionalProperties": true,
        +                        "properties": {
        +                          "maxDte": {
        +                            "type": "number"
        +                          },
        +                          "minDte": {
        +                            "type": "number"
        +                          },
        +                          "type": {
        +                            "const": "dte",
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "type"
        +                        ],
        +                        "type": "object"
        +                      },
        +                      {
        +                        "additionalProperties": true,
        +                        "properties": {
        +                          "maxDaysHeld": {
        +                            "type": "number"
        +                          },
        +                          "minDaysHeld": {
        +                            "type": "number"
        +                          },
        +                          "type": {
        +                            "const": "daysHeld",
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "type"
        +                        ],
        +                        "type": "object"
        +                      },
        +                      {
        +                        "additionalProperties": true,
        +                        "properties": {
        +                          "maxIv": {
        +                            "type": "number"
        +                          },
        +                          "maxSpreadDelta": {
        +                            "type": "number"
        +                          },
        +                          "maxSpreadTheta": {
        +                            "type": "number"
        +                          },
        +                          "minIv": {
        +                            "type": "number"
        +                          },
        +                          "minSpreadDelta": {
        +                            "type": "number"
        +                          },
        +                          "minSpreadTheta": {
        +                            "type": "number"
        +                          },
        +                          "type": {
        +                            "const": "greeks",
        +                            "type": "string"
        +                          }
        +                        },
        +                        "required": [
        +                          "type"
        +                        ],
        +                        "type": "object"
        +                      }
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "type": "array"
        +                },
        +                "type": {
        +                  "const": "CloseOption",
        +                  "type": "string"
        +                },
        +                "underlyings": {
        +                  "items": {
        +                    "type": "string"
        +                  },
        +                  "type": "array"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        },
        +        "active": {
        +          "description": "Whether the strategy is active (default true).",
        +          "type": "boolean"
        +        },
        +        "condition": {
        +          "$ref": "#/$defs/condition"
        +        },
        +        "name": {
        +          "description": "Human-readable strategy name.",
        +          "type": "string"
        +        },
        +        "orderExecution": {
        +          "description": "Optional strategy-level `orderExecution` defaults to `{type:\"Market\"}`. For a true waiting Limit, use `{type:\"Limit\",price:{type:\"UnitPrice\",amount:...},workingTime:{type:\"Day\"|\"Minutes\",minutes?:...}}` on Buy/Sell stock or crypto strategies; use `MinimumNetCredit` or `MaximumNetDebit` for OpenOption/CloseOption. `QuoteRelative` snapshots the current executable quote when the strategy fires, so it caps execution but normally does not wait for a user-named price.",
        +          "oneOf": [
        +            {
        +              "additionalProperties": false,
        +              "properties": {
        +                "type": {
        +                  "const": "Market",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "additionalProperties": false,
        +              "properties": {
        +                "price": {
        +                  "oneOf": [
        +                    {
        +                      "additionalProperties": false,
        +                      "description": "Buy/Sell only. The maximum unit price for a buy or minimum unit price for a sell. Supports stocks and crypto.",
        +                      "properties": {
        +                        "amount": {
        +                          "minimum": 1e-8,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "UnitPrice",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "amount"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": false,
        +                      "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for at least this net credit per share.",
        +                      "properties": {
        +                        "amount": {
        +                          "minimum": 1e-8,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "MinimumNetCredit",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "amount"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": false,
        +                      "description": "OpenOption/CloseOption only. Wait until the complete option structure can execute for no more than this net debit per share.",
        +                      "properties": {
        +                        "amount": {
        +                          "minimum": 1e-8,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "MaximumNetDebit",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "amount"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": false,
        +                      "description": "Snapshot a marketable Limit from the current executable quote when the strategy fires. Valid for all order-producing strategy actions; this is a protection cap, not a user-named waiting price.",
        +                      "properties": {
        +                        "reference": {
        +                          "const": "Current",
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "QuoteRelative",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "reference"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ]
        +                },
        +                "type": {
        +                  "const": "Limit",
        +                  "type": "string"
        +                },
        +                "workingTime": {
        +                  "oneOf": [
        +                    {
        +                      "additionalProperties": false,
        +                      "description": "Stocks/options expire after the current regular US session; crypto expires after a rolling 24 hours.",
        +                      "properties": {
        +                        "type": {
        +                          "const": "Day",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": false,
        +                      "properties": {
        +                        "minutes": {
        +                          "minimum": 1,
        +                          "type": "number"
        +                        },
        +                        "type": {
        +                          "const": "Minutes",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "minutes"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ]
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "price"
        +              ],
        +              "type": "object"
        +            }
        +          ],
        +          "type": "object"
        +        }
        +      },
        +      "required": [
        +        "name",
        +        "condition",
        +        "action"
        +      ],
        +      "type": "object"
        +    },
        +    "type": "array"
        +  },
        +  "targetStrategyId": {
        +    "type": "string"
        +  },
        +  "targetStrategyName": {
        +    "type": "string"
        +  },
        +  "type": {
        +    "enum": [
        +      "deploy",
        +      "undeploy",
        +      "addStrategies",
        +      "removeStrategies",
        +      "replaceStrategy",
        +      "replaceStrategies",
        +      "setDeploymentFrequency",
        +      "rename",
        +      "delete"
        +    ],
        +    "type": "string"
        +  }
        +}
      • addedInput schema / properties / operations / items / required
        Added value: +[
        +  "type",
        +  "portfolioId"
        +]
  14. 1 tool update
    • Changedbuild_portfolio6 fields changed
      • changedInput schema / $defs / condition / description
        Previous value: -"A condition tree (Bridge pattern). type='Base' compares lhs vs rhs with a comparator; type='And'/'Or' combine an array of nested conditions; type='Multi' fires when N nested conditions are true (count vs threshold)."New value: +"A condition tree (Bridge pattern). type='Base' compares lhs vs rhs with a comparator; type='And'/'Or' combine an array of nested conditions; type='Multi' fires when N nested conditions are true (count vs threshold); type='Then' is sequential — it fires when the last nested condition is true now and each earlier one was true at a strictly earlier tick within 'window' of the next, so it needs at least 2 conditions and a window with length > 0."
      • changedInput schema / $defs / condition / properties / conditions / description
        Previous value: -"And / Or / Multi only: nested conditions."New value: +"And / Or / Multi / Then only: nested conditions. Then reads them in order (at least 2)."
      • changedInput schema / $defs / condition / properties / type / enum
        Previous value: -[
        -  "And",
        -  "Or",
        -  "Base",
        -  "Multi"
        -]New value: +[
        +  "And",
        +  "Or",
        +  "Base",
        +  "Multi",
        +  "Then"
        +]
      • addedInput schema / $defs / condition / properties / window
        Added value: +{
        +  "description": "Then only: how long each step has to be followed by the next one, e.g. {length: 30, interval: 'Minute'}. length must be > 0.",
        +  "properties": {
        +    "interval": {
        +      "enum": [
        +        "Day",
        +        "Hour",
        +        "Minute"
        +      ],
        +      "type": "string"
        +    },
        +    "length": {
        +      "type": "number"
        +    }
        +  },
        +  "required": [
        +    "length",
        +    "interval"
        +  ],
        +  "type": "object"
        +}
      • changedInput schema / $defs / indicator / description
        Previous value: -"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), Option* indicators (need underlying + optionType + direction + spreadType), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."New value: +"An indicator. Single permissive shape — the 'type' field selects one of ~90 indicator kinds; other fields are required only when that kind needs them. Server-side IndicatorFactory.validate enforces per-type rules. CustomIndicator (alt-data): REQUIRED customIndicatorId (24-char hex ObjectId from list_custom_indicators or MCP session catalog); optional customIndicatorName is display-only. In DynamicRebalance/RebalanceOption/OpenOption pipelines omit targetAsset on asset-scoped CustomIndicators (binds per candidate). RebalanceDecisionMetric reads the prospective DynamicRebalance/RebalanceOption plan computed before the strategy condition and requires metric allocationDrift, plannedTurnover, estimatedCost, expectedBenefit, or netBenefit. Common kinds: Value (numeric constant; needs 'value'), Price (current asset price; needs 'targetAsset'), SimpleMovingAverage/ExponentialMovingAverage/RelativeStrengthIndex/BollingerBand/MaxDrawdown/MaxDrawup/MinimumPrice/MaximumPrice/PriceStandardDeviation/PriceMeanAbsoluteDeviation/PriceRateOfChange (need targetAsset+window; BollingerBand also numStandardDeviations), Plus/Minus/Multiply/Divide/Max/Min (need 'indicators' array of 2 sub-indicators), Negative/AbsoluteValue/SquareRoot (need 1 sub-indicator), Log (needs base + 1 sub-indicator), Exponentiation (needs exponent + 1 sub-indicator), CrossAbove/CrossBelow (need 2 sub-indicators), TrailingSum/IndicatorWindowAgo/IndicatorAtMinutesAfterOpen (compound; need indicators + window/length/minutesAfterOpen), IndicatorAtEntry (compound; the operand's value frozen at the last matching fill — needs 1 nested indicator + targetAsset + side + orderStatus), Fundamental/CompoundAnnualGrowthRate (need targetAsset + metric; CAGR also needs years), Economic/Index (need metric), DaysSinceOrder/MinutesSinceOrder/SumOrderQuantity/SumOrderAmount/LastOrderPrice (need targetAssets/targetAsset + side + orderStatus), DaysSinceStrategyFired/DaysSinceLastRebalanceOptionOrder (no fields), DaysSinceTransaction (transactionType + transactionStatus), IsAsset/IsNotAsset/IsAssetType/IsIndustry/IsIndexMember (need targetAsset + matchAsset/assetType/industry/index), Option* indicators (need underlying + optionType + direction + spreadType), DaysSinceAgent/MinutesSinceAgent/DaysSinceAlert/MinutesSinceAlert, Day/Month/Year/Date/CurrentTimeHours/CurrentTimeMinutes/CurrentTimeSeconds/MinutesAfterOpen/MinutesUntilClose, PortfolioValue/BuyingPower/InitialValue, PositionValue/PositionPercentChange/PositionMaxDrawdown/PositionMaxDrawup/UnderlyingMaxDrawdown."
      • changedInput schema / $defs / indicator / properties / type / enum
        Previous value: -[
        -  "DaysSinceAgent",
        -  "MinutesSinceAgent",
        -  "DaysSinceAlert",
        -  "MinutesSinceAlert",
        -  "StockReport",
        -  "DaysUntilEarnings",
        -  "DaysSinceEarnings",
        -  "ImpliedVolatility",
        -  "IVRank",
        -  "IVPercentile",
        -  "IVHVRatio",
        -  "LastOrderPrice",
        -  "Fundamental",
        -  "Economic",
        -  "CustomIndicator",
        -  "Index",
        -  "BollingerBand",
        -  "RelativeStrengthIndex",
        -  "PriceMeanAbsoluteDeviation",
        -  "ExponentialMovingAverage",
        -  "SimpleMovingAverage",
        -  "PriceStandardDeviation",
        -  "PriceRateOfChange",
        -  "MaxDrawdown",
        -  "MaxDrawup",
        -  "MinimumPrice",
        -  "MaximumPrice",
        -  "IndicatorMeanAbsoluteDeviation",
        -  "IndicatorExponentialMovingAverage",
        -  "IndicatorSimpleMovingAverage",
        -  "IndicatorStandardDeviation",
        -  "IndicatorRateOfChange",
        -  "DaysSinceOrder",
        -  "DaysSinceOptionOrder",
        -  "DaysSinceStrategyFired",
        -  "DaysSinceLastRebalanceOptionOrder",
        -  "MinutesSinceOptionOrder",
        -  "MinutesSinceOrder",
        -  "DaysSinceTransaction",
        -  "InitialValue",
        -  "BuyingPower",
        -  "PositionValue",
        -  "PositionPercentChange",
        -  "PortfolioValue",
        -  "RebalanceDecisionMetric",
        -  "Value",
        -  "Price",
        -  "Plus",
        -  "Minus",
        -  "Multiply",
        -  "Divide",
        -  "Negative",
        -  "AbsoluteValue",
        -  "SquareRoot",
        -  "Max",
        -  "Min",
        -  "Day",
        -  "Month",
        -  "Date",
        -  "Year",
        -  "CurrentTimeSeconds",
        -  "CurrentTimeMinutes",
        -  "CurrentTimeHours",
        -  "TrailingSum",
        -  "CompoundAnnualGrowthRate",
        -  "Log",
        -  "Exponentiation",
        -  "SumOrderQuantity",
        -  "SumOrderAmount",
        -  "MinutesAfterOpen",
        -  "OpeningPrice",
        -  "PreviousClosingPrice",
        -  "HighOfDay",
        -  "LowOfDay",
        -  "MinutesUntilClose",
        -  "PriceChangeSinceOpen",
        -  "GapSize",
        -  "GapPercentage",
        -  "TrueRange",
        -  "AverageTrueRange",
        -  "Volume",
        -  "VWAP",
        -  "BullishFairValueGap",
        -  "BearishFairValueGap",
        -  "IndicatorAtMinutesAfterOpen",
        -  "IndicatorWindowAgo",
        -  "IsIndexMember",
        -  "IsIndustry",
        -  "IsAssetType",
        -  "IsAsset",
        -  "IsNotAsset",
        -  "CrossAbove",
        -  "CrossBelow",
        -  "PositionMaxDrawdown",
        -  "PositionMaxDrawup",
        -  "UnderlyingMaxDrawdown",
        -  "ConsecutiveTrue",
        -  "CountTrue",
        -  "OptionPositionValue",
        -  "OptionPositionCount",
        -  "OptionPositionPercentChange",
        -  "OptionPositionMaxDrawdown",
        -  "OptionDaysToExpiration",
        -  "OptionDaysHeld",
        -  "OptionCollateral",
        -  "OptionSpreadCount",
        -  "OptionUnrealizedPnL",
        -  "OptionGrossExposurePercent"
        -]New value: +[
        +  "DaysSinceAgent",
        +  "MinutesSinceAgent",
        +  "DaysSinceAlert",
        +  "MinutesSinceAlert",
        +  "StockReport",
        +  "DaysUntilEarnings",
        +  "DaysSinceEarnings",
        +  "ImpliedVolatility",
        +  "IVRank",
        +  "IVPercentile",
        +  "IVHVRatio",
        +  "LastOrderPrice",
        +  "Fundamental",
        +  "Economic",
        +  "CustomIndicator",
        +  "Index",
        +  "BollingerBand",
        +  "RelativeStrengthIndex",
        +  "PriceMeanAbsoluteDeviation",
        +  "ExponentialMovingAverage",
        +  "SimpleMovingAverage",
        +  "PriceStandardDeviation",
        +  "PriceRateOfChange",
        +  "MaxDrawdown",
        +  "MaxDrawup",
        +  "MinimumPrice",
        +  "MaximumPrice",
        +  "IndicatorMeanAbsoluteDeviation",
        +  "IndicatorExponentialMovingAverage",
        +  "IndicatorSimpleMovingAverage",
        +  "IndicatorStandardDeviation",
        +  "IndicatorRateOfChange",
        +  "DaysSinceOrder",
        +  "DaysSinceOptionOrder",
        +  "DaysSinceStrategyFired",
        +  "DaysSinceLastRebalanceOptionOrder",
        +  "MinutesSinceOptionOrder",
        +  "MinutesSinceOrder",
        +  "DaysSinceTransaction",
        +  "InitialValue",
        +  "BuyingPower",
        +  "PositionValue",
        +  "PositionPercentChange",
        +  "PortfolioValue",
        +  "RebalanceDecisionMetric",
        +  "Value",
        +  "Price",
        +  "Plus",
        +  "Minus",
        +  "Multiply",
        +  "Divide",
        +  "Negative",
        +  "AbsoluteValue",
        +  "SquareRoot",
        +  "Max",
        +  "Min",
        +  "Day",
        +  "Month",
        +  "Date",
        +  "Year",
        +  "CurrentTimeSeconds",
        +  "CurrentTimeMinutes",
        +  "CurrentTimeHours",
        +  "TrailingSum",
        +  "CompoundAnnualGrowthRate",
        +  "Log",
        +  "Exponentiation",
        +  "SumOrderQuantity",
        +  "SumOrderAmount",
        +  "MinutesAfterOpen",
        +  "OpeningPrice",
        +  "PreviousClosingPrice",
        +  "HighOfDay",
        +  "LowOfDay",
        +  "MinutesUntilClose",
        +  "PriceChangeSinceOpen",
        +  "GapSize",
        +  "GapPercentage",
        +  "TrueRange",
        +  "AverageTrueRange",
        +  "Volume",
        +  "VWAP",
        +  "BullishFairValueGap",
        +  "BearishFairValueGap",
        +  "IndicatorAtMinutesAfterOpen",
        +  "IndicatorWindowAgo",
        +  "IndicatorAtEntry",
        +  "IsIndexMember",
        +  "IsIndustry",
        +  "IsAssetType",
        +  "IsAsset",
        +  "IsNotAsset",
        +  "CrossAbove",
        +  "CrossBelow",
        +  "PositionMaxDrawdown",
        +  "PositionMaxDrawup",
        +  "UnderlyingMaxDrawdown",
        +  "ConsecutiveTrue",
        +  "CountTrue",
        +  "OptionPositionValue",
        +  "OptionPositionCount",
        +  "OptionPositionPercentChange",
        +  "OptionPositionMaxDrawdown",
        +  "OptionDaysToExpiration",
        +  "OptionDaysHeld",
        +  "OptionCollateral",
        +  "OptionSpreadCount",
        +  "OptionUnrealizedPnL",
        +  "OptionGrossExposurePercent"
        +]
  15. 23 tool updates
    • First observedapprove_agent_plan
    • First observedarchive_agent
    • First observedbacktest_portfolio
    • First observedbuild_portfolio
    • First observedclone_strategies_to_portfolio
    • First observedcreate_agent
    • First observedcreate_portfolio_variant
    • First observedfetch_portfolios
    • First observedfork_shared_portfolio
    • First observedget_agent
    • First observedget_agent_trajectory
    • First observedget_portfolio
    • First observedlist_agents
    • First observedquery_backtest_history
    • First observedquery_backtest_status
    • First observedreject_agent_action
    • First observedsearch_public_portfolios
    • First observedsend_agent_message
    • First observedsend_chat_message
    • First observedstar_agent
    • First observedstop_agent
    • First observedunarchive_agent
    • First observedupdate_portfolio

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables quant research, strategy development, backtesting, and paper trading through natural language prompts, integrated with 20+ AI agents.
    134
    -
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to mine, validate, and paper-trade quantitative trading strategies via chat, with the engine running locally on the user's own machine.
    -
  • A
    license
    A
    quality
    B
    maintenance
    Enables scanning and querying stock market data across thousands of US tickers and top cryptos, with tools for signal analysis, historical replay, and webhook subscriptions.
    35
    101 npm
    MIT
  • A
    license
    A
    quality
    F
    maintenance
    QuantContext turns plain-English strategy descriptions into executable quant research by screening stocks, backtesting, and performing factor analysis using real market data.
    3
    9
    MIT
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.