{"components":{"schemas":{"api1.AcceptInvitation":{"properties":{"token":{"description":"Invitation token","type":"string"}},"required":["token"],"type":"object"},"api1.Account":{"properties":{"account_type":{"description":"Account type (paper or live)","type":"string"},"account_value":{"description":"Total account value (cash + positions)","type":"number"},"active":{"description":"Whether account is active","type":"boolean"},"allow_entries":{"description":"Caller-owned entry hold; false keeps exit evaluation active; echoed only when supplied","type":"boolean"},"cash_balance":{"description":"Current cash balance","type":"number"},"created_at":{"description":"Creation timestamp","type":"string"},"cumulative_deposits":{"description":"Caller-owned cumulative gross deposits for the permanent capital floor; echoed only when supplied","type":"number"},"id":{"description":"Account UUID","type":"string"},"max_open_positions":{"description":"Maximum concurrent positions","type":"integer"},"max_risk_per_trade":{"description":"Maximum risk per trade (0.02 = 2%)","type":"number"},"max_trades_per_day":{"description":"Daily trade limit","type":"integer"},"min_balance_threshold":{"description":"Minimum cash reserve as percentage of balance (0.1 = 10%)","type":"number"},"min_trade_amount":{"description":"Minimum position size","type":"number"},"name":{"description":"Account name","type":"string"},"org_id":{"description":"Organization UUID","type":"string"},"reference_capital":{"description":"Caller-owned signed net funding baseline; echoed only when supplied","type":"number"},"risk_params":{"description":"Additional risk configuration","type":"object","x-mangrove-raw-json":true},"updated_at":{"description":"Last update timestamp","type":"string"},"user_id":{"description":"User UUID","type":"string"}},"type":"object"},"api1.AgeData":{"properties":{"age_days":{"description":"Asset age in days. Null if unknown.","type":"integer"},"launch_date":{"description":"Launch date (ISO 8601 date). Null if unknown.","type":"string"}},"type":"object"},"api1.AllCryptoAssetsResponse":{"properties":{"assets":{"items":{"$ref":"#/components/schemas/api1.CryptoAssetWithGates"},"type":"array"},"count":{"type":"integer"},"success":{"type":"boolean"}},"type":"object"},"api1.ApiKeyCreateErrorResponse":{"properties":{"error":{"description":"Error message","type":"string"},"success":{"description":"Operation status (false)","type":"boolean"}},"type":"object"},"api1.ApiKeyList":{"properties":{"error":{"description":"Error message if request failed","type":"string"},"keys":{"description":"List of API keys (keys are masked)","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"success":{"description":"Whether request was successful","type":"boolean"}},"type":"object"},"api1.ApiKeyListErrorResponse":{"properties":{"error":{"description":"Error message","type":"string"},"success":{"description":"Operation status (false)","type":"boolean"}},"type":"object"},"api1.ApiKeyNotFoundResponse":{"properties":{"error":{"description":"Error message","type":"string"},"success":{"description":"Operation status (false)","type":"boolean"}},"type":"object"},"api1.ApiKeyRequest":{"properties":{"expires_days":{"description":"Number of days until expiration (optional)","type":"integer"},"name":{"description":"Descriptive name for the API key","type":"string"},"scopes":{"description":"Permission scopes for this key","items":{"type":"string"},"type":"array"}},"required":["name"],"type":"object"},"api1.ApiKeyResponse":{"properties":{"created_at":{"description":"Creation timestamp","format":"date-time","type":"string"},"error":{"description":"Error message if generation failed","type":"string"},"expires_at":{"description":"Expiration timestamp (if set)","format":"date-time","type":"string"},"key":{"description":"The API key (ONLY shown once, save it!)","type":"string"},"key_id":{"description":"Key ID for management","type":"string"},"key_prefix":{"description":"Key prefix for identification","type":"string"},"name":{"description":"Key name","type":"string"},"success":{"description":"Whether key generation was successful","type":"boolean"}},"type":"object"},"api1.ApiKeyRevokeErrorResponse":{"properties":{"error":{"description":"Error message","type":"string"},"success":{"description":"Operation status (false)","type":"boolean"}},"type":"object"},"api1.ApiKeyRevokeResponse":{"properties":{"message":{"description":"Success message","type":"string"},"success":{"description":"Operation status (true)","type":"boolean"}},"type":"object"},"api1.ApprovalGates":{"properties":{"age":{"description":"Meets the asset-age threshold","type":"boolean"},"market_cap":{"description":"Meets the market-cap threshold","type":"boolean"},"volume":{"description":"Meets the 24h-volume threshold","type":"boolean"}},"type":"object"},"api1.AssetExchange":{"properties":{"exchange_id":{"description":"Exchange slug (e.g. binance)","type":"string"},"name":{"description":"Exchange name","type":"string"},"tier":{"description":"Exchange tier (1 = highest)","type":"integer"}},"type":"object"},"api1.AssetExchangesResponse":{"properties":{"count":{"type":"integer"},"exchanges":{"items":{"$ref":"#/components/schemas/api1.AssetExchange"},"type":"array"},"success":{"type":"boolean"},"symbol":{"type":"string"}},"type":"object"},"api1.AssetMarketData":{"properties":{"market_cap_usd":{"description":"Market capitalization (USD). Null if unknown.","type":"number"},"price_change_24h_pct":{"description":"24-hour price change (percent). Null if unknown.","type":"number"},"price_usd":{"description":"Last price (USD). Null if unknown.","type":"number"},"volume_24h_usd":{"description":"24-hour trading volume (USD). Null if unknown.","type":"number"}},"type":"object"},"api1.AvailabilityRequest":{"properties":{"price":{"description":"Asset price in cash","type":"number"},"strategy_config":{"description":"Strategy config in the shape /evaluate/bulk takes: execution_config with position_size_calc 'v3' and the v3 keys, execution_state with cash_balance, asset_balance and optional pending_orders, and open_positions.","type":"object","x-mangrove-raw-json":true}},"required":["price","strategy_config"],"type":"object"},"api1.AvailabilityResponse":{"properties":{"account_value":{"description":"Asset balance at price plus cash balance, less pending orders","type":"number"},"asset_balance":{"description":"execution_state.asset_balance as sent","type":"number"},"available_asset":{"description":"Asset units an entry or a withdrawal may use, net of min_balance_reserve_asset","type":"number"},"available_cash":{"description":"Cash an entry or a withdrawal may use, net of min_balance_reserve_cash","type":"number"},"cash_balance":{"description":"execution_state.cash_balance as sent","type":"number"},"core_weight":{"description":"Asset share of core value","type":"number"},"min_balance_reserve_asset":{"description":"Asset units held back for the outstanding minimum-balance sells","type":"number"},"min_balance_reserve_cash":{"description":"Cash held back for the outstanding minimum-balance buys","type":"number"},"open_risk":{"description":"Summed worst-case loss of the open trades","type":"number"},"risk_basis_asset_value":{"description":"What the risk budget of a sell entry is taken on: value at price of the asset outside open buy trades, less open risk, not below 0","type":"number"},"risk_basis_cash":{"description":"What the risk budget of a buy entry is taken on: cash less the proceeds of open sell trades and open risk, not below 0","type":"number"}},"type":"object"},"api1.Backtest":{"properties":{"asset":{"type":"string"},"created_at":{"type":"string"},"end_date":{"type":"string"},"execution_time":{"type":"number"},"id":{"type":"string"},"initial_balance":{"type":"number"},"irr_annualized":{"type":"number"},"max_drawdown":{"type":"number"},"metrics":{"type":"object","x-mangrove-raw-json":true},"sharpe_ratio":{"type":"number"},"start_date":{"type":"string"},"status":{"type":"string"},"total_return":{"type":"number"},"total_trades":{"type":"integer"},"trade_history":{"type":"object","x-mangrove-raw-json":true},"win_rate":{"type":"number"}},"type":"object"},"api1.BacktestArchiveResponse":{"properties":{"archived":{"description":"True after archive, False after unarchive","type":"boolean"},"backtest_id":{"description":"UUID of the affected backtest run","type":"string"},"success":{"description":"Whether the operation succeeded","type":"boolean"}},"type":"object"},"api1.BacktestRequest":{"properties":{"asset":{"description":"Canonical base token, e.g. BTC","type":"string"},"base_token":{"description":"Explicit market base; supply all three market fields together","type":"string"},"cooldown_bars":{"description":"DEPRECATED. Read only under execution_config.cooldown_model \"bars\", where it defaults from trading_defaults.json (24) when omitted; ignored and dropped under the default \"trades\" model.","type":"integer"},"corpus_dataset":{"description":"Exact corpus window filename from a promoted sweep run","type":"string"},"daily_momentum_limit":{"description":"DEPRECATED. Read only under execution_config.cooldown_model \"bars\", where it defaults from trading_defaults.json (3) when omitted; ignored and dropped under the default \"trades\" model.","type":"number"},"data_file":{"description":"CSV filename if data_source=\"file\"","type":"string"},"data_source":{"description":"Data source: \"api\" or \"file\" (default: api)","type":"string"},"enable_volatility_adjustment":{"description":"Enable volatility adjustment","type":"boolean"},"end_date":{"description":"End date ISO format (e.g., \"2024-12-31\"). If omitted with start_date, defaults to now","type":"string"},"exchange":{"description":"Legacy: exchange name (not used for api data source)","type":"string"},"execution_config":{"allOf":[{"$ref":"#/components/schemas/api1.ExecutionConfiguration"}],"description":"Execution config dict with atr_period, volatility_tolerance, etc. If omitted, defaults from trading_defaults.json are used."},"fee_pct":{"description":"Max fee rate as decimal (default 0.0085 = 0.85%). Size-dependent linear schedule: $10K trades pay full rate, $1M+ trades pay 0.0589%. Applied only to profitable trades. Default from trading_defaults.json.","type":"number"},"generation":{"description":"Explicit engine generation; omit for latest","type":"integer"},"hourly_data_file":{"description":"Legacy: CSV file path (treated as data_file)","type":"string"},"initial_asset_balance":{"description":"position_size_calc \"v3\" only, and required there: asset units the account starts with.","type":"number"},"initial_balance":{"description":"Initial account balance. Under position_size_calc \"v3\": the starting cash, stated by the caller (never defaulted from a saved strategy).","type":"number"},"interval":{"description":"Time interval (e.g., \"1m\",\"5m\",\"15m\",\"30m\",\"1h\",\"4h\",\"1d\")","type":"string"},"lookback_months":{"description":"Lookback window in months for API data (default: 12)","type":"integer"},"market_data_venue":{"description":"Explicit market venue","type":"string"},"max_open_positions":{"description":"Maximum open positions","type":"integer"},"max_risk_per_trade":{"description":"Maximum risk per trade","type":"number"},"max_trade_amount":{"description":"Maximum trade amount","type":"number"},"max_trades_per_day":{"description":"Maximum trades per day","type":"integer"},"max_units_per_trade":{"description":"Maximum units per trade","type":"number"},"min_balance_threshold":{"description":"Minimum cash reserve as percentage (0.1 = 10%)","type":"number"},"min_trade_amount":{"description":"Minimum trade amount","type":"number"},"quote_token":{"description":"Explicit market quote","type":"string"},"seed":{"description":"Optional deterministic simulation seed forwarded to Oracle. Omitted preserves the Oracle default.","type":"integer"},"slippage_pct":{"description":"Max slippage per leg as decimal (e.g., 0.004 = 0.4%). Random slippage drawn from uniform(0, slippage_pct) independently for entry and exit. Default from trading_defaults.json: 0.004.","type":"number"},"start_date":{"description":"Start date ISO format (e.g., \"2024-01-01\"). If omitted, calculated from lookback_months","type":"string"},"strategy_id":{"description":"UUID of a saved strategy to backtest. When provided, strategy_json (and, if omitted, asset and execution_config) are loaded from the saved strategy. Mutually exclusive with strategy_json.","type":"string"},"strategy_json":{"description":"JSON config for the strategy (entry/exit rules, reward_factor). ATR params come from execution_config. Mutually exclusive with strategy_id; one of the two is required.","type":"string"},"target_volatility":{"description":"Target volatility","type":"number"},"volatility_mode":{"description":"Volatility mode","type":"string"},"volatility_window":{"description":"Volatility calculation window","type":"integer"},"weekly_momentum_limit":{"description":"DEPRECATED. Read only under execution_config.cooldown_model \"bars\", where it defaults from trading_defaults.json (3) when omitted; ignored and dropped under the default \"trades\" model.","type":"number"}},"required":["asset","enable_volatility_adjustment","initial_balance","max_open_positions","max_risk_per_trade","max_trade_amount","max_trades_per_day","max_units_per_trade","min_balance_threshold","min_trade_amount","target_volatility","volatility_mode","volatility_window"],"type":"object"},"api1.BacktestResult":{"properties":{"base_token":{"description":"Recorded canonical base token; null for historical runs","type":["string","null"],"x-nullable":true},"core_orders":{"description":"position_size_calc \"v3\" only: the core orders of the run (side, quantity, reason, reference_price, timestamp). Absent otherwise.","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"data_info":{"description":"position_size_calc \"v3\" only: what the engine reports about the data the run used. Absent otherwise.","type":"object","x-mangrove-raw-json":true},"equity_curve":{"description":"Timestamped marked account equity samples; time is Unix seconds UTC","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"error":{"description":"Error message if backtest failed","type":"string"},"execution_time_seconds":{"description":"Time taken to run backtest","type":"number"},"market_data_venue":{"description":"Recorded market data venue; null for historical runs","type":["string","null"],"x-nullable":true},"metrics":{"description":"Performance metrics","type":"object","x-mangrove-raw-json":true},"quote_token":{"description":"Recorded quote token; null for historical runs","type":["string","null"],"x-nullable":true},"satellite_pnl":{"description":"position_size_calc \"v3\" only: profit and loss of the closed buy and sell trades, in cash. Absent otherwise.","type":"number"},"strategy_names":{"description":"List of strategy names that were run","items":{"type":"string"},"type":"array"},"success":{"description":"Whether backtest completed successfully","type":"boolean"},"trade_count":{"description":"Number of trades executed","type":"integer"},"trade_history":{"description":"List of serialized TradeRecord objects with entry/exit prices, timestamps, profit/loss, exit reasons","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"}},"required":["success"],"type":"object"},"api1.BacktestsResponse":{"properties":{"backtests":{"items":{"$ref":"#/components/schemas/api1.Backtest"},"type":"array"},"success":{"type":"boolean"},"total":{"type":"integer"}},"type":"object"},"api1.BatchJob":{"properties":{"completed":{"description":"Completion timestamp","type":"string"},"failure_reason":{"description":"Error message if failed","type":"string"},"id":{"description":"Job UUID","type":"string"},"invoked":{"description":"Start timestamp","type":"string"},"name":{"description":"Job name","type":"string"},"result_data":{"description":"Structured output from completed batch job","type":"object","x-mangrove-raw-json":true},"status":{"description":"Job status (running, complete, failed)","type":"string"}},"type":"object"},"api1.BulkBacktestRequest":{"properties":{"cooldown_bars":{"description":"DEPRECATED. Read only under execution_config.cooldown_model \"bars\", where it defaults from trading_defaults.json (24) when omitted; ignored and dropped under the default \"trades\" model.","type":"integer"},"daily_momentum_limit":{"description":"DEPRECATED. Read only under execution_config.cooldown_model \"bars\", where it defaults from trading_defaults.json (3) when omitted; ignored and dropped under the default \"trades\" model.","type":"number"},"enable_volatility_adjustment":{"description":"Enable volatility adjustment","type":"boolean"},"end_date":{"description":"End date ISO format (e.g., \"2024-12-31\")","type":"string"},"execution_config":{"allOf":[{"$ref":"#/components/schemas/api1.ExecutionConfiguration"}],"description":"Execution config applied to every strategy (atr_period, volatility_tolerance, etc.). Defaults from trading_defaults.json are used when omitted."},"fee_pct":{"description":"Max fee rate as decimal (default 0.0085). Size-dependent linear schedule, profitable trades only.","type":"number"},"generation":{"description":"Explicit engine generation; omit for latest","type":"integer"},"initial_asset_balance":{"description":"V3 only: common starting asset units; a strategy config may override it.","type":"number"},"initial_balance":{"description":"Initial account balance","type":"number"},"max_hold_time_hours":{"description":"Maximum position hold time in hours","type":"integer"},"max_open_positions":{"description":"Maximum open positions","type":"integer"},"max_risk_per_trade":{"description":"Maximum risk per trade","type":"number"},"max_trade_amount":{"description":"Maximum trade amount","type":"number"},"max_trades_per_day":{"description":"Maximum trades per day","type":"integer"},"max_units_per_trade":{"description":"Maximum units per trade","type":"number"},"min_balance_threshold":{"description":"Minimum cash reserve as percentage (0.1 = 10%)","type":"number"},"min_trade_amount":{"description":"Minimum trade amount","type":"number"},"seed":{"description":"Optional deterministic simulation seed forwarded to Oracle. Omitted preserves the Oracle default.","type":"integer"},"slippage_pct":{"description":"Max slippage per leg as decimal (default from trading_defaults.json: 0.004)","type":"number"},"start_date":{"description":"Start date ISO format (e.g., \"2024-01-01\")","type":"string"},"strategy_configs":{"description":"List of strategy config objects in the canonical entry/exit format (already parsed -- not stringified JSON). Mutually exclusive with strategy_ids.","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"strategy_ids":{"description":"List of strategy UUIDs to load from the database. Mutually exclusive with strategy_configs.","items":{"type":"string"},"type":"array"},"target_volatility":{"description":"Target volatility","type":"number"},"volatility_mode":{"description":"Volatility mode","type":"string"},"volatility_window":{"description":"Volatility calculation window","type":"integer"},"weekly_momentum_limit":{"description":"DEPRECATED. Read only under execution_config.cooldown_model \"bars\", where it defaults from trading_defaults.json (3) when omitted; ignored and dropped under the default \"trades\" model.","type":"number"}},"required":["enable_volatility_adjustment","end_date","initial_balance","max_open_positions","max_risk_per_trade","max_trade_amount","max_trades_per_day","max_units_per_trade","min_balance_threshold","min_trade_amount","start_date","target_volatility","volatility_mode","volatility_window"],"type":"object"},"api1.BulkBacktestResult":{"properties":{"data_fetches":{"description":"Number of unique (asset, timeframe) API calls made","type":"integer"},"error":{"description":"Top-level error message (only set on total failure)","type":"string"},"results":{"description":"One result per input strategy, in order","items":{"$ref":"#/components/schemas/api1.StrategyBacktestResult"},"type":"array"},"success":{"description":"True unless the request itself was invalid","type":"boolean"},"total_execution_time_seconds":{"description":"Wall-clock time for the full batch","type":"number"}},"type":"object"},"api1.BulkEvaluateRequest":{"properties":{"persist":{"default":false,"description":"Persist orders and positions to DB for each strategy (default: false)","type":"boolean"},"strategy_configs":{"description":"List of inline strategy objects to evaluate. Each must include asset, entry/rules, execution_config, and execution_state.","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"strategy_ids":{"description":"List of strategy UUIDs to load from DB and evaluate","items":{"type":"string"},"type":"array"}},"type":"object"},"api1.BulkEvaluateResult":{"properties":{"code":{"description":"Machine error code (top-level error responses)","type":"string"},"contract_version":{"default":"1.3.0","description":"Semver of the execution-response contract this response conforms to (contracts/execution_response.schema.json). Consumers assert major-compatibility per call. #1232","type":"string"},"correlation_id":{"description":"Request correlation id (error responses, when present)","type":"string"},"data_fetches":{"description":"Number of unique (asset, timeframe) market-data API calls made","type":"integer"},"error":{"description":"Top-level error/category if the batch could not start","type":"string"},"message":{"description":"Human-readable error message (top-level error responses)","type":"string"},"results":{"description":"Per-strategy results in the same order as the request","items":{"$ref":"#/components/schemas/api1.StrategyEvaluateResult"},"type":"array"},"retry_after":{"description":"Seconds to wait before retry (rate-limit/unavailable errors)","type":"integer"},"success":{"description":"True if the batch ran to completion; false only on a top-level batch error","type":"boolean"},"total_execution_time_seconds":{"description":"Wall-clock time for the full batch","type":"number"}},"type":"object"},"api1.BuyAndHoldBenchmark":{"properties":{"asset":{"description":"The asset, upper-cased","type":"string"},"bars":{"description":"How many daily closes it was computed from","type":"integer"},"base_token":{"description":"Recorded canonical base token; null for historical runs","type":["string","null"],"x-nullable":true},"buy_and_hold_return":{"description":"The return from holding, as a display string with % attached, e.g. \"12.3456%\"","type":"string"},"buy_and_hold_return_raw":{"description":"The same return as a number on a 0-100 percent scale (12.3456 means 12.3456%)","type":"number"},"end":{"description":"Window end (ISO)","type":"string"},"first_close":{"description":"The close the window opened at","type":"number"},"last_close":{"description":"The close it ended at","type":"number"},"market_data_venue":{"description":"Recorded market data venue; null for historical runs","type":["string","null"],"x-nullable":true},"quote_token":{"description":"Recorded quote token; null for historical runs","type":["string","null"],"x-nullable":true},"start":{"description":"Window start (ISO)","type":"string"},"unit":{"description":"Scale of the return: percent_0_100","type":"string"}},"type":"object"},"api1.ChainTVLResponse":{"properties":{"chain":{"type":"string"},"data":{"description":"Full provider response","type":"object","x-mangrove-raw-json":true},"success":{"type":"boolean"},"top_protocols":{"description":"Top 10 protocols on this chain","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"tvl_usd":{"type":"number"}},"type":"object"},"api1.ChatRequest":{"properties":{"execution_id":{"description":"Stable UUID for retries of this execution; requires turn_id","type":"string"},"message":{"description":"The user message content","type":"string"},"turn_id":{"description":"Platform logical turn UUID; requires execution_id","type":"string"}},"required":["message"],"type":"object"},"api1.Configuration":{"properties":{"agentic_files":{"description":"Files present in the agentic/ directory","items":{"type":"string"},"type":"array"},"context_files":{"description":"Files present in the context/ directory","items":{"type":"string"},"type":"array"},"error":{"description":"Error message if retrieval failed","type":"string"},"prompt_files":{"description":"Files present in the prompts/ directory","items":{"type":"string"},"type":"array"},"success":{"description":"Whether the configuration was retrieved successfully","type":"boolean"}},"required":["success"],"type":"object"},"api1.Conversation":{"properties":{"created_at":{"description":"Timestamp when the conversation was created","format":"date-time","type":"string"},"session_id":{"description":"Unique identifier for the conversation session","type":"string"},"thread_id":{"description":"OpenAI thread ID for the conversation","type":"string"},"title":{"description":"Human-readable title for the conversation","type":"string"},"working_context":{"description":"Optional JSONB context for state machine data","type":"object","x-mangrove-raw-json":true}},"required":["created_at","session_id","thread_id","title"],"type":"object"},"api1.ConversationList":{"properties":{"conversations":{"description":"List of conversations","items":{"$ref":"#/components/schemas/api1.Conversation"},"type":"array"},"success":{"description":"Whether the operation completed successfully","type":"boolean"}},"required":["success"],"type":"object"},"api1.ConversationResponse":{"properties":{"conversation":{"allOf":[{"$ref":"#/components/schemas/api1.Conversation"}],"description":"Conversation data if successful"},"error":{"description":"Error message if operation failed","type":"string"},"success":{"description":"Whether the operation completed successfully","type":"boolean"}},"required":["success"],"type":"object"},"api1.CoreOrder":{"properties":{"quantity":{"description":"Quantity in asset units","type":"number"},"reason":{"description":"Why the order is placed","enum":["min_balance","rebalance"],"example":"min_balance","type":"string"},"reference_price":{"description":"Asset price the order was sized at","type":"number"},"side":{"description":"Core order side","enum":["buy","sell"],"example":"buy","type":"string"},"timestamp":{"description":"Evaluation time (ISO-8601)","type":"string"}},"type":"object"},"api1.CreateAccountRequest":{"properties":{"account_type":{"description":"Account type (paper or live)","type":"string"},"initial_balance":{"default":10000,"description":"Starting cash balance","type":"number"},"max_open_positions":{"default":3,"description":"Maximum open positions","type":"integer"},"max_risk_per_trade":{"default":0.02,"description":"Maximum risk per trade","type":"number"},"max_trades_per_day":{"default":10,"description":"Maximum trades per day","type":"integer"},"min_balance_threshold":{"default":0.1,"description":"Minimum cash reserve as percentage (0.1 = 10%)","type":"number"},"min_trade_amount":{"default":25,"description":"Minimum trade amount","type":"number"},"name":{"description":"Account name","type":"string"},"risk_params":{"description":"Additional risk parameters","type":"object","x-mangrove-raw-json":true}},"required":["account_type"],"type":"object"},"api1.CreateOrganization":{"properties":{"info":{"description":"Additional organization information","type":"object","x-mangrove-raw-json":true},"name":{"description":"Organization name","type":"string"},"ria_flag":{"default":false,"description":"RIA compliance flag","type":"boolean"}},"required":["name"],"type":"object"},"api1.CreateSignalRequest":{"properties":{"code":{"description":"Python function code","type":"string"},"description":{"description":"Human-readable description","type":"string"},"name":{"description":"Signal name (lowercase, no spaces)","type":"string"},"params":{"description":"Parameter definitions (JSON object)","type":"object","x-mangrove-raw-json":true}},"required":["code","description","name","params"],"type":"object"},"api1.CreateSignalResponse":{"properties":{"category":{"type":"string"},"code":{"type":"string"},"id":{"description":"Signal ID (UUID)","type":"string"},"metadata":{"$ref":"#/components/schemas/api1.SignalMetadata"},"name":{"type":"string"},"usage_count":{"type":"integer"}},"type":"object"},"api1.CreateStrategyRequest":{"properties":{"asset":{"description":"Base token only (e.g., BTC; not BTC-USDC)","type":"string"},"description":{"description":"Human-readable strategy description","type":"string"},"entry":{"description":"Entry rules array (exactly 1 TRIGGER, 0+ FILTERs)","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"entry_short":{"description":"Entry rules of sell trades (exactly 1 TRIGGER, 0+ FILTERs). position_size_calc \"v3\" only.","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"execution_config":{"allOf":[{"$ref":"#/components/schemas/api1.ExecutionConfiguration"}],"description":"Execution configuration (risk mgmt, position limits, etc.). Auto-populated from defaults if omitted"},"execution_state":{"description":"Initial execution state (cash_balance, account_value, etc.). Auto-populated if omitted","type":"object","x-mangrove-raw-json":true},"exit":{"description":"Exit rules array (optional, 0-1 TRIGGER + 0+ FILTERs)","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"exit_short":{"description":"Exit rules of sell trades (optional, 0-1 TRIGGER + 0+ FILTERs). position_size_calc \"v3\" only.","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"market_data_venue":{"description":"Market data venue (e.g., BINANCE), optional","type":"string"},"name":{"description":"Strategy name","type":"string"},"org_id":{"description":"Deprecated: ignored, org_id is taken from JWT token. Accepted for backward compatibility.","type":"string"},"parent_strategy_id":{"description":"Parent strategy ID for derived strategies (optional)","type":"string"},"position_size_calc":{"description":"Sizing-math version: \"v1\", \"v2\" or \"v3\". Defaults from canon (currently \"v2\"). Pinned at creation; cannot be changed after. \"v3\" requires the v3 execution_config keys (min_asset_balance, min_cash_balance, target_asset_weight, rebalance_band, min_balance_days, stop_gap_allowance, taker_fee_rate) and a non-null max_trade_amount.","enum":["v1","v2","v3"],"example":"v1","type":"string"},"quote_token":{"description":"Quote currency (e.g., USDC), optional","type":"string"},"reward_factor":{"description":"Reward factor for risk/reward calculation (default: 2.0)","type":"number"},"rules":{"description":"Legacy: flat rules array (use entry/exit instead)","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"session_id":{"description":"Linked conversation session ID (optional)","type":"string"},"status":{"description":"Legacy input; new definitions always start as draft. Existing deduplicated rows retain their status.","type":"string"},"strategy_type":{"description":"Strategy type (trend_following, momentum, volatility, breakout, mean_reversion)","type":"string"},"timeframe":{"description":"Explicit default timeframe for signals that omit one; per-signal values take precedence.","type":"string"}},"required":["asset","entry","name"],"type":"object"},"api1.CreateStrategyResponse":{"properties":{"strategy":{"$ref":"#/components/schemas/api1.StrategyDetail"},"success":{"type":"boolean"}},"type":"object"},"api1.CryptoAsset":{"properties":{"age_data":{"$ref":"#/components/schemas/api1.AgeData"},"approval_gates":{"$ref":"#/components/schemas/api1.ApprovalGates"},"approval_status":{"description":"Approval workflow state (pending, approved, rejected)","type":"string"},"asset_type":{"description":"cryptocurrency or tokenized_asset","type":"string"},"exchanges":{"description":"Exchange listings. Null unless the caller loaded them; this route does not.","items":{"$ref":"#/components/schemas/api1.ExchangeListing"},"type":"array"},"id":{"description":"Asset ID (UUID)","type":"string"},"is_approved":{"description":"Approval status","type":"boolean"},"market_data":{"$ref":"#/components/schemas/api1.AssetMarketData"},"name":{"description":"Asset name (e.g., Bitcoin)","type":"string"},"native_chain":{"description":"Native chain for a token (e.g. ethereum). Null for L1 coins.","type":"string"},"regulatory_status":{"description":"Regulatory status (pending, approved, restricted, banned)","type":"string"},"risk_assessment_status":{"description":"Whether risk scores have been assessed.","enum":["assessed","outstanding"],"example":"assessed","type":"string"},"risk_scores":{"$ref":"#/components/schemas/api1.RiskScores"},"risk_tier":{"description":"Risk tier label. Null if not assigned.","type":"string"},"security_status":{"description":"Security status (pending, secure, vulnerable, compromised)","type":"string"},"supply_data":{"$ref":"#/components/schemas/api1.SupplyData"},"symbol":{"description":"Asset symbol (e.g., BTC)","type":"string"},"timestamps":{"$ref":"#/components/schemas/api1.Timestamps"},"token_standard":{"description":"Token standard (e.g. ERC-20). Null for L1 coins.","type":"string"},"volatility_data":{"$ref":"#/components/schemas/api1.VolatilityData"}},"type":"object"},"api1.CryptoAssetDetailResponse":{"properties":{"asset":{"$ref":"#/components/schemas/api1.CryptoAsset"},"success":{"type":"boolean"},"symbol":{"description":"Echo of the requested symbol, upper-cased","type":"string"}},"type":"object"},"api1.CryptoAssetListResponse":{"properties":{"assets":{"items":{"$ref":"#/components/schemas/api1.CryptoAssetSummary"},"type":"array"},"count":{"type":"integer"},"success":{"type":"boolean"}},"type":"object"},"api1.CryptoAssetQueryResponse":{"properties":{"assets":{"items":{"$ref":"#/components/schemas/api1.CryptoAssetSummary"},"type":"array"},"count":{"type":"integer"},"success":{"type":"boolean"}},"type":"object"},"api1.CryptoAssetSummary":{"properties":{"asset_type":{"description":"cryptocurrency or tokenized_asset","type":"string"},"exchange_score":{"description":"Exchange availability score (0-100)","type":"integer"},"is_approved":{"description":"Approval status","type":"boolean"},"liquidity_score":{"description":"Liquidity score (0-100)","type":"integer"},"market_cap_score":{"description":"Market cap score (0-100)","type":"integer"},"market_cap_usd":{"description":"Market capitalization (USD)","type":"number"},"name":{"description":"Asset name (e.g., Bitcoin)","type":"string"},"overall_risk_score":{"description":"Overall risk score (0-100)","type":"number"},"price_stability_score":{"description":"Price stability score (0-100)","type":"integer"},"price_usd":{"description":"Last price (USD)","type":"number"},"risk_assessment_status":{"description":"Whether risk scores have been assessed.","enum":["assessed","outstanding"],"example":"assessed","type":"string"},"symbol":{"description":"Asset symbol (e.g., BTC)","type":"string"},"volatility_score":{"description":"Volatility score (0-100)","type":"integer"},"volume_24h_usd":{"description":"24-hour trading volume (USD)","type":"number"}},"type":"object"},"api1.CryptoAssetWithGates":{"properties":{"approval_gates":{"$ref":"#/components/schemas/api1.ApprovalGates"},"asset_type":{"description":"cryptocurrency or tokenized_asset","type":"string"},"is_approved":{"description":"Approval status","type":"boolean"},"market_cap_usd":{"description":"Market capitalization (USD)","type":"number"},"name":{"description":"Asset name (e.g., Bitcoin)","type":"string"},"overall_risk_score":{"description":"Overall risk score (0-100)","type":"number"},"price_usd":{"description":"Last price (USD)","type":"number"},"risk_assessment_status":{"description":"Whether risk scores have been assessed.","enum":["assessed","outstanding"],"example":"assessed","type":"string"},"risk_scores":{"description":"Component scores: market_cap, liquidity, exchange, age, volatility, supply_distribution, price_stability","type":"object","x-mangrove-raw-json":true},"symbol":{"description":"Asset symbol (e.g., BTC)","type":"string"},"updated_at":{"description":"Last update timestamp (ISO 8601)","type":"string"},"volume_24h_usd":{"description":"24-hour trading volume (USD)","type":"number"}},"type":"object"},"api1.DefiError":{"properties":{"code":{"type":"string"},"error":{"type":"string"},"message":{"type":"string"}},"type":"object"},"api1.DeleteResponse":{"properties":{"error":{"description":"Error message if operation failed","type":"string"},"message":{"description":"Success message","type":"string"},"success":{"description":"Whether the operation completed successfully","type":"boolean"}},"required":["success"],"type":"object"},"api1.DeleteStrategyResponse":{"properties":{"message":{"type":"string"},"success":{"type":"boolean"}},"type":"object"},"api1.DocContent":{"properties":{"content":{"description":"Raw markdown content","type":"string"},"error":{"description":"Error message if request failed","type":"string"},"path":{"description":"Document path","type":"string"},"success":{"description":"Whether request was successful","type":"boolean"}},"type":"object"},"api1.DocItem":{"properties":{"name":{"description":"File name","type":"string"},"path":{"description":"Relative path to the document","type":"string"},"title":{"description":"Document title (extracted from first heading if possible)","type":"string"}},"type":"object"},"api1.DocsList":{"properties":{"docs":{"description":"List of available documents","items":{"$ref":"#/components/schemas/api1.DocItem"},"type":"array"},"error":{"description":"Error message if request failed","type":"string"},"success":{"description":"Whether request was successful","type":"boolean"}},"type":"object"},"api1.EnsureStrategyCreatedResponse":{"properties":{"created":{"description":"True when a new strategy was created","type":"boolean"},"strategy":{"$ref":"#/components/schemas/api1.StrategyDetail"},"success":{"type":"boolean"}},"type":"object"},"api1.EnsureStrategyExistingResponse":{"properties":{"created":{"description":"False when an existing strategy was returned","type":"boolean"},"strategy":{"$ref":"#/components/schemas/api1.StrategyDetail"},"success":{"type":"boolean"}},"type":"object"},"api1.Error":{"properties":{"code":{"description":"Specific error code (e.g., INVALID_PROMPT_LENGTH, MISSING_AUTH_TOKEN)","type":"string"},"correlation_id":{"description":"Request correlation ID for tracing","type":"string"},"error":{"description":"Error category (validation_error, authentication_error, authorization_error, rate_limit_error, internal_error, service_unavailable)","type":"string"},"message":{"description":"Human-readable error message","type":"string"},"retry_after":{"description":"Retry after this many seconds (for rate_limit_error and service_unavailable errors)","type":"integer"}},"required":["code","error","message"],"type":"object"},"api1.ErrorResponse":{"properties":{"error":{"description":"Error message","type":"string"}},"type":"object"},"api1.EtfFlowsResponse":{"properties":{"count":{"description":"Records in this page","type":"integer"},"data":{"description":"Asset-days in this page, newest first","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"has_more":{"type":"boolean"},"limit":{"type":"integer"},"next_offset":{"description":"Offset of the next page, or null","type":"integer"},"offset":{"type":"integer"},"provider":{"type":"string"},"skipped":{"description":"Provider records that could not be read","type":"integer"},"success":{"type":"boolean"},"total":{"description":"Records matching the filters across all pages","type":"integer"},"totals":{"description":"Per-asset totals across the whole window","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"window":{"description":"from/to dates (UTC) and lookback_days evaluated","type":"object","x-mangrove-raw-json":true}},"type":"object"},"api1.EvaluateMultipleSeriesRequest":{"properties":{"chart_timeframe":{"default":"1h","description":"Live chart timeframe; dataset mode uses its bundled timeframe","type":"string"},"dataset_key":{"description":"Bundled dataset key; replaces symbol and date range","type":"string"},"end_date":{"description":"Live-mode chart end timestamp; with start_date, or omit both for the latest 500 bars","type":"string"},"include_chart":{"default":false,"description":"Also return chart bars (latest 2,000 at most) and trigger_indices","type":"boolean"},"market_data_venue":{"description":"Live-data exchange; supply with quote_token","type":"string"},"provider":{"description":"Explicit external history provider","type":"string"},"quote_token":{"description":"Live-data quote; supply with market_data_venue","type":"string"},"signals":{"default":[],"description":"Up to 20 registered signals to evaluate","items":{"$ref":"#/components/schemas/api1.EvaluateMultipleSeriesSignal"},"type":"array"},"start_date":{"description":"Live-mode chart start timestamp; with end_date, or omit both for the latest 500 bars","type":"string"},"symbol":{"description":"Live-mode asset symbol; required unless dataset_key is provided","type":"string"}},"type":"object"},"api1.EvaluateMultipleSeriesResponse":{"properties":{"chart_bars":{"description":"Bars in the evaluated chart window","type":"integer"},"chart_data":{"description":"OHLCV bars, only with include_chart (latest 2,000 at most)","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"chart_timeframe":{"description":"Chart timeframe","type":"string"},"chart_truncated":{"description":"Whether chart_data was cut to the latest 2,000 bars","type":"boolean"},"end_date":{"description":"Chart range end","type":"string"},"signal_results":{"description":"Individual signal evaluation results","items":{"$ref":"#/components/schemas/api1.SignalTriggerResult"},"type":"array"},"start_date":{"description":"Chart range start","type":"string"}},"type":"object"},"api1.EvaluateMultipleSeriesSignal":{"properties":{"name":{"description":"Signal type/name","type":"string"},"params":{"default":{},"description":"Signal parameters; omitted values use registered defaults","type":"object","x-mangrove-raw-json":true},"timeframe":{"description":"Timeframe for this signal (5m, 15m, 30m, 1h, 4h, 1D)","type":"string"}},"required":["name"],"type":"object"},"api1.EvaluateObjectRequest":{"properties":{"open_positions":{"description":"Caller-owned open positions (stateless lane); authoritative set returned on the response","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"persist":{"default":false,"description":"Whether to persist results (default False for object-based)","type":"boolean"},"strategy":{"allOf":[{"$ref":"#/components/schemas/api1.StrategyObject"}],"description":"Strategy object to evaluate"}},"required":["strategy"],"type":"object"},"api1.EvaluateRequest":{"properties":{"persist":{"default":true,"description":"Whether to persist orders, positions, and trades to database","type":"boolean"}},"type":"object"},"api1.EvaluateResponse":{"properties":{"asset":{"description":"Asset being traded","type":"string"},"bar_evaluated":{"description":"False when the settled candle was already evaluated","type":"boolean"},"base_token":{"description":"Canonical base token of the selected market","type":"string"},"closed_trades":{"description":"Confirmed engine-owned fills only","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"code":{"description":"Machine error code (error responses)","type":"string"},"contract_version":{"default":"1.3.0","description":"Semver of the execution-response contract this response conforms to (contracts/execution_response.schema.json). Consumers assert major-compatibility per call. #1232","type":"string"},"core_orders":{"description":"Core orders placed by this evaluation: zero or one element (position_size_calc 'v3')","items":{"$ref":"#/components/schemas/api1.CoreOrder"},"type":"array"},"correlation_id":{"description":"Request correlation id (error responses, when present)","type":"string"},"current_price":{"description":"Current market price","type":"number"},"denied_signals":{"description":"Entry signals that fired but were denied by a risk/account gate. Empty list = no signal fired OR the signal converted to an order. Non-empty with new_orders empty = the strategy IS firing and being blocked.","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"error":{"description":"Error category on failure (e.g. validation_error, internal_error)","type":"string"},"execution_state":{"allOf":[{"$ref":"#/components/schemas/api1.ExecutionState"}],"description":"Strategy execution state"},"execution_time_seconds":{"description":"Time taken to complete evaluation","type":"number"},"market_data_venue":{"description":"Recorded market data venue","type":"string"},"message":{"description":"Human-readable error message (error responses)","type":"string"},"new_orders":{"description":"Orders generated or triggered during evaluation","items":{"$ref":"#/components/schemas/api1.OrderResponse"},"type":"array"},"open_positions":{"description":"Authoritative caller-owned open book; proposals do not create or close positions","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"org_id":{"description":"Organization UUID","type":"string"},"proposed_closes":{"description":"Unconfirmed exit estimates; never booked risk facts","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"proposed_positions":{"description":"Unconfirmed new-entry templates, including bracket identities; only the executor books a fill","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"quote_token":{"description":"Recorded market quote token","type":"string"},"retry_after":{"description":"Seconds to wait before retry (rate-limit/unavailable errors)","type":"integer"},"strategy_id":{"description":"Strategy UUID","type":"string"},"strategy_name":{"description":"Strategy name","type":"string"},"success":{"description":"Whether evaluation succeeded","type":"boolean"},"timestamp":{"description":"Evaluation timestamp (ISO format)","type":"string"},"user_id":{"description":"User UUID","type":"string"},"v3":{"allOf":[{"$ref":"#/components/schemas/api1.V3State"}],"description":"Balances, availability and core phase after this evaluation (position_size_calc 'v3')"}},"type":"object"},"api1.EvaluateSignalRequest":{"properties":{"market_data":{"items":{"$ref":"#/components/schemas/api1.MarketDataBar"},"type":"array"},"parameters":{"default":{},"type":"object","x-mangrove-raw-json":true}},"required":["market_data"],"type":"object"},"api1.ExchangeListResponse":{"properties":{"count":{"type":"integer"},"exchanges":{"items":{"$ref":"#/components/schemas/api1.ExchangeSummary"},"type":"array"},"success":{"type":"boolean"}},"type":"object"},"api1.ExchangeListing":{"properties":{"country":{"description":"Country of registration. Null if unknown.","type":"string"},"display_name":{"description":"Human-facing exchange name. Null if unset.","type":"string"},"exchange_id":{"description":"Exchange slug (e.g. binance)","type":"string"},"exchange_type":{"description":"centralized or decentralized","type":"string"},"id":{"description":"Exchange row ID (UUID)","type":"string"},"is_active":{"description":"Whether the exchange is currently tracked","type":"boolean"},"name":{"description":"Exchange name","type":"string"},"region":{"description":"Region. Null if unknown.","type":"string"},"tier":{"description":"Exchange tier (1 = highest)","type":"integer"}},"type":"object"},"api1.ExchangeSummary":{"properties":{"country":{"description":"Country of registration. Null if unknown.","type":"string"},"exchange_id":{"description":"Exchange slug (e.g. binance)","type":"string"},"exchange_type":{"description":"centralized, decentralized, or unknown","type":"string"},"is_active":{"description":"Whether the exchange is currently tracked","type":"boolean"},"name":{"description":"Exchange name","type":"string"},"region":{"description":"Region. Null if unknown.","type":"string"},"tier":{"description":"Exchange tier (1 = highest)","type":"integer"},"volume_24h_usd":{"description":"24-hour exchange volume (USD). Null if not tracked.","type":"number"}},"type":"object"},"api1.ExecutionConfigSchemaResponse":{"properties":{"defaults":{"allOf":[{"$ref":"#/components/schemas/api1.ExecutionConfiguration"}],"description":"Current canonical default values"},"json_schema":{"additionalProperties":true,"description":"Draft 2020-12 normalized authoring schema; boundary coercion remains separate","type":"object"},"param_glossary":{"additionalProperties":true,"description":"Canonical parameter metadata and bounds","type":"object"},"percent_scale_note":{"type":"string"},"transaction_costs":{"$ref":"#/components/schemas/api1.ExecutionConfigTransactionCosts"}},"type":"object"},"api1.ExecutionConfigTransactionCosts":{"properties":{"fee_pct":{"type":"number"},"per_strategy":{"type":"boolean"},"slippage_pct":{"type":"number"},"source":{"type":"string"}},"type":"object"},"api1.ExecutionConfiguration":{"additionalProperties":true,"description":"Execution config accepts legacy/unknown fields and server-side numeric coercion. The attached authoring schema describes normalized values, not an additional input gate.","properties":{"atr_cap_multiplier":{"description":"SUPERSEDED by volatility_tolerance. Bounded the weighted blend at this multiple of the SHORT ATR.","x-mangrove-authoring-schema":{"description":"SUPERSEDED by volatility_tolerance. Bounded the weighted blend at this multiple of the SHORT ATR.","minimum":1.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy this is what made the weight pair inert past a long weight of roughly 6-12% (#1052).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"}},"atr_long_weight":{"description":"SUPERSEDED by volatility_tolerance. Weight of the daily ATR in the weighted-blend stop model, and always 1 - atr_short_weight rather than independent.","x-mangrove-authoring-schema":{"description":"SUPERSEDED by volatility_tolerance. Weight of the daily ATR in the weighted-blend stop model, and always 1 - atr_short_weight rather than independent.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. Derived, never independently effective.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"}},"atr_period":{"description":"ATR lookback in bars (default 14) used to measure volatility for stop sizing.","x-mangrove-authoring-schema":{"default":14,"description":"ATR lookback in bars (default 14) used to measure volatility for stop sizing.","maximum":1000,"minimum":5,"type":["integer","null"],"x-mangrove-effect":"Higher smooths the volatility estimate (steadier, slower-reacting stops). Lower reacts faster to recent volatility (choppier stops).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"atr_short_weight":{"description":"SUPERSEDED by volatility_tolerance. Weight of the signal-timeframe ATR in the weighted-blend stop model. Readable on a strategy created under that model; refused on any write.","x-mangrove-authoring-schema":{"description":"SUPERSEDED by volatility_tolerance. Weight of the signal-timeframe ATR in the weighted-blend stop model. Readable on a strategy created under that model; refused on any write.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy, higher favours the signal timeframe's own volatility -- though the cap made settings past a few percent of long weight indistinguishable (#1052).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"}},"atr_volatility_factor":{"description":"SUPERSEDED by volatility_tolerance. Multiplied the blended ATR to give the stop distance. The dial's two endpoint factors carry this instead, one at each end of the width.","x-mangrove-authoring-schema":{"description":"SUPERSEDED by volatility_tolerance. Multiplied the blended ATR to give the stop distance. The dial's two endpoint factors carry this instead, one at each end of the width.","exclusiveMinimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy, higher widens the stop and shrinks the position for the same risk.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"}},"circuit_breaker":{"description":"Parameters for cooldown_model 'trades': pause on consecutive net losses or accumulated loss amount, pause on marked drawdown from the peak (including unrealized changes), resume new alpha positions at a reduced size, and stop after consecutive pauses. Canon defaults are 36 primary bars for a loss pause, 72 for a drawdown pause, and three strikes for a permanent halt. Pause counts are clamped to 24 hours through 14 days by default. max_drawdown_halt_limit separately stops entries on realized loss of cumulative gross deposits. Existing exits remain active during holds.","x-mangrove-authoring-schema":{"additionalProperties":false,"default":{"consecutive_loss_limit":2,"drawdown_pause_bars":72,"loss_amount_pct":0.06,"max_consecutive_pauses":3,"pause_bars":36,"pause_max_days":14,"pause_min_hours":24,"resume_size_fraction":0.5,"resume_trades":3},"description":"Parameters for cooldown_model 'trades': pause on consecutive net losses or accumulated loss amount, pause on marked drawdown from the peak (including unrealized changes), resume new alpha positions at a reduced size, and stop after consecutive pauses. Canon defaults are 36 primary bars for a loss pause, 72 for a drawdown pause, and three strikes for a permanent halt. Pause counts are clamped to 24 hours through 14 days by default. max_drawdown_halt_limit separately stops entries on realized loss of cumulative gross deposits. Existing exits remain active during holds.","properties":{"consecutive_loss_limit":{"default":2,"description":"Consecutive losing closes on an asset that start a pause. A winning close resets the count.","maximum":100,"minimum":1,"type":"integer","x-mangrove-effect":"Lower pauses sooner after a losing run; higher tolerates longer runs.","x-mangrove-status":"tunable"},"drawdown_pause_bars":{"default":72,"description":"Primary-timeframe bars denying entries after a drawdown pause (canon default 72). At drawdown-pause expiry the peak re-baselines to current account value. An alpha resume window opens only once no pause remains and no permanent halt is latched. The count is raised to cover pause_min_hours and lowered to fit pause_max_days (24 hours through 14 days by default).","maximum":8760,"minimum":1,"type":"integer","x-mangrove-effect":"Longer holds the pause longer before trading can resume.","x-mangrove-status":"tunable"},"loss_amount_pct":{"default":0.06,"description":"Accumulated net losses as a fraction of the closed-equity reset baseline that start a loss pause. A winning close clears the accumulation and resets the baseline. An asset loss pause clears it at the start and re-baselines at expiry; a global drawdown pause does not itself reset it.","exclusiveMinimum":0.0,"maximum":1.0,"type":"number","x-mangrove-effect":"Lower pauses after smaller cumulative losses; higher tolerates larger ones.","x-mangrove-status":"tunable"},"max_consecutive_pauses":{"default":3,"description":"Strikes that stop the strategy until a manual restart. A strike is one pause started, of any kind (consecutive losses, loss amount, drawdown, a resume window that lost money). Strikes reset to 0 only on a new equity high: a close that leaves closed equity above the high-water mark the strategy had when the first strike of the run was recorded. A winning close below that mark does not reset them, and a deposit or withdrawal does not count as a high.","maximum":100,"minimum":1,"type":"integer","x-mangrove-effect":"Lower stops the strategy sooner; higher tolerates more repeated pauses.","x-mangrove-status":"tunable"},"pause_bars":{"default":36,"description":"Primary-timeframe bars denying entries after a loss pause (canon default 36). The count is raised to cover pause_min_hours and lowered to fit pause_max_days on that timeframe (24 hours through 14 days by default).","maximum":8760,"minimum":1,"type":"integer","x-mangrove-effect":"Longer sits out more of a bad regime; shorter resumes sooner.","x-mangrove-status":"tunable"},"pause_max_days":{"default":14,"description":"A pause lasts at most this many days on every timeframe: the bar count is lowered to fit it.","exclusiveMinimum":0.0,"maximum":365,"type":"number","x-mangrove-effect":"Lower ends every pause sooner on long timeframes; higher leaves the bar count to decide.","x-mangrove-status":"tunable"},"pause_min_hours":{"default":24,"description":"A pause lasts at least this many hours on every timeframe: the bar count of pause_bars or drawdown_pause_bars is raised to cover it.","exclusiveMinimum":0.0,"maximum":336,"type":"number","x-mangrove-effect":"Higher makes every pause at least that long on short timeframes; lower leaves the bar count to decide.","x-mangrove-status":"tunable"},"resume_size_fraction":{"default":0.5,"description":"Fraction of normal size for new alpha positions while a resume window is open (canon default 0.5). Eligible confirmed position closes count toward resume_trades; a negative net result starts another loss pause and strike, while zero or a profit restores full alpha size. Core orders keep their normal allocation quantities after pause expiry: they are not positions and do not consume resume-trade counts. 1.0 disables the alpha size reduction.","exclusiveMinimum":0.0,"maximum":1.0,"type":"number","x-mangrove-effect":"Lower risks less while the strategy proves itself again after a pause; higher resumes closer to full size.","x-mangrove-status":"tunable"},"resume_trades":{"default":3,"description":"Eligible confirmed position closes booked in a resume window (canon default three). When the window completes, a negative net realized result starts a new loss pause and strike; zero or a profit restores full alpha size. A pause cancels the active window; a new one opens only once no pause remains and no permanent halt is latched. Core orders do not count as position closes.","maximum":50,"minimum":1,"type":"integer","x-mangrove-effect":"Higher judges the resumed strategy over more trades before full size returns; lower decides sooner.","x-mangrove-status":"tunable"}},"type":["object","null"],"x-mangrove-effect":"Tighter limits pause and stop sooner; looser limits keep trading through losing runs.","x-mangrove-status":"guardrail"}},"cooldown_model":{"description":"Loss-streak breaker model. 'bars' counts losing closes inside rolling windows of the primary timeframe (cooldown_config). 'trades' counts consecutive losing closes and realized loss amount, pauses for circuit_breaker bars of the primary timeframe (at least pause_min_hours and at most pause_max_days), and stops after repeated pauses (circuit_breaker). An absent model adopts the canonical 'trades' defaults; explicit 'bars' retains the legacy model.","x-mangrove-authoring-schema":{"default":"trades","description":"Loss-streak breaker model. 'bars' counts losing closes inside rolling windows of the primary timeframe (cooldown_config). 'trades' counts consecutive losing closes and realized loss amount, pauses for circuit_breaker bars of the primary timeframe (at least pause_min_hours and at most pause_max_days), and stops after repeated pauses (circuit_breaker). An absent model adopts the canonical 'trades' defaults; explicit 'bars' retains the legacy model.","enum":["bars","trades",null],"type":["string","null"],"x-mangrove-effect":"'trades' trips on trade count and loss size regardless of how far apart trades are spaced; 'bars' trips only when losses land inside the window. cooldown_config, cooldown_bars, daily_momentum_limit and weekly_momentum_limit are read only under 'bars': they are left out of a resolved config under 'trades', and a config that carries them under 'trades' has them dropped.","x-mangrove-status":"guardrail"}},"enable_volatility_adjustment":{"description":"Toggles volatility-based position scaling (default false).","x-mangrove-authoring-schema":{"default":false,"description":"Toggles volatility-based position scaling (default false).","type":["boolean","null"],"x-mangrove-effect":"When true, positions are scaled down by target_volatility / (atr/entry) if ATR%% exceeds target; only reduces size, never increases.","x-mangrove-status":"gated"}},"exit_on_loss_after_bars":{"description":"Exit a losing position after this many bars.","x-mangrove-authoring-schema":{"default":1000,"description":"Exit a losing position after this many bars.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Lower cuts losers sooner; higher gives them more time to recover.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"exit_on_profit_after_bars":{"description":"Exit a winning position after this many bars.","x-mangrove-authoring-schema":{"default":1000,"description":"Exit a winning position after this many bars.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Lower banks winners sooner; higher lets them run.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"initial_balance":{"description":"Starting balance for the backtest/simulation (default $10,000).","x-mangrove-authoring-schema":{"default":10000,"description":"Starting balance for the backtest/simulation (default $10,000).","maximum":1000000000.0,"minimum":25.0,"type":["number","null"],"x-mangrove-effect":"Scales absolute dollar figures; not a strategy-character knob.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"max_drawdown_halt_limit":{"description":"Permanent capital-floor entry halt (0.20 = 20%). Closed, realized equity is compared with cumulative gross deposits (execution_state.cumulative_deposits), not a rolling peak or the signed net-funding balance; withdrawals do not reduce this reference. Legacy requests without cumulative_deposits use execution_config.initial_balance. The shared live/paper evaluator checks before each bar and latches execution_state.halt. New alpha entries and v3 core allocations are denied, while authoritative positions retain protective exits and exits_pending until physically flat. Engine-owned strategies become inactive only after that book is flat; caller-owned executors retain their exit monitor. An explicit manual restart is required to clear the latch. Backtests enforce the same floor when evaluate_bar receives enforce_capital_floor=True, managing open-position exits through the final bar. Applies to both cooldown models; null disables new floor trips, while an existing halt remains latched.","x-mangrove-authoring-schema":{"default":0.2,"description":"Permanent capital-floor entry halt (0.20 = 20%). Closed, realized equity is compared with cumulative gross deposits (execution_state.cumulative_deposits), not a rolling peak or the signed net-funding balance; withdrawals do not reduce this reference. Legacy requests without cumulative_deposits use execution_config.initial_balance. The shared live/paper evaluator checks before each bar and latches execution_state.halt. New alpha entries and v3 core allocations are denied, while authoritative positions retain protective exits and exits_pending until physically flat. Engine-owned strategies become inactive only after that book is flat; caller-owned executors retain their exit monitor. An explicit manual restart is required to clear the latch. Backtests enforce the same floor when evaluate_bar receives enforce_capital_floor=True, managing open-position exits through the final bar. Applies to both cooldown models; null disables new floor trips, while an existing halt remains latched.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Lower protects more of gross deposited capital before a permanent entry halt; higher tolerates a deeper realized loss. This does not resize positions or stop protective exit evaluation. Do not add a separate floor where the shared evaluator enforces it.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"max_drawdown_limit":{"description":"Peak-relative entry pause (0.20 = 20%). The canonical 'trades' model measures marked equity against its high-water mark. A breach starts one drawdown pause and strike; circuit_breaker.drawdown_pause_bars defaults to 72 primary bars, clamped to pause_min_hours and pause_max_days (24 hours and 14 days by default). At drawdown-pause expiry the peak re-baselines; a reduced-size alpha resume window opens only once no pause remains and no permanent halt is latched. Explicit 'bars' retains the legacy closed-equity measurement and per-timeframe long cooldown. Both models deny new entries while allowing existing positions to exit; automatic v3 core allocations honor the hold too. null disables new drawdown trips.","x-mangrove-authoring-schema":{"default":0.2,"description":"Peak-relative entry pause (0.20 = 20%). The canonical 'trades' model measures marked equity against its high-water mark. A breach starts one drawdown pause and strike; circuit_breaker.drawdown_pause_bars defaults to 72 primary bars, clamped to pause_min_hours and pause_max_days (24 hours and 14 days by default). At drawdown-pause expiry the peak re-baselines; a reduced-size alpha resume window opens only once no pause remains and no permanent halt is latched. Explicit 'bars' retains the legacy closed-equity measurement and per-timeframe long cooldown. Both models deny new entries while allowing existing positions to exit; automatic v3 core allocations honor the hold too. null disables new drawdown trips.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Lower pauses entries after a smaller drawdown; higher tolerates a deeper drawdown. The shared entry breaker enforces this in single/bulk live and paper evaluation, v3 core allocation and backtests built with risk_manager_from_execution_config. Alpha resume sizing is a separate control; do not add a second drawdown stop.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"max_hold_bars":{"description":"Maximum bars to hold any position before a forced exit.","x-mangrove-authoring-schema":{"default":1000,"description":"Maximum bars to hold any position before a forced exit.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher lets trades run longer; lower forces earlier time-based exits.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"max_hold_time_hours":{"description":"Maximum position hold time in hours (null = no limit).","x-mangrove-authoring-schema":{"default":null,"description":"Maximum position hold time in hours (null = no limit).","exclusiveMinimum":1,"maximum":8760,"type":["integer","null"],"x-mangrove-effect":"Lower forces earlier time-based exits; null/higher lets trades run indefinitely on time.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"max_open_positions":{"description":"Maximum concurrent open positions.","x-mangrove-authoring-schema":{"default":10,"description":"Maximum concurrent open positions.","maximum":1000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher allows more simultaneous exposure (more diversification but more aggregate risk); lower is more selective with less aggregate exposure.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"max_risk_per_trade":{"description":"Fraction of account equity risked per trade (0.01 = 1%). Position size is derived from this and the stop distance.","x-mangrove-authoring-schema":{"default":0.01,"description":"Fraction of account equity risked per trade (0.01 = 1%). Position size is derived from this and the stop distance.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Higher risks more per trade: bigger positions, larger gains AND larger drawdowns. Lower is more conservative: smaller positions, smaller swings.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"max_trade_amount":{"description":"Absolute cap on dollar size per trade.","x-mangrove-authoring-schema":{"default":10000000,"description":"Absolute cap on dollar size per trade.","exclusiveMinimum":0.0,"maximum":1000000000000.0,"type":["number","null"],"x-mangrove-effect":"Size guardrail; rarely binding.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"max_trades_per_day":{"description":"Daily trade cap.","x-mangrove-authoring-schema":{"default":50,"description":"Daily trade cap.","maximum":1440,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher permits more churn; lower throttles activity.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"max_units_per_trade":{"description":"Absolute cap on units per trade.","x-mangrove-authoring-schema":{"default":1000000,"description":"Absolute cap on units per trade.","exclusiveMinimum":0.0,"maximum":1000000000000.0,"type":["number","null"],"x-mangrove-effect":"Size guardrail; rarely binding.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"min_asset_balance":{"description":"position_size_calc 'v3' only. Minimum asset balance, in asset units, the strategy holds outside open trades.","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Minimum asset balance, in asset units, the strategy holds outside open trades.","minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more of the asset out of reach of sell trades and core sells, and takes more cash to reach; lower frees more of the asset for trading.","x-mangrove-status":"guardrail"}},"min_balance_days":{"description":"position_size_calc 'v3' only. Number of equal daily orders used to bring a side up to its minimum balance.","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Number of equal daily orders used to bring a side up to its minimum balance.","minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher spreads the minimum-balance orders over more days at smaller size; lower reaches the minimum sooner with larger orders.","x-mangrove-status":"guardrail"}},"min_balance_threshold":{"description":"Cash reserve fraction held back from new entries (0.1 = 10%). v1 reserves this fraction of cash; v2 reserves this fraction of account value (cash + open positions at market). An entry may only use cash above the reserve; when no cash is deployable the entry is denied (insufficient_cash / insufficient_cash_v2_account_reserve). It never halts the strategy and never closes positions.","x-mangrove-authoring-schema":{"default":0.1,"description":"Cash reserve fraction held back from new entries (0.1 = 10%). v1 reserves this fraction of cash; v2 reserves this fraction of account value (cash + open positions at market). An entry may only use cash above the reserve; when no cash is deployable the entry is denied (insufficient_cash / insufficient_cash_v2_account_reserve). It never halts the strategy and never closes positions.","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more cash idle and makes entries smaller or rarer as the account shrinks; lower lets entries use more of the balance. Not a drawdown stop; see max_drawdown_limit and max_drawdown_halt_limit.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"min_cash_balance":{"description":"position_size_calc 'v3' only. Minimum cash balance the strategy holds after the worst-case loss of every open trade.","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Minimum cash balance the strategy holds after the worst-case loss of every open trade.","minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more cash out of reach of buy trades and core buys, so entries are smaller or rarer; lower frees more cash for trading.","x-mangrove-status":"guardrail"}},"min_stop_distance_pct":{"description":"Hard floor on stop distance as a fraction of entry price (crypto minimum), applied after ATR sizing.","x-mangrove-authoring-schema":{"default":0.005,"description":"Hard floor on stop distance as a fraction of entry price (crypto minimum), applied after ATR sizing.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher enforces a wider minimum stop; lower allows tighter stops down to the floor.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"min_trade_amount":{"description":"Minimum trade size in dollars; smaller intended trades are skipped.","x-mangrove-authoring-schema":{"default":25,"description":"Minimum trade size in dollars; smaller intended trades are skipped.","maximum":1000000.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher skips more small signals; lower allows smaller trades.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"position_size_calc":{"description":"Sizing-engine version ('v1', 'v2' or 'v3'). Pinned at creation and immutable. 'v3' holds an asset balance and a cash balance, sizes against equity net of open risk, and requires the position_size_calc 'v3' parameters.","x-mangrove-authoring-schema":{"default":"v2","description":"Sizing-engine version ('v1', 'v2' or 'v3'). Pinned at creation and immutable. 'v3' holds an asset balance and a cash balance, sizes against equity net of open risk, and requires the position_size_calc 'v3' parameters.","enum":["v1","v2","v3",null],"type":["string","null"],"x-mangrove-effect":"Not a magnitude knob; selects the sizing algorithm. Do not change on an existing strategy.","x-mangrove-status":"guardrail"}},"profit_threshold_pct":{"description":"Profit threshold (5%% default) above which a position counts as 'winning' for the time-based exit logic.","x-mangrove-authoring-schema":{"default":0.05,"description":"Profit threshold (5%% default) above which a position counts as 'winning' for the time-based exit logic.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher requires a larger gain before a position is treated as winning; lower treats smaller gains as wins.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"rebalance_band":{"description":"position_size_calc 'v3' only. Absolute deviation of the asset weight from target_asset_weight that triggers a rebalance order (0.05 = 5 points).","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Absolute deviation of the asset weight from target_asset_weight that triggers a rebalance order (0.05 = 5 points).","exclusiveMaximum":1.0,"exclusiveMinimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher lets the split drift further before a rebalance order, so fewer core orders; lower holds the split closer to target with more core orders and more fees.","x-mangrove-status":"tunable"}},"reward_factor":{"description":"Risk/reward target. Take-profit distance = reward_factor * stop_distance.","x-mangrove-authoring-schema":{"default":2,"description":"Risk/reward target. Take-profit distance = reward_factor * stop_distance.","exclusiveMinimum":0.0,"maximum":100.0,"type":["number","null"],"x-mangrove-effect":"Higher sets a wider profit target: lower win rate but bigger wins. Lower sets a tighter target: higher win rate but smaller wins.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"stop_gap_allowance":{"description":"position_size_calc 'v3' only. Fraction of the stop price a stop fill is assumed to miss by when computing the worst-case loss of a trade (0.01 = 1%).","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Fraction of the stop price a stop fill is assumed to miss by when computing the worst-case loss of a trade (0.01 = 1%).","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher counts more risk per open trade, leaving less available cash and smaller positions; lower counts less.","x-mangrove-status":"guardrail"}},"stop_model":{"description":"Which stop model the strategy uses: 'atr_width_dial' (one parameter, volatility_tolerance, positioned on the ATR width) or 'weighted_atr' (superseded: a weighted blend of two ATRs, capped). Pinned at creation and immutable.","x-mangrove-authoring-schema":{"default":"atr_width_dial","description":"Which stop model the strategy uses: 'atr_width_dial' (one parameter, volatility_tolerance, positioned on the ATR width) or 'weighted_atr' (superseded: a weighted blend of two ATRs, capped). Pinned at creation and immutable.","enum":["atr_width_dial","weighted_atr",null],"type":["string","null"],"x-mangrove-effect":"Not a magnitude knob; selects the stop algorithm. Do not change on an existing strategy -- it would move every stop the strategy takes.","x-mangrove-status":"guardrail"}},"taker_fee_rate":{"description":"position_size_calc 'v3' only. Venue fee per fill as a fraction of notional, charged in cash (0.004 = 0.4%).","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Venue fee per fill as a fraction of notional, charged in cash (0.004 = 0.4%).","exclusiveMaximum":0.1,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher counts more cost per fill, raising the risk of each trade and lowering available cash. Models the venue; not a strategy-character knob.","x-mangrove-status":"guardrail"}},"target_asset_weight":{"description":"position_size_calc 'v3' only. Target share of core value held in the asset (0.8 = 80% asset, 20% cash; 0 = all cash).","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Target share of core value held in the asset (0.8 = 80% asset, 20% cash; 0 = all cash).","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher holds more of the asset and less cash; lower holds more cash. The daily core order moves the split back to this value once it drifts past rebalance_band. At 0 with no asset held, no core order is placed and only buy trades can pass.","x-mangrove-status":"tunable"}},"target_volatility":{"description":"Target volatility (0.10 = 10%). ONLY active when enable_volatility_adjustment is true (default false). When active, scales position size down if ATR%% of entry exceeds the target (never up).","x-mangrove-authoring-schema":{"default":0.1,"description":"Target volatility (0.10 = 10%). ONLY active when enable_volatility_adjustment is true (default false). When active, scales position size down if ATR%% of entry exceeds the target (never up).","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"With the gate off (the default), changing this has no effect. With it on, lower scales positions down more aggressively in high volatility.","x-mangrove-gate-field":"enable_volatility_adjustment","x-mangrove-gate-required":true,"x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"gated"}},"volatility_mode":{"description":"Unused (retained for backward compatibility). Volatility is derived from ATR.","x-mangrove-authoring-schema":{"default":"stddev","description":"Unused (retained for backward compatibility). Volatility is derived from ATR.","enum":["stddev","atr",null],"type":["string","null"],"x-mangrove-effect":"No runtime effect. Do not tune.","x-mangrove-status":"unused"}},"volatility_tolerance":{"description":"Where on the ATR width the stop is taken, as the ATR_long-vs-ATR_short contribution ratio: 0 is all short end (0.5x the signal timeframe's ATR), 1 is all long end (2x the daily ATR). Interpolated geometrically, so the value is exactly the long end's share of log(stop) and each 0.1 is the same multiplicative step. Replaces atr_short_weight, atr_long_weight and atr_cap_multiplier.","x-mangrove-authoring-schema":{"default":0.5,"description":"Where on the ATR width the stop is taken, as the ATR_long-vs-ATR_short contribution ratio: 0 is all short end (0.5x the signal timeframe's ATR), 1 is all long end (2x the daily ATR). Interpolated geometrically, so the value is exactly the long end's share of log(stop) and each 0.1 is the same multiplicative step. Replaces atr_short_weight, atr_long_weight and atr_cap_multiplier.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher widens the stop, and because position size is the risk budget divided by the stop distance, exposure shrinks in exact inverse proportion at the SAME risk. Low means many units with little room to be wrong and frequent stop-outs; high means few units that are hard to shake out but need a much larger move to reach the same reward. Both risk max_risk_per_trade.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"volatility_window":{"description":"Unused (retained for backward compatibility). ATR windowing is controlled by atr_period.","x-mangrove-authoring-schema":{"default":24,"description":"Unused (retained for backward compatibility). ATR windowing is controlled by atr_period.","maximum":1000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"No runtime effect. Do not tune.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"unused"}}},"type":"object","x-mangrove-authoring-schema":{"$id":"urn:mangrove:execution-config:1","$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":true,"description":"Canonical authoring representation derived from server metadata and defaults. Top-level optional keys may be omitted or null. The existing HTTP validator separately coerces top-level numeric strings, enforces their declared bounds and permits unknown/legacy fields; it does not enforce this whole nested schema. Runtime strategy/version/timeframe checks remain authoritative. Cooldown durations may be omitted by legacy configs and then fall back to their corresponding windows.","properties":{"atr_cap_multiplier":{"description":"SUPERSEDED by volatility_tolerance. Bounded the weighted blend at this multiple of the SHORT ATR.","minimum":1.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy this is what made the weight pair inert past a long weight of roughly 6-12% (#1052).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"},"atr_long_weight":{"description":"SUPERSEDED by volatility_tolerance. Weight of the daily ATR in the weighted-blend stop model, and always 1 - atr_short_weight rather than independent.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. Derived, never independently effective.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"},"atr_period":{"default":14,"description":"ATR lookback in bars (default 14) used to measure volatility for stop sizing.","maximum":1000,"minimum":5,"type":["integer","null"],"x-mangrove-effect":"Higher smooths the volatility estimate (steadier, slower-reacting stops). Lower reacts faster to recent volatility (choppier stops).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"atr_short_weight":{"description":"SUPERSEDED by volatility_tolerance. Weight of the signal-timeframe ATR in the weighted-blend stop model. Readable on a strategy created under that model; refused on any write.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy, higher favours the signal timeframe's own volatility -- though the cap made settings past a few percent of long weight indistinguishable (#1052).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"},"atr_volatility_factor":{"description":"SUPERSEDED by volatility_tolerance. Multiplied the blended ATR to give the stop distance. The dial's two endpoint factors carry this instead, one at each end of the width.","exclusiveMinimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy, higher widens the stop and shrinks the position for the same risk.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"},"circuit_breaker":{"additionalProperties":false,"default":{"consecutive_loss_limit":2,"drawdown_pause_bars":72,"loss_amount_pct":0.06,"max_consecutive_pauses":3,"pause_bars":36,"pause_max_days":14,"pause_min_hours":24,"resume_size_fraction":0.5,"resume_trades":3},"description":"Parameters for cooldown_model 'trades': pause on consecutive net losses or accumulated loss amount, pause on marked drawdown from the peak (including unrealized changes), resume new alpha positions at a reduced size, and stop after consecutive pauses. Canon defaults are 36 primary bars for a loss pause, 72 for a drawdown pause, and three strikes for a permanent halt. Pause counts are clamped to 24 hours through 14 days by default. max_drawdown_halt_limit separately stops entries on realized loss of cumulative gross deposits. Existing exits remain active during holds.","properties":{"consecutive_loss_limit":{"default":2,"description":"Consecutive losing closes on an asset that start a pause. A winning close resets the count.","maximum":100,"minimum":1,"type":"integer","x-mangrove-effect":"Lower pauses sooner after a losing run; higher tolerates longer runs.","x-mangrove-status":"tunable"},"drawdown_pause_bars":{"default":72,"description":"Primary-timeframe bars denying entries after a drawdown pause (canon default 72). At drawdown-pause expiry the peak re-baselines to current account value. An alpha resume window opens only once no pause remains and no permanent halt is latched. The count is raised to cover pause_min_hours and lowered to fit pause_max_days (24 hours through 14 days by default).","maximum":8760,"minimum":1,"type":"integer","x-mangrove-effect":"Longer holds the pause longer before trading can resume.","x-mangrove-status":"tunable"},"loss_amount_pct":{"default":0.06,"description":"Accumulated net losses as a fraction of the closed-equity reset baseline that start a loss pause. A winning close clears the accumulation and resets the baseline. An asset loss pause clears it at the start and re-baselines at expiry; a global drawdown pause does not itself reset it.","exclusiveMinimum":0.0,"maximum":1.0,"type":"number","x-mangrove-effect":"Lower pauses after smaller cumulative losses; higher tolerates larger ones.","x-mangrove-status":"tunable"},"max_consecutive_pauses":{"default":3,"description":"Strikes that stop the strategy until a manual restart. A strike is one pause started, of any kind (consecutive losses, loss amount, drawdown, a resume window that lost money). Strikes reset to 0 only on a new equity high: a close that leaves closed equity above the high-water mark the strategy had when the first strike of the run was recorded. A winning close below that mark does not reset them, and a deposit or withdrawal does not count as a high.","maximum":100,"minimum":1,"type":"integer","x-mangrove-effect":"Lower stops the strategy sooner; higher tolerates more repeated pauses.","x-mangrove-status":"tunable"},"pause_bars":{"default":36,"description":"Primary-timeframe bars denying entries after a loss pause (canon default 36). The count is raised to cover pause_min_hours and lowered to fit pause_max_days on that timeframe (24 hours through 14 days by default).","maximum":8760,"minimum":1,"type":"integer","x-mangrove-effect":"Longer sits out more of a bad regime; shorter resumes sooner.","x-mangrove-status":"tunable"},"pause_max_days":{"default":14,"description":"A pause lasts at most this many days on every timeframe: the bar count is lowered to fit it.","exclusiveMinimum":0.0,"maximum":365,"type":"number","x-mangrove-effect":"Lower ends every pause sooner on long timeframes; higher leaves the bar count to decide.","x-mangrove-status":"tunable"},"pause_min_hours":{"default":24,"description":"A pause lasts at least this many hours on every timeframe: the bar count of pause_bars or drawdown_pause_bars is raised to cover it.","exclusiveMinimum":0.0,"maximum":336,"type":"number","x-mangrove-effect":"Higher makes every pause at least that long on short timeframes; lower leaves the bar count to decide.","x-mangrove-status":"tunable"},"resume_size_fraction":{"default":0.5,"description":"Fraction of normal size for new alpha positions while a resume window is open (canon default 0.5). Eligible confirmed position closes count toward resume_trades; a negative net result starts another loss pause and strike, while zero or a profit restores full alpha size. Core orders keep their normal allocation quantities after pause expiry: they are not positions and do not consume resume-trade counts. 1.0 disables the alpha size reduction.","exclusiveMinimum":0.0,"maximum":1.0,"type":"number","x-mangrove-effect":"Lower risks less while the strategy proves itself again after a pause; higher resumes closer to full size.","x-mangrove-status":"tunable"},"resume_trades":{"default":3,"description":"Eligible confirmed position closes booked in a resume window (canon default three). When the window completes, a negative net realized result starts a new loss pause and strike; zero or a profit restores full alpha size. A pause cancels the active window; a new one opens only once no pause remains and no permanent halt is latched. Core orders do not count as position closes.","maximum":50,"minimum":1,"type":"integer","x-mangrove-effect":"Higher judges the resumed strategy over more trades before full size returns; lower decides sooner.","x-mangrove-status":"tunable"}},"type":["object","null"],"x-mangrove-effect":"Tighter limits pause and stop sooner; looser limits keep trading through losing runs.","x-mangrove-status":"guardrail"},"cooldown_model":{"default":"trades","description":"Loss-streak breaker model. 'bars' counts losing closes inside rolling windows of the primary timeframe (cooldown_config). 'trades' counts consecutive losing closes and realized loss amount, pauses for circuit_breaker bars of the primary timeframe (at least pause_min_hours and at most pause_max_days), and stops after repeated pauses (circuit_breaker). An absent model adopts the canonical 'trades' defaults; explicit 'bars' retains the legacy model.","enum":["bars","trades",null],"type":["string","null"],"x-mangrove-effect":"'trades' trips on trade count and loss size regardless of how far apart trades are spaced; 'bars' trips only when losses land inside the window. cooldown_config, cooldown_bars, daily_momentum_limit and weekly_momentum_limit are read only under 'bars': they are left out of a resolved config under 'trades', and a config that carries them under 'trades' has them dropped.","x-mangrove-status":"guardrail"},"enable_volatility_adjustment":{"default":false,"description":"Toggles volatility-based position scaling (default false).","type":["boolean","null"],"x-mangrove-effect":"When true, positions are scaled down by target_volatility / (atr/entry) if ATR%% exceeds target; only reduces size, never increases.","x-mangrove-status":"gated"},"exit_on_loss_after_bars":{"default":1000,"description":"Exit a losing position after this many bars.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Lower cuts losers sooner; higher gives them more time to recover.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"exit_on_profit_after_bars":{"default":1000,"description":"Exit a winning position after this many bars.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Lower banks winners sooner; higher lets them run.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"initial_balance":{"default":10000,"description":"Starting balance for the backtest/simulation (default $10,000).","maximum":1000000000.0,"minimum":25.0,"type":["number","null"],"x-mangrove-effect":"Scales absolute dollar figures; not a strategy-character knob.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"max_drawdown_halt_limit":{"default":0.2,"description":"Permanent capital-floor entry halt (0.20 = 20%). Closed, realized equity is compared with cumulative gross deposits (execution_state.cumulative_deposits), not a rolling peak or the signed net-funding balance; withdrawals do not reduce this reference. Legacy requests without cumulative_deposits use execution_config.initial_balance. The shared live/paper evaluator checks before each bar and latches execution_state.halt. New alpha entries and v3 core allocations are denied, while authoritative positions retain protective exits and exits_pending until physically flat. Engine-owned strategies become inactive only after that book is flat; caller-owned executors retain their exit monitor. An explicit manual restart is required to clear the latch. Backtests enforce the same floor when evaluate_bar receives enforce_capital_floor=True, managing open-position exits through the final bar. Applies to both cooldown models; null disables new floor trips, while an existing halt remains latched.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Lower protects more of gross deposited capital before a permanent entry halt; higher tolerates a deeper realized loss. This does not resize positions or stop protective exit evaluation. Do not add a separate floor where the shared evaluator enforces it.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"max_drawdown_limit":{"default":0.2,"description":"Peak-relative entry pause (0.20 = 20%). The canonical 'trades' model measures marked equity against its high-water mark. A breach starts one drawdown pause and strike; circuit_breaker.drawdown_pause_bars defaults to 72 primary bars, clamped to pause_min_hours and pause_max_days (24 hours and 14 days by default). At drawdown-pause expiry the peak re-baselines; a reduced-size alpha resume window opens only once no pause remains and no permanent halt is latched. Explicit 'bars' retains the legacy closed-equity measurement and per-timeframe long cooldown. Both models deny new entries while allowing existing positions to exit; automatic v3 core allocations honor the hold too. null disables new drawdown trips.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Lower pauses entries after a smaller drawdown; higher tolerates a deeper drawdown. The shared entry breaker enforces this in single/bulk live and paper evaluation, v3 core allocation and backtests built with risk_manager_from_execution_config. Alpha resume sizing is a separate control; do not add a second drawdown stop.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"max_hold_bars":{"default":1000,"description":"Maximum bars to hold any position before a forced exit.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher lets trades run longer; lower forces earlier time-based exits.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"max_hold_time_hours":{"default":null,"description":"Maximum position hold time in hours (null = no limit).","exclusiveMinimum":1,"maximum":8760,"type":["integer","null"],"x-mangrove-effect":"Lower forces earlier time-based exits; null/higher lets trades run indefinitely on time.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"max_open_positions":{"default":10,"description":"Maximum concurrent open positions.","maximum":1000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher allows more simultaneous exposure (more diversification but more aggregate risk); lower is more selective with less aggregate exposure.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"max_risk_per_trade":{"default":0.01,"description":"Fraction of account equity risked per trade (0.01 = 1%). Position size is derived from this and the stop distance.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Higher risks more per trade: bigger positions, larger gains AND larger drawdowns. Lower is more conservative: smaller positions, smaller swings.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"max_trade_amount":{"default":10000000,"description":"Absolute cap on dollar size per trade.","exclusiveMinimum":0.0,"maximum":1000000000000.0,"type":["number","null"],"x-mangrove-effect":"Size guardrail; rarely binding.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"max_trades_per_day":{"default":50,"description":"Daily trade cap.","maximum":1440,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher permits more churn; lower throttles activity.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"max_units_per_trade":{"default":1000000,"description":"Absolute cap on units per trade.","exclusiveMinimum":0.0,"maximum":1000000000000.0,"type":["number","null"],"x-mangrove-effect":"Size guardrail; rarely binding.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"min_asset_balance":{"description":"position_size_calc 'v3' only. Minimum asset balance, in asset units, the strategy holds outside open trades.","minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more of the asset out of reach of sell trades and core sells, and takes more cash to reach; lower frees more of the asset for trading.","x-mangrove-status":"guardrail"},"min_balance_days":{"description":"position_size_calc 'v3' only. Number of equal daily orders used to bring a side up to its minimum balance.","minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher spreads the minimum-balance orders over more days at smaller size; lower reaches the minimum sooner with larger orders.","x-mangrove-status":"guardrail"},"min_balance_threshold":{"default":0.1,"description":"Cash reserve fraction held back from new entries (0.1 = 10%). v1 reserves this fraction of cash; v2 reserves this fraction of account value (cash + open positions at market). An entry may only use cash above the reserve; when no cash is deployable the entry is denied (insufficient_cash / insufficient_cash_v2_account_reserve). It never halts the strategy and never closes positions.","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more cash idle and makes entries smaller or rarer as the account shrinks; lower lets entries use more of the balance. Not a drawdown stop; see max_drawdown_limit and max_drawdown_halt_limit.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"min_cash_balance":{"description":"position_size_calc 'v3' only. Minimum cash balance the strategy holds after the worst-case loss of every open trade.","minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more cash out of reach of buy trades and core buys, so entries are smaller or rarer; lower frees more cash for trading.","x-mangrove-status":"guardrail"},"min_stop_distance_pct":{"default":0.005,"description":"Hard floor on stop distance as a fraction of entry price (crypto minimum), applied after ATR sizing.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher enforces a wider minimum stop; lower allows tighter stops down to the floor.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"min_trade_amount":{"default":25,"description":"Minimum trade size in dollars; smaller intended trades are skipped.","maximum":1000000.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher skips more small signals; lower allows smaller trades.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"position_size_calc":{"default":"v2","description":"Sizing-engine version ('v1', 'v2' or 'v3'). Pinned at creation and immutable. 'v3' holds an asset balance and a cash balance, sizes against equity net of open risk, and requires the position_size_calc 'v3' parameters.","enum":["v1","v2","v3",null],"type":["string","null"],"x-mangrove-effect":"Not a magnitude knob; selects the sizing algorithm. Do not change on an existing strategy.","x-mangrove-status":"guardrail"},"profit_threshold_pct":{"default":0.05,"description":"Profit threshold (5%% default) above which a position counts as 'winning' for the time-based exit logic.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher requires a larger gain before a position is treated as winning; lower treats smaller gains as wins.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"rebalance_band":{"description":"position_size_calc 'v3' only. Absolute deviation of the asset weight from target_asset_weight that triggers a rebalance order (0.05 = 5 points).","exclusiveMaximum":1.0,"exclusiveMinimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher lets the split drift further before a rebalance order, so fewer core orders; lower holds the split closer to target with more core orders and more fees.","x-mangrove-status":"tunable"},"reward_factor":{"default":2,"description":"Risk/reward target. Take-profit distance = reward_factor * stop_distance.","exclusiveMinimum":0.0,"maximum":100.0,"type":["number","null"],"x-mangrove-effect":"Higher sets a wider profit target: lower win rate but bigger wins. Lower sets a tighter target: higher win rate but smaller wins.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"stop_gap_allowance":{"description":"position_size_calc 'v3' only. Fraction of the stop price a stop fill is assumed to miss by when computing the worst-case loss of a trade (0.01 = 1%).","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher counts more risk per open trade, leaving less available cash and smaller positions; lower counts less.","x-mangrove-status":"guardrail"},"stop_model":{"default":"atr_width_dial","description":"Which stop model the strategy uses: 'atr_width_dial' (one parameter, volatility_tolerance, positioned on the ATR width) or 'weighted_atr' (superseded: a weighted blend of two ATRs, capped). Pinned at creation and immutable.","enum":["atr_width_dial","weighted_atr",null],"type":["string","null"],"x-mangrove-effect":"Not a magnitude knob; selects the stop algorithm. Do not change on an existing strategy -- it would move every stop the strategy takes.","x-mangrove-status":"guardrail"},"taker_fee_rate":{"description":"position_size_calc 'v3' only. Venue fee per fill as a fraction of notional, charged in cash (0.004 = 0.4%).","exclusiveMaximum":0.1,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher counts more cost per fill, raising the risk of each trade and lowering available cash. Models the venue; not a strategy-character knob.","x-mangrove-status":"guardrail"},"target_asset_weight":{"description":"position_size_calc 'v3' only. Target share of core value held in the asset (0.8 = 80% asset, 20% cash; 0 = all cash).","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher holds more of the asset and less cash; lower holds more cash. The daily core order moves the split back to this value once it drifts past rebalance_band. At 0 with no asset held, no core order is placed and only buy trades can pass.","x-mangrove-status":"tunable"},"target_volatility":{"default":0.1,"description":"Target volatility (0.10 = 10%). ONLY active when enable_volatility_adjustment is true (default false). When active, scales position size down if ATR%% of entry exceeds the target (never up).","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"With the gate off (the default), changing this has no effect. With it on, lower scales positions down more aggressively in high volatility.","x-mangrove-gate-field":"enable_volatility_adjustment","x-mangrove-gate-required":true,"x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"gated"},"volatility_mode":{"default":"stddev","description":"Unused (retained for backward compatibility). Volatility is derived from ATR.","enum":["stddev","atr",null],"type":["string","null"],"x-mangrove-effect":"No runtime effect. Do not tune.","x-mangrove-status":"unused"},"volatility_tolerance":{"default":0.5,"description":"Where on the ATR width the stop is taken, as the ATR_long-vs-ATR_short contribution ratio: 0 is all short end (0.5x the signal timeframe's ATR), 1 is all long end (2x the daily ATR). Interpolated geometrically, so the value is exactly the long end's share of log(stop) and each 0.1 is the same multiplicative step. Replaces atr_short_weight, atr_long_weight and atr_cap_multiplier.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher widens the stop, and because position size is the risk budget divided by the stop distance, exposure shrinks in exact inverse proportion at the SAME risk. Low means many units with little room to be wrong and frequent stop-outs; high means few units that are hard to shake out but need a much larger move to reach the same reward. Both risk max_risk_per_trade.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"volatility_window":{"default":24,"description":"Unused (retained for backward compatibility). ATR windowing is controlled by atr_period.","maximum":1000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"No runtime effect. Do not tune.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"unused"}},"title":"Execution configuration","type":"object","x-mangrove-boundary-validation":"top-level numeric bounds after legacy coercion; null means unset"}},"api1.ExecutionState":{"properties":{"account_value":{"description":"Total account value","type":"number"},"asset_balance":{"description":"Asset units held, units of open buy trades included (position_size_calc 'v3')","type":"number"},"bar_index":{"description":"Market candle counter for max_hold_bars continuity","type":"integer"},"cash_balance":{"description":"Current cash balance","type":"number"},"exits_pending":{"description":"Halted strategy still has positions requiring exit management","type":"boolean"},"halt":{"description":"Latched capital-floor halt; entries remain blocked until explicit reset","type":"object","x-mangrove-raw-json":true},"last_core_order_at":{"description":"ISO-8601 time of the last core order, or null (position_size_calc 'v3')","type":"string"},"last_evaluated_candle":{"description":"Last evaluated settled candle open time in UTC; echo unchanged","type":"string"},"last_evaluated_timeframe":{"description":"Primary timeframe of the candle cursor; echo unchanged","type":"string"},"num_open_positions":{"description":"Number of currently open positions","type":"integer"},"realized_pnl":{"description":"Profit and loss of closed trades, in cash (position_size_calc 'v3')","type":"number"},"risk_state":{"description":"Serialized RiskManager state (cooldown deques, counters, halt)","type":"object","x-mangrove-raw-json":true},"total_trades":{"description":"Total completed trades","type":"integer"}},"type":"object"},"api1.ExecutionValidationResult":{"properties":{"errors":{"items":{"type":"string"},"type":"array"},"valid":{"type":"boolean"}},"required":["valid"],"type":"object"},"api1.FlowIntelligenceResponse":{"properties":{"chain":{"type":"string"},"data":{"type":"object","x-mangrove-raw-json":true},"success":{"type":"boolean"},"symbol":{"type":"string"},"timeframe":{"type":"string"}},"type":"object"},"api1.GetStrategyResponse":{"properties":{"strategy":{"$ref":"#/components/schemas/api1.StrategyDetail"},"success":{"type":"boolean"}},"type":"object"},"api1.GlobalMarketResponse":{"properties":{"data":{"description":"CoinGecko global market statistics, passed through unchanged","type":"object","x-mangrove-raw-json":true},"success":{"type":"boolean"}},"type":"object"},"api1.HealthChecks":{"properties":{"database":{"$ref":"#/components/schemas/api1.ServiceCheck"},"llm":{"$ref":"#/components/schemas/api1.ServiceCheck"}},"type":"object"},"api1.HealthResponse":{"properties":{"checks":{"$ref":"#/components/schemas/api1.HealthChecks"},"service":{"description":"Service name","type":"string"},"status":{"description":"Overall health status (healthy/unhealthy)","type":"string"},"version":{"description":"Service version","type":"string"}},"required":["service","status","version"],"type":"object"},"api1.HelpBotAskRequest":{"properties":{"history":{"description":"Recent turns (server also uses persisted state)","items":{"$ref":"#/components/schemas/api1.HelpBotHistoryTurn"},"type":"array"},"message":{"description":"User question (4-500 chars)","type":"string"},"session_id":{"description":"Existing session UUID; omit or null to start a new one","type":"string"}},"required":["message"],"type":"object"},"api1.HelpBotAskResponse":{"properties":{"answer":{"type":"string"},"citations":{"items":{"$ref":"#/components/schemas/api1.HelpBotCitation"},"type":"array"},"confidence":{"enum":["normal","low"],"example":"normal","type":"string"},"session_id":{"type":"string"}},"type":"object"},"api1.HelpBotCitation":{"properties":{"doc_url":{"type":"string"},"section_anchor":{"type":"string"},"section_title":{"type":"string"},"source_file":{"type":"string"}},"type":"object"},"api1.HelpBotConversation":{"properties":{"message_count":{"type":"integer"},"messages":{"items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"session_id":{"type":"string"},"title":{"type":"string"}},"type":"object"},"api1.HelpBotHistoryTurn":{"properties":{"content":{"type":"string"},"role":{"enum":["user","assistant"],"example":"user","type":"string"}},"required":["content","role"],"type":"object"},"api1.InfluenceScoreResponse":{"properties":{"data":{"description":"Full user metrics","type":"object","x-mangrove-raw-json":true},"followers":{"description":"Follower count; null if the upstream had none","type":"integer"},"score":{"description":"Influence score 0-100","type":"number"},"success":{"type":"boolean"},"username":{"type":"string"}},"type":"object"},"api1.Invitation":{"properties":{"created_at":{"description":"Creation timestamp","format":"date-time","type":"string"},"email":{"description":"Invited email address","type":"string"},"expires_at":{"description":"Expiration timestamp","format":"date-time","type":"string"},"id":{"description":"Invitation UUID","type":"string"},"invited_by":{"description":"UUID of inviter","type":"string"},"inviter_email":{"description":"Inviter email address","type":"string"},"inviter_name":{"description":"Inviter display name","type":"string"},"org_id":{"description":"Organization UUID","type":"string"},"role":{"description":"Role to be assigned","type":"string"},"status":{"description":"Invitation status (pending, accepted, expired, cancelled)","type":"string"}},"type":"object"},"api1.InviteMember":{"properties":{"email":{"description":"Email address to invite","type":"string"},"role":{"default":"member","description":"Role to assign (owner, admin, member, viewer)","type":"string"}},"required":["email"],"type":"object"},"api1.LendingRatesResponse":{"properties":{"count":{"description":"Records in this page","type":"integer"},"data":{"description":"Lending pools in this page, largest TVL first","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"has_more":{"type":"boolean"},"limit":{"type":"integer"},"next_offset":{"description":"Offset of the next page, or null","type":"integer"},"offset":{"type":"integer"},"provider":{"type":"string"},"skipped":{"description":"Provider records that could not be read","type":"integer"},"success":{"type":"boolean"},"total":{"description":"Records matching the filters across all pages","type":"integer"}},"type":"object"},"api1.LocalDeploymentResponse":{"description":"A validated definition snapshot; this read never activates trading or copies execution state.","properties":{"activation_blocker":{"type":["string","null"],"x-nullable":true},"activation_ready":{"description":"Current server status and backtest eligibility; a separate activation flow is required.","type":"boolean"},"asset_class":{"enum":["crypto","equity"],"type":"string"},"contract_version":{"enum":[1],"type":"integer"},"fingerprint":{"pattern":"^[a-f0-9]{64}$","type":"string"},"name":{"type":["string","null"],"x-nullable":true},"owner":{"properties":{"org_id":{"format":"uuid","type":"string"},"user_id":{"format":"uuid","type":"string"}},"required":["user_id","org_id"],"type":"object"},"snapshot":{"additionalProperties":true,"description":"Resolved strategy definition and execution configuration; rule and configuration contents remain opaque here.","type":"object"},"strategy_id":{"format":"uuid","type":"string"},"timeframe":{"enum":["1m","5m","15m","1h","4h","1d"],"type":"string"}},"required":["contract_version","strategy_id","owner","name","fingerprint","timeframe","asset_class","snapshot","activation_ready","activation_blocker"],"type":"object"},"api1.LoginErrorResponse":{"properties":{"error":{"description":"Error message","type":"string"},"success":{"description":"Operation status (false)","type":"boolean"}},"type":"object"},"api1.LoginRequest":{"properties":{"firebase_token":{"description":"Firebase ID token from client authentication","type":"string"}},"required":["firebase_token"],"type":"object"},"api1.LoginResponse":{"properties":{"access_token":{"description":"JWT access token for API requests","type":"string"},"error":{"description":"Error message if login failed","type":"string"},"success":{"description":"Whether login was successful","type":"boolean"},"user":{"description":"User profile information","type":"object","x-mangrove-raw-json":true}},"type":"object"},"api1.MarketDataBar":{"properties":{},"type":"object"},"api1.MarketDataResponse":{"properties":{"base_token":{"type":"string"},"data":{"$ref":"#/components/schemas/api1.MarketDataSnapshot"},"market_cap_provider":{"type":"string"},"market_data_venue":{"description":"Price exchange; null for aggregate sources","type":"string"},"price_as_of":{"type":"string"},"price_stale":{"description":"Trade older than five minutes; null if unknown","type":"boolean"},"provider":{"description":"Price provider","type":"string"},"quote_token":{"description":"Currency of current_price","type":"string"},"success":{"type":"boolean"},"symbol":{"type":"string"},"volume_24h_provider":{"type":"string"}},"type":"object"},"api1.MarketDataSnapshot":{"properties":{"current_price":{"description":"Last trade price in quote_token","type":"number"},"market_cap":{"description":"Market capitalization (USD)","type":"number"},"volume_24h":{"description":"24-hour trading volume (USD)","type":"number"}},"type":"object"},"api1.MarketRegimeResponse":{"properties":{"asset":{"description":"The asset that was classified, upper-cased","type":"string"},"bars":{"description":"How many daily closes the classification was made from","type":"integer"},"regime":{"description":"The regime service's reading: `asof` (last date read); `direction` keyed by horizon (`90d`, `180d`, `365d`), each {return_pct (0-100 percent), band} or {error, bars} when history is too short for that horizon; `volatility` {vol_ann_pct (annualised, 0-100 percent), z_vs_baseline, bucket: low|medium|high} or {error} against the asset's own baseline; `window`: the whole lookback in the sweep catalog's labels, {start_date, end_date, length (1-month, 3-month, 6-month, 12-month or null), asset_class, direction, volatility: low|medium|high|unscored, trend: clean|mixed|choppy, volatility_probabilities {low, medium, high} or null, total_return_pct, realized_vol_ann_pct, r_squared}","type":"object","x-mangrove-raw-json":true},"venue":{"description":"The price feed read: binance (crypto), yahoo (a listed stock, ETF or bond) or yahoofut (a listed future, e.g. GOLD, CRUDE)","type":"string"}},"type":"object"},"api1.MarketSegmentResponse":{"properties":{"asset":{"description":"The asset the stretch belongs to","type":"string"},"bars":{"description":"How many closes the classification was made from","type":"integer"},"direction":{"description":"Band over the whole stretch, mega_bear through mega_bull","type":"string"},"duration_days":{"description":"Stretch length in days; selects the volatility band","type":"integer"},"end_date":{"description":"Last day of the stretch","type":"string"},"features":{"description":"total_return_pct and realized_vol_ann_pct (0-100 percent) and r_squared (0-1) the labels were read from","type":"object","x-mangrove-raw-json":true},"regime_composite":{"description":"The three joined, e.g. bear_medium_mixed","type":"string"},"scale":{"description":"The fitted length band used; null when none applied","type":"string"},"scale_bands":{"description":"Stretch lengths that have a fitted volatility band","type":"object","x-mangrove-raw-json":true},"start_date":{"description":"First day of the stretch","type":"string"},"timeframe":{"description":"The candle size the stretch was read at","type":"string"},"trend":{"description":"clean | mixed | choppy -- how closely the path tracked a line","type":"string"},"venue":{"description":"The price feed the stretch was read on: binance (a crypto date range), yahoo or yahoofut (a listed ticker), or the exchange a catalog window was cut from","type":"string"},"volatility":{"description":"low | medium | high | unscored (no fitted band covers the length)","type":"string"}},"type":"object"},"api1.MatchSignalsRequest":{"properties":{"description":{"description":"Natural language description of the desired signal/rule","type":"string"},"regime_direction":{"description":"Market regime band","type":"string"},"role":{"description":"Signal role","enum":["TRIGGER","FILTER"],"example":"TRIGGER","type":"string"},"similarity_threshold":{"default":0.3,"description":"Minimum similarity score to include","type":"number"},"top_k":{"default":5,"description":"Number of matches to return","type":"integer"},"user_intent":{"description":"Optional intent dict (e.g., from intent extractor)","type":"object","x-mangrove-raw-json":true}},"required":["description"],"type":"object"},"api1.MatchSignalsResponse":{"properties":{"description":{"type":"string"},"filter":{"type":"object","x-mangrove-raw-json":true},"matches":{"items":{"$ref":"#/components/schemas/api1.MatchedSignal"},"type":"array"},"query":{"type":"string"},"similarity_threshold":{"type":"number"},"top_k":{"type":"integer"}},"type":"object"},"api1.MatchedSignal":{"properties":{"description":{"description":"Signal description","type":"string"},"intent_score":{"type":"number"},"match_reasoning":{"type":"string"},"params":{"type":"object","x-mangrove-raw-json":true},"semantic_score":{"type":"number"},"signal_name":{"description":"Matched signal name from registry","type":"string"},"similarity_score":{"type":"number"},"usecase_score":{"type":"number"}},"type":"object"},"api1.MentionsResponse":{"properties":{"count":{"description":"Posts the search matched","type":"integer"},"hours_back":{"description":"Window requested; X recent search covers about the last 7 days","type":"integer"},"posts":{"description":"Up to limit recent posts (at most 10): post_id, created_at, text","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"success":{"type":"boolean"},"topic":{"type":"string"},"total_mentions":{"description":"Posts the search matched; same value as count","type":"integer"}},"type":"object"},"api1.MetadataValidationResult":{"properties":{"errors":{"items":{"type":"string"},"type":"array"},"valid":{"type":"boolean"}},"required":["valid"],"type":"object"},"api1.MetricsResponse":{"properties":{"metrics":{"$ref":"#/components/schemas/api1.UserMetrics"},"success":{"description":"Operation success","type":"boolean"}},"type":"object"},"api1.OAuthErrorResponse":{"properties":{"error":{"description":"Error message","type":"string"},"success":{"description":"Operation status (false)","type":"boolean"}},"type":"object"},"api1.OHLCVResponse":{"properties":{"daily_bars":{"description":"Daily bars before any weekly roll-up","type":"integer"},"data":{"items":{"$ref":"#/components/schemas/api1.OhlcvCandle"},"type":"array"},"data_points":{"type":"integer"},"interval":{"description":"1d, or 1w when more than 1,000 daily bars were rolled up","type":"string"},"success":{"type":"boolean"},"symbol":{"type":"string"}},"type":"object"},"api1.OhlcvCandle":{"properties":{"close":{"description":"Close price","type":"number"},"high":{"description":"High price","type":"number"},"low":{"description":"Low price","type":"number"},"open":{"description":"Open price","type":"number"},"timestamp":{"description":"Candle open time (ISO 8601)","type":"string"},"volume":{"description":"Volume in the candle interval","type":"number"}},"type":"object"},"api1.OnChainError":{"properties":{"code":{"type":"string"},"error":{"type":"string"},"message":{"type":"string"}},"type":"object"},"api1.OnChainSeriesBody":{"properties":{"chain":{"default":"ethereum","type":"string"},"date_range":{"description":"{from: YYYY-MM-DD, to: YYYY-MM-DD}; default trailing 10 days","type":"object","x-mangrove-raw-json":true},"interval":{"default":"1h","description":"1h | 4h | 1d | 1w","type":"string"},"metrics":{"description":"SmartMoneyNetflow, SmartMoneyHoldings, ExchangeNetflow, WhaleNetInflow, HolderConcentration","items":{"type":"string"},"type":"array"},"provider":{"description":"'nansen' (the default and only provider)","type":"string"},"symbol":{"description":"Token symbol, e.g. WETH","type":"string"},"top_n":{"default":10,"description":"Top-N holders for HolderConcentration","type":"integer"}},"required":["metrics","symbol"],"type":"object"},"api1.OnChainSeriesResponse":{"properties":{"chain":{"type":"string"},"count":{"type":"integer"},"date_range":{"type":"object","x-mangrove-raw-json":true},"interval":{"type":"string"},"metrics":{"items":{"type":"string"},"type":"array"},"series":{"items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"success":{"type":"boolean"},"symbol":{"type":"string"}},"type":"object"},"api1.OnChainTokenHoldersResponse":{"properties":{"concentration_score":{"type":"number"},"data":{"type":"object","x-mangrove-raw-json":true},"holder_count":{"type":"integer"},"success":{"type":"boolean"},"symbol":{"type":"string"},"top_10_holders_pct":{"type":"number"}},"type":"object"},"api1.OrderHistory":{"properties":{"activated":{"description":"Order activation timestamp (ISO format)","type":"string"},"cancelled":{"description":"Order cancellation timestamp (ISO format)","type":"string"},"created":{"description":"Order creation timestamp (ISO format)","type":"string"},"filled":{"description":"Order fill timestamp (ISO format)","type":"string"}},"type":"object"},"api1.OrderResponse":{"properties":{"action":{"description":"Whether this order OPENS or CLOSES a position, derived from side. Use this (not order_type) to tell an entry from an exit.","enum":["enter","exit"],"example":"enter","type":"string"},"asset":{"description":"Asset symbol (e.g., BTC-USD)","type":"string"},"entry_reason":{"description":"Fired trigger and filters for a filled entry; null when evidence was unavailable","type":"string"},"exit_reason":{"description":"Reason a filled exit closed the position (SL, TP, SIGNAL, TIME_LOSS, TIME_WIN, TIME_MAX); null for entries and cancelled orders","type":"string"},"history":{"allOf":[{"$ref":"#/components/schemas/api1.OrderHistory"}],"description":"Order lifecycle timestamps"},"is_exit":{"description":"True iff this order closes a position (side exit_long/exit_short). Convenience boolean mirroring `action == \"exit\"`.","type":"boolean"},"order_id":{"description":"Order UUID","type":"string"},"order_type":{"description":"Order type. Entry and triggered exit fills are \"market\"; resting brackets stay \"stop_loss\"/\"take_profit\" until they trigger or are cancelled.","enum":["market","limit","stop_loss","take_profit"],"example":"market","type":"string"},"position_id":{"description":"Associated position UUID","type":"string"},"position_size":{"description":"Position size in units","type":"number"},"price":{"description":"Order price (null for unfilled market orders)","type":"number"},"side":{"description":"Order side (enter_long, exit_long, enter_short, exit_short)","enum":["enter_long","exit_long","enter_short","exit_short"],"example":"enter_long","type":"string"},"status":{"description":"Order status","enum":["inactive","pending","filled","cancelled"],"example":"inactive","type":"string"}},"type":"object"},"api1.Organization":{"properties":{"created_at":{"description":"Creation timestamp","format":"date-time","type":"string"},"id":{"description":"Organization UUID","type":"string"},"info":{"description":"Additional organization information","type":"object","x-mangrove-raw-json":true},"is_active":{"description":"Whether organization is active","type":"boolean"},"name":{"description":"Organization name","type":"string"},"ria_flag":{"description":"RIA compliance flag","type":"boolean"},"settings":{"description":"Organization settings","type":"object","x-mangrove-raw-json":true},"suspended_at":{"description":"Suspension timestamp","format":"date-time","type":"string"},"updated_at":{"description":"Last update timestamp","format":"date-time","type":"string"}},"required":["name"],"type":"object"},"api1.OrganizationMember":{"properties":{"id":{"description":"Member UUID","type":"string"},"invited_by":{"description":"UUID of inviter","type":"string"},"joined_at":{"description":"Join timestamp","format":"date-time","type":"string"},"org_id":{"description":"Organization UUID","type":"string"},"role":{"description":"Member role (owner, admin, member, viewer)","type":"string"},"user_email":{"description":"User email address","type":"string"},"user_id":{"description":"User UUID","type":"string"},"user_name":{"description":"User display name","type":"string"}},"type":"object"},"api1.PerpFundingResponse":{"properties":{"count":{"description":"Records in this page","type":"integer"},"data":{"description":"Perp markets in this page, largest open interest first","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"has_more":{"type":"boolean"},"limit":{"type":"integer"},"next_offset":{"description":"Offset of the next page, or null","type":"integer"},"offset":{"type":"integer"},"provider":{"type":"string"},"skipped":{"description":"Provider records that could not be read","type":"integer"},"success":{"type":"boolean"},"total":{"description":"Records matching the filters across all pages","type":"integer"}},"type":"object"},"api1.PortfolioEntry":{"properties":{"asset":{"description":"Asset symbol","type":"string"},"execution_state":{"allOf":[{"$ref":"#/components/schemas/api1.PortfolioExecutionState"}],"description":"Execution state snapshot"},"last_evaluated_at":{"description":"Last evaluation timestamp (ISO 8601, nullable)","type":"string"},"open_positions_count":{"description":"Number of currently open positions (from DB)","type":"integer"},"recent_trades":{"description":"Last 5 trades, newest first","items":{"$ref":"#/components/schemas/api1.RecentTradeEntry"},"type":"array"},"strategy_id":{"description":"Strategy UUID","type":"string"},"strategy_name":{"description":"Strategy name","type":"string"}},"type":"object"},"api1.PortfolioExecutionState":{"properties":{"account_value":{"description":"Total account value","type":"number"},"cash_balance":{"description":"Current cash balance","type":"number"},"num_open_positions":{"description":"Number of currently open positions","type":"integer"},"total_trades":{"description":"Total completed trades","type":"integer"}},"type":"object"},"api1.PortfolioResponse":{"properties":{"missing":{"description":"Strategy IDs that were not found","items":{"type":"string"},"type":"array"},"results":{"description":"Portfolio entries in the order requested (missing ones omitted)","items":{"$ref":"#/components/schemas/api1.PortfolioEntry"},"type":"array"}},"type":"object"},"api1.Position":{"properties":{"account_id":{"description":"Account UUID","type":"string"},"asset":{"description":"Asset symbol","type":"string"},"cost":{"description":"Total cost (entry_price * position_size)","type":"number"},"created_at":{"description":"Creation timestamp","type":"string"},"entry_price":{"description":"Entry price","type":"number"},"entry_reason":{"description":"Fired trigger and filters when this position opened","type":"string"},"entry_timestamp":{"description":"Entry timestamp","type":"string"},"exchange":{"description":"Exchange name","type":"string"},"exit_price":{"description":"Exit price","type":"number"},"exit_reason":{"description":"Exit reason (SL, TP, MN, MANUAL)","type":"string"},"exit_timestamp":{"description":"Exit timestamp","type":"string"},"id":{"description":"Position UUID","type":"string"},"open":{"description":"Whether position is currently open","type":"boolean"},"org_id":{"description":"Organization UUID","type":"string"},"position_size":{"description":"Position size (units)","type":"number"},"stop_loss_price":{"description":"Stop loss price","type":"number"},"strategy_id":{"description":"Strategy UUID","type":"string"},"take_profit_price":{"description":"Take profit price","type":"number"},"user_id":{"description":"User UUID","type":"string"},"value_at_close":{"description":"Value at close","type":"number"}},"type":"object"},"api1.ProfileErrorResponse":{"properties":{"error":{"description":"Error message","type":"string"}},"type":"object"},"api1.ProfileUpdateErrorResponse":{"properties":{"error":{"description":"Error message","type":"string"}},"type":"object"},"api1.ProtocolTVLResponse":{"properties":{"chains":{"description":"Chain name -> TVL breakdown","type":"object","x-mangrove-raw-json":true},"data":{"description":"Full provider response","type":"object","x-mangrove-raw-json":true},"protocol":{"type":"string"},"success":{"type":"boolean"},"tvl_usd":{"type":"number"}},"type":"object"},"api1.RecentTradeEntry":{"properties":{"asset":{"description":"Asset symbol","type":"string"},"closed_at":{"description":"Trade close timestamp (ISO 8601, nullable)","type":"string"},"outcome":{"description":"Trade outcome (win or loss)","type":"string"},"profit_loss":{"description":"Profit/loss in dollars","type":"number"},"profit_loss_pct":{"description":"Profit/loss as percentage","type":"number"}},"type":"object"},"api1.RefreshResponse":{"properties":{"access_token":{"description":"New JWT access token","type":"string"},"error":{"description":"Error message if refresh failed","type":"string"},"success":{"description":"Whether refresh was successful","type":"boolean"}},"type":"object"},"api1.RenameRequest":{"properties":{"title":{"description":"New conversation title","type":"string"}},"required":["title"],"type":"object"},"api1.RenameResponse":{"properties":{"error":{"description":"Error message if operation failed","type":"string"},"message":{"description":"Success message","type":"string"},"success":{"description":"Whether the operation completed successfully","type":"boolean"}},"required":["success"],"type":"object"},"api1.ResourceUtilization":{"properties":{"api_calls":{"description":"API call utilization details","type":"object","x-mangrove-raw-json":true},"backtests":{"description":"Backtest utilization details","type":"object","x-mangrove-raw-json":true},"conversations":{"description":"Conversation count (uncapped)","type":"object","x-mangrove-raw-json":true},"messages":{"description":"Message count across conversations (uncapped)","type":"object","x-mangrove-raw-json":true},"strategies":{"description":"Strategy utilization details","type":"object","x-mangrove-raw-json":true},"tokens":{"description":"Token utilization details","type":"object","x-mangrove-raw-json":true}},"type":"object"},"api1.RiskScores":{"properties":{"age":{"description":"Age score (0-100)","type":"integer"},"exchange":{"description":"Exchange availability score (0-100)","type":"integer"},"liquidity":{"description":"Liquidity score (0-100)","type":"integer"},"market_cap":{"description":"Market cap score (0-100)","type":"integer"},"overall":{"description":"Overall risk score (weighted average, 0-100)","type":"number"},"price_stability":{"description":"Price stability score (0-100)","type":"integer"},"supply_distribution":{"description":"Supply distribution score (0-100)","type":"integer"},"volatility":{"description":"Volatility score (0-100)","type":"integer"}},"type":"object"},"api1.ScreenRequest":{"properties":{"asset":{"description":"The asset every candidate trades.","type":"string"},"candidates":{"description":"Each {entry: [{name, params?, timeframe?}], exit: [...]}. Signal roles are resolved from the library, so do not send signal_type.","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"}},"required":["asset","candidates"],"type":"object"},"api1.ScreenResult":{"properties":{"asset":{"type":"string"},"candidates":{"description":"Rank order, highest p_trades first. Each carries rank, p_trades, p_no_trades and the rules as composed.","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"code_version":{"type":"string"},"count":{"type":"integer"},"model_version":{"type":"string"}},"type":"object"},"api1.SearchSignalsRequest":{"properties":{"category":{"description":"Signal library module","type":"string"},"limit":{"default":20,"description":"Maximum results","type":"integer"},"offset":{"default":0,"description":"Pagination offset","type":"integer"},"query":{"description":"Search query string","type":"string"},"regime_direction":{"description":"Market regime band","type":"string"},"role":{"description":"Signal role","enum":["TRIGGER","FILTER"],"example":"TRIGGER","type":"string"},"search_type":{"default":"keywords","description":"Type of search","enum":["name","params","keywords"],"example":"name","type":"string"}},"required":["query"],"type":"object"},"api1.SentimentResponse":{"properties":{"data":{"description":"Full provider response","type":"object","x-mangrove-raw-json":true},"hours_back":{"description":"Window requested; X recent search covers about the last 7 days","type":"integer"},"mention_count":{"description":"Posts read","type":"integer"},"mentions":{"description":"Posts read; same value as mention_count","type":"integer"},"negative_count":{"description":"Posts containing a negative keyword","type":"integer"},"positive_count":{"description":"Posts containing a positive keyword","type":"integer"},"score":{"description":"Positive share of polar posts, 0-100; null when no post carried a sentiment keyword","type":"number"},"sentiment":{"description":"From score: bullish at 70 or more, bearish at 30 or less, neutral between; insufficient_signal when no post carried a sentiment keyword","enum":["bullish","neutral","bearish","insufficient_signal"],"example":"bullish","type":"string"},"success":{"type":"boolean"},"topic":{"type":"string"}},"type":"object"},"api1.ServiceCheck":{"properties":{"error":{"description":"Error message if unhealthy","type":"string"},"status":{"description":"Health status (healthy/unhealthy)","type":"string"}},"type":"object"},"api1.Signal":{"properties":{"category":{"type":"string"},"data_provider":{"description":"Live data provider; null for frame-only signals","type":["string","null"],"x-nullable":true},"display_name":{"description":"Readable technical name","type":"string"},"evaluation_mode":{"description":"frame for supplied data, live for current provider data","type":"string"},"friendly_name":{"description":"Plain-language name, four words or fewer","type":"string"},"metadata":{"$ref":"#/components/schemas/api1.SignalMetadata"},"name":{"type":"string"},"short_description":{"description":"One plain sentence on what the signal detects","type":"string"},"signal_type":{"description":"TRIGGER or FILTER","type":"string"},"usage_count":{"description":"Number of strategies using this signal","type":"integer"}},"required":["category","name"],"type":"object"},"api1.SignalBehaviorRequest":{"properties":{"category":{"description":"find: restrict to one family, e.g. oscillator, volatility, momentum","type":"string"},"limit":{"default":10,"description":"Maximum results, 1-100","type":"integer"},"lookup":{"description":"describe: one signal -- parameter meanings, measured span, what its default measures. pick: settings of one signal that hit target_rate. find: which signals reach a rate band. gap_probability: share of a signal's gaps inside a range of bar lengths, per configuration.","enum":["describe","pick","find","gap_probability"],"example":"describe","type":"string"},"max_gap_bars":{"description":"pick/find, TRIGGER only: median gap at most this many bars","type":"number"},"max_gap_range_bars":{"description":"gap_probability: high end of the gap range, inclusive (required)","type":"number"},"max_rate":{"description":"find: high end of the band, same units (required)","type":"number"},"max_run_bars":{"description":"pick/find, FILTER only: mean run at most this many bars","type":"number"},"min_gap_bars":{"description":"pick/find, TRIGGER only: median gap at least this many bars","type":"number"},"min_gap_range_bars":{"description":"gap_probability: low end of the gap range, inclusive (required)","type":"number"},"min_rate":{"description":"find: low end of the band, same units (required)","type":"number"},"min_run_bars":{"description":"pick/find, FILTER only: mean run at least this many bars","type":"number"},"signal":{"description":"Signal name, e.g. rsi_oversold. Required by describe, pick, gap_probability","type":"string"},"signal_type":{"default":"FILTER","description":"FILTER (an ongoing state) or TRIGGER (a one-bar event); measured separately","enum":["FILTER","TRIGGER"],"example":"FILTER","type":"string"},"target_rate":{"description":"pick: rate to aim for -- FILTER selectivity 0-1, TRIGGER firings per 1,000 bars. Omit to list the span","type":"number"}},"required":["lookup"],"type":"object"},"api1.SignalBehaviorResponse":{"properties":{"lookup":{"description":"The lookup that ran","type":"string"},"result":{"description":"The lookup's answer. FILTER rows carry selectivity (fraction 0-1), runs, mean_run_bars, longest_run_bars; TRIGGER rows carry per_1000_bars, median_gap_bars, shortest_gap_bars, longest_gap_bars, stays_true_bars. pick adds span, matches, unreachable (null when the target was met); measured=false means the signal has no measurements yet.","type":"object","x-mangrove-raw-json":true}},"type":"object"},"api1.SignalEvaluationResponse":{"properties":{"error":{"type":"string"},"result":{"type":"boolean"},"success":{"type":"boolean"}},"required":["success"],"type":"object"},"api1.SignalLabel":{"properties":{"display_name":{"description":"Readable technical name","type":"string"},"friendly_name":{"description":"Plain-language name, four words or fewer","type":"string"},"name":{"type":"string"},"short_description":{"description":"One plain sentence on what the signal detects","type":"string"}},"required":["name"],"type":"object"},"api1.SignalLabelsResponse":{"properties":{"signals":{"items":{"$ref":"#/components/schemas/api1.SignalLabel"},"type":"array"}},"type":"object"},"api1.SignalListFilter":{"properties":{"after_filter":{"type":"integer"},"before_filter":{"type":"integer"},"regime_direction":{"type":"string"},"role":{"type":"string"}},"type":"object"},"api1.SignalListResponse":{"properties":{"filter":{"$ref":"#/components/schemas/api1.SignalListFilter"},"has_more":{"type":"boolean"},"limit":{"type":"integer"},"next_offset":{"type":"integer"},"offset":{"type":"integer"},"signals":{"items":{"$ref":"#/components/schemas/api1.Signal"},"type":"array"},"total":{"type":"integer"}},"type":"object"},"api1.SignalMetadata":{"properties":{"description":{"type":"string"},"params":{"type":"object","x-mangrove-raw-json":true},"requires":{"items":{"type":"string"},"type":"array"},"rule_name":{"type":"string"}},"required":["rule_name"],"type":"object"},"api1.SignalTriggerResult":{"properties":{"bars_fetched":{"description":"Number of bars fetched","type":"integer"},"error":{"description":"Explicit per-series failure, when present","type":"string"},"signal_name":{"description":"Name of the signal","type":"string"},"signal_type":{"description":"TRIGGER or FILTER","type":"string"},"timeframe":{"description":"Timeframe used for this signal","type":"string"},"trigger_count":{"description":"Triggers inside the chart window","type":"integer"},"trigger_indices":{"description":"Bar indices of the latest 200 triggers; only with include_chart","items":{"type":"integer"},"type":"array"},"trigger_timestamps":{"description":"ISO timestamps of the latest 200 triggers","items":{"type":"string"},"type":"array"},"triggers_truncated":{"description":"Whether trigger_timestamps lists fewer than trigger_count","type":"boolean"}},"type":"object"},"api1.SignalValidationResponse":{"properties":{"errors":{"items":{"type":"string"},"type":"array"},"valid":{"type":"boolean"}},"required":["valid"],"type":"object"},"api1.SmartMoneyDatedQueryBody":{"properties":{"chains":{"description":"Chain filter","items":{"type":"string"},"type":"array"},"date_range":{"description":"{from: YYYY-MM-DD, to: YYYY-MM-DD}; default trailing 7 days","type":"object","x-mangrove-raw-json":true},"filters":{"type":"object","x-mangrove-raw-json":true},"order_by":{"type":"object","x-mangrove-raw-json":true},"page":{"default":1,"type":"integer"},"per_page":{"default":25,"type":"integer"}},"type":"object"},"api1.SmartMoneyDexTradesResponse":{"properties":{"chains":{"items":{"type":"string"},"type":"array"},"count":{"type":"integer"},"filters":{"type":"object","x-mangrove-raw-json":true},"order_by":{"type":"object","x-mangrove-raw-json":true},"success":{"type":"boolean"},"trades":{"items":{"type":"object","x-mangrove-raw-json":true},"type":"array"}},"type":"object"},"api1.SmartMoneyHistoricalHoldingsResponse":{"properties":{"chains":{"items":{"type":"string"},"type":"array"},"count":{"type":"integer"},"date_range":{"type":"object","x-mangrove-raw-json":true},"filters":{"type":"object","x-mangrove-raw-json":true},"holdings":{"items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"order_by":{"type":"object","x-mangrove-raw-json":true},"success":{"type":"boolean"}},"type":"object"},"api1.SmartMoneyHoldingsResponse":{"properties":{"chains":{"items":{"type":"string"},"type":"array"},"count":{"type":"integer"},"data":{"description":"Nansen rows, passed through unchanged","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"labels":{"items":{"type":"string"},"type":"array"},"min_value_usd":{"type":"number"},"success":{"type":"boolean"}},"type":"object"},"api1.SmartMoneyNetflowsResponse":{"properties":{"chains":{"items":{"type":"string"},"type":"array"},"count":{"type":"integer"},"data":{"description":"Nansen rows, passed through unchanged","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"labels":{"items":{"type":"string"},"type":"array"},"success":{"type":"boolean"},"timeframe":{"type":"string"}},"type":"object"},"api1.SmartMoneyPerpQueryBody":{"properties":{"filters":{"description":"action, side, token_symbol, value_usd:{min,max}, only_new_positions","type":"object","x-mangrove-raw-json":true},"order_by":{"type":"object","x-mangrove-raw-json":true},"page":{"default":1,"type":"integer"},"per_page":{"default":25,"type":"integer"}},"type":"object"},"api1.SmartMoneyPerpTradesResponse":{"properties":{"count":{"type":"integer"},"filters":{"type":"object","x-mangrove-raw-json":true},"order_by":{"type":"object","x-mangrove-raw-json":true},"success":{"type":"boolean"},"trades":{"items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"venue":{"description":"Always 'hyperliquid' currently","type":"string"}},"type":"object"},"api1.SmartMoneyQueryBody":{"properties":{"chains":{"description":"Chain filter (default: ['ethereum'])","items":{"type":"string"},"type":"array"},"filters":{"description":"Nansen-shape filter dict (e.g. include_smart_money_labels, value_usd: {min,max})","type":"object","x-mangrove-raw-json":true},"order_by":{"description":"Nansen-shape order_by list (e.g. [{field, direction}])","type":"object","x-mangrove-raw-json":true},"page":{"default":1,"type":"integer"},"per_page":{"default":25,"type":"integer"}},"type":"object"},"api1.SmartMoneyScreenResponse":{"properties":{"chains":{"items":{"type":"string"},"type":"array"},"count":{"type":"integer"},"success":{"type":"boolean"},"timeframe":{"type":"string"},"tokens":{"items":{"type":"object","x-mangrove-raw-json":true},"type":"array"}},"type":"object"},"api1.SmartMoneySentimentResponse":{"properties":{"chain":{"type":"string"},"data":{"type":"object","x-mangrove-raw-json":true},"net_flow_usd":{"type":"number"},"sentiment":{"description":"accumulating, distributing, or neutral","type":"string"},"smart_money_inflow_usd":{"type":"number"},"smart_money_outflow_usd":{"type":"number"},"success":{"type":"boolean"},"symbol":{"type":"string"},"trend_7d":{"type":"string"}},"type":"object"},"api1.SocialError":{"properties":{"code":{"type":"string"},"error":{"type":"string"},"message":{"type":"string"}},"type":"object"},"api1.StablecoinMetricsResponse":{"properties":{"data":{"description":"Top stablecoins and metadata","type":"object","x-mangrove-raw-json":true},"success":{"type":"boolean"},"supply_by_chain":{"description":"Chain name -> stablecoin supply","type":"object","x-mangrove-raw-json":true},"total_supply_usd":{"type":"number"}},"type":"object"},"api1.StrategiesResponse":{"properties":{"strategies":{"items":{"$ref":"#/components/schemas/api1.Strategy"},"type":"array"},"success":{"type":"boolean"},"total":{"type":"integer"}},"type":"object"},"api1.Strategy":{"properties":{"asset":{"type":"string"},"config":{"type":"object","x-mangrove-raw-json":true},"created_at":{"type":"string"},"entry_signals":{"items":{"type":"string"},"type":"array"},"exit_signals":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"type":"object"},"api1.StrategyArchiveResponse":{"properties":{"archived":{"description":"True after archive, False after unarchive","type":"boolean"},"strategy_id":{"description":"UUID of the affected strategy","type":"string"},"success":{"description":"Whether the operation succeeded","type":"boolean"}},"type":"object"},"api1.StrategyBacktestResult":{"properties":{"base_token":{"description":"Recorded canonical base token; null for historical runs","type":["string","null"],"x-nullable":true},"core_orders":{"description":"v3 core orders; absent for legacy runs","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"data_info":{"description":"Engine data metadata; present for v3 runs","type":"object","x-mangrove-raw-json":true},"error":{"description":"Error message if success is false","type":"string"},"execution_time_seconds":{"description":"Time taken for this strategy","type":"number"},"market_data_venue":{"description":"Recorded market data venue; null for historical runs","type":["string","null"],"x-nullable":true},"metrics":{"description":"Performance metrics (empty dict on failure)","type":"object","x-mangrove-raw-json":true},"quote_token":{"description":"Recorded quote token; null for historical runs","type":["string","null"],"x-nullable":true},"satellite_pnl":{"description":"v3 satellite profit and loss; absent for legacy runs","type":"number"},"strategy_id":{"description":"DB UUID of the strategy (null for inline configs)","type":"string"},"strategy_name":{"description":"Name from the strategy config","type":"string"},"success":{"description":"Whether this strategy completed without error","type":"boolean"},"trade_count":{"description":"Number of trades executed","type":"integer"}},"type":"object"},"api1.StrategyDetail":{"properties":{"archived":{"description":"True if the strategy is archived (hidden from the default list)","type":"boolean"},"archived_at":{"description":"ISO timestamp when archived, or null if active","type":"string"},"asset":{"description":"Asset symbol","type":"string"},"content_hash":{"description":"Content hash for deduplication","type":"string"},"created_at":{"description":"Creation timestamp","type":"string"},"description":{"description":"Human-readable strategy description","type":"string"},"evaluation_count":{"description":"Total number of evaluations performed","type":"integer"},"execution_config":{"allOf":[{"$ref":"#/components/schemas/api1.ExecutionConfiguration"}],"description":"Execution configuration (risk management, position limits, etc.)"},"execution_state":{"description":"Runtime execution state (cash_balance, account_value, trades)","type":"object","x-mangrove-raw-json":true},"id":{"description":"Strategy ID (UUID)","type":"string"},"last_evaluated_at":{"description":"Timestamp of last evaluation (ISO format, null if never evaluated)","type":"string"},"market_data_venue":{"description":"Market data venue, nullable during migration","type":"string"},"name":{"description":"Strategy name","type":"string"},"org_id":{"description":"Organization ID","type":"string"},"parent_strategy_id":{"description":"Parent strategy ID (for derived strategies)","type":"string"},"position_size_calc":{"description":"Sizing-math version: \"v1\", \"v2\" or \"v3\". Pinned at creation; cannot be changed after.","enum":["v1","v2","v3"],"example":"v1","type":"string"},"quote_token":{"description":"Quote currency, nullable during migration","type":"string"},"rules":{"description":"Entry/exit rules (JSON)","type":"object","x-mangrove-raw-json":true},"session_id":{"description":"Linked conversation session ID","type":"string"},"status":{"description":"Strategy status (draft, inactive, paper, live, archived)","type":"string"},"strategy_type":{"description":"Strategy type (trend_following, momentum, volatility, breakout, mean_reversion)","type":"string"},"user_id":{"description":"User ID (owner)","type":"string"}},"type":"object"},"api1.StrategyEvaluateResult":{"properties":{"asset":{"description":"Asset symbol","type":"string"},"bar_evaluated":{"description":"False when the settled candle was already evaluated","type":"boolean"},"base_token":{"description":"Canonical base token of the selected market","type":"string"},"closed_trades":{"description":"Confirmed engine-owned fills only","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"core_orders":{"description":"Core orders placed by this evaluation: zero or one element (position_size_calc 'v3')","items":{"$ref":"#/components/schemas/api1.CoreOrder"},"type":"array"},"current_price":{"description":"Market price at evaluation time","type":"number"},"denied_signals":{"description":"Entry signals that fired but were denied by a risk/account gate. Empty list = no signal fired OR the signal converted to an order. Non-empty with new_orders empty = the strategy IS firing and being blocked.","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"error":{"description":"Error message if success=False","type":"string"},"execution_state":{"allOf":[{"$ref":"#/components/schemas/api1.ExecutionState"}],"description":"Strategy execution state (echoed for stateless round-trip)"},"execution_time_seconds":{"description":"Wall-clock time for this strategy","type":"number"},"market_data_venue":{"description":"Recorded market data venue","type":"string"},"new_orders":{"description":"Orders generated or triggered during evaluation","items":{"$ref":"#/components/schemas/api1.OrderResponse"},"type":"array"},"open_positions":{"description":"Authoritative caller-owned open positions; proposals are separate","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"org_id":{"description":"Strategy owner organisation UUID","type":"string"},"proposed_closes":{"description":"Unconfirmed exit estimates; never booked risk facts","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"proposed_positions":{"description":"Unconfirmed new-entry templates, including bracket identities; only the executor books a fill","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"quote_token":{"description":"Recorded market quote token","type":"string"},"reason":{"description":"Human-readable skip reason","type":"string"},"skipped":{"description":"True if the strategy was skipped (non-evaluable status)","type":"boolean"},"status":{"description":"Strategy status when skipped","type":"string"},"strategy_id":{"description":"Strategy UUID (null for inline configs)","type":"string"},"strategy_name":{"description":"Strategy name","type":"string"},"strategy_summary":{"description":"Per-strategy performance summary (null when no trades closed)","type":"object","x-mangrove-raw-json":true},"success":{"description":"Whether this strategy evaluated without error","type":"boolean"},"user_id":{"description":"Strategy owner user UUID","type":"string"},"v3":{"allOf":[{"$ref":"#/components/schemas/api1.V3State"}],"description":"Balances, availability and core phase after this evaluation (position_size_calc 'v3')"}},"type":"object"},"api1.StrategyListItem":{"properties":{"archived":{"description":"True if the strategy is archived (hidden from the default list)","type":"boolean"},"archived_at":{"description":"ISO timestamp when archived, or null if active","type":"string"},"asset":{"description":"Asset symbol","type":"string"},"created_at":{"description":"Creation timestamp","type":"string"},"description":{"description":"Human-readable strategy description","type":"string"},"id":{"description":"Strategy ID (UUID)","type":"string"},"market_data_venue":{"description":"Market data venue, nullable during migration","type":"string"},"name":{"description":"Strategy name","type":"string"},"position_size_calc":{"description":"Sizing-math version: \"v1\", \"v2\" or \"v3\"","enum":["v1","v2","v3"],"example":"v1","type":"string"},"quote_token":{"description":"Quote currency, nullable during migration","type":"string"},"status":{"description":"Strategy status","type":"string"},"strategy_type":{"description":"Strategy type","type":"string"}},"type":"object"},"api1.StrategyListResponse":{"properties":{"limit":{"type":"integer"},"skip":{"type":"integer"},"strategies":{"items":{"$ref":"#/components/schemas/api1.StrategyListItem"},"type":"array"},"success":{"type":"boolean"},"total":{"type":"integer"}},"type":"object"},"api1.StrategyObject":{"properties":{"asset":{"description":"Asset symbol (e.g., BTC)","type":"string"},"base_token":{"description":"Canonical base token of the selected market","type":"string"},"execution_config":{"description":"Execution configuration (risk management, position limits)","type":"object","x-mangrove-raw-json":true},"execution_state":{"description":"Initial execution state (balances, trade counts)","type":"object","x-mangrove-raw-json":true},"market_data_venue":{"description":"Recorded market data venue","type":"string"},"name":{"description":"Strategy name","type":"string"},"quote_token":{"description":"Recorded market quote token","type":"string"},"rules":{"description":"Entry/exit rules (JSON)","type":"object","x-mangrove-raw-json":true}},"required":["asset","rules"],"type":"object"},"api1.StrategyVerification":{"properties":{"conforms":{"description":"Whether it will run. False means `problems` says why","type":"boolean"},"found":{"description":"Always true on a 200; a missing strategy is a 404","type":"boolean"},"problems":{"description":"What to fix before backtesting, one per fault, each naming the signal: unknown signal names, invalid parameter keys, roles that do not compose, a signal with no timeframe. Empty when it conforms","items":{"type":"string"},"type":"array"},"warnings":{"description":"Legal but worth a second look -- a parameter still at its library default. Never makes `conforms` false","items":{"type":"string"},"type":"array"}},"type":"object"},"api1.SubscriptionStatus":{"properties":{"current_period_end":{"description":"Current billing period end","format":"date-time","type":"string"},"current_period_start":{"description":"Current billing period start","format":"date-time","type":"string"},"limits":{"description":"Resource limits","type":"object","x-mangrove-raw-json":true},"limits_exceeded":{"description":"Whether any limits are exceeded","type":"boolean"},"price_monthly":{"description":"Monthly price","type":"number"},"tier_id":{"description":"Subscription tier ID","type":"string"},"tier_name":{"description":"Subscription tier name","type":"string"},"usage":{"description":"Current usage","type":"object","x-mangrove-raw-json":true}},"type":"object"},"api1.SupplyData":{"properties":{"circulating":{"description":"Circulating supply. Null if unknown.","type":"number"},"max":{"description":"Maximum supply. Null if uncapped or unknown.","type":"number"},"total":{"description":"Total supply. Null if unknown.","type":"number"}},"type":"object"},"api1.SwitchOrgRequest":{"properties":{"org_id":{"description":"Organization UUID to switch to","type":"string"}},"required":["org_id"],"type":"object"},"api1.SyntaxValidationResult":{"properties":{"errors":{"items":{"type":"string"},"type":"array"},"valid":{"type":"boolean"}},"required":["valid"],"type":"object"},"api1.Timestamps":{"properties":{"approved_at":{"description":"Approval timestamp (ISO 8601). Null if not approved.","type":"string"},"created_at":{"description":"Creation timestamp (ISO 8601). Null if unset.","type":"string"},"last_evaluated_at":{"description":"Last risk evaluation timestamp (ISO 8601). Null if never evaluated.","type":"string"},"updated_at":{"description":"Last update timestamp (ISO 8601). Null if unset.","type":"string"}},"type":"object"},"api1.TokenBreakdown":{"properties":{"assistant_tokens":{"description":"Assistant response tokens","type":"integer"},"context_tokens":{"description":"Context/RAG/tool tokens","type":"integer"},"system_tokens":{"description":"System/agent profile tokens","type":"integer"},"total_tokens":{"description":"Total tokens","type":"integer"},"user_tokens":{"description":"User input tokens","type":"integer"}},"type":"object"},"api1.TokenDatedQueryBody":{"properties":{"chain":{"description":"Blockchain (default: ethereum)","type":"string"},"date_range":{"description":"{from: YYYY-MM-DD, to: YYYY-MM-DD}; default trailing 7 days","type":"object","x-mangrove-raw-json":true},"filters":{"type":"object","x-mangrove-raw-json":true},"order_by":{"type":"object","x-mangrove-raw-json":true},"page":{"default":1,"type":"integer"},"per_page":{"default":25,"type":"integer"}},"type":"object"},"api1.TokenDexTradesResponse":{"properties":{"chain":{"type":"string"},"contract_address":{"type":"string"},"count":{"type":"integer"},"date_range":{"type":"object","x-mangrove-raw-json":true},"filters":{"type":"object","x-mangrove-raw-json":true},"order_by":{"type":"object","x-mangrove-raw-json":true},"success":{"type":"boolean"},"symbol":{"type":"string"},"trades":{"items":{"type":"object","x-mangrove-raw-json":true},"type":"array"}},"type":"object"},"api1.TokenFlowsResponse":{"properties":{"chain":{"type":"string"},"contract_address":{"type":"string"},"count":{"type":"integer"},"date_range":{"type":"object","x-mangrove-raw-json":true},"filters":{"type":"object","x-mangrove-raw-json":true},"flows":{"items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"order_by":{"type":"object","x-mangrove-raw-json":true},"success":{"type":"boolean"},"symbol":{"type":"string"}},"type":"object"},"api1.TokenHoldersResponse":{"properties":{"data":{"type":"object","x-mangrove-raw-json":true},"success":{"type":"boolean"},"symbol":{"type":"string"}},"type":"object"},"api1.TokenUnlocksResponse":{"properties":{"count":{"description":"Records in this page","type":"integer"},"data":{"description":"Tokens in this page, soonest or largest unlock first","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"has_more":{"type":"boolean"},"limit":{"type":"integer"},"next_offset":{"description":"Offset of the next page, or null","type":"integer"},"offset":{"type":"integer"},"provider":{"type":"string"},"skipped":{"description":"Provider records that could not be read","type":"integer"},"success":{"type":"boolean"},"total":{"description":"Records matching the filters across all pages","type":"integer"},"window":{"description":"from/to (UTC) and days_ahead evaluated","type":"object","x-mangrove-raw-json":true}},"type":"object"},"api1.Trade":{"properties":{"account_id":{"description":"Account UUID","type":"string"},"asset":{"description":"Asset symbol","type":"string"},"beginning_balance":{"description":"Account balance before trade","type":"number"},"closed_at":{"description":"Trade close timestamp","type":"string"},"ending_balance":{"description":"Account balance after trade","type":"number"},"entry_price":{"description":"Entry price","type":"number"},"exchange":{"description":"Exchange name","type":"string"},"exit_price":{"description":"Exit price","type":"number"},"id":{"description":"Trade UUID","type":"string"},"org_id":{"description":"Organization UUID","type":"string"},"outcome":{"description":"Trade outcome (win or loss)","type":"string"},"position_id":{"description":"Position UUID","type":"string"},"position_size":{"description":"Position size","type":"number"},"profit_loss":{"description":"Profit/loss in dollars","type":"number"},"profit_loss_pct":{"description":"Profit/loss percentage","type":"number"},"strategy_name":{"description":"Strategy name","type":"string"},"user_id":{"description":"User UUID","type":"string"}},"type":"object"},"api1.TradesValidationResult":{"properties":{"errors":{"items":{"type":"string"},"type":"array"},"valid":{"type":"boolean"}},"required":["valid"],"type":"object"},"api1.TreasuriesResponse":{"properties":{"count":{"description":"Records in this page","type":"integer"},"data":{"description":"Treasuries in this page, largest holdings first","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"has_more":{"type":"boolean"},"limit":{"type":"integer"},"next_offset":{"description":"Offset of the next page, or null","type":"integer"},"offset":{"type":"integer"},"provider":{"type":"string"},"skipped":{"description":"Provider records that could not be read","type":"integer"},"success":{"type":"boolean"},"total":{"description":"Records matching the filters across all pages","type":"integer"}},"type":"object"},"api1.TrendingAssetsResponse":{"properties":{"count":{"type":"integer"},"success":{"type":"boolean"},"trending":{"description":"CoinGecko trending entries, passed through unchanged","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"}},"type":"object"},"api1.UpdateMemberRole":{"properties":{"role":{"description":"New role (owner, admin, member, viewer)","type":"string"}},"required":["role"],"type":"object"},"api1.UpdateOrganization":{"properties":{"info":{"description":"Additional organization information","type":"object","x-mangrove-raw-json":true},"name":{"description":"Organization name","type":"string"},"ria_flag":{"description":"RIA compliance flag","type":"boolean"},"settings":{"description":"Organization settings","type":"object","x-mangrove-raw-json":true}},"type":"object"},"api1.UpdateProfile":{"properties":{"name":{"description":"New display name","type":"string"}},"type":"object"},"api1.UpdateStrategyResponse":{"properties":{"strategy":{"$ref":"#/components/schemas/api1.StrategyDetail"},"success":{"type":"boolean"}},"type":"object"},"api1.UpdateStrategyStatusRequest":{"properties":{"status":{"description":"New status (draft, inactive, paper, live, archived)","type":"string"}},"required":["status"],"type":"object"},"api1.UpdateStrategyStatusResponse":{"properties":{"message":{"type":"string"},"success":{"type":"boolean"}},"type":"object"},"api1.UserMetrics":{"properties":{"backtests_count":{"type":"integer"},"conversations_count":{"type":"integer"},"estimated_tokens":{"type":"integer"},"messages_count":{"type":"integer"},"strategies_count":{"type":"integer"},"token_breakdown":{"allOf":[{"$ref":"#/components/schemas/api1.TokenBreakdown"}],"description":"Token usage by category"},"tool_calls":{"type":"object","x-mangrove-raw-json":true}},"type":"object"},"api1.UserProfile":{"properties":{"created_at":{"description":"Account creation timestamp","format":"date-time","type":"string"},"email":{"description":"User email address","type":"string"},"id":{"description":"User ID","type":"string"},"name":{"description":"User display name","type":"string"},"org_id":{"description":"Organization ID","type":"string"}},"type":"object"},"api1.V3State":{"properties":{"account_value":{"description":"asset_balance * price + cash_balance","type":"number"},"asset_balance":{"description":"Asset units held after this evaluation","type":"number"},"available_asset":{"description":"Asset units an entry or a withdrawal may use, net of min_balance_reserve_asset","type":"number"},"available_cash":{"description":"Cash an entry or a withdrawal may use, net of min_balance_reserve_cash","type":"number"},"cash_balance":{"description":"Cash held after this evaluation","type":"number"},"core_skip_reason":{"description":"Why no core order was placed (both_below_minimum, below_min_trade_amount, limited_by_minimum, waiting_for_open_trades); null when one was placed, none was due, or the UTC day already has one","type":"string"},"core_weight":{"description":"Asset share of core value","type":"number"},"min_balance_reserve_asset":{"description":"Asset units held back from entries for the outstanding minimum-balance sells","type":"number"},"min_balance_reserve_cash":{"description":"Cash held back from entries for the outstanding minimum-balance buys","type":"number"},"open_risk":{"description":"Summed worst-case loss of the open trades","type":"number"},"phase":{"description":"Core phase","enum":["min_balance","active","deposit_required"],"example":"min_balance","type":"string"},"risk_basis_asset_value":{"description":"What the risk budget of a sell entry is taken on: value at price of the asset outside open buy trades, less open risk, not below 0","type":"number"},"risk_basis_cash":{"description":"What the risk budget of a buy entry is taken on: cash less the proceeds of open sell trades and open risk, not below 0","type":"number"}},"type":"object"},"api1.ValidateSignalCodeRequest":{"properties":{"code":{"description":"Python function code","type":"string"},"description":{"description":"Signal description","type":"string"},"params":{"description":"Parameter definitions (JSON object)","type":"object","x-mangrove-raw-json":true},"rule_name":{"description":"Expected function/rule name","type":"string"}},"required":["code","description","params"],"type":"object"},"api1.ValidateSignalParamsRequest":{"properties":{"parameters":{"default":{},"type":"object","x-mangrove-raw-json":true}},"type":"object"},"api1.ValidationResult":{"properties":{"errors":{"items":{"type":"string"},"type":"array"},"execution_valid":{"type":"boolean"},"metadata_valid":{"type":"boolean"},"syntax_valid":{"type":"boolean"},"trades_valid":{"type":"boolean"},"valid":{"type":"boolean"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["valid"],"type":"object"},"api1.VolatilityData":{"properties":{"max_drawdown_30d_pct":{"description":"30-day maximum drawdown (percent). Null if not computed.","type":"number"},"volatility_30d_pct":{"description":"30-day volatility (percent). Null if not computed.","type":"number"}},"type":"object"},"api1.XPostCountsResponse":{"properties":{"bucket_count":{"type":"integer"},"buckets":{"description":"Closed buckets, oldest first: start, end (ISO-8601 UTC), count","items":{"type":"object","x-mangrove-raw-json":true},"type":"array"},"buckets_cached":{"description":"Buckets served from the cache","type":"integer"},"days_back":{"type":"integer"},"granularity":{"enum":["hour","day"],"example":"hour","type":"string"},"query":{"description":"The exact X search query counted","type":"string"},"success":{"type":"boolean"},"symbol":{"type":"string"},"total_posts":{"description":"Sum of the bucket counts","type":"integer"},"x_query":{"enum":["all","en_original"],"example":"all","type":"string"},"x_requests":{"description":"X API requests made; 0 when fully cached","type":"integer"}},"type":"object"},"api2.AgentChatRequest":{"properties":{"execution_id":{"description":"Stable retry identity, paired with turn_id","type":"string"},"message":{"description":"What the person said","type":"string"},"turn_id":{"description":"Logical turn identity","type":"string"}},"required":["message"],"type":"object"},"api2.AsyncBacktestStatusResponse":{"properties":{"backtest_id":{"description":"UUID of the backtest run","type":"string"},"base_token":{"description":"Recorded canonical base token; null for historical runs","type":["string","null"],"x-nullable":true},"completed_at":{"description":"ISO timestamp when run finished","type":"string"},"created_at":{"description":"ISO timestamp when run was created","type":"string"},"equity_curve":{"description":"Timestamped marked account equity samples; time is Unix seconds UTC","type":"object","x-mangrove-raw-json":true},"error_message":{"description":"Error detail (populated when failed)","type":"string"},"execution_time_seconds":{"description":"Wall-clock simulation time","type":"number"},"market_data_venue":{"description":"Recorded market data venue; null for historical runs","type":["string","null"],"x-nullable":true},"metrics":{"description":"Performance metrics (populated when completed)","type":"object","x-mangrove-raw-json":true},"quote_token":{"description":"Recorded quote token; null for historical runs","type":["string","null"],"x-nullable":true},"status":{"description":"\"running\" | \"completed\" | \"failed\"","type":"string"},"trade_history":{"description":"Trade list (populated when completed)","type":"object","x-mangrove-raw-json":true}},"type":"object"},"api2.AsyncBacktestSubmitResponse":{"properties":{"backtest_id":{"description":"UUID of the enqueued backtest run","type":"string"},"base_token":{"description":"Recorded canonical base token; null for historical runs","type":["string","null"],"x-nullable":true},"market_data_venue":{"description":"Recorded market data venue; null for historical runs","type":["string","null"],"x-nullable":true},"quote_token":{"description":"Recorded quote token; null for historical runs","type":["string","null"],"x-nullable":true},"status":{"description":"Initial status (\"running\")","type":"string"}},"type":"object"},"api2.BacktestRequest":{"properties":{"asset":{"description":"Canonical base token, e.g. BTC","type":"string"},"base_token":{"description":"Explicit market base; supply all three market fields together","type":"string"},"cooldown_bars":{"description":"DEPRECATED. Read only under execution_config.cooldown_model \"bars\", where it defaults from trading_defaults.json (24) when omitted; ignored and dropped under the default \"trades\" model.","type":"integer"},"corpus_dataset":{"description":"Exact corpus window filename from a promoted sweep run","type":"string"},"daily_momentum_limit":{"description":"DEPRECATED. Read only under execution_config.cooldown_model \"bars\", where it defaults from trading_defaults.json (3) when omitted; ignored and dropped under the default \"trades\" model.","type":"number"},"data_file":{"description":"CSV filename if data_source=\"file\"","type":"string"},"data_source":{"description":"Data source: \"api\" or \"file\" (default: api)","type":"string"},"enable_volatility_adjustment":{"description":"Enable volatility adjustment","type":"boolean"},"end_date":{"description":"End date ISO format (e.g., \"2024-12-31\"). If omitted with start_date, defaults to now","type":"string"},"exchange":{"description":"Legacy: exchange name (not used for api data source)","type":"string"},"execution_config":{"allOf":[{"$ref":"#/components/schemas/api2.ExecutionConfiguration"}],"description":"Execution config dict with atr_period, volatility_tolerance, etc. If omitted, defaults from trading_defaults.json are used."},"fee_pct":{"description":"Max fee rate as decimal (default 0.0085 = 0.85%). Size-dependent linear schedule: $10K trades pay full rate, $1M+ trades pay 0.0589%. Applied only to profitable trades. Default from trading_defaults.json.","type":"number"},"generation":{"description":"Explicit engine generation; omit for latest","type":"integer"},"hourly_data_file":{"description":"Legacy: CSV file path (treated as data_file)","type":"string"},"initial_asset_balance":{"description":"position_size_calc \"v3\" only, and required there: asset units the account starts with.","type":"number"},"initial_balance":{"description":"Initial account balance. Under position_size_calc \"v3\": the starting cash, stated by the caller (never defaulted from a saved strategy).","type":"number"},"interval":{"description":"Time interval (e.g., \"1m\",\"5m\",\"15m\",\"30m\",\"1h\",\"4h\",\"1d\")","type":"string"},"lookback_months":{"description":"Lookback window in months for API data (default: 12)","type":"integer"},"market_data_venue":{"description":"Explicit market venue","type":"string"},"max_open_positions":{"description":"Maximum open positions","type":"integer"},"max_risk_per_trade":{"description":"Maximum risk per trade","type":"number"},"max_trade_amount":{"description":"Maximum trade amount","type":"number"},"max_trades_per_day":{"description":"Maximum trades per day","type":"integer"},"max_units_per_trade":{"description":"Maximum units per trade","type":"number"},"min_balance_threshold":{"description":"Minimum cash reserve as percentage (0.1 = 10%)","type":"number"},"min_trade_amount":{"description":"Minimum trade amount","type":"number"},"quote_token":{"description":"Explicit market quote","type":"string"},"seed":{"description":"Optional deterministic simulation seed forwarded to Oracle. Omitted preserves the Oracle default.","type":"integer"},"slippage_pct":{"description":"Max slippage per leg as decimal (e.g., 0.004 = 0.4%). Random slippage drawn from uniform(0, slippage_pct) independently for entry and exit. Default from trading_defaults.json: 0.004.","type":"number"},"start_date":{"description":"Start date ISO format (e.g., \"2024-01-01\"). If omitted, calculated from lookback_months","type":"string"},"strategy_id":{"description":"UUID of a saved strategy to backtest. When provided, strategy_json (and, if omitted, asset and execution_config) are loaded from the saved strategy. Mutually exclusive with strategy_json.","type":"string"},"strategy_json":{"description":"JSON config for the strategy (entry/exit rules, reward_factor). ATR params come from execution_config. Mutually exclusive with strategy_id; one of the two is required.","type":"string"},"target_volatility":{"description":"Target volatility","type":"number"},"volatility_mode":{"description":"Volatility mode","type":"string"},"volatility_window":{"description":"Volatility calculation window","type":"integer"},"weekly_momentum_limit":{"description":"DEPRECATED. Read only under execution_config.cooldown_model \"bars\", where it defaults from trading_defaults.json (3) when omitted; ignored and dropped under the default \"trades\" model.","type":"number"}},"required":["asset","enable_volatility_adjustment","initial_balance","max_open_positions","max_risk_per_trade","max_trade_amount","max_trades_per_day","max_units_per_trade","min_balance_threshold","min_trade_amount","target_volatility","volatility_mode","volatility_window"],"type":"object"},"api2.Error":{"properties":{"code":{"description":"Specific error code (e.g., INVALID_PROMPT_LENGTH, MISSING_AUTH_TOKEN)","type":"string"},"correlation_id":{"description":"Request correlation ID for tracing","type":"string"},"error":{"description":"Error category (validation_error, authentication_error, authorization_error, rate_limit_error, internal_error, service_unavailable)","type":"string"},"message":{"description":"Human-readable error message","type":"string"},"retry_after":{"description":"Retry after this many seconds (for rate_limit_error and service_unavailable errors)","type":"integer"}},"required":["code","error","message"],"type":"object"},"api2.ExecutionConfiguration":{"additionalProperties":true,"description":"Execution config accepts legacy/unknown fields and server-side numeric coercion. The attached authoring schema describes normalized values, not an additional input gate.","properties":{"atr_cap_multiplier":{"description":"SUPERSEDED by volatility_tolerance. Bounded the weighted blend at this multiple of the SHORT ATR.","x-mangrove-authoring-schema":{"description":"SUPERSEDED by volatility_tolerance. Bounded the weighted blend at this multiple of the SHORT ATR.","minimum":1.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy this is what made the weight pair inert past a long weight of roughly 6-12% (#1052).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"}},"atr_long_weight":{"description":"SUPERSEDED by volatility_tolerance. Weight of the daily ATR in the weighted-blend stop model, and always 1 - atr_short_weight rather than independent.","x-mangrove-authoring-schema":{"description":"SUPERSEDED by volatility_tolerance. Weight of the daily ATR in the weighted-blend stop model, and always 1 - atr_short_weight rather than independent.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. Derived, never independently effective.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"}},"atr_period":{"description":"ATR lookback in bars (default 14) used to measure volatility for stop sizing.","x-mangrove-authoring-schema":{"default":14,"description":"ATR lookback in bars (default 14) used to measure volatility for stop sizing.","maximum":1000,"minimum":5,"type":["integer","null"],"x-mangrove-effect":"Higher smooths the volatility estimate (steadier, slower-reacting stops). Lower reacts faster to recent volatility (choppier stops).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"atr_short_weight":{"description":"SUPERSEDED by volatility_tolerance. Weight of the signal-timeframe ATR in the weighted-blend stop model. Readable on a strategy created under that model; refused on any write.","x-mangrove-authoring-schema":{"description":"SUPERSEDED by volatility_tolerance. Weight of the signal-timeframe ATR in the weighted-blend stop model. Readable on a strategy created under that model; refused on any write.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy, higher favours the signal timeframe's own volatility -- though the cap made settings past a few percent of long weight indistinguishable (#1052).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"}},"atr_volatility_factor":{"description":"SUPERSEDED by volatility_tolerance. Multiplied the blended ATR to give the stop distance. The dial's two endpoint factors carry this instead, one at each end of the width.","x-mangrove-authoring-schema":{"description":"SUPERSEDED by volatility_tolerance. Multiplied the blended ATR to give the stop distance. The dial's two endpoint factors carry this instead, one at each end of the width.","exclusiveMinimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy, higher widens the stop and shrinks the position for the same risk.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"}},"circuit_breaker":{"description":"Parameters for cooldown_model 'trades': pause on consecutive net losses or accumulated loss amount, pause on marked drawdown from the peak (including unrealized changes), resume new alpha positions at a reduced size, and stop after consecutive pauses. Canon defaults are 36 primary bars for a loss pause, 72 for a drawdown pause, and three strikes for a permanent halt. Pause counts are clamped to 24 hours through 14 days by default. max_drawdown_halt_limit separately stops entries on realized loss of cumulative gross deposits. Existing exits remain active during holds.","x-mangrove-authoring-schema":{"additionalProperties":false,"default":{"consecutive_loss_limit":2,"drawdown_pause_bars":72,"loss_amount_pct":0.06,"max_consecutive_pauses":3,"pause_bars":36,"pause_max_days":14,"pause_min_hours":24,"resume_size_fraction":0.5,"resume_trades":3},"description":"Parameters for cooldown_model 'trades': pause on consecutive net losses or accumulated loss amount, pause on marked drawdown from the peak (including unrealized changes), resume new alpha positions at a reduced size, and stop after consecutive pauses. Canon defaults are 36 primary bars for a loss pause, 72 for a drawdown pause, and three strikes for a permanent halt. Pause counts are clamped to 24 hours through 14 days by default. max_drawdown_halt_limit separately stops entries on realized loss of cumulative gross deposits. Existing exits remain active during holds.","properties":{"consecutive_loss_limit":{"default":2,"description":"Consecutive losing closes on an asset that start a pause. A winning close resets the count.","maximum":100,"minimum":1,"type":"integer","x-mangrove-effect":"Lower pauses sooner after a losing run; higher tolerates longer runs.","x-mangrove-status":"tunable"},"drawdown_pause_bars":{"default":72,"description":"Primary-timeframe bars denying entries after a drawdown pause (canon default 72). At drawdown-pause expiry the peak re-baselines to current account value. An alpha resume window opens only once no pause remains and no permanent halt is latched. The count is raised to cover pause_min_hours and lowered to fit pause_max_days (24 hours through 14 days by default).","maximum":8760,"minimum":1,"type":"integer","x-mangrove-effect":"Longer holds the pause longer before trading can resume.","x-mangrove-status":"tunable"},"loss_amount_pct":{"default":0.06,"description":"Accumulated net losses as a fraction of the closed-equity reset baseline that start a loss pause. A winning close clears the accumulation and resets the baseline. An asset loss pause clears it at the start and re-baselines at expiry; a global drawdown pause does not itself reset it.","exclusiveMinimum":0.0,"maximum":1.0,"type":"number","x-mangrove-effect":"Lower pauses after smaller cumulative losses; higher tolerates larger ones.","x-mangrove-status":"tunable"},"max_consecutive_pauses":{"default":3,"description":"Strikes that stop the strategy until a manual restart. A strike is one pause started, of any kind (consecutive losses, loss amount, drawdown, a resume window that lost money). Strikes reset to 0 only on a new equity high: a close that leaves closed equity above the high-water mark the strategy had when the first strike of the run was recorded. A winning close below that mark does not reset them, and a deposit or withdrawal does not count as a high.","maximum":100,"minimum":1,"type":"integer","x-mangrove-effect":"Lower stops the strategy sooner; higher tolerates more repeated pauses.","x-mangrove-status":"tunable"},"pause_bars":{"default":36,"description":"Primary-timeframe bars denying entries after a loss pause (canon default 36). The count is raised to cover pause_min_hours and lowered to fit pause_max_days on that timeframe (24 hours through 14 days by default).","maximum":8760,"minimum":1,"type":"integer","x-mangrove-effect":"Longer sits out more of a bad regime; shorter resumes sooner.","x-mangrove-status":"tunable"},"pause_max_days":{"default":14,"description":"A pause lasts at most this many days on every timeframe: the bar count is lowered to fit it.","exclusiveMinimum":0.0,"maximum":365,"type":"number","x-mangrove-effect":"Lower ends every pause sooner on long timeframes; higher leaves the bar count to decide.","x-mangrove-status":"tunable"},"pause_min_hours":{"default":24,"description":"A pause lasts at least this many hours on every timeframe: the bar count of pause_bars or drawdown_pause_bars is raised to cover it.","exclusiveMinimum":0.0,"maximum":336,"type":"number","x-mangrove-effect":"Higher makes every pause at least that long on short timeframes; lower leaves the bar count to decide.","x-mangrove-status":"tunable"},"resume_size_fraction":{"default":0.5,"description":"Fraction of normal size for new alpha positions while a resume window is open (canon default 0.5). Eligible confirmed position closes count toward resume_trades; a negative net result starts another loss pause and strike, while zero or a profit restores full alpha size. Core orders keep their normal allocation quantities after pause expiry: they are not positions and do not consume resume-trade counts. 1.0 disables the alpha size reduction.","exclusiveMinimum":0.0,"maximum":1.0,"type":"number","x-mangrove-effect":"Lower risks less while the strategy proves itself again after a pause; higher resumes closer to full size.","x-mangrove-status":"tunable"},"resume_trades":{"default":3,"description":"Eligible confirmed position closes booked in a resume window (canon default three). When the window completes, a negative net realized result starts a new loss pause and strike; zero or a profit restores full alpha size. A pause cancels the active window; a new one opens only once no pause remains and no permanent halt is latched. Core orders do not count as position closes.","maximum":50,"minimum":1,"type":"integer","x-mangrove-effect":"Higher judges the resumed strategy over more trades before full size returns; lower decides sooner.","x-mangrove-status":"tunable"}},"type":["object","null"],"x-mangrove-effect":"Tighter limits pause and stop sooner; looser limits keep trading through losing runs.","x-mangrove-status":"guardrail"}},"cooldown_model":{"description":"Loss-streak breaker model. 'bars' counts losing closes inside rolling windows of the primary timeframe (cooldown_config). 'trades' counts consecutive losing closes and realized loss amount, pauses for circuit_breaker bars of the primary timeframe (at least pause_min_hours and at most pause_max_days), and stops after repeated pauses (circuit_breaker). An absent model adopts the canonical 'trades' defaults; explicit 'bars' retains the legacy model.","x-mangrove-authoring-schema":{"default":"trades","description":"Loss-streak breaker model. 'bars' counts losing closes inside rolling windows of the primary timeframe (cooldown_config). 'trades' counts consecutive losing closes and realized loss amount, pauses for circuit_breaker bars of the primary timeframe (at least pause_min_hours and at most pause_max_days), and stops after repeated pauses (circuit_breaker). An absent model adopts the canonical 'trades' defaults; explicit 'bars' retains the legacy model.","enum":["bars","trades",null],"type":["string","null"],"x-mangrove-effect":"'trades' trips on trade count and loss size regardless of how far apart trades are spaced; 'bars' trips only when losses land inside the window. cooldown_config, cooldown_bars, daily_momentum_limit and weekly_momentum_limit are read only under 'bars': they are left out of a resolved config under 'trades', and a config that carries them under 'trades' has them dropped.","x-mangrove-status":"guardrail"}},"enable_volatility_adjustment":{"description":"Toggles volatility-based position scaling (default false).","x-mangrove-authoring-schema":{"default":false,"description":"Toggles volatility-based position scaling (default false).","type":["boolean","null"],"x-mangrove-effect":"When true, positions are scaled down by target_volatility / (atr/entry) if ATR%% exceeds target; only reduces size, never increases.","x-mangrove-status":"gated"}},"exit_on_loss_after_bars":{"description":"Exit a losing position after this many bars.","x-mangrove-authoring-schema":{"default":1000,"description":"Exit a losing position after this many bars.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Lower cuts losers sooner; higher gives them more time to recover.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"exit_on_profit_after_bars":{"description":"Exit a winning position after this many bars.","x-mangrove-authoring-schema":{"default":1000,"description":"Exit a winning position after this many bars.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Lower banks winners sooner; higher lets them run.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"initial_balance":{"description":"Starting balance for the backtest/simulation (default $10,000).","x-mangrove-authoring-schema":{"default":10000,"description":"Starting balance for the backtest/simulation (default $10,000).","maximum":1000000000.0,"minimum":25.0,"type":["number","null"],"x-mangrove-effect":"Scales absolute dollar figures; not a strategy-character knob.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"max_drawdown_halt_limit":{"description":"Permanent capital-floor entry halt (0.20 = 20%). Closed, realized equity is compared with cumulative gross deposits (execution_state.cumulative_deposits), not a rolling peak or the signed net-funding balance; withdrawals do not reduce this reference. Legacy requests without cumulative_deposits use execution_config.initial_balance. The shared live/paper evaluator checks before each bar and latches execution_state.halt. New alpha entries and v3 core allocations are denied, while authoritative positions retain protective exits and exits_pending until physically flat. Engine-owned strategies become inactive only after that book is flat; caller-owned executors retain their exit monitor. An explicit manual restart is required to clear the latch. Backtests enforce the same floor when evaluate_bar receives enforce_capital_floor=True, managing open-position exits through the final bar. Applies to both cooldown models; null disables new floor trips, while an existing halt remains latched.","x-mangrove-authoring-schema":{"default":0.2,"description":"Permanent capital-floor entry halt (0.20 = 20%). Closed, realized equity is compared with cumulative gross deposits (execution_state.cumulative_deposits), not a rolling peak or the signed net-funding balance; withdrawals do not reduce this reference. Legacy requests without cumulative_deposits use execution_config.initial_balance. The shared live/paper evaluator checks before each bar and latches execution_state.halt. New alpha entries and v3 core allocations are denied, while authoritative positions retain protective exits and exits_pending until physically flat. Engine-owned strategies become inactive only after that book is flat; caller-owned executors retain their exit monitor. An explicit manual restart is required to clear the latch. Backtests enforce the same floor when evaluate_bar receives enforce_capital_floor=True, managing open-position exits through the final bar. Applies to both cooldown models; null disables new floor trips, while an existing halt remains latched.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Lower protects more of gross deposited capital before a permanent entry halt; higher tolerates a deeper realized loss. This does not resize positions or stop protective exit evaluation. Do not add a separate floor where the shared evaluator enforces it.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"max_drawdown_limit":{"description":"Peak-relative entry pause (0.20 = 20%). The canonical 'trades' model measures marked equity against its high-water mark. A breach starts one drawdown pause and strike; circuit_breaker.drawdown_pause_bars defaults to 72 primary bars, clamped to pause_min_hours and pause_max_days (24 hours and 14 days by default). At drawdown-pause expiry the peak re-baselines; a reduced-size alpha resume window opens only once no pause remains and no permanent halt is latched. Explicit 'bars' retains the legacy closed-equity measurement and per-timeframe long cooldown. Both models deny new entries while allowing existing positions to exit; automatic v3 core allocations honor the hold too. null disables new drawdown trips.","x-mangrove-authoring-schema":{"default":0.2,"description":"Peak-relative entry pause (0.20 = 20%). The canonical 'trades' model measures marked equity against its high-water mark. A breach starts one drawdown pause and strike; circuit_breaker.drawdown_pause_bars defaults to 72 primary bars, clamped to pause_min_hours and pause_max_days (24 hours and 14 days by default). At drawdown-pause expiry the peak re-baselines; a reduced-size alpha resume window opens only once no pause remains and no permanent halt is latched. Explicit 'bars' retains the legacy closed-equity measurement and per-timeframe long cooldown. Both models deny new entries while allowing existing positions to exit; automatic v3 core allocations honor the hold too. null disables new drawdown trips.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Lower pauses entries after a smaller drawdown; higher tolerates a deeper drawdown. The shared entry breaker enforces this in single/bulk live and paper evaluation, v3 core allocation and backtests built with risk_manager_from_execution_config. Alpha resume sizing is a separate control; do not add a second drawdown stop.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"max_hold_bars":{"description":"Maximum bars to hold any position before a forced exit.","x-mangrove-authoring-schema":{"default":1000,"description":"Maximum bars to hold any position before a forced exit.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher lets trades run longer; lower forces earlier time-based exits.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"max_hold_time_hours":{"description":"Maximum position hold time in hours (null = no limit).","x-mangrove-authoring-schema":{"default":null,"description":"Maximum position hold time in hours (null = no limit).","exclusiveMinimum":1,"maximum":8760,"type":["integer","null"],"x-mangrove-effect":"Lower forces earlier time-based exits; null/higher lets trades run indefinitely on time.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"max_open_positions":{"description":"Maximum concurrent open positions.","x-mangrove-authoring-schema":{"default":10,"description":"Maximum concurrent open positions.","maximum":1000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher allows more simultaneous exposure (more diversification but more aggregate risk); lower is more selective with less aggregate exposure.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"max_risk_per_trade":{"description":"Fraction of account equity risked per trade (0.01 = 1%). Position size is derived from this and the stop distance.","x-mangrove-authoring-schema":{"default":0.01,"description":"Fraction of account equity risked per trade (0.01 = 1%). Position size is derived from this and the stop distance.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Higher risks more per trade: bigger positions, larger gains AND larger drawdowns. Lower is more conservative: smaller positions, smaller swings.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"max_trade_amount":{"description":"Absolute cap on dollar size per trade.","x-mangrove-authoring-schema":{"default":10000000,"description":"Absolute cap on dollar size per trade.","exclusiveMinimum":0.0,"maximum":1000000000000.0,"type":["number","null"],"x-mangrove-effect":"Size guardrail; rarely binding.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"max_trades_per_day":{"description":"Daily trade cap.","x-mangrove-authoring-schema":{"default":50,"description":"Daily trade cap.","maximum":1440,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher permits more churn; lower throttles activity.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"max_units_per_trade":{"description":"Absolute cap on units per trade.","x-mangrove-authoring-schema":{"default":1000000,"description":"Absolute cap on units per trade.","exclusiveMinimum":0.0,"maximum":1000000000000.0,"type":["number","null"],"x-mangrove-effect":"Size guardrail; rarely binding.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"min_asset_balance":{"description":"position_size_calc 'v3' only. Minimum asset balance, in asset units, the strategy holds outside open trades.","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Minimum asset balance, in asset units, the strategy holds outside open trades.","minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more of the asset out of reach of sell trades and core sells, and takes more cash to reach; lower frees more of the asset for trading.","x-mangrove-status":"guardrail"}},"min_balance_days":{"description":"position_size_calc 'v3' only. Number of equal daily orders used to bring a side up to its minimum balance.","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Number of equal daily orders used to bring a side up to its minimum balance.","minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher spreads the minimum-balance orders over more days at smaller size; lower reaches the minimum sooner with larger orders.","x-mangrove-status":"guardrail"}},"min_balance_threshold":{"description":"Cash reserve fraction held back from new entries (0.1 = 10%). v1 reserves this fraction of cash; v2 reserves this fraction of account value (cash + open positions at market). An entry may only use cash above the reserve; when no cash is deployable the entry is denied (insufficient_cash / insufficient_cash_v2_account_reserve). It never halts the strategy and never closes positions.","x-mangrove-authoring-schema":{"default":0.1,"description":"Cash reserve fraction held back from new entries (0.1 = 10%). v1 reserves this fraction of cash; v2 reserves this fraction of account value (cash + open positions at market). An entry may only use cash above the reserve; when no cash is deployable the entry is denied (insufficient_cash / insufficient_cash_v2_account_reserve). It never halts the strategy and never closes positions.","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more cash idle and makes entries smaller or rarer as the account shrinks; lower lets entries use more of the balance. Not a drawdown stop; see max_drawdown_limit and max_drawdown_halt_limit.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"min_cash_balance":{"description":"position_size_calc 'v3' only. Minimum cash balance the strategy holds after the worst-case loss of every open trade.","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Minimum cash balance the strategy holds after the worst-case loss of every open trade.","minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more cash out of reach of buy trades and core buys, so entries are smaller or rarer; lower frees more cash for trading.","x-mangrove-status":"guardrail"}},"min_stop_distance_pct":{"description":"Hard floor on stop distance as a fraction of entry price (crypto minimum), applied after ATR sizing.","x-mangrove-authoring-schema":{"default":0.005,"description":"Hard floor on stop distance as a fraction of entry price (crypto minimum), applied after ATR sizing.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher enforces a wider minimum stop; lower allows tighter stops down to the floor.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"min_trade_amount":{"description":"Minimum trade size in dollars; smaller intended trades are skipped.","x-mangrove-authoring-schema":{"default":25,"description":"Minimum trade size in dollars; smaller intended trades are skipped.","maximum":1000000.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher skips more small signals; lower allows smaller trades.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"position_size_calc":{"description":"Sizing-engine version ('v1', 'v2' or 'v3'). Pinned at creation and immutable. 'v3' holds an asset balance and a cash balance, sizes against equity net of open risk, and requires the position_size_calc 'v3' parameters.","x-mangrove-authoring-schema":{"default":"v2","description":"Sizing-engine version ('v1', 'v2' or 'v3'). Pinned at creation and immutable. 'v3' holds an asset balance and a cash balance, sizes against equity net of open risk, and requires the position_size_calc 'v3' parameters.","enum":["v1","v2","v3",null],"type":["string","null"],"x-mangrove-effect":"Not a magnitude knob; selects the sizing algorithm. Do not change on an existing strategy.","x-mangrove-status":"guardrail"}},"profit_threshold_pct":{"description":"Profit threshold (5%% default) above which a position counts as 'winning' for the time-based exit logic.","x-mangrove-authoring-schema":{"default":0.05,"description":"Profit threshold (5%% default) above which a position counts as 'winning' for the time-based exit logic.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher requires a larger gain before a position is treated as winning; lower treats smaller gains as wins.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"rebalance_band":{"description":"position_size_calc 'v3' only. Absolute deviation of the asset weight from target_asset_weight that triggers a rebalance order (0.05 = 5 points).","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Absolute deviation of the asset weight from target_asset_weight that triggers a rebalance order (0.05 = 5 points).","exclusiveMaximum":1.0,"exclusiveMinimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher lets the split drift further before a rebalance order, so fewer core orders; lower holds the split closer to target with more core orders and more fees.","x-mangrove-status":"tunable"}},"reward_factor":{"description":"Risk/reward target. Take-profit distance = reward_factor * stop_distance.","x-mangrove-authoring-schema":{"default":2,"description":"Risk/reward target. Take-profit distance = reward_factor * stop_distance.","exclusiveMinimum":0.0,"maximum":100.0,"type":["number","null"],"x-mangrove-effect":"Higher sets a wider profit target: lower win rate but bigger wins. Lower sets a tighter target: higher win rate but smaller wins.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"stop_gap_allowance":{"description":"position_size_calc 'v3' only. Fraction of the stop price a stop fill is assumed to miss by when computing the worst-case loss of a trade (0.01 = 1%).","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Fraction of the stop price a stop fill is assumed to miss by when computing the worst-case loss of a trade (0.01 = 1%).","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher counts more risk per open trade, leaving less available cash and smaller positions; lower counts less.","x-mangrove-status":"guardrail"}},"stop_model":{"description":"Which stop model the strategy uses: 'atr_width_dial' (one parameter, volatility_tolerance, positioned on the ATR width) or 'weighted_atr' (superseded: a weighted blend of two ATRs, capped). Pinned at creation and immutable.","x-mangrove-authoring-schema":{"default":"atr_width_dial","description":"Which stop model the strategy uses: 'atr_width_dial' (one parameter, volatility_tolerance, positioned on the ATR width) or 'weighted_atr' (superseded: a weighted blend of two ATRs, capped). Pinned at creation and immutable.","enum":["atr_width_dial","weighted_atr",null],"type":["string","null"],"x-mangrove-effect":"Not a magnitude knob; selects the stop algorithm. Do not change on an existing strategy -- it would move every stop the strategy takes.","x-mangrove-status":"guardrail"}},"taker_fee_rate":{"description":"position_size_calc 'v3' only. Venue fee per fill as a fraction of notional, charged in cash (0.004 = 0.4%).","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Venue fee per fill as a fraction of notional, charged in cash (0.004 = 0.4%).","exclusiveMaximum":0.1,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher counts more cost per fill, raising the risk of each trade and lowering available cash. Models the venue; not a strategy-character knob.","x-mangrove-status":"guardrail"}},"target_asset_weight":{"description":"position_size_calc 'v3' only. Target share of core value held in the asset (0.8 = 80% asset, 20% cash; 0 = all cash).","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Target share of core value held in the asset (0.8 = 80% asset, 20% cash; 0 = all cash).","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher holds more of the asset and less cash; lower holds more cash. The daily core order moves the split back to this value once it drifts past rebalance_band. At 0 with no asset held, no core order is placed and only buy trades can pass.","x-mangrove-status":"tunable"}},"target_volatility":{"description":"Target volatility (0.10 = 10%). ONLY active when enable_volatility_adjustment is true (default false). When active, scales position size down if ATR%% of entry exceeds the target (never up).","x-mangrove-authoring-schema":{"default":0.1,"description":"Target volatility (0.10 = 10%). ONLY active when enable_volatility_adjustment is true (default false). When active, scales position size down if ATR%% of entry exceeds the target (never up).","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"With the gate off (the default), changing this has no effect. With it on, lower scales positions down more aggressively in high volatility.","x-mangrove-gate-field":"enable_volatility_adjustment","x-mangrove-gate-required":true,"x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"gated"}},"volatility_mode":{"description":"Unused (retained for backward compatibility). Volatility is derived from ATR.","x-mangrove-authoring-schema":{"default":"stddev","description":"Unused (retained for backward compatibility). Volatility is derived from ATR.","enum":["stddev","atr",null],"type":["string","null"],"x-mangrove-effect":"No runtime effect. Do not tune.","x-mangrove-status":"unused"}},"volatility_tolerance":{"description":"Where on the ATR width the stop is taken, as the ATR_long-vs-ATR_short contribution ratio: 0 is all short end (0.5x the signal timeframe's ATR), 1 is all long end (2x the daily ATR). Interpolated geometrically, so the value is exactly the long end's share of log(stop) and each 0.1 is the same multiplicative step. Replaces atr_short_weight, atr_long_weight and atr_cap_multiplier.","x-mangrove-authoring-schema":{"default":0.5,"description":"Where on the ATR width the stop is taken, as the ATR_long-vs-ATR_short contribution ratio: 0 is all short end (0.5x the signal timeframe's ATR), 1 is all long end (2x the daily ATR). Interpolated geometrically, so the value is exactly the long end's share of log(stop) and each 0.1 is the same multiplicative step. Replaces atr_short_weight, atr_long_weight and atr_cap_multiplier.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher widens the stop, and because position size is the risk budget divided by the stop distance, exposure shrinks in exact inverse proportion at the SAME risk. Low means many units with little room to be wrong and frequent stop-outs; high means few units that are hard to shake out but need a much larger move to reach the same reward. Both risk max_risk_per_trade.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"volatility_window":{"description":"Unused (retained for backward compatibility). ATR windowing is controlled by atr_period.","x-mangrove-authoring-schema":{"default":24,"description":"Unused (retained for backward compatibility). ATR windowing is controlled by atr_period.","maximum":1000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"No runtime effect. Do not tune.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"unused"}}},"type":"object","x-mangrove-authoring-schema":{"$id":"urn:mangrove:execution-config:1","$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":true,"description":"Canonical authoring representation derived from server metadata and defaults. Top-level optional keys may be omitted or null. The existing HTTP validator separately coerces top-level numeric strings, enforces their declared bounds and permits unknown/legacy fields; it does not enforce this whole nested schema. Runtime strategy/version/timeframe checks remain authoritative. Cooldown durations may be omitted by legacy configs and then fall back to their corresponding windows.","properties":{"atr_cap_multiplier":{"description":"SUPERSEDED by volatility_tolerance. Bounded the weighted blend at this multiple of the SHORT ATR.","minimum":1.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy this is what made the weight pair inert past a long weight of roughly 6-12% (#1052).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"},"atr_long_weight":{"description":"SUPERSEDED by volatility_tolerance. Weight of the daily ATR in the weighted-blend stop model, and always 1 - atr_short_weight rather than independent.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. Derived, never independently effective.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"},"atr_period":{"default":14,"description":"ATR lookback in bars (default 14) used to measure volatility for stop sizing.","maximum":1000,"minimum":5,"type":["integer","null"],"x-mangrove-effect":"Higher smooths the volatility estimate (steadier, slower-reacting stops). Lower reacts faster to recent volatility (choppier stops).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"atr_short_weight":{"description":"SUPERSEDED by volatility_tolerance. Weight of the signal-timeframe ATR in the weighted-blend stop model. Readable on a strategy created under that model; refused on any write.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy, higher favours the signal timeframe's own volatility -- though the cap made settings past a few percent of long weight indistinguishable (#1052).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"},"atr_volatility_factor":{"description":"SUPERSEDED by volatility_tolerance. Multiplied the blended ATR to give the stop distance. The dial's two endpoint factors carry this instead, one at each end of the width.","exclusiveMinimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy, higher widens the stop and shrinks the position for the same risk.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"},"circuit_breaker":{"additionalProperties":false,"default":{"consecutive_loss_limit":2,"drawdown_pause_bars":72,"loss_amount_pct":0.06,"max_consecutive_pauses":3,"pause_bars":36,"pause_max_days":14,"pause_min_hours":24,"resume_size_fraction":0.5,"resume_trades":3},"description":"Parameters for cooldown_model 'trades': pause on consecutive net losses or accumulated loss amount, pause on marked drawdown from the peak (including unrealized changes), resume new alpha positions at a reduced size, and stop after consecutive pauses. Canon defaults are 36 primary bars for a loss pause, 72 for a drawdown pause, and three strikes for a permanent halt. Pause counts are clamped to 24 hours through 14 days by default. max_drawdown_halt_limit separately stops entries on realized loss of cumulative gross deposits. Existing exits remain active during holds.","properties":{"consecutive_loss_limit":{"default":2,"description":"Consecutive losing closes on an asset that start a pause. A winning close resets the count.","maximum":100,"minimum":1,"type":"integer","x-mangrove-effect":"Lower pauses sooner after a losing run; higher tolerates longer runs.","x-mangrove-status":"tunable"},"drawdown_pause_bars":{"default":72,"description":"Primary-timeframe bars denying entries after a drawdown pause (canon default 72). At drawdown-pause expiry the peak re-baselines to current account value. An alpha resume window opens only once no pause remains and no permanent halt is latched. The count is raised to cover pause_min_hours and lowered to fit pause_max_days (24 hours through 14 days by default).","maximum":8760,"minimum":1,"type":"integer","x-mangrove-effect":"Longer holds the pause longer before trading can resume.","x-mangrove-status":"tunable"},"loss_amount_pct":{"default":0.06,"description":"Accumulated net losses as a fraction of the closed-equity reset baseline that start a loss pause. A winning close clears the accumulation and resets the baseline. An asset loss pause clears it at the start and re-baselines at expiry; a global drawdown pause does not itself reset it.","exclusiveMinimum":0.0,"maximum":1.0,"type":"number","x-mangrove-effect":"Lower pauses after smaller cumulative losses; higher tolerates larger ones.","x-mangrove-status":"tunable"},"max_consecutive_pauses":{"default":3,"description":"Strikes that stop the strategy until a manual restart. A strike is one pause started, of any kind (consecutive losses, loss amount, drawdown, a resume window that lost money). Strikes reset to 0 only on a new equity high: a close that leaves closed equity above the high-water mark the strategy had when the first strike of the run was recorded. A winning close below that mark does not reset them, and a deposit or withdrawal does not count as a high.","maximum":100,"minimum":1,"type":"integer","x-mangrove-effect":"Lower stops the strategy sooner; higher tolerates more repeated pauses.","x-mangrove-status":"tunable"},"pause_bars":{"default":36,"description":"Primary-timeframe bars denying entries after a loss pause (canon default 36). The count is raised to cover pause_min_hours and lowered to fit pause_max_days on that timeframe (24 hours through 14 days by default).","maximum":8760,"minimum":1,"type":"integer","x-mangrove-effect":"Longer sits out more of a bad regime; shorter resumes sooner.","x-mangrove-status":"tunable"},"pause_max_days":{"default":14,"description":"A pause lasts at most this many days on every timeframe: the bar count is lowered to fit it.","exclusiveMinimum":0.0,"maximum":365,"type":"number","x-mangrove-effect":"Lower ends every pause sooner on long timeframes; higher leaves the bar count to decide.","x-mangrove-status":"tunable"},"pause_min_hours":{"default":24,"description":"A pause lasts at least this many hours on every timeframe: the bar count of pause_bars or drawdown_pause_bars is raised to cover it.","exclusiveMinimum":0.0,"maximum":336,"type":"number","x-mangrove-effect":"Higher makes every pause at least that long on short timeframes; lower leaves the bar count to decide.","x-mangrove-status":"tunable"},"resume_size_fraction":{"default":0.5,"description":"Fraction of normal size for new alpha positions while a resume window is open (canon default 0.5). Eligible confirmed position closes count toward resume_trades; a negative net result starts another loss pause and strike, while zero or a profit restores full alpha size. Core orders keep their normal allocation quantities after pause expiry: they are not positions and do not consume resume-trade counts. 1.0 disables the alpha size reduction.","exclusiveMinimum":0.0,"maximum":1.0,"type":"number","x-mangrove-effect":"Lower risks less while the strategy proves itself again after a pause; higher resumes closer to full size.","x-mangrove-status":"tunable"},"resume_trades":{"default":3,"description":"Eligible confirmed position closes booked in a resume window (canon default three). When the window completes, a negative net realized result starts a new loss pause and strike; zero or a profit restores full alpha size. A pause cancels the active window; a new one opens only once no pause remains and no permanent halt is latched. Core orders do not count as position closes.","maximum":50,"minimum":1,"type":"integer","x-mangrove-effect":"Higher judges the resumed strategy over more trades before full size returns; lower decides sooner.","x-mangrove-status":"tunable"}},"type":["object","null"],"x-mangrove-effect":"Tighter limits pause and stop sooner; looser limits keep trading through losing runs.","x-mangrove-status":"guardrail"},"cooldown_model":{"default":"trades","description":"Loss-streak breaker model. 'bars' counts losing closes inside rolling windows of the primary timeframe (cooldown_config). 'trades' counts consecutive losing closes and realized loss amount, pauses for circuit_breaker bars of the primary timeframe (at least pause_min_hours and at most pause_max_days), and stops after repeated pauses (circuit_breaker). An absent model adopts the canonical 'trades' defaults; explicit 'bars' retains the legacy model.","enum":["bars","trades",null],"type":["string","null"],"x-mangrove-effect":"'trades' trips on trade count and loss size regardless of how far apart trades are spaced; 'bars' trips only when losses land inside the window. cooldown_config, cooldown_bars, daily_momentum_limit and weekly_momentum_limit are read only under 'bars': they are left out of a resolved config under 'trades', and a config that carries them under 'trades' has them dropped.","x-mangrove-status":"guardrail"},"enable_volatility_adjustment":{"default":false,"description":"Toggles volatility-based position scaling (default false).","type":["boolean","null"],"x-mangrove-effect":"When true, positions are scaled down by target_volatility / (atr/entry) if ATR%% exceeds target; only reduces size, never increases.","x-mangrove-status":"gated"},"exit_on_loss_after_bars":{"default":1000,"description":"Exit a losing position after this many bars.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Lower cuts losers sooner; higher gives them more time to recover.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"exit_on_profit_after_bars":{"default":1000,"description":"Exit a winning position after this many bars.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Lower banks winners sooner; higher lets them run.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"initial_balance":{"default":10000,"description":"Starting balance for the backtest/simulation (default $10,000).","maximum":1000000000.0,"minimum":25.0,"type":["number","null"],"x-mangrove-effect":"Scales absolute dollar figures; not a strategy-character knob.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"max_drawdown_halt_limit":{"default":0.2,"description":"Permanent capital-floor entry halt (0.20 = 20%). Closed, realized equity is compared with cumulative gross deposits (execution_state.cumulative_deposits), not a rolling peak or the signed net-funding balance; withdrawals do not reduce this reference. Legacy requests without cumulative_deposits use execution_config.initial_balance. The shared live/paper evaluator checks before each bar and latches execution_state.halt. New alpha entries and v3 core allocations are denied, while authoritative positions retain protective exits and exits_pending until physically flat. Engine-owned strategies become inactive only after that book is flat; caller-owned executors retain their exit monitor. An explicit manual restart is required to clear the latch. Backtests enforce the same floor when evaluate_bar receives enforce_capital_floor=True, managing open-position exits through the final bar. Applies to both cooldown models; null disables new floor trips, while an existing halt remains latched.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Lower protects more of gross deposited capital before a permanent entry halt; higher tolerates a deeper realized loss. This does not resize positions or stop protective exit evaluation. Do not add a separate floor where the shared evaluator enforces it.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"max_drawdown_limit":{"default":0.2,"description":"Peak-relative entry pause (0.20 = 20%). The canonical 'trades' model measures marked equity against its high-water mark. A breach starts one drawdown pause and strike; circuit_breaker.drawdown_pause_bars defaults to 72 primary bars, clamped to pause_min_hours and pause_max_days (24 hours and 14 days by default). At drawdown-pause expiry the peak re-baselines; a reduced-size alpha resume window opens only once no pause remains and no permanent halt is latched. Explicit 'bars' retains the legacy closed-equity measurement and per-timeframe long cooldown. Both models deny new entries while allowing existing positions to exit; automatic v3 core allocations honor the hold too. null disables new drawdown trips.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Lower pauses entries after a smaller drawdown; higher tolerates a deeper drawdown. The shared entry breaker enforces this in single/bulk live and paper evaluation, v3 core allocation and backtests built with risk_manager_from_execution_config. Alpha resume sizing is a separate control; do not add a second drawdown stop.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"max_hold_bars":{"default":1000,"description":"Maximum bars to hold any position before a forced exit.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher lets trades run longer; lower forces earlier time-based exits.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"max_hold_time_hours":{"default":null,"description":"Maximum position hold time in hours (null = no limit).","exclusiveMinimum":1,"maximum":8760,"type":["integer","null"],"x-mangrove-effect":"Lower forces earlier time-based exits; null/higher lets trades run indefinitely on time.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"max_open_positions":{"default":10,"description":"Maximum concurrent open positions.","maximum":1000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher allows more simultaneous exposure (more diversification but more aggregate risk); lower is more selective with less aggregate exposure.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"max_risk_per_trade":{"default":0.01,"description":"Fraction of account equity risked per trade (0.01 = 1%). Position size is derived from this and the stop distance.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Higher risks more per trade: bigger positions, larger gains AND larger drawdowns. Lower is more conservative: smaller positions, smaller swings.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"max_trade_amount":{"default":10000000,"description":"Absolute cap on dollar size per trade.","exclusiveMinimum":0.0,"maximum":1000000000000.0,"type":["number","null"],"x-mangrove-effect":"Size guardrail; rarely binding.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"max_trades_per_day":{"default":50,"description":"Daily trade cap.","maximum":1440,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher permits more churn; lower throttles activity.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"max_units_per_trade":{"default":1000000,"description":"Absolute cap on units per trade.","exclusiveMinimum":0.0,"maximum":1000000000000.0,"type":["number","null"],"x-mangrove-effect":"Size guardrail; rarely binding.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"min_asset_balance":{"description":"position_size_calc 'v3' only. Minimum asset balance, in asset units, the strategy holds outside open trades.","minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more of the asset out of reach of sell trades and core sells, and takes more cash to reach; lower frees more of the asset for trading.","x-mangrove-status":"guardrail"},"min_balance_days":{"description":"position_size_calc 'v3' only. Number of equal daily orders used to bring a side up to its minimum balance.","minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher spreads the minimum-balance orders over more days at smaller size; lower reaches the minimum sooner with larger orders.","x-mangrove-status":"guardrail"},"min_balance_threshold":{"default":0.1,"description":"Cash reserve fraction held back from new entries (0.1 = 10%). v1 reserves this fraction of cash; v2 reserves this fraction of account value (cash + open positions at market). An entry may only use cash above the reserve; when no cash is deployable the entry is denied (insufficient_cash / insufficient_cash_v2_account_reserve). It never halts the strategy and never closes positions.","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more cash idle and makes entries smaller or rarer as the account shrinks; lower lets entries use more of the balance. Not a drawdown stop; see max_drawdown_limit and max_drawdown_halt_limit.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"min_cash_balance":{"description":"position_size_calc 'v3' only. Minimum cash balance the strategy holds after the worst-case loss of every open trade.","minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more cash out of reach of buy trades and core buys, so entries are smaller or rarer; lower frees more cash for trading.","x-mangrove-status":"guardrail"},"min_stop_distance_pct":{"default":0.005,"description":"Hard floor on stop distance as a fraction of entry price (crypto minimum), applied after ATR sizing.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher enforces a wider minimum stop; lower allows tighter stops down to the floor.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"min_trade_amount":{"default":25,"description":"Minimum trade size in dollars; smaller intended trades are skipped.","maximum":1000000.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher skips more small signals; lower allows smaller trades.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"position_size_calc":{"default":"v2","description":"Sizing-engine version ('v1', 'v2' or 'v3'). Pinned at creation and immutable. 'v3' holds an asset balance and a cash balance, sizes against equity net of open risk, and requires the position_size_calc 'v3' parameters.","enum":["v1","v2","v3",null],"type":["string","null"],"x-mangrove-effect":"Not a magnitude knob; selects the sizing algorithm. Do not change on an existing strategy.","x-mangrove-status":"guardrail"},"profit_threshold_pct":{"default":0.05,"description":"Profit threshold (5%% default) above which a position counts as 'winning' for the time-based exit logic.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher requires a larger gain before a position is treated as winning; lower treats smaller gains as wins.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"rebalance_band":{"description":"position_size_calc 'v3' only. Absolute deviation of the asset weight from target_asset_weight that triggers a rebalance order (0.05 = 5 points).","exclusiveMaximum":1.0,"exclusiveMinimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher lets the split drift further before a rebalance order, so fewer core orders; lower holds the split closer to target with more core orders and more fees.","x-mangrove-status":"tunable"},"reward_factor":{"default":2,"description":"Risk/reward target. Take-profit distance = reward_factor * stop_distance.","exclusiveMinimum":0.0,"maximum":100.0,"type":["number","null"],"x-mangrove-effect":"Higher sets a wider profit target: lower win rate but bigger wins. Lower sets a tighter target: higher win rate but smaller wins.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"stop_gap_allowance":{"description":"position_size_calc 'v3' only. Fraction of the stop price a stop fill is assumed to miss by when computing the worst-case loss of a trade (0.01 = 1%).","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher counts more risk per open trade, leaving less available cash and smaller positions; lower counts less.","x-mangrove-status":"guardrail"},"stop_model":{"default":"atr_width_dial","description":"Which stop model the strategy uses: 'atr_width_dial' (one parameter, volatility_tolerance, positioned on the ATR width) or 'weighted_atr' (superseded: a weighted blend of two ATRs, capped). Pinned at creation and immutable.","enum":["atr_width_dial","weighted_atr",null],"type":["string","null"],"x-mangrove-effect":"Not a magnitude knob; selects the stop algorithm. Do not change on an existing strategy -- it would move every stop the strategy takes.","x-mangrove-status":"guardrail"},"taker_fee_rate":{"description":"position_size_calc 'v3' only. Venue fee per fill as a fraction of notional, charged in cash (0.004 = 0.4%).","exclusiveMaximum":0.1,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher counts more cost per fill, raising the risk of each trade and lowering available cash. Models the venue; not a strategy-character knob.","x-mangrove-status":"guardrail"},"target_asset_weight":{"description":"position_size_calc 'v3' only. Target share of core value held in the asset (0.8 = 80% asset, 20% cash; 0 = all cash).","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher holds more of the asset and less cash; lower holds more cash. The daily core order moves the split back to this value once it drifts past rebalance_band. At 0 with no asset held, no core order is placed and only buy trades can pass.","x-mangrove-status":"tunable"},"target_volatility":{"default":0.1,"description":"Target volatility (0.10 = 10%). ONLY active when enable_volatility_adjustment is true (default false). When active, scales position size down if ATR%% of entry exceeds the target (never up).","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"With the gate off (the default), changing this has no effect. With it on, lower scales positions down more aggressively in high volatility.","x-mangrove-gate-field":"enable_volatility_adjustment","x-mangrove-gate-required":true,"x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"gated"},"volatility_mode":{"default":"stddev","description":"Unused (retained for backward compatibility). Volatility is derived from ATR.","enum":["stddev","atr",null],"type":["string","null"],"x-mangrove-effect":"No runtime effect. Do not tune.","x-mangrove-status":"unused"},"volatility_tolerance":{"default":0.5,"description":"Where on the ATR width the stop is taken, as the ATR_long-vs-ATR_short contribution ratio: 0 is all short end (0.5x the signal timeframe's ATR), 1 is all long end (2x the daily ATR). Interpolated geometrically, so the value is exactly the long end's share of log(stop) and each 0.1 is the same multiplicative step. Replaces atr_short_weight, atr_long_weight and atr_cap_multiplier.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher widens the stop, and because position size is the risk budget divided by the stop distance, exposure shrinks in exact inverse proportion at the SAME risk. Low means many units with little room to be wrong and frequent stop-outs; high means few units that are hard to shake out but need a much larger move to reach the same reward. Both risk max_risk_per_trade.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"volatility_window":{"default":24,"description":"Unused (retained for backward compatibility). ATR windowing is controlled by atr_period.","maximum":1000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"No runtime effect. Do not tune.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"unused"}},"title":"Execution configuration","type":"object","x-mangrove-boundary-validation":"top-level numeric bounds after legacy coercion; null means unset"}}},"securitySchemes":{"MangroveBearer":{"description":"The complete header value: Bearer <API_KEY>. Keep the key on your server.","in":"header","name":"Authorization","type":"apiKey"}}},"externalDocs":{"url":"https://mangrovedeveloper.ai/llms-full.txt"},"info":{"contact":{"email":"tim.darrah@mangrove.ai","name":"Mangrove Technologies","url":"https://mangrovedeveloper.ai"},"description":"Mangrove gives trading agents guardrails. Built-in risk management enforces circuit breakers, drawdown and daily loss limits, automatic risk-based position sizing, and automatic stop-loss and take-profit orders. 100+ tools cover strategy R&D across 12+ venues. The public REST v1 and v2 operations documented by the running Mangrove API. Send Authorization: Bearer <API_KEY> for authenticated REST requests. An API key's scopes, organization role and subscription still apply. X-API-Key is supported by hosted MCP, not by the direct REST auth decorator. MCP tools and their current schemas are discovered separately at /mcp/. MCP OAuth access tokens are resource-bound and cannot authenticate direct REST calls. Some operations are billable; inspect current prices and obtain approval before compute or trading. Unregistered blueprint/proxy routes are not represented by the RESTX schema. Operations that declare x-payment-info accept x402 payment in USDC on Base without an API key.","title":"Mangrove Developer REST API","version":"1.0","x-guidance":"Mangrove gives trading agents guardrails. Built-in risk management enforces circuit breakers, drawdown and daily loss limits, automatic risk-based position sizing, and automatic stop-loss and take-profit orders. 100+ tools cover strategy R&D across 12+ venues. Send an API key as Authorization: Bearer <API_KEY>. Operations that declare x-payment-info can instead be paid per call with x402 v2 in USDC on Base (eip155:8453), with no account: request the operation without credentials, read the base64 JSON PAYMENT-REQUIRED response header, sign the payment and repeat the request with a PAYMENT-SIGNATURE header. The live 402 challenge is authoritative for the price. Operations without x-payment-info need an API key unless they declare no security. Hosted MCP tools are listed at /mcp/. Operations that create, change or delete strategies, accounts or trades act on the payer's own data."},"openapi":"3.1.0","paths":{"/api/v1/ai-copilot/chat/{session_id}":{"post":{"operationId":"api1_post_chat","parameters":[{"in":"path","name":"session_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ChatRequest"}}},"required":true},"responses":{"202":{"description":"Message accepted for processing"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Validation error"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"403":{"description":"Token quota exceeded"},"404":{"description":"Conversation not found"},"409":{"description":"Execution conflict or active work"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Service unavailable"}},"security":[{"MangroveBearer":[]},{}],"summary":"Send a message to an existing conversation (async processing)","tags":["ai-copilot"],"x-payment-info":{"price":{"amount":"0.100000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/ai-copilot/configuration":{"get":{"operationId":"api1_get_configuration_endpoint","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Configuration"}}},"description":"Configuration retrieved successfully"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"List the key reference files used by the AI Copilot workflows","tags":["ai-copilot"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/ai-copilot/conversations/{session_id}":{"delete":{"operationId":"api1_delete_get_conversation","parameters":[{"in":"path","name":"session_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DeleteResponse"}}},"description":"Conversation deleted"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Delete a conversation","tags":["ai-copilot"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}},"get":{"operationId":"api1_get_get_conversation","parameters":[{"in":"path","name":"session_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Conversation retrieved"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Validation error"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get full conversation state with working context","tags":["ai-copilot"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/ai-copilot/conversations/{session_id}/executions/{execution_id}":{"get":{"operationId":"api1_get_execution_status","parameters":[{"in":"path","name":"session_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"execution_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Execution snapshot"},"400":{"description":"Invalid identity"},"401":{"description":"Authentication required"},"404":{"description":"Execution not found"}},"security":[{"MangroveBearer":[]}],"summary":"Read an execution without consuming its status or invoking the model","tags":["ai-copilot"]}},"/api/v1/ai-copilot/conversations/{session_id}/executions/{execution_id}/cancel":{"post":{"operationId":"api1_post_execution_cancel","parameters":[{"in":"path","name":"session_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"execution_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Post execution cancel","tags":["ai-copilot"]}},"/api/v1/ai-copilot/conversations/{session_id}/rename":{"put":{"operationId":"api1_put_rename_conversation","parameters":[{"in":"path","name":"session_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.RenameRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.RenameResponse"}}},"description":"Conversation renamed"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Validation error"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Rename a conversation","tags":["ai-copilot"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/ai-copilot/get_latest_conversation":{"get":{"operationId":"api1_get_get_latest_conversation","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ConversationResponse"}}},"description":"Conversation retrieved"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get the most recently created conversation","tags":["ai-copilot"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/ai-copilot/list_conversations":{"get":{"operationId":"api1_get_list_conversations","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ConversationList"}}},"description":"Conversations listed"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"List all stored conversations","tags":["ai-copilot"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/ai-copilot/save_strategy":{"post":{"description":"Expects 'strategy_config' dict with the strategy definition.\nStrategy config should include: asset, entry rules, exit rules, reward_factor, etc.","operationId":"api1_post_save_strategy","responses":{"200":{"description":"Strategy saved"},"400":{"description":"Validation error"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Save strategy configuration to the database","tags":["ai-copilot"],"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/ai-copilot/start_new_conversation":{"post":{"operationId":"api1_post_start_conversation","responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ConversationResponse"}}},"description":"Conversation created"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Service unavailable"}},"security":[{"MangroveBearer":[]},{}],"summary":"Start a new conversation session","tags":["ai-copilot"],"x-payment-info":{"price":{"amount":"0.010000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/auth/allowlist/emails":{"get":{"operationId":"api1_get_allowlist_emails","responses":{"200":{"description":"List of allowed emails"},"401":{"description":"Unauthorized"}},"security":[{"MangroveBearer":[]}],"summary":"List all allowed emails (requires authentication)","tags":["auth"]}},"/api/v1/auth/api-keys":{"get":{"description":"Retrieves a list of all API keys associated with the currently authenticated user.\nFor security reasons, the actual key values are masked and only the key prefixes\nare shown. Use the key_prefix to identify specific keys.\n\nAuthentication is required via JWT token, API key, or Firebase token.\nThe user ID is extracted from the authentication context.\n\nReturns:\n    200 Success: List of API keys (with masked values)\n    500 Error: If server error occurs during processing","operationId":"api1_get_api_keys","parameters":[{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ApiKeyList"}}},"description":"API keys retrieved successfully"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ApiKeyListErrorResponse"}}},"description":"Internal server error"}},"security":[{"MangroveBearer":[]}],"summary":"List all API keys for the authenticated user","tags":["auth"]},"post":{"description":"Creates a new API key associated with the currently authenticated user.\nThe key is only shown once at creation time and cannot be retrieved later,\nso it must be saved securely by the client.\n\nAuthentication is required via JWT token, API key, or Firebase token.\nThe user ID is extracted from the authentication context.\n\nParameters:\n    name (str): Descriptive name for the API key (required)\n    scopes (list): Optional list of permission scopes for this key\n    expires_days (int): Optional number of days until expiration\n    \nReturns:\n    201 Created: New API key details including the actual key value\n    400 Error: If required fields are missing\n    500 Error: If server error occurs during processing\n    \nNote:\n    The API key value is only returned once and cannot be retrieved later.\n    Make sure to save it securely immediately after creation.","operationId":"api1_post_api_keys","parameters":[{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ApiKeyRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ApiKeyResponse"}}},"description":"API key created successfully"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ApiKeyCreateErrorResponse"}}},"description":"Missing required fields"},"500":{"description":"Internal server error"}},"security":[{"MangroveBearer":[]}],"summary":"Generate a new API key for the authenticated user","tags":["auth"]}},"/api/v1/auth/api-keys/{key_id}":{"delete":{"description":"Permanently revokes the specified API key, preventing it from being used for\nauthentication in the future. This operation cannot be undone. The key is not\ndeleted from the database but is marked as revoked with a timestamp.\n\nAuthentication is required via JWT token, API key, or Firebase token.\nOnly the owner of the API key can revoke it.\n\nParameters:\n    key_id (str): The UUID of the API key to revoke (from the URL path)\n    \nReturns:\n    200 Success: Confirmation that the key was revoked\n    404 Error: If the key does not exist or does not belong to the user\n    500 Error: If server error occurs during processing","operationId":"api1_delete_api_key_detail","parameters":[{"in":"path","name":"key_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ApiKeyRevokeResponse"}}},"description":"API key revoked successfully"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ApiKeyNotFoundResponse"}}},"description":"API key not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ApiKeyRevokeErrorResponse"}}},"description":"Internal server error"}},"security":[{"MangroveBearer":[]}],"summary":"Revoke an API key","tags":["auth"]}},"/api/v1/auth/callback":{"get":{"description":"This endpoint processes the callback from Google OAuth flow. It extracts the ID token\nfrom either the query parameters or URL fragment, verifies it with Google, creates or\nupdates the user record, and generates JWT tokens for API authentication.\n\nIf the ID token is not in the query parameters, it returns HTML with JavaScript that\nextracts the token from the URL fragment and reloads the page with the token as a query parameter.\n\nReturns:\n    200 Success: JWT tokens and user profile if authentication succeeds\n    400 Error: If OAuth error parameter is present or request is invalid\n    401 Error: If Google token is invalid or missing required claims\n    500 Error: If server error occurs during processing","operationId":"api1_get_auth_callback","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.LoginResponse"}}},"description":"Authentication successful"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.OAuthErrorResponse"}}},"description":"Invalid request or OAuth error"},"401":{"description":"Invalid Google token"},"500":{"description":"Internal server error"}},"security":[],"summary":"Handle OAuth callback from Google authentication","tags":["auth"]}},"/api/v1/auth/is-admin":{"get":{"operationId":"api1_get_is_admin","responses":{"200":{"description":"Admin status check"},"401":{"description":"Unauthorized"}},"security":[{"MangroveBearer":[]}],"summary":"Check if current user has admin privileges","tags":["auth"]}},"/api/v1/auth/login":{"post":{"description":"The access token is returned in JSON. The refresh token is issued only\nin the httpOnly mg_refresh cookie; mg_csrf supplies the double-submit\nvalue required by POST /auth/refresh. Retain the same cookie session.\n\nParameters:\n    firebase_token (str): Firebase ID token from client-side authentication\n    \nReturns:\n    200 Success: Access token and user profile, plus session cookies\n    400 Error: If firebase_token is missing from request\n    401 Error: If Firebase token is invalid or expired\n    500 Error: If server error occurs during processing","operationId":"api1_post_login","parameters":[{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.LoginRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.LoginResponse"}}},"description":"Authentication successful"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.LoginErrorResponse"}}},"description":"Missing firebase_token"},"401":{"description":"Invalid Firebase token"},"500":{"description":"Internal server error"}},"security":[],"summary":"Exchange a Firebase ID token for an access token and a cookie session","tags":["auth"]}},"/api/v1/auth/login/google":{"get":{"description":"Redirects the browser to Google's sign-in page. After successful authentication,\nGoogle redirects back to /auth/callback with an ID token in the URL fragment.\n\nReturns:\n    302 Redirect: Redirects to Google OAuth authorization URL\n    500 Error: If OAuth configuration is missing or an error occurs","operationId":"api1_get_google_login","responses":{"302":{"description":"Redirect to Google OAuth"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ErrorResponse"}}},"description":"Internal server error"}},"security":[],"summary":"Initiate Google OAuth login flow","tags":["auth"]}},"/api/v1/auth/logout":{"post":{"description":"Idempotent; safe to call with an\nexpired/absent access token (the frontend cannot clear an httpOnly cookie itself).","operationId":"api1_post_logout","responses":{"200":{"description":"Logged out"}},"security":[],"summary":"Clear the httpOnly refresh + CSRF cookies","tags":["auth"]}},"/api/v1/auth/markets-context":{"get":{"operationId":"api1_get_markets_context","responses":{"200":{"description":"Versioned Markets authorization context"},"401":{"description":"Invalid credential"},"403":{"description":"Customer API key and active organization membership required"},"503":{"description":"Authentication backend unavailable"}},"security":[{"MangroveBearer":[]}],"summary":"Resolve Markets permissions for the authenticated API key's bound org","tags":["auth"]}},"/api/v1/auth/markets-quota":{"post":{"operationId":"api1_post_markets_quota","responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Consume one API call for a prepared Markets read, idempotently","tags":["auth"]}},"/api/v1/auth/profile":{"get":{"description":"Retrieves the profile information for the currently authenticated user.\nAuthentication is required via JWT token, API key, or Firebase token.\nThe user ID is extracted from the authentication context.\n\nReturns:\n    200 Success: User profile information\n    404 Error: If user record is not found\n    500 Error: If server error occurs during processing","operationId":"api1_get_profile","parameters":[{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.UserProfile"}}},"description":"Profile retrieved successfully"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ProfileErrorResponse"}}},"description":"User not found"},"500":{"description":"Internal server error"}},"security":[{"MangroveBearer":[]}],"summary":"Get current user profile information","tags":["auth"]},"put":{"description":"Updates profile information for the currently authenticated user.\nAuthentication is required via JWT token, API key, or Firebase token.\nThe user ID is extracted from the authentication context.\n\nParameters:\n    name (str): New display name for the user\n    \nReturns:\n    200 Success: Updated user profile information\n    404 Error: If user record is not found\n    500 Error: If server error occurs during processing","operationId":"api1_put_profile","parameters":[{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.UpdateProfile"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.UserProfile"}}},"description":"Profile updated successfully"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ProfileUpdateErrorResponse"}}},"description":"User not found"},"500":{"description":"Internal server error"}},"security":[{"MangroveBearer":[]}],"summary":"Update current user profile information","tags":["auth"]}},"/api/v1/auth/refresh":{"post":{"description":"Send the mg_refresh and mg_csrf cookies from the same login session,\nwith X-CSRF-Token equal to mg_csrf. The request has no JSON body.\nA missing/invalid refresh cookie returns 401; failed CSRF returns 403.\nSuccessful refresh rotates both cookies. API-key requests do not use\nthis browser-session workflow.","operationId":"api1_post_refresh","parameters":[{"description":"The mg_csrf cookie value from the same login session","in":"header","name":"X-CSRF-Token","required":true,"schema":{"type":"string"}},{"description":"The same session must send mg_refresh and mg_csrf cookies. No JSON refresh token is accepted.","in":"header","name":"Cookie","required":true,"schema":{"type":"string"}},{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.RefreshResponse"}}},"description":"Token refresh successful"},"401":{"description":"Invalid or expired refresh token"},"403":{"description":"Missing or mismatched CSRF double-submit value"},"500":{"description":"Internal server error"}},"security":[],"summary":"Rotate the cookie session and return a new access token","tags":["auth"]}},"/api/v1/auth/switch-org":{"post":{"description":"Switch the active organization and get new JWT tokens","operationId":"api1_post_switch_org","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SwitchOrgRequest"}}},"required":true},"responses":{"200":{"description":"Organization switched successfully"},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"},"403":{"description":"Not a member of the target organization"},"500":{"description":"Internal server error"}},"security":[{"MangroveBearer":[]}],"summary":"Switch active organization and issue new JWT tokens","tags":["auth"]}},"/api/v1/backtesting/backtest":{"post":{"description":"This endpoint runs a single-strategy backtest using `strategy_json`.\n\nThis synchronous surface has a ~15s transport budget. Prefer the\nasync surface (`POST /api/v2/backtests/`, then poll status) for long\nlookbacks -- it has no such ceiling.\n\nThe backtest engine runs one backtest at a time. If another synchronous\nbacktest is already running (`ENGINE_BUSY`), or a cold long-window\nrequest cannot finish inside the transport budget (`ENGINE_WARMING`),\nthis returns `503` with a `Retry-After` header rather than blocking\nuntil the gateway times out -- retry after the indicated delay, or use\nthe async endpoint for long lookbacks and the bulk endpoint for\nmany-strategy workloads.\n\nStop parameters (atr_period, volatility_tolerance) are read from `execution_config`.\nIf not provided, defaults from trading_defaults.json are used. These values are\ninjected into the Strategy object at runtime and should NOT be included in strategy_json.\n\nMarket data can be sourced from:\n- Market Data API: set `data_source=\"api\"` (default) and provide `asset`, `interval`, `lookback_months`\n- Local CSV file: set `data_source=\"file\"` and provide `data_file`\n\nLegacy support:\n- `hourly_data_file` is accepted and treated as `data_file` (file mode)\n\nReturns:\n- success: Boolean indicating if backtest completed successfully\n- metrics: Dict with performance metrics\n- trade_history: List of serialized TradeRecord objects (entry/exit prices, timestamps, profit/loss, exit reasons)\n- error: Error message if backtest failed\n- execution_time_seconds: Time taken to run backtest\n- trade_count: Number of trades executed\n- strategy_names: List of strategy names that were run","operationId":"api1_post_backtest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.BacktestRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.BacktestResult"}}},"description":"Backtest completed successfully"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Validation error"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Symbol not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Engine busy or warming; retry (Retry-After) or use the async endpoint"}},"security":[{"MangroveBearer":[]},{}],"summary":"Run a backtest (synchronous -- short lookbacks only)","tags":["backtesting"],"x-payment-info":{"price":{"amount":"0.100000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/backtesting/backtest/bulk":{"post":{"description":"Market data is fetched once per unique (asset, timeframe) pair and\nshared across all strategies that need the same data.  For example,\nfour BTC/1h strategies result in a single API call for BTC 1h data.\n\nStrategy sources\n----------------\nProvide exactly one of:\n- **strategy_ids** -- list of UUIDs from the strategies table. Strategies\n  are loaded from the database and must belong to the caller's org.\n- **strategy_configs** -- list of strategy config objects in the canonical\n  entry/exit format (same structure as the ``strategy_json`` field in\n  ``POST /backtest``, but already parsed as JSON objects, not strings).\n\nDate range\n----------\nBoth ``start_date`` and ``end_date`` are required.\n\nExecution config\n----------------\n``execution_config`` is optional and is applied to every strategy in the\nbatch.  Per-strategy execution_config embedded inside each strategy record\nis merged on top of this value.  If omitted entirely, defaults from\n``trading_defaults.json`` are used (atr_period=14, volatility_tolerance=0.5).\n\nFailures\n--------\nIndividual strategy failures are captured per-result and do not abort\nthe batch.  Check ``results[i].success`` and ``results[i].error`` for\neach strategy.\n\nSubscription counting\n---------------------\nEach strategy result that produced at least one round trip\n(``trade_count >= 2``) increments the backtest usage counter once; a\nresult below that threshold is a dry run or a config error and is NOT\ncharged, as are technical failures (engine-busy, oracle error).  See\n``docs/architecture/billable-endpoints.md`` for rationale and\n``services.counts_against_quota`` for the rule itself.  Accounting lives\nin ``services.run_bulk_backtest``, not in this route.  The total\nrequired quota is checked upfront.  The response includes\n``X-Quota-Counted-Total`` and ``X-Quota-Counted-Of`` headers so callers\ncan tell how many results actually counted.","operationId":"api1_post_bulk_backtest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.BulkBacktestRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.BulkBacktestResult"}}},"description":"Bulk backtest completed"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Validation error"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Run backtests for multiple strategies over a shared date range","tags":["backtesting"],"x-payment-info":{"price":{"amount":"0.250000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/backtesting/backtest/screen":{"post":{"description":"A pre-screen for deciding which candidates are worth a backtest. SIEVE\nanswers *will this place trades*, and nothing about performance -- Oracle\nretired the outcome head, so no field here predicts profit.\n\nOne asset per call: a strategy's signals are measured on that asset's\ncandles, so a set spanning several assets is not one question.\n\nEvery candidate comes back with its score, in rank order. Nothing is\nfiltered out. A high score is real support for spending a backtest; a low\none is weak evidence and is not a finding that the strategy will not\ntrade -- on the measured model a 0.5 cutoff recovers under half of the\nstrategies that go on to trade.\n\nAt most 99 candidates per call.","operationId":"api1_post_screen_candidates","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ScreenRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ScreenResult"}}},"description":"Candidates ranked"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Validation error"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Rank candidate strategies by how likely each is to trade at all","tags":["backtesting"],"x-payment-info":{"price":{"amount":"0.020000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/backtesting/backtest/{backtest_id}":{"get":{"description":"Returns the complete backtest result including:\n- status (pending, completed, failed)\n- metrics (performance statistics)\n- trade_history (all trades executed)\n- config (strategy configuration used)\n- timestamps (created_at, completed_at)\n\nAuthorization: Only returns backtest if it belongs to the authenticated user's organization","operationId":"api1_get_backtest_by_id","parameters":[{"in":"path","name":"backtest_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Backtest retrieved successfully"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Backtest not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Retrieve a backtest result by ID","tags":["backtesting"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/backtesting/backtest/{backtest_id}/trades":{"get":{"description":"Returns the list of trades executed during the backtest, including\nentry/exit prices, timestamps, profit/loss, and exit reasons.","operationId":"api1_get_backtest_trades","parameters":[{"in":"path","name":"backtest_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Trades retrieved successfully"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Backtest not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Retrieve trade history for a backtest run","tags":["backtesting"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/backtests":{"post":{"description":"This endpoint runs a single-strategy backtest using `strategy_json`.\n\nThis synchronous surface has a ~15s transport budget. Prefer the\nasync surface (`POST /api/v2/backtests/`, then poll status) for long\nlookbacks -- it has no such ceiling.\n\nThe backtest engine runs one backtest at a time. If another synchronous\nbacktest is already running (`ENGINE_BUSY`), or a cold long-window\nrequest cannot finish inside the transport budget (`ENGINE_WARMING`),\nthis returns `503` with a `Retry-After` header rather than blocking\nuntil the gateway times out -- retry after the indicated delay, or use\nthe async endpoint for long lookbacks and the bulk endpoint for\nmany-strategy workloads.\n\nStop parameters (atr_period, volatility_tolerance) are read from `execution_config`.\nIf not provided, defaults from trading_defaults.json are used. These values are\ninjected into the Strategy object at runtime and should NOT be included in strategy_json.\n\nMarket data can be sourced from:\n- Market Data API: set `data_source=\"api\"` (default) and provide `asset`, `interval`, `lookback_months`\n- Local CSV file: set `data_source=\"file\"` and provide `data_file`\n\nLegacy support:\n- `hourly_data_file` is accepted and treated as `data_file` (file mode)\n\nReturns:\n- success: Boolean indicating if backtest completed successfully\n- metrics: Dict with performance metrics\n- trade_history: List of serialized TradeRecord objects (entry/exit prices, timestamps, profit/loss, exit reasons)\n- error: Error message if backtest failed\n- execution_time_seconds: Time taken to run backtest\n- trade_count: Number of trades executed\n- strategy_names: List of strategy names that were run","operationId":"api1_post_backtests_collection","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.BacktestRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.BacktestResult"}}},"description":"Backtest completed successfully"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Validation error"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Symbol not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Engine busy or warming; retry (Retry-After) or use the async endpoint"}},"security":[{"MangroveBearer":[]},{}],"summary":"Run a backtest (synchronous -- short lookbacks only)","tags":["backtests"],"x-payment-info":{"price":{"amount":"0.100000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/backtests/benchmark":{"get":{"description":"First daily close to last daily close, as a percentage -- the comparison a\nstrategy's return needs. Same reading the copilot's get_benchmark tool returns,\nplus `buy_and_hold_return_raw` for arithmetic.","operationId":"api1_get_benchmark","parameters":[{"description":"Asset symbol, e.g. BTC (required)","in":"query","name":"asset","schema":{"type":"string"}},{"description":"ISO start of the window, e.g. 2026-01-01 (required)","in":"query","name":"start_date","schema":{"type":"string"}},{"description":"ISO end after start_date (required). YYYY-MM-DD covers that whole UTC day; today stops at the end of yesterday, the last complete day; exact timestamps are passed through unchanged.","in":"query","name":"end_date","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.BuyAndHoldBenchmark"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Invalid arguments"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"No daily closes for the asset and window"}},"security":[{"MangroveBearer":[]},{}],"summary":"What holding the asset would have returned between two dates","tags":["backtests"],"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/backtests/bulk":{"post":{"description":"Market data is fetched once per unique (asset, timeframe) pair and\nshared across all strategies that need the same data.  For example,\nfour BTC/1h strategies result in a single API call for BTC 1h data.\n\nStrategy sources\n----------------\nProvide exactly one of:\n- **strategy_ids** -- list of UUIDs from the strategies table. Strategies\n  are loaded from the database and must belong to the caller's org.\n- **strategy_configs** -- list of strategy config objects in the canonical\n  entry/exit format (same structure as the ``strategy_json`` field in\n  ``POST /backtest``, but already parsed as JSON objects, not strings).\n\nDate range\n----------\nBoth ``start_date`` and ``end_date`` are required.\n\nExecution config\n----------------\n``execution_config`` is optional and is applied to every strategy in the\nbatch.  Per-strategy execution_config embedded inside each strategy record\nis merged on top of this value.  If omitted entirely, defaults from\n``trading_defaults.json`` are used (atr_period=14, volatility_tolerance=0.5).\n\nFailures\n--------\nIndividual strategy failures are captured per-result and do not abort\nthe batch.  Check ``results[i].success`` and ``results[i].error`` for\neach strategy.\n\nSubscription counting\n---------------------\nEach strategy result that produced at least one round trip\n(``trade_count >= 2``) increments the backtest usage counter once; a\nresult below that threshold is a dry run or a config error and is NOT\ncharged, as are technical failures (engine-busy, oracle error).  See\n``docs/architecture/billable-endpoints.md`` for rationale and\n``services.counts_against_quota`` for the rule itself.  Accounting lives\nin ``services.run_bulk_backtest``, not in this route.  The total\nrequired quota is checked upfront.  The response includes\n``X-Quota-Counted-Total`` and ``X-Quota-Counted-Of`` headers so callers\ncan tell how many results actually counted.","operationId":"api1_post_backtests_bulk_alias","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.BulkBacktestRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.BulkBacktestResult"}}},"description":"Bulk backtest completed"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Validation error"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Run backtests for multiple strategies over a shared date range","tags":["backtests"],"x-payment-info":{"price":{"amount":"0.250000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/backtests/{backtest_id}":{"get":{"description":"Returns the complete backtest result including:\n- status (pending, completed, failed)\n- metrics (performance statistics)\n- trade_history (all trades executed)\n- config (strategy configuration used)\n- timestamps (created_at, completed_at)\n\nAuthorization: Only returns backtest if it belongs to the authenticated user's organization","operationId":"api1_get_backtests_by_id_alias","parameters":[{"in":"path","name":"backtest_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Backtest retrieved successfully"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Backtest not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Retrieve a backtest result by ID","tags":["backtests"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/backtests/{backtest_id}/archive":{"post":{"description":"Backtests are never deleted -- archiving is a reversible view-state that\nremoves the run from GET /api/v1/users/me/backtests by default. Pass\n?include_archived=true to that endpoint to list archived runs, and POST\n/api/v1/backtests/<id>/unarchive to restore one.\n\nAuthorization: only affects a backtest owned by the caller's org.","operationId":"api1_post_backtest_archive","parameters":[{"in":"path","name":"backtest_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.BacktestArchiveResponse"}}},"description":"Backtest archived"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Backtest not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal server error"}},"security":[{"MangroveBearer":[]}],"summary":"Archive a backtest run (hide it from the default history view)","tags":["backtests"]}},"/api/v1/backtests/{backtest_id}/trades":{"get":{"description":"Returns the list of trades executed during the backtest, including\nentry/exit prices, timestamps, profit/loss, and exit reasons.","operationId":"api1_get_backtests_trades_alias","parameters":[{"in":"path","name":"backtest_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Trades retrieved successfully"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Backtest not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Retrieve trade history for a backtest run","tags":["backtests"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/backtests/{backtest_id}/unarchive":{"post":{"description":"The inverse of POST /api/v1/backtests/<id>/archive.\n\nAuthorization: only affects a backtest owned by the caller's org.","operationId":"api1_post_backtest_unarchive","parameters":[{"in":"path","name":"backtest_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.BacktestArchiveResponse"}}},"description":"Backtest unarchived"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Backtest not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal server error"}},"security":[{"MangroveBearer":[]}],"summary":"Unarchive a backtest run (restore it to the default history view)","tags":["backtests"]}},"/api/v1/batch/job/status":{"get":{"operationId":"api1_get_unnotified_jobs","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/api1.BatchJob"},"type":"array"}}},"description":"OK"},"500":{"description":"Internal Server Error (one or more jobs failed)"}},"security":[{"MangroveBearer":[]}],"summary":"Get all completed/failed jobs that haven't been notified yet","tags":["batch"]}},"/api/v1/batch/job/status/{job_id}":{"get":{"operationId":"api1_get_job_status","parameters":[{"in":"path","name":"job_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.BatchJob"}}},"description":"OK"},"404":{"description":"Not Found"},"500":{"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]}],"summary":"Get status of a specific batch job","tags":["batch"]}},"/api/v1/config/execution-config-schema":{"get":{"description":"`defaults` is the flattened canon config. `param_glossary` gives, per parameter,\nits `status` -- tunable (strategy character), guardrail (account/size bound),\ngated (only effective behind `gate_field`), unused (no runtime effect) or\nsuperseded -- with `description`, `effect` and bounds (`type`, `min`, `max`,\n`min_exclusive`, `max_exclusive`, `choices`). `transaction_costs` holds fee and\nslippage, which are canon and not settable per strategy. Authenticated and\nbillable, unlike the two plain defaults reads above: this is the authoring\ncontract the copilot's get_execution_config_schema tool serves.","operationId":"api1_get_execution_config_schema","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ExecutionConfigSchemaResponse"}}},"description":"Every execution_config parameter: default, effect, bounds and status"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Every execution-config parameter a strategy can carry, and what each one does","tags":["config"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/config/execution-defaults":{"get":{"description":"Matches exactly what `domains/strategies/services.py` uses when a\nrequest omits `execution_config`. Sections `risk_management`,\n`position_limits`, `volatility_settings`, `trading_rules`,\n`time_based_exits` are merged into one dict; `signal_defaults` and\n`backtest_defaults` are intentionally excluded (same as the legacy\nflattening).","operationId":"api1_get_execution_defaults","responses":{"200":{"description":"Flattened execution config as applied by the server"}},"security":[],"summary":"Return the flattened `execution_config` the server builds from defaults","tags":["config"]}},"/api/v1/config/trading-defaults":{"get":{"description":"Shape mirrors `trading_defaults.json` one-to-one: `signal_defaults`,\n`backtest_defaults`, `risk_management`, `position_limits`,\n`volatility_settings`, `trading_rules`, `time_based_exits`, plus the\ntop-level `description` field.","operationId":"api1_get_trading_defaults","responses":{"200":{"description":"Full trading_defaults.json contents (nested sections intact)"}},"security":[],"summary":"Return the full trading defaults, nested sections intact","tags":["config"]}},"/api/v1/crypto-assets/all":{"get":{"operationId":"api1_list_all_crypto_assets","parameters":[{"description":"Maximum number of results","in":"query","name":"limit","required":false,"schema":{"default":100,"type":"integer"}},{"description":"Minimum risk score (0-100)","in":"query","name":"min_score","required":false,"schema":{"type":"number"}},{"description":"Filter by approval status (true/false)","in":"query","name":"approved_only","required":false,"schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.AllCryptoAssetsResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"List all crypto assets with filtering options - for frontend dropdowns and AI copilot","tags":["crypto-assets"],"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/crypto-assets/exchanges":{"get":{"operationId":"api1_list_exchanges","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ExchangeListResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"List all exchanges with tier and volume information","tags":["crypto-assets"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/crypto-assets/flow-intelligence/{symbol}":{"get":{"operationId":"api1_get_flow_intelligence","parameters":[{"in":"path","name":"symbol","required":true,"schema":{"type":"string"}},{"description":"Time range: 5m, 1h, 6h, 12h, 1d, 7d (default: 1d)","in":"query","name":"timeframe","required":false,"schema":{"type":"string"}},{"description":"Blockchain (default: ethereum)","in":"query","name":"chain","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.FlowIntelligenceResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get real-time flow intelligence for a specific crypto asset (Nansen)","tags":["crypto-assets"],"x-payment-info":{"price":{"amount":"0.020000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/crypto-assets/global-market":{"get":{"operationId":"api1_get_global_market","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.GlobalMarketResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get global cryptocurrency market statistics","tags":["crypto-assets"],"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/crypto-assets/market-data/{symbol}":{"get":{"operationId":"api1_get_market_data","parameters":[{"in":"path","name":"symbol","required":true,"schema":{"type":"string"}},{"description":"Explicit external price source; omit to select a market","in":"query","name":"provider","schema":{"type":"string"}},{"description":"Quote currency; supply with market_data_venue","in":"query","name":"quote_token","schema":{"type":"string"}},{"description":"Exact exchange; supply with quote_token","in":"query","name":"market_data_venue","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.MarketDataResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get real-time market data for a specific crypto asset","tags":["crypto-assets"],"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/crypto-assets/ohlcv/{symbol}":{"get":{"operationId":"api1_get_ohlcv","parameters":[{"in":"path","name":"symbol","required":true,"schema":{"type":"string"}},{"description":"Explicit external provider, or omit to select a Mangrove market.","in":"query","name":"provider","required":false,"schema":{"type":"string"}},{"description":"Number of days (default: 30, maximum: 3650); more than 1,000 daily bars come back weekly","in":"query","name":"days","required":false,"schema":{"type":"integer"}},{"description":"Exact exchange; supply with quote_token","in":"query","name":"market_data_venue","schema":{"type":"string"}},{"description":"Quote currency; supply with market_data_venue","in":"query","name":"quote_token","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.OHLCVResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Symbol not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get OHLCV (candlestick) data for a specific crypto asset","tags":["crypto-assets"],"x-payment-info":{"price":{"amount":"0.010000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/crypto-assets/query":{"get":{"operationId":"api1_query_crypto_assets","parameters":[{"description":"Maximum number of results","in":"query","name":"limit","schema":{"default":100,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.CryptoAssetQueryResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Query approved crypto assets with simplified risk scores for frontend display","tags":["crypto-assets"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/crypto-assets/smart-money/holdings":{"get":{"operationId":"api1_get_smart_money_holdings","parameters":[{"description":"Max results (default: 15, maximum: 100)","in":"query","name":"limit","required":false,"schema":{"type":"integer"}},{"description":"Min position size in USD (default: 1000000)","in":"query","name":"min_value","required":false,"schema":{"type":"number"}},{"description":"Comma-separated labels (default: Fund,Smart Trader)","in":"query","name":"labels","required":false,"schema":{"type":"string"}},{"description":"Comma-separated chains (default: ethereum)","in":"query","name":"chains","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SmartMoneyHoldingsResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get aggregated smart money holdings across all tokens","tags":["crypto-assets"],"x-payment-info":{"price":{"amount":"0.020000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/crypto-assets/smart-money/netflows":{"get":{"operationId":"api1_get_smart_money_netflows","parameters":[{"description":"Max results (default: 15, maximum: 100)","in":"query","name":"limit","required":false,"schema":{"type":"integer"}},{"description":"1h, 24h, 7d, or 30d (default: 24h)","in":"query","name":"timeframe","required":false,"schema":{"type":"string"}},{"description":"Comma-separated labels (default: Fund,Smart Trader)","in":"query","name":"labels","required":false,"schema":{"type":"string"}},{"description":"Comma-separated chains (default: ethereum)","in":"query","name":"chains","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SmartMoneyNetflowsResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get aggregated smart money netflows across all tokens","tags":["crypto-assets"],"x-payment-info":{"price":{"amount":"0.020000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/crypto-assets/symbols":{"get":{"operationId":"api1_list_crypto_assets","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.CryptoAssetListResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"List all approved crypto assets with risk scores","tags":["crypto-assets"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/crypto-assets/symbols/{symbol}":{"get":{"operationId":"api1_get_crypto_asset","parameters":[{"in":"path","name":"symbol","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.CryptoAssetDetailResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get detailed information about a specific crypto asset","tags":["crypto-assets"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/crypto-assets/symbols/{symbol}/exchanges":{"get":{"operationId":"api1_get_asset_exchanges","parameters":[{"in":"path","name":"symbol","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.AssetExchangesResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get all exchanges where a specific asset is listed","tags":["crypto-assets"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/crypto-assets/token-holders/{symbol}":{"get":{"deprecated":true,"operationId":"api1_get_token_holders","parameters":[{"in":"path","name":"symbol","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.TokenHoldersResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get token holder distribution for a specific crypto asset (Nansen)","tags":["crypto-assets"],"x-payment-info":{"price":{"amount":"0.020000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/crypto-assets/trending":{"get":{"operationId":"api1_get_trending_assets","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.TrendingAssetsResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get top trending crypto assets (24h search volume)","tags":["crypto-assets"],"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/defi/chain/{chain}/tvl":{"get":{"operationId":"api1_get_chain_tvl","parameters":[{"description":"Blockchain name (e.g. Ethereum, Solana, Arbitrum)","in":"path","name":"chain","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ChainTVLResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DefiError"}}},"description":"Chain not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DefiError"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get TVL and top protocols for a blockchain","tags":["defi"],"x-payment-info":{"price":{"amount":"0.010000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/defi/etf-flows":{"get":{"description":"Pro.","operationId":"api1_get_etf_flows","parameters":[{"description":"Maximum results.","in":"query","name":"limit","required":false,"schema":{"default":25,"type":"integer"}},{"description":"Number of days of history to request.","in":"query","name":"lookback_days","required":false,"schema":{"default":30,"type":"integer"}},{"description":"Pagination offset in the result units documented by the tool; zero starts the first page.","in":"query","name":"offset","required":false,"schema":{"default":0,"type":"integer"}},{"description":"Asset symbol, e.g. BTC or ETH.","in":"query","name":"symbol","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.EtfFlowsResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DefiError"}}},"description":"Invalid arguments"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DefiError"}}},"description":"Upgrade required"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DefiError"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Daily spot ETF net flows with window totals, filtered and paged","tags":["defi"],"x-payment-info":{"price":{"amount":"0.010000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/defi/lending-rates":{"get":{"description":"Pro.","operationId":"api1_get_lending_borrow_rates","parameters":[{"description":"Chain name or slug, e.g. ethereum or base.","in":"query","name":"chain","required":false,"schema":{"type":"string"}},{"description":"Maximum results.","in":"query","name":"limit","required":false,"schema":{"default":25,"type":"integer"}},{"description":"Leave out pools with less than this total value locked, in USD.","in":"query","name":"min_tvl_usd","required":false,"schema":{"type":"number"}},{"description":"Pagination offset in the result units documented by the tool; zero starts the first page.","in":"query","name":"offset","required":false,"schema":{"default":0,"type":"integer"}},{"description":"Protocol or token name, DefiLlama slug or CoinGecko id, case-insensitive exact match.","in":"query","name":"protocol","required":false,"schema":{"type":"string"}},{"description":"Asset symbol, e.g. BTC or ETH.","in":"query","name":"symbol","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.LendingRatesResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DefiError"}}},"description":"Invalid arguments"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DefiError"}}},"description":"Upgrade required"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DefiError"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Lending-pool supply and borrow rates, filtered and paged","tags":["defi"],"x-payment-info":{"price":{"amount":"0.010000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/defi/perp-funding":{"get":{"description":"Pro.","operationId":"api1_get_perp_funding","parameters":[{"description":"Maximum results.","in":"query","name":"limit","required":false,"schema":{"default":25,"type":"integer"}},{"description":"Pagination offset in the result units documented by the tool; zero starts the first page.","in":"query","name":"offset","required":false,"schema":{"default":0,"type":"integer"}},{"description":"Asset symbol, e.g. BTC or ETH.","in":"query","name":"symbol","required":false,"schema":{"type":"string"}},{"description":"Exchange the perp trades on, e.g. Binance or OKX, case-insensitive.","in":"query","name":"venue","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.PerpFundingResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DefiError"}}},"description":"Invalid arguments"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DefiError"}}},"description":"Upgrade required"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DefiError"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Perp funding rates by venue and market, filtered and paged","tags":["defi"],"x-payment-info":{"price":{"amount":"0.010000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/defi/protocol/{protocol_name}/tvl":{"get":{"operationId":"api1_get_protocol_tvl","parameters":[{"description":"Protocol name or slug (e.g. aave, uniswap, lido)","in":"path","name":"protocol_name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ProtocolTVLResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DefiError"}}},"description":"Protocol not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DefiError"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get TVL and chain breakdown for a DeFi protocol","tags":["defi"],"x-payment-info":{"price":{"amount":"0.010000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/defi/stablecoins/metrics":{"get":{"operationId":"api1_get_stablecoin_metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.StablecoinMetricsResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DefiError"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get stablecoin supply metrics with per-chain breakdown","tags":["defi"],"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/defi/token-unlocks":{"get":{"description":"Pro.","operationId":"api1_get_token_unlocks","parameters":[{"description":"Window length in days from now. Without symbol or protocol, only tokens with a scheduled unlock in this window are returned.","in":"query","name":"days_ahead","required":false,"schema":{"default":30,"maximum":365,"minimum":1,"type":"integer"}},{"description":"Maximum results.","in":"query","name":"limit","required":false,"schema":{"default":25,"type":"integer"}},{"description":"Pagination offset in the result units documented by the tool; zero starts the first page.","in":"query","name":"offset","required":false,"schema":{"default":0,"type":"integer"}},{"description":"Protocol or token name, DefiLlama slug or CoinGecko id, case-insensitive exact match.","in":"query","name":"protocol","required":false,"schema":{"type":"string"}},{"description":"next_unlock (soonest first) or cliff_value_usd (largest USD value of cliff unlocks in the window first).","in":"query","name":"rank_by","required":false,"schema":{"default":"next_unlock","enum":["next_unlock","cliff_value_usd"],"type":"string"}},{"description":"Asset symbol, e.g. BTC or ETH.","in":"query","name":"symbol","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.TokenUnlocksResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DefiError"}}},"description":"Invalid arguments"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DefiError"}}},"description":"Upgrade required"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DefiError"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Upcoming token unlocks and supply metrics, filtered and paged","tags":["defi"],"x-payment-info":{"price":{"amount":"0.010000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/defi/treasuries":{"get":{"description":"Pro.","operationId":"api1_get_treasuries","parameters":[{"description":"Maximum results.","in":"query","name":"limit","required":false,"schema":{"default":25,"type":"integer"}},{"description":"Pagination offset in the result units documented by the tool; zero starts the first page.","in":"query","name":"offset","required":false,"schema":{"default":0,"type":"integer"}},{"description":"Protocol or token name, DefiLlama slug or CoinGecko id, case-insensitive exact match.","in":"query","name":"protocol","required":false,"schema":{"type":"string"}},{"description":"Asset symbol, e.g. BTC or ETH.","in":"query","name":"symbol","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.TreasuriesResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DefiError"}}},"description":"Invalid arguments"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DefiError"}}},"description":"Upgrade required"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DefiError"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Protocol treasury holdings, filtered and paged","tags":["defi"],"x-payment-info":{"price":{"amount":"0.010000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/docs/content":{"get":{"description":"Returns raw markdown content for the requested document.","operationId":"api1_get_doc_content","parameters":[{"description":"Relative path to the document (e.g., \"api/authentication.md\")","in":"query","name":"path","schema":{"type":"string"}},{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DocContent"}}},"description":"Success"}},"security":[],"summary":"Get the content of a specific documentation file","tags":["docs"]}},"/api/v1/docs/list":{"get":{"description":"Returns a list of markdown files in the docs/ directory.","operationId":"api1_get_docs_list","parameters":[{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DocsList"}}},"description":"Success"}},"security":[],"summary":"List all available documentation files","tags":["docs"]}},"/api/v1/execution/accounts":{"get":{"description":"List trading accounts for the authenticated user","operationId":"api1_get_account_list","parameters":[{"description":"Filter by account type (paper or live)","in":"query","name":"account_type","schema":{"type":"string"}},{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/api1.Account"},"type":"array"}}},"description":"Success"},"401":{"description":"Unauthorized"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"List user's trading accounts","tags":["execution"],"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}},"post":{"description":"Create a new trading account","operationId":"api1_post_account_list","parameters":[{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.CreateAccountRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Account"}}},"description":"Account created"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Create a new trading account","tags":["execution"],"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/execution/accounts/{account_id}":{"get":{"description":"Get account details","operationId":"api1_get_account_detail","parameters":[{"description":"Account UUID","in":"path","name":"account_id","required":true,"schema":{"type":"string"}},{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Account"}}},"description":"Success"},"401":{"description":"Unauthorized"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"description":"Account not found"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get account by ID","tags":["execution"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/execution/availability":{"post":{"description":"Available cash and asset of a position_size_calc 'v3' strategy, computed from the config, balances and open positions in the request. The numbers are the ones that size and gate trades in /evaluate/bulk. No market data is fetched and nothing is persisted.","operationId":"api1_post_strategy_availability","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.AvailabilityRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.AvailabilityResponse"}}},"description":"Availability computed"},"400":{"description":"Validation error (position_size_calc is not 'v3', or a required field is missing)"},"401":{"description":"Unauthorized"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal server error"}},"security":[{"MangroveBearer":[]}],"summary":"Available cash and asset of a v3 strategy from caller-owned state","tags":["execution"]}},"/api/v1/execution/evaluate":{"post":{"description":"Evaluate strategy using strategy object (JSON) instead of ID\nThis endpoint allows evaluation without persisting the strategy first.\nUseful for:\n- Testing draft strategies before saving\n- One-off evaluations\n- Dry-run with modified parameters\n\nRequest body:\n{\n    \"strategy\": {\n        \"name\": \"my_strategy\",\n        \"asset\": \"BTC-USD\",\n        \"rules\": {...},\n        \"execution_config\": {...},\n        \"execution_state\": {\n            \"cash_balance\": 100000,\n            \"account_value\": 100000,\n            \"total_trades\": 0,\n            \"num_open_positions\": 0\n        }\n    },\n    \"persist\": false\n}\n\nx402 payer wallets get 30 free calls per UTC day on this operation; the listed price applies after that.","operationId":"api1_post_evaluate_strategy_by_object","parameters":[{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.EvaluateObjectRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.EvaluateResponse"}}},"description":"Evaluation complete"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Evaluate strategy with current market data using strategy object","tags":["execution"],"x-payment-info":{"price":{"amount":"0.050000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/execution/evaluate/bulk":{"post":{"description":"Evaluate multiple strategies at the current market bar. Market data is fetched once per unique (asset, timeframe) pair and shared across all strategies that need it, minimizing API calls. Individual strategy failures are captured per-result without aborting the batch. Both strategy_ids and strategy_configs may be provided in the same request.\nSupply strategy_ids (DB UUIDs), strategy_configs (inline objects), or both.\nEach strategy is evaluated independently at the current price bar; results\ninclude any orders generated (entry, SL, TP) without running a full\nhistorical simulation.\n\nx402 payer wallets get 30 free calls per UTC day on this operation; the listed price applies after that.","operationId":"api1_post_bulk_evaluate_strategies","parameters":[{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.BulkEvaluateRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.BulkEvaluateResult"}}},"description":"Bulk evaluation complete"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Evaluate multiple strategies at the current bar with shared market data","tags":["execution"],"x-payment-info":{"price":{"amount":"0.050000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/execution/evaluate/{strategy_id}":{"post":{"description":"Evaluate strategy with current market data and optionally persist results\nThis endpoint evaluates a strategy against current market conditions:\n1. Loads strategy with execution_config and execution_state\n2. Loads any open positions and their orders from database\n3. Evaluates exit conditions (SL, TP, signals, time-based) for open positions\n4. Evaluates entry signals for new positions\n5. Returns order objects (existing SL/TP or new market orders)\n\nBy default (persist=True), positions, orders, and trades are saved to the database.\nSet persist=False for dry-run evaluation without affecting database state.\n\nx402 payer wallets get 30 free calls per UTC day on this operation; the listed price applies after that.","operationId":"api1_post_evaluate_strategy","parameters":[{"description":"Strategy UUID to evaluate","in":"path","name":"strategy_id","required":true,"schema":{"type":"string"}},{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.EvaluateRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.EvaluateResponse"}}},"description":"Evaluation complete"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Evaluate strategy with current market data","tags":["execution"],"x-payment-info":{"price":{"amount":"0.050000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/execution/paper/{strategy_id}":{"get":{"operationId":"api1_get_paper_status","parameters":[{"in":"path","name":"strategy_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Get paper status","tags":["execution"],"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/execution/paper/{strategy_id}/pause":{"post":{"operationId":"api1_post_paper_pause","parameters":[{"in":"path","name":"strategy_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post paper pause","tags":["execution"],"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/execution/paper/{strategy_id}/start":{"post":{"operationId":"api1_post_paper_start","parameters":[{"in":"path","name":"strategy_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post paper start","tags":["execution"],"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/execution/paper/{strategy_id}/tick":{"post":{"operationId":"api1_post_paper_tick","parameters":[{"in":"path","name":"strategy_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post paper tick","tags":["execution"],"x-payment-info":{"price":{"amount":"0.020000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/execution/portfolio":{"get":{"description":"Batch-read portfolio data for multiple strategies in one call. Accepts a CSV of strategy IDs or repeated query params. Returns execution state, open position counts, and recent trades for each strategy. Max 100 IDs per request.\nDesigned for dashboard UIs that render multiple strategy cards.\nFetches all data in batched DB queries (strategies, open position\ncounts, recent trades) instead of N+1 individual calls.","operationId":"api1_get_portfolio_read","parameters":[{"description":"Comma-separated strategy UUIDs, or repeated query param (?strategy_ids=a&strategy_ids=b). Max 100.","in":"query","name":"strategy_ids","schema":{"type":"string"}},{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.PortfolioResponse"}}},"description":"Portfolio data"},"400":{"description":"Validation error (missing IDs or exceeds 100)"},"401":{"description":"Unauthorized"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Batch-read portfolio data for N strategies","tags":["execution"],"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/execution/positions":{"get":{"description":"List positions with optional filters","operationId":"api1_get_position_list","parameters":[{"description":"Filter by account UUID","in":"query","name":"account_id","schema":{"type":"string"}},{"description":"Filter by strategy UUID","in":"query","name":"strategy_id","schema":{"type":"string"}},{"description":"Filter by asset symbol","in":"query","name":"asset","schema":{"type":"string"}},{"description":"Only return open positions (default: true)","in":"query","name":"open_only","schema":{"type":"string"}},{"description":"Number of records to skip (pagination)","in":"query","name":"skip","schema":{"type":"string"}},{"description":"Maximum number of records to return","in":"query","name":"limit","schema":{"type":"string"}},{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/api1.Position"},"type":"array"}}},"description":"Success"},"401":{"description":"Unauthorized"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"List positions","tags":["execution"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/execution/trades":{"get":{"description":"List trade history with optional filters","operationId":"api1_get_trade_list","parameters":[{"description":"Filter by account UUID","in":"query","name":"account_id","schema":{"type":"string"}},{"description":"Filter by asset symbol","in":"query","name":"asset","schema":{"type":"string"}},{"description":"Filter by outcome (win or loss)","in":"query","name":"outcome","schema":{"type":"string"}},{"description":"Number of records to skip (pagination)","in":"query","name":"skip","schema":{"type":"string"}},{"description":"Maximum number of records to return","in":"query","name":"limit","schema":{"type":"string"}},{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/api1.Trade"},"type":"array"}}},"description":"Success"},"401":{"description":"Unauthorized"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"List trade history","tags":["execution"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/health":{"get":{"operationId":"api1_get_health","parameters":[{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.HealthResponse"}}},"description":"Success"}},"security":[],"summary":"Unified health check endpoint for the entire application","tags":["health"]}},"/api/v1/help/ask":{"post":{"operationId":"api1_post_help_bot_ask","parameters":[{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.HelpBotAskRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.HelpBotAskResponse"}}},"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Post help bot ask","tags":["help"]}},"/api/v1/help/ask/stream":{"post":{"operationId":"api1_post_help_bot_ask_stream","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.HelpBotAskRequest"}}},"required":true},"responses":{"200":{"content":{"text/event-stream":{"schema":{"type":"string"}}},"description":"Server-Sent Events"}},"security":[{"MangroveBearer":[]}],"summary":"Post help bot ask stream","tags":["help"]}},"/api/v1/help/conversations/{session_id}":{"get":{"operationId":"api1_get_help_bot_conversation","parameters":[{"in":"path","name":"session_id","required":true,"schema":{"type":"string"}},{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.HelpBotConversation"}}},"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Get help bot conversation","tags":["help"]}},"/api/v1/knowledge/documents":{"get":{"operationId":"api1_get_documents","responses":{"200":{"description":"Success"}},"security":[],"summary":"Get documents","tags":["knowledge"]}},"/api/v1/knowledge/documents/{slug}":{"get":{"operationId":"api1_get_document","parameters":[{"in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"}},"security":[],"summary":"Get document","tags":["knowledge"]}},"/api/v1/knowledge/glossary":{"get":{"operationId":"api1_get_glossary","responses":{"200":{"description":"Success"}},"security":[],"summary":"Get glossary","tags":["knowledge"]}},"/api/v1/knowledge/query":{"post":{"operationId":"api1_post_query","responses":{"200":{"description":"Success"}},"security":[],"summary":"Post query","tags":["knowledge"]}},"/api/v1/knowledge/quick-reference":{"get":{"operationId":"api1_get_quick_reference","responses":{"200":{"description":"Success"}},"security":[],"summary":"Get quick reference","tags":["knowledge"]}},"/api/v1/knowledge/search":{"get":{"operationId":"api1_get_search","responses":{"200":{"description":"Success"}},"security":[],"summary":"Get search","tags":["knowledge"]}},"/api/v1/market-data/regime/{asset}":{"get":{"description":"The return and a bull/neutral/bear band over each horizon, and annualised\nvolatility with a low/medium/high bucket and a z-score against the asset's own\nbaseline, from up to 12 months of daily closes. The stocks, ETFs, commodities\nand bonds in Oracle's regime catalog (SPY, QQQ, AAPL, GLD, GOLD, CRUDE, TLT and\nthe rest of GET /api/v2/regime/assets) are read from their exchange-session\nseries, even where a crypto token shares the ticker; any other ticker is read\nas crypto. `venue` names the feed. A listed ticker's lookback is calendar days\nand needs at least 15 sessions with a close, about three weeks; shorter is 422.","operationId":"api1_get_market_regime","parameters":[{"description":"Asset symbol, e.g. BTC, SPY, GOLD or CRUDE","in":"path","name":"asset","required":true,"schema":{"type":"string"}},{"description":"Days of daily closes to read, 1-365 (default 180)","in":"query","name":"lookback_days","schema":{"type":"string"}},{"description":"Quote currency; supply with market_data_venue","in":"query","name":"quote_token","schema":{"type":"string"}},{"description":"Exact exchange; supply with quote_token","in":"query","name":"market_data_venue","schema":{"type":"string"}},{"description":"Explicit external history provider","in":"query","name":"provider","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.MarketRegimeResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Invalid arguments"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"No data for the asset"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Too little history to classify"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Upstream failure"}},"security":[{"MangroveBearer":[]},{}],"summary":"Direction over 90/180/365 days plus volatility for one asset","tags":["market-data"],"x-payment-info":{"price":{"amount":"0.020000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/market-data/segment":{"get":{"description":"Returns the direction band, volatility band (`unscored` when no fitted band\ncovers the stretch's length -- `scale_bands` says which lengths have one),\ntrend character, the three features behind them, and the `venue` read.\nA date range for a stock, ETF, commodity or bond in Oracle's regime catalog is\nread from its exchange-session series and needs at least 15 sessions with a\nclose, about three weeks; shorter is 422. Any other ticker is read as crypto.","operationId":"api1_classify_market_segment","parameters":[{"description":"Asset symbol; required with start_date and end_date","in":"query","name":"asset","schema":{"type":"string"}},{"description":"ISO start of the stretch, e.g. 2026-01-01","in":"query","name":"start_date","schema":{"type":"string"}},{"description":"ISO end of the stretch, inclusive","in":"query","name":"end_date","schema":{"type":"string"}},{"description":"Candle size the stretch is read at (default 1d)","in":"query","name":"candle_size","schema":{"type":"string"}},{"description":"A sweep-catalog window's file name; supply this OR asset + dates","in":"query","name":"window_file","schema":{"type":"string"}},{"description":"Quote currency for date-based history","in":"query","name":"quote_token","schema":{"type":"string"}},{"description":"Exchange for date-based history","in":"query","name":"market_data_venue","schema":{"type":"string"}},{"description":"Explicit external history provider","in":"query","name":"provider","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.MarketSegmentResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Invalid arguments"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"No data or no such window"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Too little history to classify"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Upstream failure"}},"security":[{"MangroveBearer":[]},{}],"summary":"Classify a date range, or a catalog window, in the sweep catalog's labels","tags":["market-data"],"x-payment-info":{"price":{"amount":"0.020000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/on-chain/exchange-flows":{"get":{"operationId":"api1_get_unsupported_legacy_read","responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Get unsupported legacy read","tags":["on-chain"]}},"/api/v1/on-chain/series":{"post":{"description":"The same call serves a live trailing window (e.g. last 10 days, ending now)\nor a long historical range -- it is just a different date_range.","operationId":"api1_onchain_series","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.OnChainSeriesBody"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.OnChainSeriesResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.OnChainError"}}},"description":"Bad Request"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.OnChainError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.OnChainError"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Per-bar on-chain metric series (one key per metric), indexed by timestamp","tags":["on-chain"],"x-payment-info":{"price":{"amount":"0.050000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/on-chain/smart-money/dex-trades":{"post":{"description":"Body mirrors upstream Nansen `/v1/smart-money/dex-trades`.","operationId":"api1_smart_money_dex_trades","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SmartMoneyQueryBody"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SmartMoneyDexTradesResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.OnChainError"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get recent DEX trades from Smart Money wallets","tags":["on-chain"],"x-payment-info":{"price":{"amount":"0.020000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/on-chain/smart-money/historical-holdings":{"post":{"description":"Body mirrors upstream Nansen `/v1/smart-money/historical-holdings`:\nchains, date_range, filters, order_by, page, per_page.","operationId":"api1_smart_money_historical_holdings","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SmartMoneyDatedQueryBody"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SmartMoneyHistoricalHoldingsResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.OnChainError"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get date-stamped Smart Money holdings snapshots across chains","tags":["on-chain"],"x-payment-info":{"price":{"amount":"0.020000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/on-chain/smart-money/perp-trades":{"post":{"description":"Body mirrors upstream Nansen `/v1/smart-money/perp-trades` (no chains -- Hyperliquid only).","operationId":"api1_smart_money_perp_trades","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SmartMoneyPerpQueryBody"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SmartMoneyPerpTradesResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.OnChainError"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get perpetual-futures trades from Smart Money wallets on Hyperliquid","tags":["on-chain"],"x-payment-info":{"price":{"amount":"0.020000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/on-chain/smart-money/screen":{"get":{"operationId":"api1_screen_smart_money_tokens","parameters":[{"description":"Max results (default: 20, maximum: 100)","in":"query","name":"limit","schema":{"type":"integer"}},{"description":"5m, 1h, 6h, 24h, 7d, 30d (default: 24h)","in":"query","name":"timeframe","schema":{"type":"string"}},{"description":"Comma-separated chains (default: ethereum)","in":"query","name":"chains","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SmartMoneyScreenResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.OnChainError"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Screen for tokens with high smart money activity","tags":["on-chain"],"x-payment-info":{"price":{"amount":"0.020000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/on-chain/smart-money/sentiment":{"get":{"operationId":"api1_get_smart_money_sentiment","parameters":[{"description":"Blockchain (default: ethereum)","in":"query","name":"chain","schema":{"type":"string"}},{"description":"Token symbol (e.g. ETH, UNI)","in":"query","name":"symbol","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SmartMoneySentimentResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.OnChainError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.OnChainError"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get smart money sentiment (accumulation vs distribution) for a token","tags":["on-chain"],"x-payment-info":{"price":{"amount":"0.020000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/on-chain/token-holders/{symbol}":{"get":{"operationId":"api1_get_token_holders_f215770c0c255a6c","parameters":[{"description":"Token symbol (e.g. ETH, UNI)","in":"path","name":"symbol","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.OnChainTokenHoldersResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.OnChainError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.OnChainError"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get token holder distribution from Nansen","tags":["on-chain"],"x-payment-info":{"price":{"amount":"0.020000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/on-chain/token/{symbol}/dex-trades":{"post":{"description":"Body mirrors upstream Nansen `/v1/tgm/dex-trades`.","operationId":"api1_token_dex_trades","parameters":[{"description":"Token symbol (e.g. UNI, ETH). Resolved to its contract address on the requested chain.","in":"path","name":"symbol","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.TokenDatedQueryBody"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.TokenDexTradesResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.OnChainError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.OnChainError"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get DEX trades for a single token across all participants in a date window","tags":["on-chain"],"x-payment-info":{"price":{"amount":"0.020000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/on-chain/token/{symbol}/flows":{"post":{"description":"Body mirrors upstream Nansen `/v1/tgm/flows`. Stablecoins return 404.","operationId":"api1_token_flows","parameters":[{"description":"Token symbol (e.g. uniswap, ETH). Stablecoins not supported by this endpoint.","in":"path","name":"symbol","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.TokenDatedQueryBody"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.TokenFlowsResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.OnChainError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.OnChainError"}}},"description":"Internal Server Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get aggregated per-wallet-category flow data for a single token in a date window","tags":["on-chain"],"x-payment-info":{"price":{"amount":"0.020000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/on-chain/whale-activity/{symbol}":{"get":{"operationId":"api1_get_unsupported_legacy_read_061b616deadf7f20","parameters":[{"in":"path","name":"symbol","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Get unsupported legacy read 061b616deadf7f20","tags":["on-chain"]}},"/api/v1/on-chain/whale-transactions":{"get":{"operationId":"api1_get_unsupported_legacy_read_b47bd4163a46b73a","responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Get unsupported legacy read b47bd4163a46b73a","tags":["on-chain"]}},"/api/v1/organizations/":{"get":{"description":"Get current user organization","operationId":"api1_get_organization_list","responses":{"200":{"description":"Success"},"401":{"description":"Unauthorized"},"404":{"description":"Organization not found"},"500":{"description":"Server error"}},"security":[{"MangroveBearer":[]}],"summary":"Get the organization for the current user","tags":["organizations"]},"post":{"description":"Create a new organization","operationId":"api1_post_organization_list","parameters":[{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.CreateOrganization"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Organization"}}},"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"500":{"description":"Server error"}},"security":[{"MangroveBearer":[]}],"summary":"Create a new organization","tags":["organizations"]}},"/api/v1/organizations/invitations/accept":{"post":{"description":"Accept an invitation","operationId":"api1_post_accept_invitation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.AcceptInvitation"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"404":{"description":"Not found"},"500":{"description":"Server error"}},"security":[{"MangroveBearer":[]}],"summary":"Accept an invitation to join an organization","tags":["organizations"]}},"/api/v1/organizations/invitations/mine":{"get":{"description":"List pending invitations for the current user","operationId":"api1_get_my_invitations","responses":{"200":{"description":"Success"},"401":{"description":"Unauthorized"},"500":{"description":"Server error"}},"security":[{"MangroveBearer":[]}],"summary":"Get pending invitations for the current user's email","tags":["organizations"]}},"/api/v1/organizations/mine":{"get":{"description":"List all organizations the current user belongs to","operationId":"api1_get_user_organizations","responses":{"200":{"description":"Success"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"500":{"description":"Server error"}},"security":[{"MangroveBearer":[]}],"summary":"List all organizations for the current user with their role in each","tags":["organizations"]}},"/api/v1/organizations/{org_id}":{"get":{"description":"Get organization by ID","operationId":"api1_get_organization_detail","parameters":[{"in":"path","name":"org_id","required":true,"schema":{"type":"string"}},{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Organization"}}},"description":"Success"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Server error"}},"security":[{"MangroveBearer":[]}],"summary":"Get organization details","tags":["organizations"]},"put":{"description":"Update organization","operationId":"api1_put_organization_detail","parameters":[{"in":"path","name":"org_id","required":true,"schema":{"type":"string"}},{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.UpdateOrganization"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Organization"}}},"description":"Success"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Server error"}},"security":[{"MangroveBearer":[]}],"summary":"Update organization details","tags":["organizations"]}},"/api/v1/organizations/{org_id}/invitations":{"get":{"description":"List organization invitations","operationId":"api1_get_organization_invitations","parameters":[{"in":"path","name":"org_id","required":true,"schema":{"type":"string"}},{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/api1.Invitation"},"type":"array"}}},"description":"Success"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"500":{"description":"Server error"}},"security":[{"MangroveBearer":[]}],"summary":"List all invitations for an organization","tags":["organizations"]},"post":{"description":"Invite a user to organization","operationId":"api1_post_organization_invitations","parameters":[{"in":"path","name":"org_id","required":true,"schema":{"type":"string"}},{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.InviteMember"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Invitation"}}},"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"500":{"description":"Server error"}},"security":[{"MangroveBearer":[]}],"summary":"Invite a user to join the organization","tags":["organizations"]}},"/api/v1/organizations/{org_id}/invitations/{invitation_id}":{"delete":{"description":"Cancel an invitation","operationId":"api1_delete_organization_invitation_detail","parameters":[{"in":"path","name":"org_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"invitation_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Server error"}},"security":[{"MangroveBearer":[]}],"summary":"Cancel a pending invitation","tags":["organizations"]}},"/api/v1/organizations/{org_id}/members":{"get":{"description":"List organization members","operationId":"api1_get_organization_members","parameters":[{"in":"path","name":"org_id","required":true,"schema":{"type":"string"}},{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/api1.OrganizationMember"},"type":"array"}}},"description":"Success"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"500":{"description":"Server error"}},"security":[{"MangroveBearer":[]}],"summary":"List all members of an organization","tags":["organizations"]}},"/api/v1/organizations/{org_id}/members/{user_id}":{"delete":{"description":"Remove member from organization","operationId":"api1_delete_organization_member_detail","parameters":[{"in":"path","name":"org_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"user_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Server error"}},"security":[{"MangroveBearer":[]}],"summary":"Remove a member from the organization","tags":["organizations"]},"put":{"description":"Update member role","operationId":"api1_put_organization_member_detail","parameters":[{"in":"path","name":"org_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"user_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.UpdateMemberRole"}}},"required":true},"responses":{"200":{"description":"Success"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Server error"}},"security":[{"MangroveBearer":[]}],"summary":"Update a member's role","tags":["organizations"]}},"/api/v1/signals/":{"get":{"description":"Use it to browse the catalogue, or narrow it by regime band, role or library category.\n\nTHE FIRST LINE IS A PUBLIC DESCRIPTION, NOT A NOTE TO OURSELVES. It is what an\nMCP client reads in ``tools/list`` -- the scanner takes this docstring's first\nline for the advertised tool (``mcp/billable_scanner.py::_extract_description``)\n-- and it is the Swagger summary. It has to tell a model WHEN to reach for this\noperation, because that is what it picks a tool from a list of ~68 with. Keep it\none line, keep the selection guidance, leave the per-argument detail to the\n``@ns.param`` descriptions above, which travel in the same schema.\n\nA transport adapter over the canonical ``signals.list`` operation (#812, T05).\nIt reads the query string and translates the operation's domain errors into\nthis API's status codes. It holds no opinion about defaults, bounds or valid\nfilter values -- those are the contract's, in\n``domains/signals/operations/list_signals.py``.\n\nNO CHARGE ON 400 OR 503. Not handled here: ``@billable`` reserves units before\nthe view runs and the ``after_request`` hook refunds every reservation in full\non any status >= 400, so returning the right status IS the billing behavior.\nThat invariant belongs to another module and this route silently depends on\nit; it is pinned by ``tests/utils/metering/test_settlement.py``\n(``test_4xx_refunds_every_reservation``, ``test_5xx_refunds_every_reservation``).","operationId":"api1_get_signals_list","parameters":[{"description":"Filter by the part a signal plays in a strategy (TRIGGER or FILTER)","in":"query","name":"role","schema":{"type":"string"}},{"description":"Filter to signals admissible for a regime band (mega_bull, super_bull, bull, neutral, bear, super_bear, mega_bear)","in":"query","name":"regime_direction","schema":{"type":"string"}},{"description":"Filter by category (momentum, trend, volume, volatility, patterns, onchain, social)","in":"query","name":"category","schema":{"type":"string"}},{"description":"Pagination offset","in":"query","name":"offset","schema":{"default":0,"type":"integer"}},{"description":"Page size: default 30, maximum 30. Larger requests are capped; use next_offset to continue.","in":"query","name":"limit","schema":{"default":30,"type":"integer"}},{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SignalListResponse"}}},"description":"Success"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Validation error"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Signal catalogue unavailable"}},"security":[],"summary":"List available trading signals: names, types (TRIGGER or FILTER) and short descriptions","tags":["signals"]},"post":{"operationId":"api1_post_signals_list","parameters":[{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.CreateSignalRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.CreateSignalResponse"}}},"description":"Success"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.CreateSignalResponse"}}},"description":"Signal created"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Validation error"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Duplicate signal"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Server error"}},"security":[{"MangroveBearer":[]}],"summary":"Retired: the signal library is fixed and curated","tags":["signals"]}},"/api/v1/signals/behavior":{"post":{"description":"A FILTER is measured for how OFTEN it is true (selectivity) and for how LONG it\nstays true; a TRIGGER for its activity (firings per 1,000 bars) and reactivity\n(the distribution of gaps between firings). Same answer the copilot's\nquery_signal_behavior tool returns.","operationId":"api1_post_signals_behavior","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SignalBehaviorRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SignalBehaviorResponse"}}},"description":"Success"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Validation error"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Query measured signal behaviour: describe, pick, find or gap_probability","tags":["signals"],"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/signals/evaluate-multiple-series":{"post":{"description":"Accepts either:\n- dataset_key (playground mode): loads local CSV data, no CoinAPI call\n- symbol + start_date + end_date (live mode): fetches from CoinAPI","operationId":"api1_evaluate_multiple_signals_series","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.EvaluateMultipleSeriesRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.EvaluateMultipleSeriesResponse"}}},"description":"Success"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Validation Error"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Internal Error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Evaluate chart data and optional signal triggers over a specific range","tags":["signals"],"x-payment-info":{"price":{"amount":"0.050000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/signals/labels":{"get":{"description":"One unpaginated, unbilled read for rendering signal names in a UI: the catalogue is a few\nhundred small rows, and a page that shows signal names needs all of them.","operationId":"api1_get_signal_labels","parameters":[{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SignalLabelsResponse"}}},"description":"Success"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Signal catalogue unavailable"}},"security":[{"MangroveBearer":[]}],"summary":"Every signal's friendly name, display name and short description, keyed by code name","tags":["signals"]}},"/api/v1/signals/match":{"post":{"operationId":"api1_post_signals_match","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.MatchSignalsRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.MatchSignalsResponse"}}},"description":"Success"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Validation error"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Match a trading description to ranked signals","tags":["signals"],"x-payment-info":{"price":{"amount":"0.010000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/signals/playground-data/{dataset_key}":{"get":{"operationId":"api1_get_playground_data","parameters":[{"in":"path","name":"dataset_key","required":true,"schema":{"type":"string"}},{"description":"ISO end of the window.","in":"query","name":"end_date","required":false,"schema":{"type":"string"}},{"description":"Maximum results.","in":"query","name":"limit","required":false,"schema":{"default":500,"type":"integer"}},{"description":"Pagination offset in the result units documented by the tool; zero starts the first page.","in":"query","name":"offset","required":false,"schema":{"default":0,"type":"integer"}},{"description":"ISO start of the window, e.g. 2026-01-01.","in":"query","name":"start_date","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Return one page of OHLCV bars from a playground dataset, newest page first","tags":["signals"]}},"/api/v1/signals/playground-datasets":{"get":{"operationId":"api1_list_playground_datasets","responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Return metadata for all available playground CSV datasets","tags":["signals"]}},"/api/v1/signals/search":{"post":{"operationId":"api1_post_signals_search","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SearchSignalsRequest"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Validation error"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Server error"}},"security":[],"summary":"Search signal names, parameters or description keywords","tags":["signals"]}},"/api/v1/signals/validate":{"post":{"operationId":"api1_post_validate_signal_endpoint","parameters":[{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ValidateSignalCodeRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ValidationResult"}}},"description":"Success"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Bad request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Server error"}},"security":[{"MangroveBearer":[]}],"summary":"Run full signal validation (syntax, metadata, execution, trades)","tags":["signals"]}},"/api/v1/signals/validate-execution":{"post":{"operationId":"api1_post_validate_execution_endpoint","parameters":[{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ValidateSignalCodeRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ExecutionValidationResult"}}},"description":"Success"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Bad request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Server error"}},"security":[{"MangroveBearer":[]}],"summary":"Validate signal execution with test data","tags":["signals"]}},"/api/v1/signals/validate-metadata":{"post":{"operationId":"api1_post_validate_metadata_endpoint","parameters":[{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ValidateSignalCodeRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.MetadataValidationResult"}}},"description":"Success"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Bad request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Server error"}},"security":[{"MangroveBearer":[]}],"summary":"Validate signal metadata matches function signature","tags":["signals"]}},"/api/v1/signals/validate-syntax":{"post":{"operationId":"api1_post_validate_syntax_endpoint","parameters":[{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ValidateSignalCodeRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SyntaxValidationResult"}}},"description":"Success"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Bad request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Server error"}},"security":[{"MangroveBearer":[]}],"summary":"Validate signal syntax (AST parsing, function definition, signature)","tags":["signals"]}},"/api/v1/signals/validate-trades":{"post":{"operationId":"api1_post_validate_trades_endpoint","parameters":[{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ValidateSignalCodeRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.TradesValidationResult"}}},"description":"Success"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Bad request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Server error"}},"security":[{"MangroveBearer":[]}],"summary":"Validate signal produces both True and False results","tags":["signals"]}},"/api/v1/signals/{signal_name}":{"get":{"operationId":"api1_get_signal_detail","parameters":[{"description":"Signal name","in":"path","name":"signal_name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Signal"}}},"description":"Success"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Server error"}},"security":[],"summary":"Get complete metadata for an exact registered signal name","tags":["signals"]}},"/api/v1/signals/{signal_name}/evaluate":{"post":{"operationId":"api1_post_signal_evaluate","parameters":[{"description":"Signal name","in":"path","name":"signal_name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.EvaluateSignalRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SignalEvaluationResponse"}}},"description":"Success"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Validation error"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Evaluate a signal against provided market data and parameters","tags":["signals"],"x-payment-info":{"price":{"amount":"0.020000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/signals/{signal_name}/validate-params":{"post":{"operationId":"api1_post_signal_validate","parameters":[{"description":"Signal name","in":"path","name":"signal_name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ValidateSignalParamsRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SignalValidationResponse"}}},"description":"Success"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Validation error"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.Error"}}},"description":"Server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Validate parameters for a signal","tags":["signals"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/social/influence/{username}":{"get":{"operationId":"api1_get_influence","parameters":[{"description":"X/Twitter username (without @)","in":"path","name":"username","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.InfluenceScoreResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SocialError"}}},"description":"Internal Server Error"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SocialError"}}},"description":"X/Twitter request failed, including an unknown username"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SocialError"}}},"description":"X/Twitter not configured"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get influence score and follower metrics for a user","tags":["social"],"x-payment-info":{"price":{"amount":"0.020000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/social/mentions/{topic}":{"get":{"operationId":"api1_get_mentions","parameters":[{"description":"Topic or keyword to search","in":"path","name":"topic","required":true,"schema":{"type":"string"}},{"description":"Max posts to return (default 20)","in":"query","name":"limit","schema":{"type":"integer"}},{"description":"Time window in hours (default 24)","in":"query","name":"hours_back","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.MentionsResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SocialError"}}},"description":"Internal Server Error"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SocialError"}}},"description":"X/Twitter request failed"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SocialError"}}},"description":"X/Twitter not configured"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get recent mentions for a topic","tags":["social"],"x-payment-info":{"price":{"amount":"1.000000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/social/sentiment/{topic}":{"get":{"operationId":"api1_get_sentiment","parameters":[{"description":"Topic or symbol to analyze (e.g. BTC, ETH, Solana)","in":"path","name":"topic","required":true,"schema":{"type":"string"}},{"description":"Time window in hours (default 24)","in":"query","name":"hours_back","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SentimentResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SocialError"}}},"description":"Internal Server Error"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SocialError"}}},"description":"X/Twitter request failed"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SocialError"}}},"description":"X/Twitter not configured"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get social sentiment score for a topic","tags":["social"],"x-payment-info":{"price":{"amount":"1.000000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/social/x-post-counts/{symbol}":{"get":{"operationId":"api1_get_x_post_counts","parameters":[{"description":"Asset ticker, e.g. BTC (counted as the $BTC cashtag)","in":"path","name":"symbol","required":true,"schema":{"type":"string"}},{"description":"Query variant: all (default) or en_original","in":"query","name":"x_query","schema":{"type":"string"}},{"description":"Bucket size: hour (default) or day","in":"query","name":"granularity","schema":{"type":"string"}},{"description":"Window in days ending now, 1-31 (default 7)","in":"query","name":"days_back","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.XPostCountsResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SocialError"}}},"description":"Invalid symbol, window, granularity or x_query"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SocialError"}}},"description":"Internal Server Error"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SocialError"}}},"description":"X/Twitter request failed"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SocialError"}}},"description":"X social signals off or X/Twitter not configured"}},"security":[{"MangroveBearer":[]},{}],"summary":"Get hourly or daily X post counts for an asset (the x_attention signal input)","tags":["social"],"x-payment-info":{"price":{"amount":"0.020000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategies/":{"get":{"operationId":"api1_list_strategies","parameters":[{"description":"Include archived strategies (default false). Strategies are never deleted; archived ones are hidden by default.","in":"query","name":"include_archived","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.StrategyListResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"List all strategies for authenticated user","tags":["strategies"],"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}},"post":{"operationId":"api1_post_strategy_list_create","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.CreateStrategyRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.CreateStrategyResponse"}}},"description":"Created"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Create new strategy","tags":["strategies"],"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategies/ensure":{"post":{"operationId":"api1_post_strategy_ensure","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.CreateStrategyRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.EnsureStrategyExistingResponse"}}},"description":"Existing strategy returned"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.EnsureStrategyCreatedResponse"}}},"description":"Strategy created"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Get-or-create a strategy idempotently by content hash","tags":["strategies"],"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategies/{strategy_id}":{"delete":{"description":"Product ruling (#806): strategies follow the same archive-only contract\nas backtests -- they are never removed from the database. This route is\nretained for back-compat but now ARCHIVES the strategy (reversible via\nPOST /strategies/<id>/unarchive) instead of hard-deleting it. Prefer the\nexplicit POST /strategies/<id>/archive endpoint (which only needs\nstrategy:update_status, not strategy:delete).","operationId":"api1_delete_strategy","parameters":[{"in":"path","name":"strategy_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.DeleteStrategyResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"DEPRECATED: archive a strategy (strategies are archived, not hard-deleted)","tags":["strategies"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}},"get":{"operationId":"api1_get_strategy","parameters":[{"in":"path","name":"strategy_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.GetStrategyResponse"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Get strategy by ID","tags":["strategies"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}},"put":{"operationId":"api1_update_strategy","parameters":[{"in":"path","name":"strategy_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.UpdateStrategyResponse"}}},"description":"OK"},"400":{"description":"Validation error (not draft or invalid fields)"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"description":"Strategy not found"}},"security":[{"MangroveBearer":[]},{}],"summary":"Update a draft strategy (name, asset, rules, execution_config)","tags":["strategies"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategies/{strategy_id}/archive":{"post":{"description":"Strategies are never deleted -- archiving is a reversible view-state\nthat removes the strategy from the default list views (GET /strategies,\nGET /users/me/strategies). Restore it with POST /strategies/<id>/unarchive.\nDoes not affect the active-strategy cap (owned by platform-backend).\n\nAuthorization: strategy:update_status (any member/owner/admin of the org).","operationId":"api1_archive_strategy","parameters":[{"in":"path","name":"strategy_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.StrategyArchiveResponse"}}},"description":"Strategy archived"},"404":{"description":"Strategy not found"}},"security":[{"MangroveBearer":[]}],"summary":"Archive a strategy","tags":["strategies"]}},"/api/v1/strategies/{strategy_id}/execution-state":{"patch":{"description":").","operationId":"api1_update_execution_state","parameters":[{"in":"path","name":"strategy_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"description":"Strategy not found"}},"security":[{"MangroveBearer":[]},{}],"summary":"Update execution_state (cash_balance, account_value, etc","tags":["strategies"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategies/{strategy_id}/local-deployment":{"get":{"operationId":"api1_get_local_deployment","parameters":[{"in":"path","name":"strategy_id","required":true,"schema":{"type":"string"}},{"description":"Asset class for the separate local broker runner.","in":"query","name":"asset_class","required":true,"schema":{"enum":["crypto","equity"],"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.LocalDeploymentResponse"}}},"description":"Versioned owner-scoped definition snapshot"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"description":"Strategy is missing or outside the authenticated owner scope"},"409":{"description":"Stored strategy or deployment request is incompatible"},"500":{"description":"Deployment validation could not be completed"}},"security":[{"MangroveBearer":[]},{}],"summary":"Validate a versioned local Robinhood snapshot; it does not activate trading","tags":["strategies"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategies/{strategy_id}/status":{"patch":{"operationId":"api1_update_strategy_status","parameters":[{"in":"path","name":"strategy_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.UpdateStrategyStatusRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.UpdateStrategyStatusResponse"}}},"description":"OK"},"400":{"description":"Validation error"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"description":"Strategy not found"}},"security":[{"MangroveBearer":[]},{}],"summary":"Update strategy status (draft, inactive, paper, live, archived)","tags":["strategies"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategies/{strategy_id}/unarchive":{"post":{"description":"Authorization: strategy:update_status (any member/owner/admin of the org).","operationId":"api1_unarchive_strategy","parameters":[{"in":"path","name":"strategy_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.StrategyArchiveResponse"}}},"description":"Strategy unarchived"},"404":{"description":"Strategy not found"}},"security":[{"MangroveBearer":[]}],"summary":"Unarchive a strategy (the inverse of POST /strategies/<id>/archive)","tags":["strategies"]}},"/api/v1/strategies/{strategy_id}/verify":{"get":{"description":"Reads what is STORED, so it answers for the strategy as it exists. Call it after\nsaving and before backtesting -- a backtest is billed at submission whether or\nnot it runs. Same check the copilot's verify_strategy tool runs.","operationId":"api1_verify_strategy","parameters":[{"in":"path","name":"strategy_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.StrategyVerification"}}},"description":"OK"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"description":"Strategy not found"},"500":{"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Verify a stored strategy: signal names, parameter keys, roles, timeframes","tags":["strategies"],"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategy-workflow/build_strategy_for_regime":{"post":{"operationId":"api1_post_build_strategy_for_regime_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post build strategy for regime operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"asset":{"description":"Asset symbol, e.g. BTC or ETH.","type":"string"},"candle_size":{"description":"Duration of one candle, e.g. 1h or 1d.","type":"string"}},"required":["asset"],"type":"object"},"x-payment-info":{"price":{"amount":"0.100000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategy-workflow/create_sweep":{"post":{"operationId":"api1_post_create_sweep_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Post create sweep operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"assets":{"description":"Asset symbols, e.g. [\"BTC\", \"ETH\"].","items":{"type":"string"},"type":"array"},"candidate_shape":{"description":"How many parts a drawn strategy gets, any of n_entry_triggers, min_entry_filters, max_entry_filters, min_exit_triggers, max_exit_triggers, min_exit_filters, max_exit_filters. Omitted, the platform default shape.","type":"object"},"candle_sizes":{"description":"Candle sizes, e.g. [\"1h\"]. Omitted, every size Oracle holds for those assets, which multiplies the windows.","items":{"type":"string"},"type":"array"},"categories":{"description":"Draw only from these signal classes, e.g. [\"momentum\"]. The classes are averaging, flow, momentum, oscillator, pattern and volatility. Omitted, the whole library.","items":{"type":"string"},"type":"array"},"draws_per_dataset":{"default":100,"description":"How many candidate strategies to draw PER WINDOW. The runs that execute are this multiplied by the number of windows.","type":"integer"},"entry_filters":{"description":"Draw entry filters only from these. Omitted, every filter.","items":{"type":"string"},"type":"array"},"entry_triggers":{"description":"Draw the entry trigger only from these signals, named as the knowledge graph registers them. Omitted, every trigger.","items":{"type":"string"},"type":"array"},"execution_base":{"description":"Risk settings every run shares, from the execution config schema. Omitted, platform canon.","type":"object"},"execution_sweeps":{"description":"Execution parameters to search too, each {param: {min, max, n}}. Every one of these multiplies the run count.","type":"object"},"exit_filters":{"description":"Draw exit filters only from these.","items":{"type":"string"},"type":"array"},"exit_triggers":{"description":"Draw an exit trigger only from these. Omitted, no exit signal is drawn at all and runs exit on the risk settings.","items":{"type":"string"},"type":"array"},"include_gapped":{"default":false,"description":"Include windows missing bars. Off by default, because a metric over a half-covered window is not comparable to one over a whole window.","type":"boolean"},"max_total_runs":{"description":"A ceiling on the executed runs, applied by Oracle.","type":"integer"},"param_samples":{"default":3,"description":"How many values each signal parameter contributes. The space is their product, so this is the dial that decides whether the search explores parameters at all; at 1 every candidate runs at a single setting.","type":"integer"},"pre_filter_threshold":{"description":"Skip a drawn candidate the SIEVE model predicts will not trade at all, above this confidence. A will-it-trade gate and nothing about whether it will make money. Omitted, no skipping.","type":"number"},"regimes":{"description":"Market conditions to keep: current, bear, neutral, bull. current means data within the last 30 days, which is recency and not direction. Omitted, every condition.","items":{"type":"string"},"type":"array"},"signal_groups":{"description":"Keep kinds of signal apart. A candidate draws ALL of its signals from ONE group, so two signals in different groups never appear on the same strategy. Runs are split across the groups.","items":{"additionalProperties":false,"properties":{"categories":{"description":"Signal classes whose members belong to it.","items":{"type":"string"},"type":"array"},"exclude":{"description":"Signal names removed from it.","items":{"type":"string"},"type":"array"},"filters":{"additionalProperties":false,"description":"Select which group members may serve as filters. Role selections only narrow the parent membership; they cannot reassign a signal's role.","properties":{"categories":{"items":{"type":"string"},"type":"array"},"exclude":{"items":{"type":"string"},"type":"array"},"include":{"items":{"type":"string"},"type":"array"}},"required":[],"type":"object"},"include":{"description":"Signal names forced in even when their class is not listed.","items":{"type":"string"},"type":"array"},"name":{"description":"What to call the group.","type":"string"},"triggers":{"additionalProperties":false,"description":"Select which group members may serve as triggers.","properties":{"categories":{"items":{"type":"string"},"type":"array"},"exclude":{"items":{"type":"string"},"type":"array"},"include":{"items":{"type":"string"},"type":"array"}},"required":[],"type":"object"},"weight":{"description":"Its share of the strategies drawn. Omitted on every group is an even split.","type":"number"}},"required":[],"type":"object"},"type":"array"},"sweep_name":{"description":"What to call it.","type":"string"},"windows":{"description":"Specific window files to include whatever else is chosen.","items":{"type":"string"},"type":"array"}},"required":["sweep_name"],"type":"object"}}},"/api/v1/strategy-workflow/delete_strategy":{"post":{"operationId":"api1_post_delete_strategy_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post delete strategy operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"strategy_id":{"description":"The strategy's UUID.","type":"string"}},"required":["strategy_id"],"type":"object"},"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategy-workflow/evaluate_strategy":{"post":{"description":"x402 payer wallets get 30 free calls per UTC day on this operation; the listed price applies after that.","operationId":"api1_post_evaluate_strategy_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post evaluate strategy operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"strategy_id":{"description":"The strategy's UUID.","type":"string"}},"required":["strategy_id"],"type":"object"},"x-payment-info":{"price":{"amount":"0.050000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategy-workflow/find_sweep_runs":{"post":{"operationId":"api1_post_find_sweep_runs_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post find sweep runs operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"asset":{"description":"Asset symbol, e.g. BTC or ETH.","type":"string"},"atr_period":{"description":"Only runs that used this ATR period. Needs experiment_id.","type":"integer"},"beats_benchmarks":{"default":false,"description":"Only runs that beat all three benchmarks over the same","type":"boolean"},"beats_crypto_benchmarks":{"default":false,"description":"Only runs that beat the crypto benchmarks rather than only their own asset.","type":"boolean"},"candle_size":{"description":"Duration of one candle, e.g. 1h or 1d.","type":"string"},"cooldown_bars":{"description":"Only runs that used this cooldown. Needs experiment_id.","type":"integer"},"covering":{"description":"Only runs over windows covering this single date, as YYYY-MM-DD. A different question from a span.","type":"string"},"covering_from":{"description":"Only runs whose window OVERLAPS this date onwards. A run is relevant to 2024 if any of it happened in 2024.","type":"string"},"covering_to":{"description":"Only runs whose window overlaps up to this date.","type":"string"},"experiment_id":{"description":"The sweep, as create_sweep returned it.","type":"string"},"generation":{"description":"Only runs from this engine generation, so runs made under different engine behaviour are not compared as though alike.","type":"string"},"limit":{"default":20,"description":"Maximum results.","type":"integer"},"market_direction":{"description":"Only runs from windows of this market character, e.g. bear or mega_bull. Several are one comma-separated string, e.g. \"bull,super_bull\", and a run matching any of them counts. What a run did in one kind of market says little about another.","type":"string"},"max_delta_vs_asset":{"description":"Only runs beating their own asset by at most this much.","type":"number"},"max_delta_vs_benchmark":{"description":"Only runs beating their benchmark by at most this much, so \"between 3 and 8\" is one question rather than a page fetched and thrown away.","type":"number"},"max_irr":{"description":"Only runs at or below this annualised IRR.","type":"number"},"max_return":{"description":"Only runs at or below this total return.","type":"number"},"max_risk_per_trade":{"description":"Only runs that risked this fraction per trade. Needs experiment_id.","type":"number"},"max_sharpe":{"description":"Only runs at or below this Sharpe ratio.","type":"number"},"max_trades":{"description":"Only runs at or below this trade count. Pairs with min_trades to ask for a band rather than a floor.","type":"integer"},"max_win_rate":{"description":"Only runs at or below this win rate.","type":"number"},"min_delta_vs_asset":{"description":"Only runs beating buy-and-hold on their own asset by at least this much.","type":"number"},"min_delta_vs_benchmark":{"description":"Only runs that beat their benchmark by at least this much. A return in a rising market is not skill.","type":"number"},"min_irr":{"description":"Only runs at or above this annualised IRR.","type":"number"},"min_return":{"description":"Only runs at or above this total return.","type":"number"},"min_sharpe":{"description":"Only runs at or above this Sharpe ratio.","type":"number"},"min_trades":{"default":0,"description":"Drop runs with fewer trades than this. Metrics from a handful of trades are noise.","type":"integer"},"min_win_rate":{"description":"Only runs at or above this win rate.","type":"number"},"offset":{"default":0,"description":"Pagination offset in the result units documented by the tool; zero starts the first page.","type":"integer"},"order":{"default":"desc","description":"desc for best-first on that metric, asc for worst-first.","type":"string"},"regime_composite":{"description":"Only runs from windows with this full regime label, e.g. mega_bull_high_clean, when the three parts together matter; several comma-separated, any of them counts. Across different regime filters every one must hold.","type":"string"},"regime_direction":{"description":"The direction band from get_market_regime, e.g. bear. The signal searches filter by it and find_sweep_runs marks each row's regime_fit with it; save_strategy and update_strategy read the current band themselves, so their check runs without it.","type":"string"},"reward_factor":{"description":"Only runs that used this reward-to-risk setting. Execution filters need experiment_id; the cross-sweep surface does not serve them.","type":"number"},"run_index":{"description":"Which run, as find_sweep_runs reported it.","type":"integer"},"run_status":{"description":"Only runs with this outcome, e.g. no_trades for the ones that never opened a position.","type":"string"},"sort_by":{"description":"The metric to order by, e.g. sharpe_ratio, sortino_ratio, irr_annualized, total_return, max_drawdown, total_trades. Required, because the choice IS the question being asked.","type":"string"},"trend":{"description":"Only runs from windows of this trend character, e.g. clean or choppy; several comma-separated, any of them counts.","type":"string"},"trigger_name":{"description":"Only runs whose entry trigger is this signal.","type":"string"},"volatility":{"description":"Only runs from windows of this volatility band, e.g. low; several comma-separated, any of them counts.","type":"string"}},"required":["sort_by"],"type":"object"},"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategy-workflow/get_backtest":{"post":{"operationId":"api1_post_get_backtest_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post get backtest operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"backtest_id":{"description":"The run's UUID, as run_backtest returned it.","type":"string"}},"required":["backtest_id"],"type":"object"},"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategy-workflow/get_backtest_trades":{"post":{"operationId":"api1_post_get_backtest_trades_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post get backtest trades operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"backtest_id":{"description":"The run's UUID, as run_backtest returned it.","type":"string"},"limit":{"default":25,"description":"Maximum results.","type":"integer"},"offset":{"default":0,"description":"Pagination offset in the result units documented by the tool; zero starts the first page.","type":"integer"}},"required":["backtest_id"],"type":"object"},"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategy-workflow/get_execution_config_schema":{"post":{"operationId":"api1_post_get_execution_config_schema_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":false},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ExecutionConfigSchemaResponse"}}},"description":"Canonical execution configuration metadata and JSON Schema"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post get execution config schema operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{},"required":[],"type":"object"},"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategy-workflow/get_marketplace_strategy":{"post":{"operationId":"api1_post_get_marketplace_strategy_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post get marketplace strategy operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"strategy_id":{"description":"The strategy's UUID.","type":"string"}},"required":["strategy_id"],"type":"object"},"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategy-workflow/get_strategy":{"post":{"operationId":"api1_post_get_strategy_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":false},"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post get strategy operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"name":{"description":"Its name, if the id is unknown.","type":"string"},"strategy_id":{"description":"The strategy's UUID.","type":"string"}},"required":[],"type":"object"},"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategy-workflow/get_sweep":{"post":{"operationId":"api1_post_get_sweep_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Post get sweep operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"experiment_id":{"description":"The sweep, as create_sweep returned it.","type":"string"}},"required":["experiment_id"],"type":"object"}}},"/api/v1/strategy-workflow/get_sweep_limits":{"post":{"operationId":"api1_post_get_sweep_limits_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":false},"responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Post get sweep limits operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{},"required":[],"type":"object"}}},"/api/v1/strategy-workflow/get_sweep_run":{"post":{"operationId":"api1_post_get_sweep_run_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Post get sweep run operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"config_hash":{"description":"The row's config_hash, as find_sweep_runs reported it. Pass it whenever you have it: a relaunched sweep can give one run_index to several runs, and without it such an index is refused, not guessed.","type":"string"},"experiment_id":{"description":"The sweep, as create_sweep returned it.","type":"string"},"run_index":{"description":"Which run, as find_sweep_runs reported it.","type":"integer"}},"required":["experiment_id","run_index"],"type":"object"}}},"/api/v1/strategy-workflow/get_trades_for_strategy":{"post":{"operationId":"api1_post_get_trades_for_strategy_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Post get trades for strategy operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"limit":{"default":25,"description":"Maximum results.","type":"integer"},"offset":{"default":0,"description":"Pagination offset in the result units documented by the tool; zero starts the first page.","type":"integer"},"strategy_id":{"description":"The strategy's UUID.","type":"string"}},"required":["strategy_id"],"type":"object"}}},"/api/v1/strategy-workflow/launch_sweep":{"post":{"operationId":"api1_post_launch_sweep_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post launch sweep operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"experiment_id":{"description":"The sweep, as create_sweep returned it.","type":"string"}},"required":["experiment_id"],"type":"object"},"x-payment-info":{"price":{"amount":"0.250000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategy-workflow/list_backtest_markets":{"post":{"operationId":"api1_post_list_backtest_markets_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Post list backtest markets operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"asset":{"description":"Asset symbol, e.g. BTC or ETH.","type":"string"}},"required":["asset"],"type":"object"}}},"/api/v1/strategy-workflow/list_backtests":{"post":{"operationId":"api1_post_list_backtests_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":false},"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post list backtests operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"limit":{"default":10,"description":"Maximum results.","type":"integer"},"strategy_id":{"description":"The strategy's UUID.","type":"string"}},"required":[],"type":"object"},"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategy-workflow/list_evaluations":{"post":{"operationId":"api1_post_list_evaluations_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Post list evaluations operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"include_details":{"default":false,"description":"Also return each evaluation's market_snapshot, sdk_response and order_intents.","type":"boolean"},"limit":{"default":20,"description":"Maximum results.","type":"integer"},"offset":{"default":0,"description":"Pagination offset in the result units documented by the tool; zero starts the first page.","type":"integer"},"strategy_id":{"description":"The strategy's UUID.","type":"string"}},"required":["strategy_id"],"type":"object"}}},"/api/v1/strategy-workflow/list_platform_strategies":{"post":{"operationId":"api1_post_list_platform_strategies_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":false},"responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Post list platform strategies operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"limit":{"default":100,"description":"Maximum results.","type":"integer"}},"required":[],"type":"object"}}},"/api/v1/strategy-workflow/list_positions":{"post":{"operationId":"api1_post_list_positions_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":false},"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post list positions operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"asset":{"description":"Asset symbol, e.g. BTC or ETH.","type":"string"},"limit":{"default":25,"description":"Maximum results.","type":"integer"},"offset":{"default":0,"description":"Pagination offset in the result units documented by the tool; zero starts the first page.","type":"integer"},"open_only":{"default":true,"description":"Leave out positions that have already been closed.","type":"boolean"},"strategy_id":{"description":"The strategy's UUID.","type":"string"}},"required":[],"type":"object"},"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategy-workflow/list_run_filters":{"post":{"operationId":"api1_post_list_run_filters_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Post list run filters operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"experiment_id":{"description":"The sweep, as create_sweep returned it.","type":"string"}},"required":["experiment_id"],"type":"object"}}},"/api/v1/strategy-workflow/list_strategies":{"post":{"operationId":"api1_post_list_strategies_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":false},"responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Post list strategies operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"limit":{"default":20,"description":"Maximum results.","type":"integer"},"offset":{"default":0,"description":"Pagination offset in the result units documented by the tool; zero starts the first page.","type":"integer"}},"required":[],"type":"object"}}},"/api/v1/strategy-workflow/list_sweep_markets":{"post":{"operationId":"api1_post_list_sweep_markets_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":false},"responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Post list sweep markets operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"assets":{"description":"Asset symbols, e.g. [\"BTC\", \"ETH\"].","items":{"type":"string"},"type":"array"},"candle_sizes":{"description":"Candle sizes, e.g. [\"1h\"]. Omitted, every size Oracle holds for those assets, which multiplies the windows.","items":{"type":"string"},"type":"array"},"include_gapped":{"default":false,"description":"Include windows missing bars. Off by default, because a metric over a half-covered window is not comparable to one over a whole window.","type":"boolean"},"regimes":{"description":"Market conditions to keep: current, bear, neutral, bull. current means data within the last 30 days, which is recency and not direction. Omitted, every condition.","items":{"type":"string"},"type":"array"},"windows":{"description":"Specific window files to include whatever else is chosen.","items":{"type":"string"},"type":"array"}},"required":[],"type":"object"}}},"/api/v1/strategy-workflow/list_sweeps":{"post":{"operationId":"api1_post_list_sweeps_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":false},"responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Post list sweeps operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"limit":{"default":20,"description":"Maximum results.","type":"integer"}},"required":[],"type":"object"}}},"/api/v1/strategy-workflow/list_trades":{"post":{"operationId":"api1_post_list_trades_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":false},"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post list trades operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"asset":{"description":"Asset symbol, e.g. BTC or ETH.","type":"string"},"limit":{"default":25,"description":"Maximum results.","type":"integer"},"offset":{"default":0,"description":"Pagination offset in the result units documented by the tool; zero starts the first page.","type":"integer"},"outcome":{"description":"Only \"win\" or only \"loss\".","type":"string"},"strategy_id":{"description":"The strategy's UUID.","type":"string"}},"required":[],"type":"object"},"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategy-workflow/load_skill":{"post":{"operationId":"api1_post_load_skill_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Post load skill operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"resource":{"description":"One file the skill carries, by name, as `resources` lists them.","type":"string"},"section":{"description":"One section of it, by heading. Omit for the whole skill.","type":"string"},"skill":{"description":"Which skill, by the name the turn announced.","type":"string"}},"required":["skill"],"type":"object"}}},"/api/v1/strategy-workflow/pause_sweep":{"post":{"operationId":"api1_post_pause_sweep_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Post pause sweep operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"experiment_id":{"description":"The sweep, as create_sweep returned it.","type":"string"}},"required":["experiment_id"],"type":"object"}}},"/api/v1/strategy-workflow/run_backtest":{"post":{"operationId":"api1_post_run_backtest_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post run backtest operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"acknowledge_defaults":{"default":false,"description":"Pass True to submit even though signal parameters are at their library defaults -- an explicit statement that the defaults were considered and stood by, never a way to skip considering them.","type":"boolean"},"end_date":{"description":"ISO end of the window.","type":"string"},"engine_generation":{"description":"Only set when the person specifies an engine generation; omitted uses latest.","type":"integer"},"market_data_venue":{"description":"Exact venue of the requested market.","type":"string"},"quote_token":{"description":"Quote currency of the requested market.","type":"string"},"start_date":{"description":"ISO start of the window, e.g. 2026-01-01.","type":"string"},"strategy_id":{"description":"The strategy's UUID.","type":"string"}},"required":["end_date","start_date","strategy_id"],"type":"object"},"x-payment-info":{"price":{"amount":"0.100000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategy-workflow/save_strategy":{"post":{"operationId":"api1_post_save_strategy_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post save strategy operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"asset":{"description":"Asset symbol, e.g. BTC or ETH.","type":"string"},"constraints":{"additionalProperties":true,"description":"Supported execution overrides requested by the person or justified by the composition workflow after reading the execution-config contract. Preserve explicit user choices and explain agent-selected adjustments. Each supplied value is kept exactly as given rather than nudged.","properties":{"atr_cap_multiplier":{"description":"SUPERSEDED by volatility_tolerance. Bounded the weighted blend at this multiple of the SHORT ATR.","x-mangrove-authoring-schema":{"description":"SUPERSEDED by volatility_tolerance. Bounded the weighted blend at this multiple of the SHORT ATR.","minimum":1.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy this is what made the weight pair inert past a long weight of roughly 6-12% (#1052).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"}},"atr_long_weight":{"description":"SUPERSEDED by volatility_tolerance. Weight of the daily ATR in the weighted-blend stop model, and always 1 - atr_short_weight rather than independent.","x-mangrove-authoring-schema":{"description":"SUPERSEDED by volatility_tolerance. Weight of the daily ATR in the weighted-blend stop model, and always 1 - atr_short_weight rather than independent.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. Derived, never independently effective.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"}},"atr_period":{"description":"ATR lookback in bars (default 14) used to measure volatility for stop sizing.","x-mangrove-authoring-schema":{"default":14,"description":"ATR lookback in bars (default 14) used to measure volatility for stop sizing.","maximum":1000,"minimum":5,"type":["integer","null"],"x-mangrove-effect":"Higher smooths the volatility estimate (steadier, slower-reacting stops). Lower reacts faster to recent volatility (choppier stops).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"atr_short_weight":{"description":"SUPERSEDED by volatility_tolerance. Weight of the signal-timeframe ATR in the weighted-blend stop model. Readable on a strategy created under that model; refused on any write.","x-mangrove-authoring-schema":{"description":"SUPERSEDED by volatility_tolerance. Weight of the signal-timeframe ATR in the weighted-blend stop model. Readable on a strategy created under that model; refused on any write.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy, higher favours the signal timeframe's own volatility -- though the cap made settings past a few percent of long weight indistinguishable (#1052).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"}},"atr_volatility_factor":{"description":"SUPERSEDED by volatility_tolerance. Multiplied the blended ATR to give the stop distance. The dial's two endpoint factors carry this instead, one at each end of the width.","x-mangrove-authoring-schema":{"description":"SUPERSEDED by volatility_tolerance. Multiplied the blended ATR to give the stop distance. The dial's two endpoint factors carry this instead, one at each end of the width.","exclusiveMinimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy, higher widens the stop and shrinks the position for the same risk.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"}},"circuit_breaker":{"description":"Parameters for cooldown_model 'trades': pause on consecutive net losses or accumulated loss amount, pause on marked drawdown from the peak (including unrealized changes), resume new alpha positions at a reduced size, and stop after consecutive pauses. Canon defaults are 36 primary bars for a loss pause, 72 for a drawdown pause, and three strikes for a permanent halt. Pause counts are clamped to 24 hours through 14 days by default. max_drawdown_halt_limit separately stops entries on realized loss of cumulative gross deposits. Existing exits remain active during holds.","x-mangrove-authoring-schema":{"additionalProperties":false,"default":{"consecutive_loss_limit":2,"drawdown_pause_bars":72,"loss_amount_pct":0.06,"max_consecutive_pauses":3,"pause_bars":36,"pause_max_days":14,"pause_min_hours":24,"resume_size_fraction":0.5,"resume_trades":3},"description":"Parameters for cooldown_model 'trades': pause on consecutive net losses or accumulated loss amount, pause on marked drawdown from the peak (including unrealized changes), resume new alpha positions at a reduced size, and stop after consecutive pauses. Canon defaults are 36 primary bars for a loss pause, 72 for a drawdown pause, and three strikes for a permanent halt. Pause counts are clamped to 24 hours through 14 days by default. max_drawdown_halt_limit separately stops entries on realized loss of cumulative gross deposits. Existing exits remain active during holds.","properties":{"consecutive_loss_limit":{"default":2,"description":"Consecutive losing closes on an asset that start a pause. A winning close resets the count.","maximum":100,"minimum":1,"type":"integer","x-mangrove-effect":"Lower pauses sooner after a losing run; higher tolerates longer runs.","x-mangrove-status":"tunable"},"drawdown_pause_bars":{"default":72,"description":"Primary-timeframe bars denying entries after a drawdown pause (canon default 72). At drawdown-pause expiry the peak re-baselines to current account value. An alpha resume window opens only once no pause remains and no permanent halt is latched. The count is raised to cover pause_min_hours and lowered to fit pause_max_days (24 hours through 14 days by default).","maximum":8760,"minimum":1,"type":"integer","x-mangrove-effect":"Longer holds the pause longer before trading can resume.","x-mangrove-status":"tunable"},"loss_amount_pct":{"default":0.06,"description":"Accumulated net losses as a fraction of the closed-equity reset baseline that start a loss pause. A winning close clears the accumulation and resets the baseline. An asset loss pause clears it at the start and re-baselines at expiry; a global drawdown pause does not itself reset it.","exclusiveMinimum":0.0,"maximum":1.0,"type":"number","x-mangrove-effect":"Lower pauses after smaller cumulative losses; higher tolerates larger ones.","x-mangrove-status":"tunable"},"max_consecutive_pauses":{"default":3,"description":"Strikes that stop the strategy until a manual restart. A strike is one pause started, of any kind (consecutive losses, loss amount, drawdown, a resume window that lost money). Strikes reset to 0 only on a new equity high: a close that leaves closed equity above the high-water mark the strategy had when the first strike of the run was recorded. A winning close below that mark does not reset them, and a deposit or withdrawal does not count as a high.","maximum":100,"minimum":1,"type":"integer","x-mangrove-effect":"Lower stops the strategy sooner; higher tolerates more repeated pauses.","x-mangrove-status":"tunable"},"pause_bars":{"default":36,"description":"Primary-timeframe bars denying entries after a loss pause (canon default 36). The count is raised to cover pause_min_hours and lowered to fit pause_max_days on that timeframe (24 hours through 14 days by default).","maximum":8760,"minimum":1,"type":"integer","x-mangrove-effect":"Longer sits out more of a bad regime; shorter resumes sooner.","x-mangrove-status":"tunable"},"pause_max_days":{"default":14,"description":"A pause lasts at most this many days on every timeframe: the bar count is lowered to fit it.","exclusiveMinimum":0.0,"maximum":365,"type":"number","x-mangrove-effect":"Lower ends every pause sooner on long timeframes; higher leaves the bar count to decide.","x-mangrove-status":"tunable"},"pause_min_hours":{"default":24,"description":"A pause lasts at least this many hours on every timeframe: the bar count of pause_bars or drawdown_pause_bars is raised to cover it.","exclusiveMinimum":0.0,"maximum":336,"type":"number","x-mangrove-effect":"Higher makes every pause at least that long on short timeframes; lower leaves the bar count to decide.","x-mangrove-status":"tunable"},"resume_size_fraction":{"default":0.5,"description":"Fraction of normal size for new alpha positions while a resume window is open (canon default 0.5). Eligible confirmed position closes count toward resume_trades; a negative net result starts another loss pause and strike, while zero or a profit restores full alpha size. Core orders keep their normal allocation quantities after pause expiry: they are not positions and do not consume resume-trade counts. 1.0 disables the alpha size reduction.","exclusiveMinimum":0.0,"maximum":1.0,"type":"number","x-mangrove-effect":"Lower risks less while the strategy proves itself again after a pause; higher resumes closer to full size.","x-mangrove-status":"tunable"},"resume_trades":{"default":3,"description":"Eligible confirmed position closes booked in a resume window (canon default three). When the window completes, a negative net realized result starts a new loss pause and strike; zero or a profit restores full alpha size. A pause cancels the active window; a new one opens only once no pause remains and no permanent halt is latched. Core orders do not count as position closes.","maximum":50,"minimum":1,"type":"integer","x-mangrove-effect":"Higher judges the resumed strategy over more trades before full size returns; lower decides sooner.","x-mangrove-status":"tunable"}},"type":["object","null"],"x-mangrove-effect":"Tighter limits pause and stop sooner; looser limits keep trading through losing runs.","x-mangrove-status":"guardrail"}},"cooldown_model":{"description":"Loss-streak breaker model. 'bars' counts losing closes inside rolling windows of the primary timeframe (cooldown_config). 'trades' counts consecutive losing closes and realized loss amount, pauses for circuit_breaker bars of the primary timeframe (at least pause_min_hours and at most pause_max_days), and stops after repeated pauses (circuit_breaker). An absent model adopts the canonical 'trades' defaults; explicit 'bars' retains the legacy model.","x-mangrove-authoring-schema":{"default":"trades","description":"Loss-streak breaker model. 'bars' counts losing closes inside rolling windows of the primary timeframe (cooldown_config). 'trades' counts consecutive losing closes and realized loss amount, pauses for circuit_breaker bars of the primary timeframe (at least pause_min_hours and at most pause_max_days), and stops after repeated pauses (circuit_breaker). An absent model adopts the canonical 'trades' defaults; explicit 'bars' retains the legacy model.","enum":["bars","trades",null],"type":["string","null"],"x-mangrove-effect":"'trades' trips on trade count and loss size regardless of how far apart trades are spaced; 'bars' trips only when losses land inside the window. cooldown_config, cooldown_bars, daily_momentum_limit and weekly_momentum_limit are read only under 'bars': they are left out of a resolved config under 'trades', and a config that carries them under 'trades' has them dropped.","x-mangrove-status":"guardrail"}},"enable_volatility_adjustment":{"description":"Toggles volatility-based position scaling (default false).","x-mangrove-authoring-schema":{"default":false,"description":"Toggles volatility-based position scaling (default false).","type":["boolean","null"],"x-mangrove-effect":"When true, positions are scaled down by target_volatility / (atr/entry) if ATR%% exceeds target; only reduces size, never increases.","x-mangrove-status":"gated"}},"exit_on_loss_after_bars":{"description":"Exit a losing position after this many bars.","x-mangrove-authoring-schema":{"default":1000,"description":"Exit a losing position after this many bars.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Lower cuts losers sooner; higher gives them more time to recover.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"exit_on_profit_after_bars":{"description":"Exit a winning position after this many bars.","x-mangrove-authoring-schema":{"default":1000,"description":"Exit a winning position after this many bars.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Lower banks winners sooner; higher lets them run.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"initial_balance":{"description":"Starting balance for the backtest/simulation (default $10,000).","x-mangrove-authoring-schema":{"default":10000,"description":"Starting balance for the backtest/simulation (default $10,000).","maximum":1000000000.0,"minimum":25.0,"type":["number","null"],"x-mangrove-effect":"Scales absolute dollar figures; not a strategy-character knob.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"max_drawdown_halt_limit":{"description":"Permanent capital-floor entry halt (0.20 = 20%). Closed, realized equity is compared with cumulative gross deposits (execution_state.cumulative_deposits), not a rolling peak or the signed net-funding balance; withdrawals do not reduce this reference. Legacy requests without cumulative_deposits use execution_config.initial_balance. The shared live/paper evaluator checks before each bar and latches execution_state.halt. New alpha entries and v3 core allocations are denied, while authoritative positions retain protective exits and exits_pending until physically flat. Engine-owned strategies become inactive only after that book is flat; caller-owned executors retain their exit monitor. An explicit manual restart is required to clear the latch. Backtests enforce the same floor when evaluate_bar receives enforce_capital_floor=True, managing open-position exits through the final bar. Applies to both cooldown models; null disables new floor trips, while an existing halt remains latched.","x-mangrove-authoring-schema":{"default":0.2,"description":"Permanent capital-floor entry halt (0.20 = 20%). Closed, realized equity is compared with cumulative gross deposits (execution_state.cumulative_deposits), not a rolling peak or the signed net-funding balance; withdrawals do not reduce this reference. Legacy requests without cumulative_deposits use execution_config.initial_balance. The shared live/paper evaluator checks before each bar and latches execution_state.halt. New alpha entries and v3 core allocations are denied, while authoritative positions retain protective exits and exits_pending until physically flat. Engine-owned strategies become inactive only after that book is flat; caller-owned executors retain their exit monitor. An explicit manual restart is required to clear the latch. Backtests enforce the same floor when evaluate_bar receives enforce_capital_floor=True, managing open-position exits through the final bar. Applies to both cooldown models; null disables new floor trips, while an existing halt remains latched.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Lower protects more of gross deposited capital before a permanent entry halt; higher tolerates a deeper realized loss. This does not resize positions or stop protective exit evaluation. Do not add a separate floor where the shared evaluator enforces it.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"max_drawdown_limit":{"description":"Peak-relative entry pause (0.20 = 20%). The canonical 'trades' model measures marked equity against its high-water mark. A breach starts one drawdown pause and strike; circuit_breaker.drawdown_pause_bars defaults to 72 primary bars, clamped to pause_min_hours and pause_max_days (24 hours and 14 days by default). At drawdown-pause expiry the peak re-baselines; a reduced-size alpha resume window opens only once no pause remains and no permanent halt is latched. Explicit 'bars' retains the legacy closed-equity measurement and per-timeframe long cooldown. Both models deny new entries while allowing existing positions to exit; automatic v3 core allocations honor the hold too. null disables new drawdown trips.","x-mangrove-authoring-schema":{"default":0.2,"description":"Peak-relative entry pause (0.20 = 20%). The canonical 'trades' model measures marked equity against its high-water mark. A breach starts one drawdown pause and strike; circuit_breaker.drawdown_pause_bars defaults to 72 primary bars, clamped to pause_min_hours and pause_max_days (24 hours and 14 days by default). At drawdown-pause expiry the peak re-baselines; a reduced-size alpha resume window opens only once no pause remains and no permanent halt is latched. Explicit 'bars' retains the legacy closed-equity measurement and per-timeframe long cooldown. Both models deny new entries while allowing existing positions to exit; automatic v3 core allocations honor the hold too. null disables new drawdown trips.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Lower pauses entries after a smaller drawdown; higher tolerates a deeper drawdown. The shared entry breaker enforces this in single/bulk live and paper evaluation, v3 core allocation and backtests built with risk_manager_from_execution_config. Alpha resume sizing is a separate control; do not add a second drawdown stop.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"max_hold_bars":{"description":"Maximum bars to hold any position before a forced exit.","x-mangrove-authoring-schema":{"default":1000,"description":"Maximum bars to hold any position before a forced exit.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher lets trades run longer; lower forces earlier time-based exits.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"max_hold_time_hours":{"description":"Maximum position hold time in hours (null = no limit).","x-mangrove-authoring-schema":{"default":null,"description":"Maximum position hold time in hours (null = no limit).","exclusiveMinimum":1,"maximum":8760,"type":["integer","null"],"x-mangrove-effect":"Lower forces earlier time-based exits; null/higher lets trades run indefinitely on time.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"max_open_positions":{"description":"Maximum concurrent open positions.","x-mangrove-authoring-schema":{"default":10,"description":"Maximum concurrent open positions.","maximum":1000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher allows more simultaneous exposure (more diversification but more aggregate risk); lower is more selective with less aggregate exposure.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"max_risk_per_trade":{"description":"Fraction of account equity risked per trade (0.01 = 1%). Position size is derived from this and the stop distance.","x-mangrove-authoring-schema":{"default":0.01,"description":"Fraction of account equity risked per trade (0.01 = 1%). Position size is derived from this and the stop distance.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Higher risks more per trade: bigger positions, larger gains AND larger drawdowns. Lower is more conservative: smaller positions, smaller swings.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"max_trade_amount":{"description":"Absolute cap on dollar size per trade.","x-mangrove-authoring-schema":{"default":10000000,"description":"Absolute cap on dollar size per trade.","exclusiveMinimum":0.0,"maximum":1000000000000.0,"type":["number","null"],"x-mangrove-effect":"Size guardrail; rarely binding.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"max_trades_per_day":{"description":"Daily trade cap.","x-mangrove-authoring-schema":{"default":50,"description":"Daily trade cap.","maximum":1440,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher permits more churn; lower throttles activity.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"max_units_per_trade":{"description":"Absolute cap on units per trade.","x-mangrove-authoring-schema":{"default":1000000,"description":"Absolute cap on units per trade.","exclusiveMinimum":0.0,"maximum":1000000000000.0,"type":["number","null"],"x-mangrove-effect":"Size guardrail; rarely binding.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"min_asset_balance":{"description":"position_size_calc 'v3' only. Minimum asset balance, in asset units, the strategy holds outside open trades.","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Minimum asset balance, in asset units, the strategy holds outside open trades.","minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more of the asset out of reach of sell trades and core sells, and takes more cash to reach; lower frees more of the asset for trading.","x-mangrove-status":"guardrail"}},"min_balance_days":{"description":"position_size_calc 'v3' only. Number of equal daily orders used to bring a side up to its minimum balance.","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Number of equal daily orders used to bring a side up to its minimum balance.","minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher spreads the minimum-balance orders over more days at smaller size; lower reaches the minimum sooner with larger orders.","x-mangrove-status":"guardrail"}},"min_balance_threshold":{"description":"Cash reserve fraction held back from new entries (0.1 = 10%). v1 reserves this fraction of cash; v2 reserves this fraction of account value (cash + open positions at market). An entry may only use cash above the reserve; when no cash is deployable the entry is denied (insufficient_cash / insufficient_cash_v2_account_reserve). It never halts the strategy and never closes positions.","x-mangrove-authoring-schema":{"default":0.1,"description":"Cash reserve fraction held back from new entries (0.1 = 10%). v1 reserves this fraction of cash; v2 reserves this fraction of account value (cash + open positions at market). An entry may only use cash above the reserve; when no cash is deployable the entry is denied (insufficient_cash / insufficient_cash_v2_account_reserve). It never halts the strategy and never closes positions.","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more cash idle and makes entries smaller or rarer as the account shrinks; lower lets entries use more of the balance. Not a drawdown stop; see max_drawdown_limit and max_drawdown_halt_limit.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"min_cash_balance":{"description":"position_size_calc 'v3' only. Minimum cash balance the strategy holds after the worst-case loss of every open trade.","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Minimum cash balance the strategy holds after the worst-case loss of every open trade.","minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more cash out of reach of buy trades and core buys, so entries are smaller or rarer; lower frees more cash for trading.","x-mangrove-status":"guardrail"}},"min_stop_distance_pct":{"description":"Hard floor on stop distance as a fraction of entry price (crypto minimum), applied after ATR sizing.","x-mangrove-authoring-schema":{"default":0.005,"description":"Hard floor on stop distance as a fraction of entry price (crypto minimum), applied after ATR sizing.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher enforces a wider minimum stop; lower allows tighter stops down to the floor.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"min_trade_amount":{"description":"Minimum trade size in dollars; smaller intended trades are skipped.","x-mangrove-authoring-schema":{"default":25,"description":"Minimum trade size in dollars; smaller intended trades are skipped.","maximum":1000000.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher skips more small signals; lower allows smaller trades.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"position_size_calc":{"description":"Sizing-engine version ('v1', 'v2' or 'v3'). Pinned at creation and immutable. 'v3' holds an asset balance and a cash balance, sizes against equity net of open risk, and requires the position_size_calc 'v3' parameters.","x-mangrove-authoring-schema":{"default":"v2","description":"Sizing-engine version ('v1', 'v2' or 'v3'). Pinned at creation and immutable. 'v3' holds an asset balance and a cash balance, sizes against equity net of open risk, and requires the position_size_calc 'v3' parameters.","enum":["v1","v2","v3",null],"type":["string","null"],"x-mangrove-effect":"Not a magnitude knob; selects the sizing algorithm. Do not change on an existing strategy.","x-mangrove-status":"guardrail"}},"profit_threshold_pct":{"description":"Profit threshold (5%% default) above which a position counts as 'winning' for the time-based exit logic.","x-mangrove-authoring-schema":{"default":0.05,"description":"Profit threshold (5%% default) above which a position counts as 'winning' for the time-based exit logic.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher requires a larger gain before a position is treated as winning; lower treats smaller gains as wins.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"rebalance_band":{"description":"position_size_calc 'v3' only. Absolute deviation of the asset weight from target_asset_weight that triggers a rebalance order (0.05 = 5 points).","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Absolute deviation of the asset weight from target_asset_weight that triggers a rebalance order (0.05 = 5 points).","exclusiveMaximum":1.0,"exclusiveMinimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher lets the split drift further before a rebalance order, so fewer core orders; lower holds the split closer to target with more core orders and more fees.","x-mangrove-status":"tunable"}},"reward_factor":{"description":"Risk/reward target. Take-profit distance = reward_factor * stop_distance.","x-mangrove-authoring-schema":{"default":2,"description":"Risk/reward target. Take-profit distance = reward_factor * stop_distance.","exclusiveMinimum":0.0,"maximum":100.0,"type":["number","null"],"x-mangrove-effect":"Higher sets a wider profit target: lower win rate but bigger wins. Lower sets a tighter target: higher win rate but smaller wins.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"stop_gap_allowance":{"description":"position_size_calc 'v3' only. Fraction of the stop price a stop fill is assumed to miss by when computing the worst-case loss of a trade (0.01 = 1%).","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Fraction of the stop price a stop fill is assumed to miss by when computing the worst-case loss of a trade (0.01 = 1%).","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher counts more risk per open trade, leaving less available cash and smaller positions; lower counts less.","x-mangrove-status":"guardrail"}},"stop_model":{"description":"Which stop model the strategy uses: 'atr_width_dial' (one parameter, volatility_tolerance, positioned on the ATR width) or 'weighted_atr' (superseded: a weighted blend of two ATRs, capped). Pinned at creation and immutable.","x-mangrove-authoring-schema":{"default":"atr_width_dial","description":"Which stop model the strategy uses: 'atr_width_dial' (one parameter, volatility_tolerance, positioned on the ATR width) or 'weighted_atr' (superseded: a weighted blend of two ATRs, capped). Pinned at creation and immutable.","enum":["atr_width_dial","weighted_atr",null],"type":["string","null"],"x-mangrove-effect":"Not a magnitude knob; selects the stop algorithm. Do not change on an existing strategy -- it would move every stop the strategy takes.","x-mangrove-status":"guardrail"}},"taker_fee_rate":{"description":"position_size_calc 'v3' only. Venue fee per fill as a fraction of notional, charged in cash (0.004 = 0.4%).","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Venue fee per fill as a fraction of notional, charged in cash (0.004 = 0.4%).","exclusiveMaximum":0.1,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher counts more cost per fill, raising the risk of each trade and lowering available cash. Models the venue; not a strategy-character knob.","x-mangrove-status":"guardrail"}},"target_asset_weight":{"description":"position_size_calc 'v3' only. Target share of core value held in the asset (0.8 = 80% asset, 20% cash; 0 = all cash).","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Target share of core value held in the asset (0.8 = 80% asset, 20% cash; 0 = all cash).","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher holds more of the asset and less cash; lower holds more cash. The daily core order moves the split back to this value once it drifts past rebalance_band. At 0 with no asset held, no core order is placed and only buy trades can pass.","x-mangrove-status":"tunable"}},"target_volatility":{"description":"Target volatility (0.10 = 10%). ONLY active when enable_volatility_adjustment is true (default false). When active, scales position size down if ATR%% of entry exceeds the target (never up).","x-mangrove-authoring-schema":{"default":0.1,"description":"Target volatility (0.10 = 10%). ONLY active when enable_volatility_adjustment is true (default false). When active, scales position size down if ATR%% of entry exceeds the target (never up).","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"With the gate off (the default), changing this has no effect. With it on, lower scales positions down more aggressively in high volatility.","x-mangrove-gate-field":"enable_volatility_adjustment","x-mangrove-gate-required":true,"x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"gated"}},"volatility_mode":{"description":"Unused (retained for backward compatibility). Volatility is derived from ATR.","x-mangrove-authoring-schema":{"default":"stddev","description":"Unused (retained for backward compatibility). Volatility is derived from ATR.","enum":["stddev","atr",null],"type":["string","null"],"x-mangrove-effect":"No runtime effect. Do not tune.","x-mangrove-status":"unused"}},"volatility_tolerance":{"description":"Where on the ATR width the stop is taken, as the ATR_long-vs-ATR_short contribution ratio: 0 is all short end (0.5x the signal timeframe's ATR), 1 is all long end (2x the daily ATR). Interpolated geometrically, so the value is exactly the long end's share of log(stop) and each 0.1 is the same multiplicative step. Replaces atr_short_weight, atr_long_weight and atr_cap_multiplier.","x-mangrove-authoring-schema":{"default":0.5,"description":"Where on the ATR width the stop is taken, as the ATR_long-vs-ATR_short contribution ratio: 0 is all short end (0.5x the signal timeframe's ATR), 1 is all long end (2x the daily ATR). Interpolated geometrically, so the value is exactly the long end's share of log(stop) and each 0.1 is the same multiplicative step. Replaces atr_short_weight, atr_long_weight and atr_cap_multiplier.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher widens the stop, and because position size is the risk budget divided by the stop distance, exposure shrinks in exact inverse proportion at the SAME risk. Low means many units with little room to be wrong and frequent stop-outs; high means few units that are hard to shake out but need a much larger move to reach the same reward. Both risk max_risk_per_trade.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"volatility_window":{"description":"Unused (retained for backward compatibility). ATR windowing is controlled by atr_period.","x-mangrove-authoring-schema":{"default":24,"description":"Unused (retained for backward compatibility). ATR windowing is controlled by atr_period.","maximum":1000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"No runtime effect. Do not tune.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"unused"}}},"type":"object","x-mangrove-authoring-schema":{"$id":"urn:mangrove:execution-config:1","$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":true,"description":"Canonical authoring representation derived from server metadata and defaults. Top-level optional keys may be omitted or null. The existing HTTP validator separately coerces top-level numeric strings, enforces their declared bounds and permits unknown/legacy fields; it does not enforce this whole nested schema. Runtime strategy/version/timeframe checks remain authoritative. Cooldown durations may be omitted by legacy configs and then fall back to their corresponding windows.","properties":{"atr_cap_multiplier":{"description":"SUPERSEDED by volatility_tolerance. Bounded the weighted blend at this multiple of the SHORT ATR.","minimum":1.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy this is what made the weight pair inert past a long weight of roughly 6-12% (#1052).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"},"atr_long_weight":{"description":"SUPERSEDED by volatility_tolerance. Weight of the daily ATR in the weighted-blend stop model, and always 1 - atr_short_weight rather than independent.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. Derived, never independently effective.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"},"atr_period":{"default":14,"description":"ATR lookback in bars (default 14) used to measure volatility for stop sizing.","maximum":1000,"minimum":5,"type":["integer","null"],"x-mangrove-effect":"Higher smooths the volatility estimate (steadier, slower-reacting stops). Lower reacts faster to recent volatility (choppier stops).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"atr_short_weight":{"description":"SUPERSEDED by volatility_tolerance. Weight of the signal-timeframe ATR in the weighted-blend stop model. Readable on a strategy created under that model; refused on any write.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy, higher favours the signal timeframe's own volatility -- though the cap made settings past a few percent of long weight indistinguishable (#1052).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"},"atr_volatility_factor":{"description":"SUPERSEDED by volatility_tolerance. Multiplied the blended ATR to give the stop distance. The dial's two endpoint factors carry this instead, one at each end of the width.","exclusiveMinimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy, higher widens the stop and shrinks the position for the same risk.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"},"circuit_breaker":{"additionalProperties":false,"default":{"consecutive_loss_limit":2,"drawdown_pause_bars":72,"loss_amount_pct":0.06,"max_consecutive_pauses":3,"pause_bars":36,"pause_max_days":14,"pause_min_hours":24,"resume_size_fraction":0.5,"resume_trades":3},"description":"Parameters for cooldown_model 'trades': pause on consecutive net losses or accumulated loss amount, pause on marked drawdown from the peak (including unrealized changes), resume new alpha positions at a reduced size, and stop after consecutive pauses. Canon defaults are 36 primary bars for a loss pause, 72 for a drawdown pause, and three strikes for a permanent halt. Pause counts are clamped to 24 hours through 14 days by default. max_drawdown_halt_limit separately stops entries on realized loss of cumulative gross deposits. Existing exits remain active during holds.","properties":{"consecutive_loss_limit":{"default":2,"description":"Consecutive losing closes on an asset that start a pause. A winning close resets the count.","maximum":100,"minimum":1,"type":"integer","x-mangrove-effect":"Lower pauses sooner after a losing run; higher tolerates longer runs.","x-mangrove-status":"tunable"},"drawdown_pause_bars":{"default":72,"description":"Primary-timeframe bars denying entries after a drawdown pause (canon default 72). At drawdown-pause expiry the peak re-baselines to current account value. An alpha resume window opens only once no pause remains and no permanent halt is latched. The count is raised to cover pause_min_hours and lowered to fit pause_max_days (24 hours through 14 days by default).","maximum":8760,"minimum":1,"type":"integer","x-mangrove-effect":"Longer holds the pause longer before trading can resume.","x-mangrove-status":"tunable"},"loss_amount_pct":{"default":0.06,"description":"Accumulated net losses as a fraction of the closed-equity reset baseline that start a loss pause. A winning close clears the accumulation and resets the baseline. An asset loss pause clears it at the start and re-baselines at expiry; a global drawdown pause does not itself reset it.","exclusiveMinimum":0.0,"maximum":1.0,"type":"number","x-mangrove-effect":"Lower pauses after smaller cumulative losses; higher tolerates larger ones.","x-mangrove-status":"tunable"},"max_consecutive_pauses":{"default":3,"description":"Strikes that stop the strategy until a manual restart. A strike is one pause started, of any kind (consecutive losses, loss amount, drawdown, a resume window that lost money). Strikes reset to 0 only on a new equity high: a close that leaves closed equity above the high-water mark the strategy had when the first strike of the run was recorded. A winning close below that mark does not reset them, and a deposit or withdrawal does not count as a high.","maximum":100,"minimum":1,"type":"integer","x-mangrove-effect":"Lower stops the strategy sooner; higher tolerates more repeated pauses.","x-mangrove-status":"tunable"},"pause_bars":{"default":36,"description":"Primary-timeframe bars denying entries after a loss pause (canon default 36). The count is raised to cover pause_min_hours and lowered to fit pause_max_days on that timeframe (24 hours through 14 days by default).","maximum":8760,"minimum":1,"type":"integer","x-mangrove-effect":"Longer sits out more of a bad regime; shorter resumes sooner.","x-mangrove-status":"tunable"},"pause_max_days":{"default":14,"description":"A pause lasts at most this many days on every timeframe: the bar count is lowered to fit it.","exclusiveMinimum":0.0,"maximum":365,"type":"number","x-mangrove-effect":"Lower ends every pause sooner on long timeframes; higher leaves the bar count to decide.","x-mangrove-status":"tunable"},"pause_min_hours":{"default":24,"description":"A pause lasts at least this many hours on every timeframe: the bar count of pause_bars or drawdown_pause_bars is raised to cover it.","exclusiveMinimum":0.0,"maximum":336,"type":"number","x-mangrove-effect":"Higher makes every pause at least that long on short timeframes; lower leaves the bar count to decide.","x-mangrove-status":"tunable"},"resume_size_fraction":{"default":0.5,"description":"Fraction of normal size for new alpha positions while a resume window is open (canon default 0.5). Eligible confirmed position closes count toward resume_trades; a negative net result starts another loss pause and strike, while zero or a profit restores full alpha size. Core orders keep their normal allocation quantities after pause expiry: they are not positions and do not consume resume-trade counts. 1.0 disables the alpha size reduction.","exclusiveMinimum":0.0,"maximum":1.0,"type":"number","x-mangrove-effect":"Lower risks less while the strategy proves itself again after a pause; higher resumes closer to full size.","x-mangrove-status":"tunable"},"resume_trades":{"default":3,"description":"Eligible confirmed position closes booked in a resume window (canon default three). When the window completes, a negative net realized result starts a new loss pause and strike; zero or a profit restores full alpha size. A pause cancels the active window; a new one opens only once no pause remains and no permanent halt is latched. Core orders do not count as position closes.","maximum":50,"minimum":1,"type":"integer","x-mangrove-effect":"Higher judges the resumed strategy over more trades before full size returns; lower decides sooner.","x-mangrove-status":"tunable"}},"type":["object","null"],"x-mangrove-effect":"Tighter limits pause and stop sooner; looser limits keep trading through losing runs.","x-mangrove-status":"guardrail"},"cooldown_model":{"default":"trades","description":"Loss-streak breaker model. 'bars' counts losing closes inside rolling windows of the primary timeframe (cooldown_config). 'trades' counts consecutive losing closes and realized loss amount, pauses for circuit_breaker bars of the primary timeframe (at least pause_min_hours and at most pause_max_days), and stops after repeated pauses (circuit_breaker). An absent model adopts the canonical 'trades' defaults; explicit 'bars' retains the legacy model.","enum":["bars","trades",null],"type":["string","null"],"x-mangrove-effect":"'trades' trips on trade count and loss size regardless of how far apart trades are spaced; 'bars' trips only when losses land inside the window. cooldown_config, cooldown_bars, daily_momentum_limit and weekly_momentum_limit are read only under 'bars': they are left out of a resolved config under 'trades', and a config that carries them under 'trades' has them dropped.","x-mangrove-status":"guardrail"},"enable_volatility_adjustment":{"default":false,"description":"Toggles volatility-based position scaling (default false).","type":["boolean","null"],"x-mangrove-effect":"When true, positions are scaled down by target_volatility / (atr/entry) if ATR%% exceeds target; only reduces size, never increases.","x-mangrove-status":"gated"},"exit_on_loss_after_bars":{"default":1000,"description":"Exit a losing position after this many bars.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Lower cuts losers sooner; higher gives them more time to recover.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"exit_on_profit_after_bars":{"default":1000,"description":"Exit a winning position after this many bars.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Lower banks winners sooner; higher lets them run.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"initial_balance":{"default":10000,"description":"Starting balance for the backtest/simulation (default $10,000).","maximum":1000000000.0,"minimum":25.0,"type":["number","null"],"x-mangrove-effect":"Scales absolute dollar figures; not a strategy-character knob.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"max_drawdown_halt_limit":{"default":0.2,"description":"Permanent capital-floor entry halt (0.20 = 20%). Closed, realized equity is compared with cumulative gross deposits (execution_state.cumulative_deposits), not a rolling peak or the signed net-funding balance; withdrawals do not reduce this reference. Legacy requests without cumulative_deposits use execution_config.initial_balance. The shared live/paper evaluator checks before each bar and latches execution_state.halt. New alpha entries and v3 core allocations are denied, while authoritative positions retain protective exits and exits_pending until physically flat. Engine-owned strategies become inactive only after that book is flat; caller-owned executors retain their exit monitor. An explicit manual restart is required to clear the latch. Backtests enforce the same floor when evaluate_bar receives enforce_capital_floor=True, managing open-position exits through the final bar. Applies to both cooldown models; null disables new floor trips, while an existing halt remains latched.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Lower protects more of gross deposited capital before a permanent entry halt; higher tolerates a deeper realized loss. This does not resize positions or stop protective exit evaluation. Do not add a separate floor where the shared evaluator enforces it.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"max_drawdown_limit":{"default":0.2,"description":"Peak-relative entry pause (0.20 = 20%). The canonical 'trades' model measures marked equity against its high-water mark. A breach starts one drawdown pause and strike; circuit_breaker.drawdown_pause_bars defaults to 72 primary bars, clamped to pause_min_hours and pause_max_days (24 hours and 14 days by default). At drawdown-pause expiry the peak re-baselines; a reduced-size alpha resume window opens only once no pause remains and no permanent halt is latched. Explicit 'bars' retains the legacy closed-equity measurement and per-timeframe long cooldown. Both models deny new entries while allowing existing positions to exit; automatic v3 core allocations honor the hold too. null disables new drawdown trips.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Lower pauses entries after a smaller drawdown; higher tolerates a deeper drawdown. The shared entry breaker enforces this in single/bulk live and paper evaluation, v3 core allocation and backtests built with risk_manager_from_execution_config. Alpha resume sizing is a separate control; do not add a second drawdown stop.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"max_hold_bars":{"default":1000,"description":"Maximum bars to hold any position before a forced exit.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher lets trades run longer; lower forces earlier time-based exits.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"max_hold_time_hours":{"default":null,"description":"Maximum position hold time in hours (null = no limit).","exclusiveMinimum":1,"maximum":8760,"type":["integer","null"],"x-mangrove-effect":"Lower forces earlier time-based exits; null/higher lets trades run indefinitely on time.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"max_open_positions":{"default":10,"description":"Maximum concurrent open positions.","maximum":1000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher allows more simultaneous exposure (more diversification but more aggregate risk); lower is more selective with less aggregate exposure.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"max_risk_per_trade":{"default":0.01,"description":"Fraction of account equity risked per trade (0.01 = 1%). Position size is derived from this and the stop distance.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Higher risks more per trade: bigger positions, larger gains AND larger drawdowns. Lower is more conservative: smaller positions, smaller swings.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"max_trade_amount":{"default":10000000,"description":"Absolute cap on dollar size per trade.","exclusiveMinimum":0.0,"maximum":1000000000000.0,"type":["number","null"],"x-mangrove-effect":"Size guardrail; rarely binding.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"max_trades_per_day":{"default":50,"description":"Daily trade cap.","maximum":1440,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher permits more churn; lower throttles activity.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"max_units_per_trade":{"default":1000000,"description":"Absolute cap on units per trade.","exclusiveMinimum":0.0,"maximum":1000000000000.0,"type":["number","null"],"x-mangrove-effect":"Size guardrail; rarely binding.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"min_asset_balance":{"description":"position_size_calc 'v3' only. Minimum asset balance, in asset units, the strategy holds outside open trades.","minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more of the asset out of reach of sell trades and core sells, and takes more cash to reach; lower frees more of the asset for trading.","x-mangrove-status":"guardrail"},"min_balance_days":{"description":"position_size_calc 'v3' only. Number of equal daily orders used to bring a side up to its minimum balance.","minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher spreads the minimum-balance orders over more days at smaller size; lower reaches the minimum sooner with larger orders.","x-mangrove-status":"guardrail"},"min_balance_threshold":{"default":0.1,"description":"Cash reserve fraction held back from new entries (0.1 = 10%). v1 reserves this fraction of cash; v2 reserves this fraction of account value (cash + open positions at market). An entry may only use cash above the reserve; when no cash is deployable the entry is denied (insufficient_cash / insufficient_cash_v2_account_reserve). It never halts the strategy and never closes positions.","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more cash idle and makes entries smaller or rarer as the account shrinks; lower lets entries use more of the balance. Not a drawdown stop; see max_drawdown_limit and max_drawdown_halt_limit.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"min_cash_balance":{"description":"position_size_calc 'v3' only. Minimum cash balance the strategy holds after the worst-case loss of every open trade.","minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more cash out of reach of buy trades and core buys, so entries are smaller or rarer; lower frees more cash for trading.","x-mangrove-status":"guardrail"},"min_stop_distance_pct":{"default":0.005,"description":"Hard floor on stop distance as a fraction of entry price (crypto minimum), applied after ATR sizing.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher enforces a wider minimum stop; lower allows tighter stops down to the floor.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"min_trade_amount":{"default":25,"description":"Minimum trade size in dollars; smaller intended trades are skipped.","maximum":1000000.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher skips more small signals; lower allows smaller trades.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"position_size_calc":{"default":"v2","description":"Sizing-engine version ('v1', 'v2' or 'v3'). Pinned at creation and immutable. 'v3' holds an asset balance and a cash balance, sizes against equity net of open risk, and requires the position_size_calc 'v3' parameters.","enum":["v1","v2","v3",null],"type":["string","null"],"x-mangrove-effect":"Not a magnitude knob; selects the sizing algorithm. Do not change on an existing strategy.","x-mangrove-status":"guardrail"},"profit_threshold_pct":{"default":0.05,"description":"Profit threshold (5%% default) above which a position counts as 'winning' for the time-based exit logic.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher requires a larger gain before a position is treated as winning; lower treats smaller gains as wins.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"rebalance_band":{"description":"position_size_calc 'v3' only. Absolute deviation of the asset weight from target_asset_weight that triggers a rebalance order (0.05 = 5 points).","exclusiveMaximum":1.0,"exclusiveMinimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher lets the split drift further before a rebalance order, so fewer core orders; lower holds the split closer to target with more core orders and more fees.","x-mangrove-status":"tunable"},"reward_factor":{"default":2,"description":"Risk/reward target. Take-profit distance = reward_factor * stop_distance.","exclusiveMinimum":0.0,"maximum":100.0,"type":["number","null"],"x-mangrove-effect":"Higher sets a wider profit target: lower win rate but bigger wins. Lower sets a tighter target: higher win rate but smaller wins.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"stop_gap_allowance":{"description":"position_size_calc 'v3' only. Fraction of the stop price a stop fill is assumed to miss by when computing the worst-case loss of a trade (0.01 = 1%).","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher counts more risk per open trade, leaving less available cash and smaller positions; lower counts less.","x-mangrove-status":"guardrail"},"stop_model":{"default":"atr_width_dial","description":"Which stop model the strategy uses: 'atr_width_dial' (one parameter, volatility_tolerance, positioned on the ATR width) or 'weighted_atr' (superseded: a weighted blend of two ATRs, capped). Pinned at creation and immutable.","enum":["atr_width_dial","weighted_atr",null],"type":["string","null"],"x-mangrove-effect":"Not a magnitude knob; selects the stop algorithm. Do not change on an existing strategy -- it would move every stop the strategy takes.","x-mangrove-status":"guardrail"},"taker_fee_rate":{"description":"position_size_calc 'v3' only. Venue fee per fill as a fraction of notional, charged in cash (0.004 = 0.4%).","exclusiveMaximum":0.1,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher counts more cost per fill, raising the risk of each trade and lowering available cash. Models the venue; not a strategy-character knob.","x-mangrove-status":"guardrail"},"target_asset_weight":{"description":"position_size_calc 'v3' only. Target share of core value held in the asset (0.8 = 80% asset, 20% cash; 0 = all cash).","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher holds more of the asset and less cash; lower holds more cash. The daily core order moves the split back to this value once it drifts past rebalance_band. At 0 with no asset held, no core order is placed and only buy trades can pass.","x-mangrove-status":"tunable"},"target_volatility":{"default":0.1,"description":"Target volatility (0.10 = 10%). ONLY active when enable_volatility_adjustment is true (default false). When active, scales position size down if ATR%% of entry exceeds the target (never up).","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"With the gate off (the default), changing this has no effect. With it on, lower scales positions down more aggressively in high volatility.","x-mangrove-gate-field":"enable_volatility_adjustment","x-mangrove-gate-required":true,"x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"gated"},"volatility_mode":{"default":"stddev","description":"Unused (retained for backward compatibility). Volatility is derived from ATR.","enum":["stddev","atr",null],"type":["string","null"],"x-mangrove-effect":"No runtime effect. Do not tune.","x-mangrove-status":"unused"},"volatility_tolerance":{"default":0.5,"description":"Where on the ATR width the stop is taken, as the ATR_long-vs-ATR_short contribution ratio: 0 is all short end (0.5x the signal timeframe's ATR), 1 is all long end (2x the daily ATR). Interpolated geometrically, so the value is exactly the long end's share of log(stop) and each 0.1 is the same multiplicative step. Replaces atr_short_weight, atr_long_weight and atr_cap_multiplier.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher widens the stop, and because position size is the risk budget divided by the stop distance, exposure shrinks in exact inverse proportion at the SAME risk. Low means many units with little room to be wrong and frequent stop-outs; high means few units that are hard to shake out but need a much larger move to reach the same reward. Both risk max_risk_per_trade.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"volatility_window":{"default":24,"description":"Unused (retained for backward compatibility). ATR windowing is controlled by atr_period.","maximum":1000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"No runtime effect. Do not tune.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"unused"}},"title":"Execution configuration","type":"object","x-mangrove-boundary-validation":"top-level numeric bounds after legacy coercion; null means unset"}},"entry_signals":{"description":"The signals that open a position. Exactly one must be a TRIGGER in the knowledge graph; the rest are FILTERs.","items":{"additionalProperties":false,"properties":{"name":{"description":"The signal's name, exactly as the knowledge graph has it.","type":"string"},"params":{"description":"Its parameters and the value chosen for each, keyed by parameter name -- the shape `query_knowledge op=get` shows them in. A parameter left out takes the signal's own default, which is a choice nobody made. A name the signal does not take, or a value outside its declared range, is refused.","type":"object"},"timeframe":{"description":"The candle size this signal runs on.","enum":["5m","15m","30m","1h","4h","1D"],"type":"string"}},"required":["name","timeframe"],"type":"object"},"type":"array"},"exit_signals":{"description":"The signals that close one, same shape. A strategy may have none, and then it exits on risk rules alone.","items":{"additionalProperties":false,"properties":{"name":{"description":"The signal's name, exactly as the knowledge graph has it.","type":"string"},"params":{"description":"Its parameters and the value chosen for each, keyed by parameter name -- the shape `query_knowledge op=get` shows them in. A parameter left out takes the signal's own default, which is a choice nobody made. A name the signal does not take, or a value outside its declared range, is refused.","type":"object"},"timeframe":{"description":"The candle size this signal runs on.","enum":["5m","15m","30m","1h","4h","1D"],"type":"string"}},"required":["name","timeframe"],"type":"object"},"type":"array"},"market_data_venue":{"description":"Exact venue of the requested market.","type":"string"},"quote_token":{"description":"Quote currency of the requested market.","type":"string"},"regime_direction":{"description":"The direction band from get_market_regime, e.g. bear. The signal searches filter by it and find_sweep_runs marks each row's regime_fit with it; save_strategy and update_strategy read the current band themselves, so their check runs without it.","type":"string"},"regime_override":{"default":false,"description":"Save anyway when the regime check refuses. Only ever on the person's explicit say-so, after they have been told why.","type":"boolean"},"source_config_hash":{"description":"The selected row's config_hash, as find_sweep_runs reported it. Pass it with the other two: a relaunched sweep can give one run_index to several runs, and without it such an index is refused.","type":"string"},"source_experiment_id":{"description":"For a sweep pick, its experiment ID. Supply with source_run_index. The stored run supplies the exact signals and execution settings. With no market given, it saves on the run's market when ref-data lists it, otherwise on a market ref-data lists, the run's venue first.","type":"string"},"source_run_index":{"description":"The selected sweep row, including zero.","type":"integer"},"strategy_name":{"description":"What to call it, in plain words a person reads -- the entry trigger's friendly_name from the knowledge graph, then the asset and timeframe, e.g. \"Upside Range Breakout - BTC 1h\". Never a code name such as btc_strategy or bb_upper_breakout.","type":"string"}},"required":["asset","strategy_name"],"type":"object"},"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategy-workflow/screen_candidates":{"post":{"operationId":"api1_post_screen_candidates_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post screen candidates operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"asset":{"description":"Asset symbol, e.g. BTC or ETH.","type":"string"},"candidates":{"description":"Each {entry: [{name, params?, timeframe?}], exit: [...]}.","items":{"type":"object"},"type":"array"}},"required":["asset","candidates"],"type":"object"},"x-payment-info":{"price":{"amount":"0.020000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategy-workflow/search_marketplace":{"post":{"operationId":"api1_post_search_marketplace_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":false},"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post search marketplace operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"asset":{"description":"Asset symbol, e.g. BTC or ETH.","type":"string"},"asset_class":{"description":"Keep listings in these asset classes. Platform listings are all digital_assets; stocks, options and futures exist only as NexusTrade partner listings the chat cannot reach.","items":{"type":"string"},"type":"array"},"backtest_direction":{"description":"Keep listings backtested in this market direction, e.g. bull, neutral or bear -- the band get_market_regime reports; or unclassified.","type":"string"},"backtest_trend":{"description":"Keep listings backtested in this trend character, e.g. clean, choppy; or unclassified.","type":"string"},"backtest_volatility":{"description":"Keep listings backtested in this volatility band, e.g. low, medium, high; or unclassified.","type":"string"},"beats_all_benchmarks":{"default":false,"description":"Keep only listings whose return beat BTC, ETH and the S&P over their own window.","type":"boolean"},"candle_size":{"description":"Duration of one candle, e.g. 1h or 1d.","type":"string"},"free_only":{"default":false,"description":"Keep only listings with no subscription price.","type":"boolean"},"limit":{"default":20,"description":"Maximum results.","type":"integer"},"max_drawdown_pct":{"description":"Keep listings whose max drawdown is at or below this, in percent.","type":"number"},"min_calmar_ratio":{"description":"Keep listings at or above this Calmar ratio.","type":"number"},"min_gain_to_pain_ratio":{"description":"Keep listings at or above this gain-to-pain ratio.","type":"number"},"min_irr_pct":{"description":"Keep listings at or above this annualised IRR, in percent.","type":"number"},"min_sharpe_ratio":{"description":"Keep listings at or above this Sharpe ratio.","type":"number"},"min_sortino_ratio":{"description":"Keep listings at or above this Sortino ratio.","type":"number"},"min_total_return_pct":{"description":"Keep listings at or above this total return, in percent.","type":"number"},"min_total_trades":{"description":"Keep listings with at least this many trades.","type":"integer"},"min_trades_per_week":{"description":"Keep listings trading at least this often, per week.","type":"number"},"min_win_rate_pct":{"description":"Keep listings at or above this win rate, in percent.","type":"number"},"offset":{"default":0,"description":"Pagination offset in the result units documented by the tool; zero starts the first page.","type":"integer"},"order":{"default":"desc","description":"desc for best-first on that metric, asc for worst-first.","type":"string"},"risk_level":{"description":"Keep listings at any of these risk levels, e.g. low, medium, high.","items":{"type":"string"},"type":"array"},"search":{"description":"Free text matched against listing name, description and creator.","type":"string"},"sort":{"description":"The column to order by. Omitted, the marketplace's trending order.","enum":["name","asset","timeframe","asset_class","return","irr","sharpe","sortino","calmar","gain_to_pain","alpha","trades_per_week","max_drawdown","volatility","win_rate","trades","duration","users","rating","listed_at","price"],"type":"string"}},"required":[],"type":"object"},"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategy-workflow/size_sweep":{"post":{"operationId":"api1_post_size_sweep_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":false},"responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Post size sweep operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"assets":{"description":"Asset symbols, e.g. [\"BTC\", \"ETH\"].","items":{"type":"string"},"type":"array"},"candidate_shape":{"description":"How many parts a drawn strategy gets, any of n_entry_triggers, min_entry_filters, max_entry_filters, min_exit_triggers, max_exit_triggers, min_exit_filters, max_exit_filters. Omitted, the platform default shape.","type":"object"},"candle_sizes":{"description":"Candle sizes, e.g. [\"1h\"]. Omitted, every size Oracle holds for those assets, which multiplies the windows.","items":{"type":"string"},"type":"array"},"categories":{"description":"Draw only from these signal classes, e.g. [\"momentum\"]. The classes are averaging, flow, momentum, oscillator, pattern and volatility. Omitted, the whole library.","items":{"type":"string"},"type":"array"},"draws_per_dataset":{"default":100,"description":"How many candidate strategies to draw PER WINDOW. The runs that execute are this multiplied by the number of windows.","type":"integer"},"entry_filters":{"description":"Draw entry filters only from these. Omitted, every filter.","items":{"type":"string"},"type":"array"},"entry_triggers":{"description":"Draw the entry trigger only from these signals, named as the knowledge graph registers them. Omitted, every trigger.","items":{"type":"string"},"type":"array"},"execution_base":{"description":"Risk settings every run shares, from the execution config schema. Omitted, platform canon.","type":"object"},"execution_sweeps":{"description":"Execution parameters to search too, each {param: {min, max, n}}. Every one of these multiplies the run count.","type":"object"},"exit_filters":{"description":"Draw exit filters only from these.","items":{"type":"string"},"type":"array"},"exit_triggers":{"description":"Draw an exit trigger only from these. Omitted, no exit signal is drawn at all and runs exit on the risk settings.","items":{"type":"string"},"type":"array"},"include_gapped":{"default":false,"description":"Include windows missing bars. Off by default, because a metric over a half-covered window is not comparable to one over a whole window.","type":"boolean"},"max_total_runs":{"description":"A ceiling on the executed runs, applied by Oracle.","type":"integer"},"param_samples":{"default":3,"description":"How many values each signal parameter contributes. The space is their product, so this is the dial that decides whether the search explores parameters at all; at 1 every candidate runs at a single setting.","type":"integer"},"pre_filter_threshold":{"description":"Skip a drawn candidate the SIEVE model predicts will not trade at all, above this confidence. A will-it-trade gate and nothing about whether it will make money. Omitted, no skipping.","type":"number"},"regimes":{"description":"Market conditions to keep: current, bear, neutral, bull. current means data within the last 30 days, which is recency and not direction. Omitted, every condition.","items":{"type":"string"},"type":"array"},"signal_groups":{"description":"Keep kinds of signal apart. A candidate draws ALL of its signals from ONE group, so two signals in different groups never appear on the same strategy. Runs are split across the groups.","items":{"additionalProperties":false,"properties":{"categories":{"description":"Signal classes whose members belong to it.","items":{"type":"string"},"type":"array"},"exclude":{"description":"Signal names removed from it.","items":{"type":"string"},"type":"array"},"filters":{"additionalProperties":false,"description":"Select which group members may serve as filters. Role selections only narrow the parent membership; they cannot reassign a signal's role.","properties":{"categories":{"items":{"type":"string"},"type":"array"},"exclude":{"items":{"type":"string"},"type":"array"},"include":{"items":{"type":"string"},"type":"array"}},"required":[],"type":"object"},"include":{"description":"Signal names forced in even when their class is not listed.","items":{"type":"string"},"type":"array"},"name":{"description":"What to call the group.","type":"string"},"triggers":{"additionalProperties":false,"description":"Select which group members may serve as triggers.","properties":{"categories":{"items":{"type":"string"},"type":"array"},"exclude":{"items":{"type":"string"},"type":"array"},"include":{"items":{"type":"string"},"type":"array"}},"required":[],"type":"object"},"weight":{"description":"Its share of the strategies drawn. Omitted on every group is an even split.","type":"number"}},"required":[],"type":"object"},"type":"array"},"windows":{"description":"Specific window files to include whatever else is chosen.","items":{"type":"string"},"type":"array"}},"required":[],"type":"object"}}},"/api/v1/strategy-workflow/update_strategy":{"post":{"operationId":"api1_post_update_strategy_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post update strategy operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"constraints":{"additionalProperties":true,"description":"Supported execution overrides requested by the person or justified by the composition workflow after reading the execution-config contract. Preserve explicit user choices and explain agent-selected adjustments. Each supplied value is kept exactly as given rather than nudged.","properties":{"atr_cap_multiplier":{"description":"SUPERSEDED by volatility_tolerance. Bounded the weighted blend at this multiple of the SHORT ATR.","x-mangrove-authoring-schema":{"description":"SUPERSEDED by volatility_tolerance. Bounded the weighted blend at this multiple of the SHORT ATR.","minimum":1.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy this is what made the weight pair inert past a long weight of roughly 6-12% (#1052).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"}},"atr_long_weight":{"description":"SUPERSEDED by volatility_tolerance. Weight of the daily ATR in the weighted-blend stop model, and always 1 - atr_short_weight rather than independent.","x-mangrove-authoring-schema":{"description":"SUPERSEDED by volatility_tolerance. Weight of the daily ATR in the weighted-blend stop model, and always 1 - atr_short_weight rather than independent.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. Derived, never independently effective.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"}},"atr_period":{"description":"ATR lookback in bars (default 14) used to measure volatility for stop sizing.","x-mangrove-authoring-schema":{"default":14,"description":"ATR lookback in bars (default 14) used to measure volatility for stop sizing.","maximum":1000,"minimum":5,"type":["integer","null"],"x-mangrove-effect":"Higher smooths the volatility estimate (steadier, slower-reacting stops). Lower reacts faster to recent volatility (choppier stops).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"atr_short_weight":{"description":"SUPERSEDED by volatility_tolerance. Weight of the signal-timeframe ATR in the weighted-blend stop model. Readable on a strategy created under that model; refused on any write.","x-mangrove-authoring-schema":{"description":"SUPERSEDED by volatility_tolerance. Weight of the signal-timeframe ATR in the weighted-blend stop model. Readable on a strategy created under that model; refused on any write.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy, higher favours the signal timeframe's own volatility -- though the cap made settings past a few percent of long weight indistinguishable (#1052).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"}},"atr_volatility_factor":{"description":"SUPERSEDED by volatility_tolerance. Multiplied the blended ATR to give the stop distance. The dial's two endpoint factors carry this instead, one at each end of the width.","x-mangrove-authoring-schema":{"description":"SUPERSEDED by volatility_tolerance. Multiplied the blended ATR to give the stop distance. The dial's two endpoint factors carry this instead, one at each end of the width.","exclusiveMinimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy, higher widens the stop and shrinks the position for the same risk.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"}},"circuit_breaker":{"description":"Parameters for cooldown_model 'trades': pause on consecutive net losses or accumulated loss amount, pause on marked drawdown from the peak (including unrealized changes), resume new alpha positions at a reduced size, and stop after consecutive pauses. Canon defaults are 36 primary bars for a loss pause, 72 for a drawdown pause, and three strikes for a permanent halt. Pause counts are clamped to 24 hours through 14 days by default. max_drawdown_halt_limit separately stops entries on realized loss of cumulative gross deposits. Existing exits remain active during holds.","x-mangrove-authoring-schema":{"additionalProperties":false,"default":{"consecutive_loss_limit":2,"drawdown_pause_bars":72,"loss_amount_pct":0.06,"max_consecutive_pauses":3,"pause_bars":36,"pause_max_days":14,"pause_min_hours":24,"resume_size_fraction":0.5,"resume_trades":3},"description":"Parameters for cooldown_model 'trades': pause on consecutive net losses or accumulated loss amount, pause on marked drawdown from the peak (including unrealized changes), resume new alpha positions at a reduced size, and stop after consecutive pauses. Canon defaults are 36 primary bars for a loss pause, 72 for a drawdown pause, and three strikes for a permanent halt. Pause counts are clamped to 24 hours through 14 days by default. max_drawdown_halt_limit separately stops entries on realized loss of cumulative gross deposits. Existing exits remain active during holds.","properties":{"consecutive_loss_limit":{"default":2,"description":"Consecutive losing closes on an asset that start a pause. A winning close resets the count.","maximum":100,"minimum":1,"type":"integer","x-mangrove-effect":"Lower pauses sooner after a losing run; higher tolerates longer runs.","x-mangrove-status":"tunable"},"drawdown_pause_bars":{"default":72,"description":"Primary-timeframe bars denying entries after a drawdown pause (canon default 72). At drawdown-pause expiry the peak re-baselines to current account value. An alpha resume window opens only once no pause remains and no permanent halt is latched. The count is raised to cover pause_min_hours and lowered to fit pause_max_days (24 hours through 14 days by default).","maximum":8760,"minimum":1,"type":"integer","x-mangrove-effect":"Longer holds the pause longer before trading can resume.","x-mangrove-status":"tunable"},"loss_amount_pct":{"default":0.06,"description":"Accumulated net losses as a fraction of the closed-equity reset baseline that start a loss pause. A winning close clears the accumulation and resets the baseline. An asset loss pause clears it at the start and re-baselines at expiry; a global drawdown pause does not itself reset it.","exclusiveMinimum":0.0,"maximum":1.0,"type":"number","x-mangrove-effect":"Lower pauses after smaller cumulative losses; higher tolerates larger ones.","x-mangrove-status":"tunable"},"max_consecutive_pauses":{"default":3,"description":"Strikes that stop the strategy until a manual restart. A strike is one pause started, of any kind (consecutive losses, loss amount, drawdown, a resume window that lost money). Strikes reset to 0 only on a new equity high: a close that leaves closed equity above the high-water mark the strategy had when the first strike of the run was recorded. A winning close below that mark does not reset them, and a deposit or withdrawal does not count as a high.","maximum":100,"minimum":1,"type":"integer","x-mangrove-effect":"Lower stops the strategy sooner; higher tolerates more repeated pauses.","x-mangrove-status":"tunable"},"pause_bars":{"default":36,"description":"Primary-timeframe bars denying entries after a loss pause (canon default 36). The count is raised to cover pause_min_hours and lowered to fit pause_max_days on that timeframe (24 hours through 14 days by default).","maximum":8760,"minimum":1,"type":"integer","x-mangrove-effect":"Longer sits out more of a bad regime; shorter resumes sooner.","x-mangrove-status":"tunable"},"pause_max_days":{"default":14,"description":"A pause lasts at most this many days on every timeframe: the bar count is lowered to fit it.","exclusiveMinimum":0.0,"maximum":365,"type":"number","x-mangrove-effect":"Lower ends every pause sooner on long timeframes; higher leaves the bar count to decide.","x-mangrove-status":"tunable"},"pause_min_hours":{"default":24,"description":"A pause lasts at least this many hours on every timeframe: the bar count of pause_bars or drawdown_pause_bars is raised to cover it.","exclusiveMinimum":0.0,"maximum":336,"type":"number","x-mangrove-effect":"Higher makes every pause at least that long on short timeframes; lower leaves the bar count to decide.","x-mangrove-status":"tunable"},"resume_size_fraction":{"default":0.5,"description":"Fraction of normal size for new alpha positions while a resume window is open (canon default 0.5). Eligible confirmed position closes count toward resume_trades; a negative net result starts another loss pause and strike, while zero or a profit restores full alpha size. Core orders keep their normal allocation quantities after pause expiry: they are not positions and do not consume resume-trade counts. 1.0 disables the alpha size reduction.","exclusiveMinimum":0.0,"maximum":1.0,"type":"number","x-mangrove-effect":"Lower risks less while the strategy proves itself again after a pause; higher resumes closer to full size.","x-mangrove-status":"tunable"},"resume_trades":{"default":3,"description":"Eligible confirmed position closes booked in a resume window (canon default three). When the window completes, a negative net realized result starts a new loss pause and strike; zero or a profit restores full alpha size. A pause cancels the active window; a new one opens only once no pause remains and no permanent halt is latched. Core orders do not count as position closes.","maximum":50,"minimum":1,"type":"integer","x-mangrove-effect":"Higher judges the resumed strategy over more trades before full size returns; lower decides sooner.","x-mangrove-status":"tunable"}},"type":["object","null"],"x-mangrove-effect":"Tighter limits pause and stop sooner; looser limits keep trading through losing runs.","x-mangrove-status":"guardrail"}},"cooldown_model":{"description":"Loss-streak breaker model. 'bars' counts losing closes inside rolling windows of the primary timeframe (cooldown_config). 'trades' counts consecutive losing closes and realized loss amount, pauses for circuit_breaker bars of the primary timeframe (at least pause_min_hours and at most pause_max_days), and stops after repeated pauses (circuit_breaker). An absent model adopts the canonical 'trades' defaults; explicit 'bars' retains the legacy model.","x-mangrove-authoring-schema":{"default":"trades","description":"Loss-streak breaker model. 'bars' counts losing closes inside rolling windows of the primary timeframe (cooldown_config). 'trades' counts consecutive losing closes and realized loss amount, pauses for circuit_breaker bars of the primary timeframe (at least pause_min_hours and at most pause_max_days), and stops after repeated pauses (circuit_breaker). An absent model adopts the canonical 'trades' defaults; explicit 'bars' retains the legacy model.","enum":["bars","trades",null],"type":["string","null"],"x-mangrove-effect":"'trades' trips on trade count and loss size regardless of how far apart trades are spaced; 'bars' trips only when losses land inside the window. cooldown_config, cooldown_bars, daily_momentum_limit and weekly_momentum_limit are read only under 'bars': they are left out of a resolved config under 'trades', and a config that carries them under 'trades' has them dropped.","x-mangrove-status":"guardrail"}},"enable_volatility_adjustment":{"description":"Toggles volatility-based position scaling (default false).","x-mangrove-authoring-schema":{"default":false,"description":"Toggles volatility-based position scaling (default false).","type":["boolean","null"],"x-mangrove-effect":"When true, positions are scaled down by target_volatility / (atr/entry) if ATR%% exceeds target; only reduces size, never increases.","x-mangrove-status":"gated"}},"exit_on_loss_after_bars":{"description":"Exit a losing position after this many bars.","x-mangrove-authoring-schema":{"default":1000,"description":"Exit a losing position after this many bars.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Lower cuts losers sooner; higher gives them more time to recover.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"exit_on_profit_after_bars":{"description":"Exit a winning position after this many bars.","x-mangrove-authoring-schema":{"default":1000,"description":"Exit a winning position after this many bars.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Lower banks winners sooner; higher lets them run.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"initial_balance":{"description":"Starting balance for the backtest/simulation (default $10,000).","x-mangrove-authoring-schema":{"default":10000,"description":"Starting balance for the backtest/simulation (default $10,000).","maximum":1000000000.0,"minimum":25.0,"type":["number","null"],"x-mangrove-effect":"Scales absolute dollar figures; not a strategy-character knob.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"max_drawdown_halt_limit":{"description":"Permanent capital-floor entry halt (0.20 = 20%). Closed, realized equity is compared with cumulative gross deposits (execution_state.cumulative_deposits), not a rolling peak or the signed net-funding balance; withdrawals do not reduce this reference. Legacy requests without cumulative_deposits use execution_config.initial_balance. The shared live/paper evaluator checks before each bar and latches execution_state.halt. New alpha entries and v3 core allocations are denied, while authoritative positions retain protective exits and exits_pending until physically flat. Engine-owned strategies become inactive only after that book is flat; caller-owned executors retain their exit monitor. An explicit manual restart is required to clear the latch. Backtests enforce the same floor when evaluate_bar receives enforce_capital_floor=True, managing open-position exits through the final bar. Applies to both cooldown models; null disables new floor trips, while an existing halt remains latched.","x-mangrove-authoring-schema":{"default":0.2,"description":"Permanent capital-floor entry halt (0.20 = 20%). Closed, realized equity is compared with cumulative gross deposits (execution_state.cumulative_deposits), not a rolling peak or the signed net-funding balance; withdrawals do not reduce this reference. Legacy requests without cumulative_deposits use execution_config.initial_balance. The shared live/paper evaluator checks before each bar and latches execution_state.halt. New alpha entries and v3 core allocations are denied, while authoritative positions retain protective exits and exits_pending until physically flat. Engine-owned strategies become inactive only after that book is flat; caller-owned executors retain their exit monitor. An explicit manual restart is required to clear the latch. Backtests enforce the same floor when evaluate_bar receives enforce_capital_floor=True, managing open-position exits through the final bar. Applies to both cooldown models; null disables new floor trips, while an existing halt remains latched.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Lower protects more of gross deposited capital before a permanent entry halt; higher tolerates a deeper realized loss. This does not resize positions or stop protective exit evaluation. Do not add a separate floor where the shared evaluator enforces it.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"max_drawdown_limit":{"description":"Peak-relative entry pause (0.20 = 20%). The canonical 'trades' model measures marked equity against its high-water mark. A breach starts one drawdown pause and strike; circuit_breaker.drawdown_pause_bars defaults to 72 primary bars, clamped to pause_min_hours and pause_max_days (24 hours and 14 days by default). At drawdown-pause expiry the peak re-baselines; a reduced-size alpha resume window opens only once no pause remains and no permanent halt is latched. Explicit 'bars' retains the legacy closed-equity measurement and per-timeframe long cooldown. Both models deny new entries while allowing existing positions to exit; automatic v3 core allocations honor the hold too. null disables new drawdown trips.","x-mangrove-authoring-schema":{"default":0.2,"description":"Peak-relative entry pause (0.20 = 20%). The canonical 'trades' model measures marked equity against its high-water mark. A breach starts one drawdown pause and strike; circuit_breaker.drawdown_pause_bars defaults to 72 primary bars, clamped to pause_min_hours and pause_max_days (24 hours and 14 days by default). At drawdown-pause expiry the peak re-baselines; a reduced-size alpha resume window opens only once no pause remains and no permanent halt is latched. Explicit 'bars' retains the legacy closed-equity measurement and per-timeframe long cooldown. Both models deny new entries while allowing existing positions to exit; automatic v3 core allocations honor the hold too. null disables new drawdown trips.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Lower pauses entries after a smaller drawdown; higher tolerates a deeper drawdown. The shared entry breaker enforces this in single/bulk live and paper evaluation, v3 core allocation and backtests built with risk_manager_from_execution_config. Alpha resume sizing is a separate control; do not add a second drawdown stop.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"max_hold_bars":{"description":"Maximum bars to hold any position before a forced exit.","x-mangrove-authoring-schema":{"default":1000,"description":"Maximum bars to hold any position before a forced exit.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher lets trades run longer; lower forces earlier time-based exits.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"max_hold_time_hours":{"description":"Maximum position hold time in hours (null = no limit).","x-mangrove-authoring-schema":{"default":null,"description":"Maximum position hold time in hours (null = no limit).","exclusiveMinimum":1,"maximum":8760,"type":["integer","null"],"x-mangrove-effect":"Lower forces earlier time-based exits; null/higher lets trades run indefinitely on time.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"max_open_positions":{"description":"Maximum concurrent open positions.","x-mangrove-authoring-schema":{"default":10,"description":"Maximum concurrent open positions.","maximum":1000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher allows more simultaneous exposure (more diversification but more aggregate risk); lower is more selective with less aggregate exposure.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"max_risk_per_trade":{"description":"Fraction of account equity risked per trade (0.01 = 1%). Position size is derived from this and the stop distance.","x-mangrove-authoring-schema":{"default":0.01,"description":"Fraction of account equity risked per trade (0.01 = 1%). Position size is derived from this and the stop distance.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Higher risks more per trade: bigger positions, larger gains AND larger drawdowns. Lower is more conservative: smaller positions, smaller swings.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"max_trade_amount":{"description":"Absolute cap on dollar size per trade.","x-mangrove-authoring-schema":{"default":10000000,"description":"Absolute cap on dollar size per trade.","exclusiveMinimum":0.0,"maximum":1000000000000.0,"type":["number","null"],"x-mangrove-effect":"Size guardrail; rarely binding.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"max_trades_per_day":{"description":"Daily trade cap.","x-mangrove-authoring-schema":{"default":50,"description":"Daily trade cap.","maximum":1440,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher permits more churn; lower throttles activity.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"max_units_per_trade":{"description":"Absolute cap on units per trade.","x-mangrove-authoring-schema":{"default":1000000,"description":"Absolute cap on units per trade.","exclusiveMinimum":0.0,"maximum":1000000000000.0,"type":["number","null"],"x-mangrove-effect":"Size guardrail; rarely binding.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"min_asset_balance":{"description":"position_size_calc 'v3' only. Minimum asset balance, in asset units, the strategy holds outside open trades.","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Minimum asset balance, in asset units, the strategy holds outside open trades.","minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more of the asset out of reach of sell trades and core sells, and takes more cash to reach; lower frees more of the asset for trading.","x-mangrove-status":"guardrail"}},"min_balance_days":{"description":"position_size_calc 'v3' only. Number of equal daily orders used to bring a side up to its minimum balance.","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Number of equal daily orders used to bring a side up to its minimum balance.","minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher spreads the minimum-balance orders over more days at smaller size; lower reaches the minimum sooner with larger orders.","x-mangrove-status":"guardrail"}},"min_balance_threshold":{"description":"Cash reserve fraction held back from new entries (0.1 = 10%). v1 reserves this fraction of cash; v2 reserves this fraction of account value (cash + open positions at market). An entry may only use cash above the reserve; when no cash is deployable the entry is denied (insufficient_cash / insufficient_cash_v2_account_reserve). It never halts the strategy and never closes positions.","x-mangrove-authoring-schema":{"default":0.1,"description":"Cash reserve fraction held back from new entries (0.1 = 10%). v1 reserves this fraction of cash; v2 reserves this fraction of account value (cash + open positions at market). An entry may only use cash above the reserve; when no cash is deployable the entry is denied (insufficient_cash / insufficient_cash_v2_account_reserve). It never halts the strategy and never closes positions.","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more cash idle and makes entries smaller or rarer as the account shrinks; lower lets entries use more of the balance. Not a drawdown stop; see max_drawdown_limit and max_drawdown_halt_limit.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"min_cash_balance":{"description":"position_size_calc 'v3' only. Minimum cash balance the strategy holds after the worst-case loss of every open trade.","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Minimum cash balance the strategy holds after the worst-case loss of every open trade.","minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more cash out of reach of buy trades and core buys, so entries are smaller or rarer; lower frees more cash for trading.","x-mangrove-status":"guardrail"}},"min_stop_distance_pct":{"description":"Hard floor on stop distance as a fraction of entry price (crypto minimum), applied after ATR sizing.","x-mangrove-authoring-schema":{"default":0.005,"description":"Hard floor on stop distance as a fraction of entry price (crypto minimum), applied after ATR sizing.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher enforces a wider minimum stop; lower allows tighter stops down to the floor.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"min_trade_amount":{"description":"Minimum trade size in dollars; smaller intended trades are skipped.","x-mangrove-authoring-schema":{"default":25,"description":"Minimum trade size in dollars; smaller intended trades are skipped.","maximum":1000000.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher skips more small signals; lower allows smaller trades.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"}},"position_size_calc":{"description":"Sizing-engine version ('v1', 'v2' or 'v3'). Pinned at creation and immutable. 'v3' holds an asset balance and a cash balance, sizes against equity net of open risk, and requires the position_size_calc 'v3' parameters.","x-mangrove-authoring-schema":{"default":"v2","description":"Sizing-engine version ('v1', 'v2' or 'v3'). Pinned at creation and immutable. 'v3' holds an asset balance and a cash balance, sizes against equity net of open risk, and requires the position_size_calc 'v3' parameters.","enum":["v1","v2","v3",null],"type":["string","null"],"x-mangrove-effect":"Not a magnitude knob; selects the sizing algorithm. Do not change on an existing strategy.","x-mangrove-status":"guardrail"}},"profit_threshold_pct":{"description":"Profit threshold (5%% default) above which a position counts as 'winning' for the time-based exit logic.","x-mangrove-authoring-schema":{"default":0.05,"description":"Profit threshold (5%% default) above which a position counts as 'winning' for the time-based exit logic.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher requires a larger gain before a position is treated as winning; lower treats smaller gains as wins.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"rebalance_band":{"description":"position_size_calc 'v3' only. Absolute deviation of the asset weight from target_asset_weight that triggers a rebalance order (0.05 = 5 points).","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Absolute deviation of the asset weight from target_asset_weight that triggers a rebalance order (0.05 = 5 points).","exclusiveMaximum":1.0,"exclusiveMinimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher lets the split drift further before a rebalance order, so fewer core orders; lower holds the split closer to target with more core orders and more fees.","x-mangrove-status":"tunable"}},"reward_factor":{"description":"Risk/reward target. Take-profit distance = reward_factor * stop_distance.","x-mangrove-authoring-schema":{"default":2,"description":"Risk/reward target. Take-profit distance = reward_factor * stop_distance.","exclusiveMinimum":0.0,"maximum":100.0,"type":["number","null"],"x-mangrove-effect":"Higher sets a wider profit target: lower win rate but bigger wins. Lower sets a tighter target: higher win rate but smaller wins.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"stop_gap_allowance":{"description":"position_size_calc 'v3' only. Fraction of the stop price a stop fill is assumed to miss by when computing the worst-case loss of a trade (0.01 = 1%).","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Fraction of the stop price a stop fill is assumed to miss by when computing the worst-case loss of a trade (0.01 = 1%).","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher counts more risk per open trade, leaving less available cash and smaller positions; lower counts less.","x-mangrove-status":"guardrail"}},"stop_model":{"description":"Which stop model the strategy uses: 'atr_width_dial' (one parameter, volatility_tolerance, positioned on the ATR width) or 'weighted_atr' (superseded: a weighted blend of two ATRs, capped). Pinned at creation and immutable.","x-mangrove-authoring-schema":{"default":"atr_width_dial","description":"Which stop model the strategy uses: 'atr_width_dial' (one parameter, volatility_tolerance, positioned on the ATR width) or 'weighted_atr' (superseded: a weighted blend of two ATRs, capped). Pinned at creation and immutable.","enum":["atr_width_dial","weighted_atr",null],"type":["string","null"],"x-mangrove-effect":"Not a magnitude knob; selects the stop algorithm. Do not change on an existing strategy -- it would move every stop the strategy takes.","x-mangrove-status":"guardrail"}},"taker_fee_rate":{"description":"position_size_calc 'v3' only. Venue fee per fill as a fraction of notional, charged in cash (0.004 = 0.4%).","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Venue fee per fill as a fraction of notional, charged in cash (0.004 = 0.4%).","exclusiveMaximum":0.1,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher counts more cost per fill, raising the risk of each trade and lowering available cash. Models the venue; not a strategy-character knob.","x-mangrove-status":"guardrail"}},"target_asset_weight":{"description":"position_size_calc 'v3' only. Target share of core value held in the asset (0.8 = 80% asset, 20% cash; 0 = all cash).","x-mangrove-authoring-schema":{"description":"position_size_calc 'v3' only. Target share of core value held in the asset (0.8 = 80% asset, 20% cash; 0 = all cash).","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher holds more of the asset and less cash; lower holds more cash. The daily core order moves the split back to this value once it drifts past rebalance_band. At 0 with no asset held, no core order is placed and only buy trades can pass.","x-mangrove-status":"tunable"}},"target_volatility":{"description":"Target volatility (0.10 = 10%). ONLY active when enable_volatility_adjustment is true (default false). When active, scales position size down if ATR%% of entry exceeds the target (never up).","x-mangrove-authoring-schema":{"default":0.1,"description":"Target volatility (0.10 = 10%). ONLY active when enable_volatility_adjustment is true (default false). When active, scales position size down if ATR%% of entry exceeds the target (never up).","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"With the gate off (the default), changing this has no effect. With it on, lower scales positions down more aggressively in high volatility.","x-mangrove-gate-field":"enable_volatility_adjustment","x-mangrove-gate-required":true,"x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"gated"}},"volatility_mode":{"description":"Unused (retained for backward compatibility). Volatility is derived from ATR.","x-mangrove-authoring-schema":{"default":"stddev","description":"Unused (retained for backward compatibility). Volatility is derived from ATR.","enum":["stddev","atr",null],"type":["string","null"],"x-mangrove-effect":"No runtime effect. Do not tune.","x-mangrove-status":"unused"}},"volatility_tolerance":{"description":"Where on the ATR width the stop is taken, as the ATR_long-vs-ATR_short contribution ratio: 0 is all short end (0.5x the signal timeframe's ATR), 1 is all long end (2x the daily ATR). Interpolated geometrically, so the value is exactly the long end's share of log(stop) and each 0.1 is the same multiplicative step. Replaces atr_short_weight, atr_long_weight and atr_cap_multiplier.","x-mangrove-authoring-schema":{"default":0.5,"description":"Where on the ATR width the stop is taken, as the ATR_long-vs-ATR_short contribution ratio: 0 is all short end (0.5x the signal timeframe's ATR), 1 is all long end (2x the daily ATR). Interpolated geometrically, so the value is exactly the long end's share of log(stop) and each 0.1 is the same multiplicative step. Replaces atr_short_weight, atr_long_weight and atr_cap_multiplier.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher widens the stop, and because position size is the risk budget divided by the stop distance, exposure shrinks in exact inverse proportion at the SAME risk. Low means many units with little room to be wrong and frequent stop-outs; high means few units that are hard to shake out but need a much larger move to reach the same reward. Both risk max_risk_per_trade.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"}},"volatility_window":{"description":"Unused (retained for backward compatibility). ATR windowing is controlled by atr_period.","x-mangrove-authoring-schema":{"default":24,"description":"Unused (retained for backward compatibility). ATR windowing is controlled by atr_period.","maximum":1000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"No runtime effect. Do not tune.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"unused"}}},"type":"object","x-mangrove-authoring-schema":{"$id":"urn:mangrove:execution-config:1","$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":true,"description":"Canonical authoring representation derived from server metadata and defaults. Top-level optional keys may be omitted or null. The existing HTTP validator separately coerces top-level numeric strings, enforces their declared bounds and permits unknown/legacy fields; it does not enforce this whole nested schema. Runtime strategy/version/timeframe checks remain authoritative. Cooldown durations may be omitted by legacy configs and then fall back to their corresponding windows.","properties":{"atr_cap_multiplier":{"description":"SUPERSEDED by volatility_tolerance. Bounded the weighted blend at this multiple of the SHORT ATR.","minimum":1.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy this is what made the weight pair inert past a long weight of roughly 6-12% (#1052).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"},"atr_long_weight":{"description":"SUPERSEDED by volatility_tolerance. Weight of the daily ATR in the weighted-blend stop model, and always 1 - atr_short_weight rather than independent.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. Derived, never independently effective.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"},"atr_period":{"default":14,"description":"ATR lookback in bars (default 14) used to measure volatility for stop sizing.","maximum":1000,"minimum":5,"type":["integer","null"],"x-mangrove-effect":"Higher smooths the volatility estimate (steadier, slower-reacting stops). Lower reacts faster to recent volatility (choppier stops).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"atr_short_weight":{"description":"SUPERSEDED by volatility_tolerance. Weight of the signal-timeframe ATR in the weighted-blend stop model. Readable on a strategy created under that model; refused on any write.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy, higher favours the signal timeframe's own volatility -- though the cap made settings past a few percent of long weight indistinguishable (#1052).","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"},"atr_volatility_factor":{"description":"SUPERSEDED by volatility_tolerance. Multiplied the blended ATR to give the stop distance. The dial's two endpoint factors carry this instead, one at each end of the width.","exclusiveMinimum":0.0,"type":["number","null"],"x-mangrove-effect":"None on a strategy using atr_width_dial. On a weighted_atr strategy, higher widens the stop and shrinks the position for the same risk.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"superseded","x-mangrove-superseded-by":"volatility_tolerance"},"circuit_breaker":{"additionalProperties":false,"default":{"consecutive_loss_limit":2,"drawdown_pause_bars":72,"loss_amount_pct":0.06,"max_consecutive_pauses":3,"pause_bars":36,"pause_max_days":14,"pause_min_hours":24,"resume_size_fraction":0.5,"resume_trades":3},"description":"Parameters for cooldown_model 'trades': pause on consecutive net losses or accumulated loss amount, pause on marked drawdown from the peak (including unrealized changes), resume new alpha positions at a reduced size, and stop after consecutive pauses. Canon defaults are 36 primary bars for a loss pause, 72 for a drawdown pause, and three strikes for a permanent halt. Pause counts are clamped to 24 hours through 14 days by default. max_drawdown_halt_limit separately stops entries on realized loss of cumulative gross deposits. Existing exits remain active during holds.","properties":{"consecutive_loss_limit":{"default":2,"description":"Consecutive losing closes on an asset that start a pause. A winning close resets the count.","maximum":100,"minimum":1,"type":"integer","x-mangrove-effect":"Lower pauses sooner after a losing run; higher tolerates longer runs.","x-mangrove-status":"tunable"},"drawdown_pause_bars":{"default":72,"description":"Primary-timeframe bars denying entries after a drawdown pause (canon default 72). At drawdown-pause expiry the peak re-baselines to current account value. An alpha resume window opens only once no pause remains and no permanent halt is latched. The count is raised to cover pause_min_hours and lowered to fit pause_max_days (24 hours through 14 days by default).","maximum":8760,"minimum":1,"type":"integer","x-mangrove-effect":"Longer holds the pause longer before trading can resume.","x-mangrove-status":"tunable"},"loss_amount_pct":{"default":0.06,"description":"Accumulated net losses as a fraction of the closed-equity reset baseline that start a loss pause. A winning close clears the accumulation and resets the baseline. An asset loss pause clears it at the start and re-baselines at expiry; a global drawdown pause does not itself reset it.","exclusiveMinimum":0.0,"maximum":1.0,"type":"number","x-mangrove-effect":"Lower pauses after smaller cumulative losses; higher tolerates larger ones.","x-mangrove-status":"tunable"},"max_consecutive_pauses":{"default":3,"description":"Strikes that stop the strategy until a manual restart. A strike is one pause started, of any kind (consecutive losses, loss amount, drawdown, a resume window that lost money). Strikes reset to 0 only on a new equity high: a close that leaves closed equity above the high-water mark the strategy had when the first strike of the run was recorded. A winning close below that mark does not reset them, and a deposit or withdrawal does not count as a high.","maximum":100,"minimum":1,"type":"integer","x-mangrove-effect":"Lower stops the strategy sooner; higher tolerates more repeated pauses.","x-mangrove-status":"tunable"},"pause_bars":{"default":36,"description":"Primary-timeframe bars denying entries after a loss pause (canon default 36). The count is raised to cover pause_min_hours and lowered to fit pause_max_days on that timeframe (24 hours through 14 days by default).","maximum":8760,"minimum":1,"type":"integer","x-mangrove-effect":"Longer sits out more of a bad regime; shorter resumes sooner.","x-mangrove-status":"tunable"},"pause_max_days":{"default":14,"description":"A pause lasts at most this many days on every timeframe: the bar count is lowered to fit it.","exclusiveMinimum":0.0,"maximum":365,"type":"number","x-mangrove-effect":"Lower ends every pause sooner on long timeframes; higher leaves the bar count to decide.","x-mangrove-status":"tunable"},"pause_min_hours":{"default":24,"description":"A pause lasts at least this many hours on every timeframe: the bar count of pause_bars or drawdown_pause_bars is raised to cover it.","exclusiveMinimum":0.0,"maximum":336,"type":"number","x-mangrove-effect":"Higher makes every pause at least that long on short timeframes; lower leaves the bar count to decide.","x-mangrove-status":"tunable"},"resume_size_fraction":{"default":0.5,"description":"Fraction of normal size for new alpha positions while a resume window is open (canon default 0.5). Eligible confirmed position closes count toward resume_trades; a negative net result starts another loss pause and strike, while zero or a profit restores full alpha size. Core orders keep their normal allocation quantities after pause expiry: they are not positions and do not consume resume-trade counts. 1.0 disables the alpha size reduction.","exclusiveMinimum":0.0,"maximum":1.0,"type":"number","x-mangrove-effect":"Lower risks less while the strategy proves itself again after a pause; higher resumes closer to full size.","x-mangrove-status":"tunable"},"resume_trades":{"default":3,"description":"Eligible confirmed position closes booked in a resume window (canon default three). When the window completes, a negative net realized result starts a new loss pause and strike; zero or a profit restores full alpha size. A pause cancels the active window; a new one opens only once no pause remains and no permanent halt is latched. Core orders do not count as position closes.","maximum":50,"minimum":1,"type":"integer","x-mangrove-effect":"Higher judges the resumed strategy over more trades before full size returns; lower decides sooner.","x-mangrove-status":"tunable"}},"type":["object","null"],"x-mangrove-effect":"Tighter limits pause and stop sooner; looser limits keep trading through losing runs.","x-mangrove-status":"guardrail"},"cooldown_model":{"default":"trades","description":"Loss-streak breaker model. 'bars' counts losing closes inside rolling windows of the primary timeframe (cooldown_config). 'trades' counts consecutive losing closes and realized loss amount, pauses for circuit_breaker bars of the primary timeframe (at least pause_min_hours and at most pause_max_days), and stops after repeated pauses (circuit_breaker). An absent model adopts the canonical 'trades' defaults; explicit 'bars' retains the legacy model.","enum":["bars","trades",null],"type":["string","null"],"x-mangrove-effect":"'trades' trips on trade count and loss size regardless of how far apart trades are spaced; 'bars' trips only when losses land inside the window. cooldown_config, cooldown_bars, daily_momentum_limit and weekly_momentum_limit are read only under 'bars': they are left out of a resolved config under 'trades', and a config that carries them under 'trades' has them dropped.","x-mangrove-status":"guardrail"},"enable_volatility_adjustment":{"default":false,"description":"Toggles volatility-based position scaling (default false).","type":["boolean","null"],"x-mangrove-effect":"When true, positions are scaled down by target_volatility / (atr/entry) if ATR%% exceeds target; only reduces size, never increases.","x-mangrove-status":"gated"},"exit_on_loss_after_bars":{"default":1000,"description":"Exit a losing position after this many bars.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Lower cuts losers sooner; higher gives them more time to recover.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"exit_on_profit_after_bars":{"default":1000,"description":"Exit a winning position after this many bars.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Lower banks winners sooner; higher lets them run.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"initial_balance":{"default":10000,"description":"Starting balance for the backtest/simulation (default $10,000).","maximum":1000000000.0,"minimum":25.0,"type":["number","null"],"x-mangrove-effect":"Scales absolute dollar figures; not a strategy-character knob.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"max_drawdown_halt_limit":{"default":0.2,"description":"Permanent capital-floor entry halt (0.20 = 20%). Closed, realized equity is compared with cumulative gross deposits (execution_state.cumulative_deposits), not a rolling peak or the signed net-funding balance; withdrawals do not reduce this reference. Legacy requests without cumulative_deposits use execution_config.initial_balance. The shared live/paper evaluator checks before each bar and latches execution_state.halt. New alpha entries and v3 core allocations are denied, while authoritative positions retain protective exits and exits_pending until physically flat. Engine-owned strategies become inactive only after that book is flat; caller-owned executors retain their exit monitor. An explicit manual restart is required to clear the latch. Backtests enforce the same floor when evaluate_bar receives enforce_capital_floor=True, managing open-position exits through the final bar. Applies to both cooldown models; null disables new floor trips, while an existing halt remains latched.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Lower protects more of gross deposited capital before a permanent entry halt; higher tolerates a deeper realized loss. This does not resize positions or stop protective exit evaluation. Do not add a separate floor where the shared evaluator enforces it.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"max_drawdown_limit":{"default":0.2,"description":"Peak-relative entry pause (0.20 = 20%). The canonical 'trades' model measures marked equity against its high-water mark. A breach starts one drawdown pause and strike; circuit_breaker.drawdown_pause_bars defaults to 72 primary bars, clamped to pause_min_hours and pause_max_days (24 hours and 14 days by default). At drawdown-pause expiry the peak re-baselines; a reduced-size alpha resume window opens only once no pause remains and no permanent halt is latched. Explicit 'bars' retains the legacy closed-equity measurement and per-timeframe long cooldown. Both models deny new entries while allowing existing positions to exit; automatic v3 core allocations honor the hold too. null disables new drawdown trips.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Lower pauses entries after a smaller drawdown; higher tolerates a deeper drawdown. The shared entry breaker enforces this in single/bulk live and paper evaluation, v3 core allocation and backtests built with risk_manager_from_execution_config. Alpha resume sizing is a separate control; do not add a second drawdown stop.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"max_hold_bars":{"default":1000,"description":"Maximum bars to hold any position before a forced exit.","maximum":10000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher lets trades run longer; lower forces earlier time-based exits.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"max_hold_time_hours":{"default":null,"description":"Maximum position hold time in hours (null = no limit).","exclusiveMinimum":1,"maximum":8760,"type":["integer","null"],"x-mangrove-effect":"Lower forces earlier time-based exits; null/higher lets trades run indefinitely on time.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"max_open_positions":{"default":10,"description":"Maximum concurrent open positions.","maximum":1000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher allows more simultaneous exposure (more diversification but more aggregate risk); lower is more selective with less aggregate exposure.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"max_risk_per_trade":{"default":0.01,"description":"Fraction of account equity risked per trade (0.01 = 1%). Position size is derived from this and the stop distance.","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"Higher risks more per trade: bigger positions, larger gains AND larger drawdowns. Lower is more conservative: smaller positions, smaller swings.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"max_trade_amount":{"default":10000000,"description":"Absolute cap on dollar size per trade.","exclusiveMinimum":0.0,"maximum":1000000000000.0,"type":["number","null"],"x-mangrove-effect":"Size guardrail; rarely binding.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"max_trades_per_day":{"default":50,"description":"Daily trade cap.","maximum":1440,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher permits more churn; lower throttles activity.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"max_units_per_trade":{"default":1000000,"description":"Absolute cap on units per trade.","exclusiveMinimum":0.0,"maximum":1000000000000.0,"type":["number","null"],"x-mangrove-effect":"Size guardrail; rarely binding.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"min_asset_balance":{"description":"position_size_calc 'v3' only. Minimum asset balance, in asset units, the strategy holds outside open trades.","minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more of the asset out of reach of sell trades and core sells, and takes more cash to reach; lower frees more of the asset for trading.","x-mangrove-status":"guardrail"},"min_balance_days":{"description":"position_size_calc 'v3' only. Number of equal daily orders used to bring a side up to its minimum balance.","minimum":1,"type":["integer","null"],"x-mangrove-effect":"Higher spreads the minimum-balance orders over more days at smaller size; lower reaches the minimum sooner with larger orders.","x-mangrove-status":"guardrail"},"min_balance_threshold":{"default":0.1,"description":"Cash reserve fraction held back from new entries (0.1 = 10%). v1 reserves this fraction of cash; v2 reserves this fraction of account value (cash + open positions at market). An entry may only use cash above the reserve; when no cash is deployable the entry is denied (insufficient_cash / insufficient_cash_v2_account_reserve). It never halts the strategy and never closes positions.","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more cash idle and makes entries smaller or rarer as the account shrinks; lower lets entries use more of the balance. Not a drawdown stop; see max_drawdown_limit and max_drawdown_halt_limit.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"min_cash_balance":{"description":"position_size_calc 'v3' only. Minimum cash balance the strategy holds after the worst-case loss of every open trade.","minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher keeps more cash out of reach of buy trades and core buys, so entries are smaller or rarer; lower frees more cash for trading.","x-mangrove-status":"guardrail"},"min_stop_distance_pct":{"default":0.005,"description":"Hard floor on stop distance as a fraction of entry price (crypto minimum), applied after ATR sizing.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher enforces a wider minimum stop; lower allows tighter stops down to the floor.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"min_trade_amount":{"default":25,"description":"Minimum trade size in dollars; smaller intended trades are skipped.","maximum":1000000.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher skips more small signals; lower allows smaller trades.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"guardrail"},"position_size_calc":{"default":"v2","description":"Sizing-engine version ('v1', 'v2' or 'v3'). Pinned at creation and immutable. 'v3' holds an asset balance and a cash balance, sizes against equity net of open risk, and requires the position_size_calc 'v3' parameters.","enum":["v1","v2","v3",null],"type":["string","null"],"x-mangrove-effect":"Not a magnitude knob; selects the sizing algorithm. Do not change on an existing strategy.","x-mangrove-status":"guardrail"},"profit_threshold_pct":{"default":0.05,"description":"Profit threshold (5%% default) above which a position counts as 'winning' for the time-based exit logic.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher requires a larger gain before a position is treated as winning; lower treats smaller gains as wins.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"rebalance_band":{"description":"position_size_calc 'v3' only. Absolute deviation of the asset weight from target_asset_weight that triggers a rebalance order (0.05 = 5 points).","exclusiveMaximum":1.0,"exclusiveMinimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher lets the split drift further before a rebalance order, so fewer core orders; lower holds the split closer to target with more core orders and more fees.","x-mangrove-status":"tunable"},"reward_factor":{"default":2,"description":"Risk/reward target. Take-profit distance = reward_factor * stop_distance.","exclusiveMinimum":0.0,"maximum":100.0,"type":["number","null"],"x-mangrove-effect":"Higher sets a wider profit target: lower win rate but bigger wins. Lower sets a tighter target: higher win rate but smaller wins.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"stop_gap_allowance":{"description":"position_size_calc 'v3' only. Fraction of the stop price a stop fill is assumed to miss by when computing the worst-case loss of a trade (0.01 = 1%).","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher counts more risk per open trade, leaving less available cash and smaller positions; lower counts less.","x-mangrove-status":"guardrail"},"stop_model":{"default":"atr_width_dial","description":"Which stop model the strategy uses: 'atr_width_dial' (one parameter, volatility_tolerance, positioned on the ATR width) or 'weighted_atr' (superseded: a weighted blend of two ATRs, capped). Pinned at creation and immutable.","enum":["atr_width_dial","weighted_atr",null],"type":["string","null"],"x-mangrove-effect":"Not a magnitude knob; selects the stop algorithm. Do not change on an existing strategy -- it would move every stop the strategy takes.","x-mangrove-status":"guardrail"},"taker_fee_rate":{"description":"position_size_calc 'v3' only. Venue fee per fill as a fraction of notional, charged in cash (0.004 = 0.4%).","exclusiveMaximum":0.1,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher counts more cost per fill, raising the risk of each trade and lowering available cash. Models the venue; not a strategy-character knob.","x-mangrove-status":"guardrail"},"target_asset_weight":{"description":"position_size_calc 'v3' only. Target share of core value held in the asset (0.8 = 80% asset, 20% cash; 0 = all cash).","exclusiveMaximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher holds more of the asset and less cash; lower holds more cash. The daily core order moves the split back to this value once it drifts past rebalance_band. At 0 with no asset held, no core order is placed and only buy trades can pass.","x-mangrove-status":"tunable"},"target_volatility":{"default":0.1,"description":"Target volatility (0.10 = 10%). ONLY active when enable_volatility_adjustment is true (default false). When active, scales position size down if ATR%% of entry exceeds the target (never up).","exclusiveMinimum":0.0,"maximum":1.0,"type":["number","null"],"x-mangrove-effect":"With the gate off (the default), changing this has no effect. With it on, lower scales positions down more aggressively in high volatility.","x-mangrove-gate-field":"enable_volatility_adjustment","x-mangrove-gate-required":true,"x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"gated"},"volatility_mode":{"default":"stddev","description":"Unused (retained for backward compatibility). Volatility is derived from ATR.","enum":["stddev","atr",null],"type":["string","null"],"x-mangrove-effect":"No runtime effect. Do not tune.","x-mangrove-status":"unused"},"volatility_tolerance":{"default":0.5,"description":"Where on the ATR width the stop is taken, as the ATR_long-vs-ATR_short contribution ratio: 0 is all short end (0.5x the signal timeframe's ATR), 1 is all long end (2x the daily ATR). Interpolated geometrically, so the value is exactly the long end's share of log(stop) and each 0.1 is the same multiplicative step. Replaces atr_short_weight, atr_long_weight and atr_cap_multiplier.","maximum":1.0,"minimum":0.0,"type":["number","null"],"x-mangrove-effect":"Higher widens the stop, and because position size is the risk budget divided by the stop distance, exposure shrinks in exact inverse proportion at the SAME risk. Low means many units with little room to be wrong and frequent stop-outs; high means few units that are hard to shake out but need a much larger move to reach the same reward. Both risk max_risk_per_trade.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"tunable"},"volatility_window":{"default":24,"description":"Unused (retained for backward compatibility). ATR windowing is controlled by atr_period.","maximum":1000,"minimum":1,"type":["integer","null"],"x-mangrove-effect":"No runtime effect. Do not tune.","x-mangrove-input-coercion":"Top-level validate_execution_config accepts finite numeric strings; integer fields require whole values. Version-specific checks remain separate.","x-mangrove-status":"unused"}},"title":"Execution configuration","type":"object","x-mangrove-boundary-validation":"top-level numeric bounds after legacy coercion; null means unset"}},"entry_signals":{"description":"The signals that open a position. Exactly one must be a TRIGGER in the knowledge graph; the rest are FILTERs.","items":{"additionalProperties":false,"properties":{"name":{"description":"The signal's name, exactly as the knowledge graph has it.","type":"string"},"params":{"description":"Its parameters and the value chosen for each, keyed by parameter name -- the shape `query_knowledge op=get` shows them in. A parameter left out takes the signal's own default, which is a choice nobody made. A name the signal does not take, or a value outside its declared range, is refused.","type":"object"},"timeframe":{"description":"The candle size this signal runs on.","enum":["5m","15m","30m","1h","4h","1D"],"type":"string"}},"required":["name","timeframe"],"type":"object"},"type":"array"},"exit_signals":{"description":"The signals that close one, same shape. A strategy may have none, and then it exits on risk rules alone.","items":{"additionalProperties":false,"properties":{"name":{"description":"The signal's name, exactly as the knowledge graph has it.","type":"string"},"params":{"description":"Its parameters and the value chosen for each, keyed by parameter name -- the shape `query_knowledge op=get` shows them in. A parameter left out takes the signal's own default, which is a choice nobody made. A name the signal does not take, or a value outside its declared range, is refused.","type":"object"},"timeframe":{"description":"The candle size this signal runs on.","enum":["5m","15m","30m","1h","4h","1D"],"type":"string"}},"required":["name","timeframe"],"type":"object"},"type":"array"},"regime_direction":{"description":"The direction band from get_market_regime, e.g. bear. The signal searches filter by it and find_sweep_runs marks each row's regime_fit with it; save_strategy and update_strategy read the current band themselves, so their check runs without it.","type":"string"},"regime_override":{"default":false,"description":"Save anyway when the regime check refuses. Only ever on the person's explicit say-so, after they have been told why.","type":"boolean"},"strategy_id":{"description":"The strategy's UUID.","type":"string"},"strategy_name":{"description":"What to call it, in plain words a person reads -- the entry trigger's friendly_name from the knowledge graph, then the asset and timeframe, e.g. \"Upside Range Breakout - BTC 1h\". Never a code name such as btc_strategy or bb_upper_breakout.","type":"string"}},"required":["strategy_id"],"type":"object"},"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/strategy-workflow/verify_strategy":{"post":{"operationId":"api1_post_verify_strategy_operation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Post verify strategy operation","tags":["strategy-workflow"],"x-mangrove-request-schema":{"additionalProperties":false,"properties":{"strategy_id":{"description":"The strategy's UUID.","type":"string"}},"required":["strategy_id"],"type":"object"},"x-payment-info":{"price":{"amount":"0.005000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v1/subscriptions/all-status":{"get":{"description":"Returns the user's personal subscription plus any org subscriptions\nfor organizations the user belongs to (excluding the default org).","operationId":"api1_get_all_subscription_status","responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Get user-level subscription and all org-level subscriptions","tags":["subscriptions"]}},"/api/v1/subscriptions/checkout":{"post":{"description":"Default org users: upgrades their personal (user-level) subscription.\nAny authenticated user can upgrade their own subscription.\n\nPersonal org users: upgrades the org subscription.\nRequires SUBSCRIPTION_MANAGE (owner only).","operationId":"api1_create_checkout_session","responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Create a Stripe Checkout session for upgrading subscription","tags":["subscriptions"]}},"/api/v1/subscriptions/org-status":{"get":{"description":"For default org users: returns user-level subscription with billing info.\nFor personal org users: returns org-level subscription with billing info.","operationId":"api1_get_org_subscription_status","responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Get detailed subscription status including billing info","tags":["subscriptions"]}},"/api/v1/subscriptions/portal":{"post":{"description":"Default org users: opens portal for their personal subscription.\nPersonal org users: opens portal for org subscription (owner only).\n\nAccepts optional 'scope' in request body ('user' or 'org') to\nexplicitly target a subscription. If scope='user', always opens\nthe user-level portal regardless of current org context.","operationId":"api1_create_portal_session","responses":{"200":{"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Create a Stripe Customer Portal session for billing management","tags":["subscriptions"]}},"/api/v1/subscriptions/status":{"get":{"description":"Returns org-level subscription if the user is in a non-default org\nwith an active org subscription. Otherwise returns user-level.","operationId":"api1_get_subscription_status","parameters":[{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.SubscriptionStatus"}}},"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Get subscription status and usage for the current context","tags":["subscriptions"]}},"/api/v1/subscriptions/tiers":{"get":{"operationId":"api1_get_subscription_tiers","responses":{"200":{"description":"Success"}},"security":[],"summary":"Get all active subscription tier definitions","tags":["subscriptions"]}},"/api/v1/subscriptions/utilization":{"get":{"description":"Returns org-level utilization if the user is in a non-default org\nwith an active org subscription. Otherwise returns user-level.","operationId":"api1_get_resource_utilization","parameters":[{"description":"An optional fields mask","in":"header","name":"X-Fields","schema":{"format":"mask","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.ResourceUtilization"}}},"description":"Success"}},"security":[{"MangroveBearer":[]}],"summary":"Get resource utilization for the current context","tags":["subscriptions"]}},"/api/v1/users/me/backtests":{"get":{"description":"Get my backtests with filters","operationId":"api1_get_my_backtests","parameters":[{"description":"Filter by status (pending/running/completed/failed)","in":"query","name":"status","schema":{"type":"string"}},{"description":"Filter by asset symbol","in":"query","name":"asset","schema":{"type":"string"}},{"description":"Filter from date (ISO format)","in":"query","name":"date_from","schema":{"type":"string"}},{"description":"Filter to date (ISO format)","in":"query","name":"date_to","schema":{"type":"string"}},{"description":"Page size (default 50)","in":"query","name":"limit","schema":{"type":"integer"}},{"description":"Page offset (default 0)","in":"query","name":"offset","schema":{"type":"integer"}},{"description":"Include archived runs (default false). Backtests are never deleted; archived runs are hidden by default.","in":"query","name":"include_archived","schema":{"type":"boolean"}},{"description":"Scope results to a specific chat session (used by the RecentBacktests card to paginate without leaving the session). Omit for full history.","in":"query","name":"session_id","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.BacktestsResponse"}}},"description":"Success"},"401":{"description":"Unauthorized"},"500":{"description":"Internal server error"}},"security":[{"MangroveBearer":[]}],"summary":"Get my backtests with filters","tags":["users"]}},"/api/v1/users/me/metrics":{"get":{"description":"Get my usage metrics","operationId":"api1_get_my_metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.MetricsResponse"}}},"description":"Success"},"401":{"description":"Unauthorized"},"500":{"description":"Internal server error"}},"security":[{"MangroveBearer":[]}],"summary":"Get my usage metrics (conversations, messages, tokens, etc)","tags":["users"]}},"/api/v1/users/me/strategies":{"get":{"description":"Get my strategies with search and filters","operationId":"api1_get_my_strategies","parameters":[{"description":"Search by name or asset","in":"query","name":"search","schema":{"type":"string"}},{"description":"Filter by status (active/inactive)","in":"query","name":"status","schema":{"type":"string"}},{"description":"Page size (default 50)","in":"query","name":"limit","schema":{"type":"integer"}},{"description":"Page offset (default 0)","in":"query","name":"offset","schema":{"type":"integer"}},{"description":"Include archived strategies (default false). Strategies are never deleted; archived ones are hidden by default.","in":"query","name":"include_archived","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api1.StrategiesResponse"}}},"description":"Success"},"401":{"description":"Unauthorized"},"500":{"description":"Internal server error"}},"security":[{"MangroveBearer":[]}],"summary":"Get my strategies with search and filters","tags":["users"]}},"/api/v2/agent/conversations":{"get":{"operationId":"api2_get_conversations","responses":{"200":{"description":"Conversations listed"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"List this caller's conversations","tags":["agent"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}},"post":{"operationId":"api2_post_conversations","responses":{"201":{"description":"Conversation created"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api2.Error"}}},"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Start a conversation","tags":["agent"],"x-payment-info":{"price":{"amount":"0.010000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v2/agent/conversations/latest":{"get":{"operationId":"api2_get_latest_conversation","responses":{"200":{"description":"Conversation retrieved"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api2.Error"}}},"description":"No conversation yet"}},"security":[{"MangroveBearer":[]},{}],"summary":"The most recent conversation this caller started","tags":["agent"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v2/agent/conversations/{session_id}":{"delete":{"operationId":"api2_delete_conversation","parameters":[{"in":"path","name":"session_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Conversation deleted"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Delete a conversation","tags":["agent"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}},"get":{"operationId":"api2_get_conversation","parameters":[{"in":"path","name":"session_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Conversation retrieved"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api2.Error"}}},"description":"No such conversation"}},"security":[{"MangroveBearer":[]},{}],"summary":"One conversation, with its messages","tags":["agent"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v2/agent/conversations/{session_id}/executions":{"post":{"description":"This distinct URL fails closed on older deployments that do not forward\ndelegated proposal controls. Status and Stop remain independently callable.","operationId":"api2_post_executions","parameters":[{"in":"path","name":"session_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Durable worker request: hold the HTTP request until the execution ends","tags":["agent"],"x-payment-info":{"price":{"amount":"0.100000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v2/agent/conversations/{session_id}/messages":{"post":{"description":"The turn runs on this request rather than a background thread, so the request is\nin flight for as long as the work is and the autoscaler counts it.","operationId":"api2_post_messages","parameters":[{"in":"path","name":"session_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api2.AgentChatRequest"}}},"required":true},"responses":{"200":{"description":"The turn ran and this is its reply"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api2.Error"}}},"description":"Validation error"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api2.Error"}}},"description":"Usage limit reached"}},"security":[{"MangroveBearer":[]},{}],"summary":"Send a message and get the reply","tags":["agent"],"x-payment-info":{"price":{"amount":"0.100000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v2/agent/conversations/{session_id}/rename":{"patch":{"operationId":"api2_patch_rename_conversation","parameters":[{"in":"path","name":"session_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Conversation renamed"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api2.Error"}}},"description":"Validation error"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}}},"security":[{"MangroveBearer":[]},{}],"summary":"Rename a conversation","tags":["agent"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v2/backtests/":{"post":{"description":"Identical request body to POST /api/v1/backtesting/backtest.\nUse GET /api/v2/backtests/<backtest_id>/status to poll for results.\n\nReturns 503 when the backtest thread pool is saturated (retry later).\nThe caller should apply exponential backoff and retry.","operationId":"api2_post_async_backtest_submit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api2.BacktestRequest"}}},"required":true},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api2.AsyncBacktestSubmitResponse"}}},"description":"Backtest accepted and running"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api2.Error"}}},"description":"Validation error"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api2.Error"}}},"description":"Backtest pool full \u2014 retry later"}},"security":[{"MangroveBearer":[]},{}],"summary":"Submit an async backtest \u2014 returns 202 immediately","tags":["backtests"],"x-payment-info":{"price":{"amount":"0.100000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}},"/api/v2/backtests/{backtest_id}/status":{"get":{"description":"Returns the current status of a backtest submitted via\nPOST /api/v2/backtests/.\n\nStatus values:\n- \"running\"   -- simulation in progress; poll again\n- \"completed\" -- metrics and trade_history are populated\n- \"failed\"    -- error_message is populated","operationId":"api2_get_async_backtest_status","parameters":[{"in":"path","name":"backtest_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api2.AsyncBacktestStatusResponse"}}},"description":"Backtest status"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Payment Required","headers":{"PAYMENT-REQUIRED":{"description":"The x402 v2 challenge as base64 JSON; the same JSON is the response body.","schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api2.Error"}}},"description":"Backtest not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/api2.Error"}}},"description":"Internal server error"}},"security":[{"MangroveBearer":[]},{}],"summary":"Poll async backtest status and results","tags":["backtests"],"x-payment-info":{"price":{"amount":"0.001000","currency":"USD","mode":"fixed"},"protocols":[{"x402":{"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","payTo":"0xDA913CF1D855A40560e39a1a2e0387a5f3117A2e","scheme":"exact","x402Version":2}}]}}}},"servers":[{"url":"https://api.mangrovedeveloper.ai"}],"x-mangrove-related-contracts":[{"openapi":"3.1.0","surface":"Oracle proxy","url":"https://mangrovedeveloper.ai/openapi-oracle.json"}]}
