{"openapi":"3.1.0","info":{"title":"CrashTestYourStrategy API","description":"Monte Carlo robustness testing for trading strategies","version":"1.0.0"},"paths":{"/api/v1/backtest/examples":{"get":{"tags":["Backtest"],"summary":"Get Example Strategies","description":"Get list of pre-defined example strategies for quick testing.","operationId":"get_example_strategies_api_v1_backtest_examples_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/backtest/robustness/quick":{"post":{"tags":["Backtest"],"summary":"Run Quick Robustness","description":"Run a quick robustness check with inline strategy.\n\nThis is the main endpoint for the Landing page.\nReturns full robustness data for inline display.","operationId":"run_quick_robustness_api_v1_backtest_robustness_quick_post","parameters":[{"name":"user_id","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuickRobustnessRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/backtest/cases":{"post":{"tags":["Backtest"],"summary":"Run Adhoc Cases","description":"Run a strategy against the curated case-study set for one asset.\n\nCompanion endpoint to /robustness/quick: while /quick produces the\nLayer-2 regime-ensemble robustness score (synthetic), this endpoint\nproduces the Layer-1 + Layer-3 case studies (empirical anchors plus\ntargeted synthetic stress probes).\n\nDesigned for parallel-call from the mainpage so that score and cases\narrive independently. Synthetic cases without pre-computed replicas\n(e.g. WHIPSAW pending) are skipped and reflected in n_skipped.\n\nArgs:\n    replica_limit: optional cap on synthetic replicas per case (default: 50,\n                   i.e. full cache). Set e.g. 30 for faster Mainpage runs.","operationId":"run_adhoc_cases_api_v1_backtest_cases_post","parameters":[{"name":"user_id","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"User Id"}},{"name":"replica_limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Replica Limit"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdhocCasesRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/backtest/robustness/quick/share":{"post":{"tags":["Backtest"],"summary":"Share Quick Robustness","description":"Create a shareable public report from quick robustness results.","operationId":"share_quick_robustness_api_v1_backtest_robustness_quick_share_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuickShareRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/backtest/robustness/public/{share_hash}":{"get":{"tags":["Backtest"],"summary":"Get Public Report","description":"Fetch public report data using its unique hash.","operationId":"get_public_report_api_v1_backtest_robustness_public__share_hash__get","parameters":[{"name":"share_hash","in":"path","required":true,"schema":{"type":"string","title":"Share Hash"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicReportResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/backtest/robustness/optimize":{"post":{"tags":["Backtest"],"summary":"Optimize Parameters","description":"Run parameter optimization sweep to find better strategy configurations.\nPRO feature - uses adaptive random search with Latin Hypercube sampling.\nDisabled during Beta.","operationId":"optimize_parameters_api_v1_backtest_robustness_optimize_post","parameters":[{"name":"user_id","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParameterOptimizeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParameterOptimizeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/backtest/indicators":{"get":{"tags":["Backtest"],"summary":"List Indicators","description":"List all available technical indicators.","operationId":"list_indicators_api_v1_backtest_indicators_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/backtest/indicators/{name}":{"get":{"tags":["Backtest"],"summary":"Get Indicator Info","description":"Get detailed information about a specific indicator.","operationId":"get_indicator_info_api_v1_backtest_indicators__name__get","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/backtest/indicators/category/{category}":{"get":{"tags":["Backtest"],"summary":"List Indicators By Category","description":"List all indicators in a specific category.","operationId":"list_indicators_by_category_api_v1_backtest_indicators_category__category__get","parameters":[{"name":"category","in":"path","required":true,"schema":{"type":"string","title":"Category"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/backtest/config/assets":{"get":{"tags":["Backtest"],"summary":"Get Tradeable Assets","description":"Get list of tradeable assets available for testing.","operationId":"get_tradeable_assets_api_v1_backtest_config_assets_get","parameters":[{"name":"tier","in":"query","required":false,"schema":{"type":"string","default":"free","title":"Tier"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/backtest/config/timeframes":{"get":{"tags":["Backtest"],"summary":"Get Available Timeframes","description":"Get list of available timeframes for backtesting.","operationId":"get_available_timeframes_api_v1_backtest_config_timeframes_get","parameters":[{"name":"tier","in":"query","required":false,"schema":{"type":"string","default":"free","title":"Tier"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/backtest/config/asset/{symbol}":{"get":{"tags":["Backtest"],"summary":"Get Asset Details","description":"Get detailed information about a specific asset.","operationId":"get_asset_details_api_v1_backtest_config_asset__symbol__get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/nl/parse":{"post":{"tags":["Natural Language"],"summary":"Parse Natural Language","description":"Parse natural language strategy description into structured strategy JSON.","operationId":"parse_natural_language_api_v1_nl_parse_post","parameters":[{"name":"user_id","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NLParseRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NLParseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/nl/explain":{"post":{"tags":["Natural Language"],"summary":"Explain Strategy","description":"Generate a natural language explanation of a strategy.","operationId":"explain_strategy_api_v1_nl_explain_post","parameters":[{"name":"user_id","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StrategyExplainRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/nl/examples":{"get":{"tags":["Natural Language"],"summary":"Get Strategy Examples","description":"Get example natural language strategy descriptions.","operationId":"get_strategy_examples_api_v1_nl_examples_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/nl/validate":{"post":{"tags":["Natural Language"],"summary":"Validate Strategy Text","description":"Validate that a natural language description can be parsed.","operationId":"validate_strategy_text_api_v1_nl_validate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NLParseRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/nl/retry/{retry_token}":{"post":{"tags":["Natural Language"],"summary":"Retry Parse","description":"Retry a previously failed parse using a retry token.\nDoes NOT count against daily credits — the user already 'spent' their attempt.","operationId":"retry_parse_api_v1_nl_retry__retry_token__post","parameters":[{"name":"retry_token","in":"path","required":true,"schema":{"type":"string","title":"Retry Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NLParseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/feedback/request":{"post":{"tags":["Feedback"],"summary":"Create Feature Request","description":"Log a feature request with minimal friction.\n\n- Captures revealed preference (what users actually want)\n- Soft rate-limiting: first vote per session = primary, subsequent = secondary\n- Optional email for notification when feature ships","operationId":"create_feature_request_api_v1_feedback_request_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureRequestCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureRequestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/feedback/stats":{"get":{"tags":["Feedback"],"summary":"Get Feature Stats","description":"Get aggregated statistics for all feature requests.\n\nUseful for product decisions and prioritization.","operationId":"get_feature_stats_api_v1_feedback_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureRequestStats"}}}}}}},"/api/v1/feedback/vote-count/{feature}":{"get":{"tags":["Feedback"],"summary":"Get Vote Count","description":"Get vote count for a specific feature.\n\nUsed by frontend to show \"X others want this\" without full stats.","operationId":"get_vote_count_api_v1_feedback_vote_count__feature__get","parameters":[{"name":"feature","in":"path","required":true,"schema":{"type":"string","title":"Feature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/strategies/":{"get":{"tags":["Strategy Catalog"],"summary":"List Strategies","description":"List all pre-defined strategies in the catalog.\nReturns slug, name, description, tags, asset, and whether cached results exist.","operationId":"list_strategies_api_v1_strategies__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/strategies/{slug}":{"get":{"tags":["Strategy Catalog"],"summary":"Get Strategy Result","description":"Get pre-computed robustness results for a strategy.\nReturns the full simulation data if cached, or strategy definition if not yet computed.","operationId":"get_strategy_result_api_v1_strategies__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"summary","in":"query","required":false,"schema":{"type":"boolean","description":"Omit the per-scenario equity curves (`examples`, `examples_per_regime`). Shrinks a typical report from ~930 KB to ~15 KB while keeping the robustness score, distributions, score_breakdown and case_breakdown.","default":false,"title":"Summary"},"description":"Omit the per-scenario equity curves (`examples`, `examples_per_regime`). Shrinks a typical report from ~930 KB to ~15 KB while keeping the robustness score, distributions, score_breakdown and case_breakdown."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/strategies/{slug}/cases":{"get":{"tags":["Strategy Catalog"],"summary":"Get Strategy Case Results","description":"Run the strategy against all curated case studies for an asset.\n\nEach case is a kuratierter empirischer Marktslice (real OHLC) oder eine\nsynthetische Fallstudie (50 Replicas via SME-Simulator). Returns:\n  - per-case Strategy vs. Buy-and-Hold metrics\n  - equity curves (single for empirical, median+p25/p75 for synthetic)\n  - headline aggregations (best/worst/median across cases)\n\nSynthetic cases without pre-computed replicas (Phase D pending) are skipped\nand reflected in n_skipped.","operationId":"get_strategy_case_results_api_v1_strategies__slug__cases_get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"asset","in":"query","required":false,"schema":{"type":"string","default":"SPY","title":"Asset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/strategies/{slug}/cases/{asset}/{case_id}":{"get":{"tags":["Strategy Catalog"],"summary":"Get Strategy Case Detail","description":"Return a single case-study result. Convenience wrapper around the\n/cases endpoint that filters down to one case_id.\n\nPowers AI-queryable URLs like:\n  /api/v1/strategies/sma-200-crossover/cases/spy/spy_lehman_2008","operationId":"get_strategy_case_detail_api_v1_strategies__slug__cases__asset___case_id__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"asset","in":"path","required":true,"schema":{"type":"string","title":"Asset"}},{"name":"case_id","in":"path","required":true,"schema":{"type":"string","title":"Case Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/strategies/case-assets/list":{"get":{"tags":["Strategy Catalog"],"summary":"List Case Assets","description":"List all assets with at least one defined case study.","operationId":"list_case_assets_api_v1_strategies_case_assets_list_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/agent/analyze":{"post":{"tags":["Agent API"],"summary":"Analyse a strategy and return machine-readable robustness semantics.","description":"Accepts either a natural-language description (`input_type=natural_language`) or a canonical strategy JSON (`input_type=strategy_json`). Parses (if NL), runs the robustness backtest across the curated case set, and returns agent-optimized structured semantics: per-regime behavior labels, top failure modes with impact-type ontology, evaluation confidence, and methodological limitations. Output is descriptive, not advisory. Schema family `ctys-agent`, current version `ctys-agent-v1`.","operationId":"analyze_api_v1_agent_analyze_post","requestBody":{"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/AnalyzeNLRequest"},{"$ref":"#/components/schemas/AnalyzeJSONRequest"}],"title":"Request","discriminator":{"propertyName":"input_type","mapping":{"natural_language":"#/components/schemas/AnalyzeNLRequest","strategy_json":"#/components/schemas/AnalyzeJSONRequest"}}}}},"required":true},"responses":{"200":{"description":"Successful robustness analysis with structured agent-optimized output.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentAnalyzeResponse"},"example":{"robustness_score":53.2,"robustness_class":"moderate","evaluation_confidence":{"level":"moderate","classified_ratio":0.592,"sparse_bucket_count":5,"augmented_replicas_total":305,"rationale":"59% of replicas classified ex-post; 5 bucket(s) augmented from a-priori tags."},"summary":"Robustness 53/100 (moderate). Strong in TREND_UP, SLOW_BEAR. Weak in LIQUIDITY_STRESS, SHARP_CRASH.","interpretation_text":"Returns vary substantially across the curated regimes — the model shows very different outcomes in bull versus bear and stress scenarios.","headline_metrics":{"median_return":0.05,"p5_return":-0.541,"wcdd_95":0.57,"median_drawdown":0.193,"failure_rate_pct":12.0,"n_replicas":255,"asset":"BTC"},"per_regime":[{"regime":"TREND_UP","label":"persistent directional uptrend","behavior":"stable","score":81.6,"n_replicas":39,"shrinkage_alpha":1.0,"n_augmented":0},{"regime":"LIQUIDITY_STRESS","label":"sustained high vol + deep drawdown + persistence","behavior":"degrading","score":37.0,"n_replicas":52,"shrinkage_alpha":1.0,"n_augmented":52}],"top_failure_modes":[{"mode":"LIQUIDITY_STRESS","severity":"high","impact_type":"drawdown_expansion","expected_behavior":"drawdowns deeper than the pool baseline in these scenarios","bucket_score":37.0,"delta_from_pool":-16.3}],"top_failure_modes_status":"present","regime_class_summary":{"trend_regimes":{"avg_score":73.7,"behavior":"stable","buckets":["TREND_UP","TREND_DOWN","SLOW_BEAR"]},"tail_event_regimes":{"avg_score":44.0,"behavior":"degrading","buckets":["SHARP_CRASH","LIQUIDITY_STRESS"]}},"caveats":["Scenario-simulation across 63 curated cases (31 empirical + 32 synthetic), not predictions.","BaFin/WpHG framing: descriptive output, not investment advice or suitability assessment.","Per-FM-bucket scores use a-priori augmentation when ex-post classification is sparse (Phase 18d)."],"methodological_limitations":["Synthetic stress probes are not probabilistic forecasts; they impose conditions on an agent-based simulator.","Intraday liquidity and execution slippage simplified to a single per-bar assumption.","WCDD₉₅ reports the 95th-percentile across the curated case set, not a true out-of-sample tail estimate."],"report_url":"https://crashtestyourstrategy.com/r/H0Qc46MTgm9_R2_w","methodology_url":"https://crashtestyourstrategy.com/methodology","schema_family":"ctys-agent","schema_version":"ctys-agent-v1","generated_utc":"2026-05-15T14:32:11.123456+00:00"}}}},"400":{"description":"Parse failed (natural-language input couldn't be reliably parsed).","content":{"application/json":{"example":{"detail":{"error":"parse_failed","message":"Could not reliably parse the strategy description.","confidence":0.12,"parse_status":"failed","suggestion":"Try: 'Buy when RSI < 30, sell when RSI > 70, 5% stop loss'"}}}}},"422":{"description":"Canonical strategy_json is missing required fields. Deliberately strict — garbage-shape inputs are rejected here rather than silently producing an inactive-fallback score that could be misread as a real result.","content":{"application/json":{"example":{"detail":{"error":"invalid_strategy_json","message":"strategy_json is missing required fields.","errors":[{"field":"strategy.entry_conditions","problem":"missing or empty","expected":"non-empty list of condition objects"},{"field":"strategy.direction","problem":"invalid or missing","expected":"long_only | short_only | both"}],"documentation_url":"https://crashtestyourstrategy.com/interop"}}}}},"429":{"description":"Rate limit exceeded — see /interop for tier limits.","content":{"application/json":{"example":{"detail":"Rate limit exceeded for tier 'agent'. Max 600 requests per 60s. Try again later."}}}}}}},"/api/v1/catalog/query":{"get":{"tags":["Catalog Search"],"summary":"Semantic search across the pre-computed strategy catalog.","description":"Filter the 13 pre-computed strategy reports by indicator, asset, failure-mode coverage, regime class, or robustness class. All filters are AND-combined. Used by agents to discover relevant prior reports without having to enumerate /s/{slug} manually. Schema family `ctys-agent`, current version `ctys-catalog-v1`.","operationId":"query_api_v1_catalog_query_get","parameters":[{"name":"indicator","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Indicator name (e.g. RSI, MACD, SMA, EMA, BB).","title":"Indicator"},"description":"Indicator name (e.g. RSI, MACD, SMA, EMA, BB)."},{"name":"asset","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Asset symbol (SPY/BTC/GOLD/...).","title":"Asset"},"description":"Asset symbol (SPY/BTC/GOLD/...)."},{"name":"failure_mode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"FM-bucket key (e.g. SHARP_CRASH, TREND_UP).","title":"Failure Mode"},"description":"FM-bucket key (e.g. SHARP_CRASH, TREND_UP)."},{"name":"regime_class","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Regime class (trend_regimes / volatility_regimes / mean_reverting_regimes / tail_event_regimes).","title":"Regime Class"},"description":"Regime class (trend_regimes / volatility_regimes / mean_reverting_regimes / tail_event_regimes)."},{"name":"robustness_class","in":"query","required":false,"schema":{"anyOf":[{"enum":["fragile","moderate","robust"],"type":"string"},{"type":"null"}],"description":"fragile | moderate | robust.","title":"Robustness Class"},"description":"fragile | moderate | robust."},{"name":"min_score","in":"query","required":false,"schema":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"description":"Minimum robustness score.","title":"Min Score"},"description":"Minimum robustness score."},{"name":"max_score","in":"query","required":false,"schema":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"description":"Maximum robustness score.","title":"Max Score"},"description":"Maximum robustness score."},{"name":"sort_by_bucket","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Sort by per-FM-bucket score instead of overall robustness score. Value: FM termCode (e.g. LIQUIDITY_STRESS, SHARP_CRASH, TREND_UP). When set, each match's `bucket_scores` field is populated with the relevant bucket score. Useful for answering 'which strategies fail hardest in X regime?' — use direction=asc.","examples":["LIQUIDITY_STRESS"],"title":"Sort By Bucket"},"description":"Sort by per-FM-bucket score instead of overall robustness score. Value: FM termCode (e.g. LIQUIDITY_STRESS, SHARP_CRASH, TREND_UP). When set, each match's `bucket_scores` field is populated with the relevant bucket score. Useful for answering 'which strategies fail hardest in X regime?' — use direction=asc."},{"name":"sort_direction","in":"query","required":false,"schema":{"type":"string","pattern":"^(asc|desc)$","description":"Sort direction: 'desc' (best first, default) or 'asc' (worst first).","examples":["asc"],"default":"desc","title":"Sort Direction"},"description":"Sort direction: 'desc' (best first, default) or 'asc' (worst first)."}],"responses":{"200":{"description":"Matching catalog strategies sorted by score desc.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatalogQueryResponse"},"example":{"matches":[{"slug":"rsi-30-70-btc","name":"RSI 30/70 Mean Reversion (BTC)","robustness_score":50.6,"robustness_class":"moderate","fragility_grade":"moderate","asset":"BTC","indicators":["RSI"],"failure_modes_covered":["LIQUIDITY_STRESS","SHARP_CRASH","SIDEWAYS","SLOW_BEAR","TREND_DOWN","TREND_UP","VOL_COMPRESSION","VOL_EXPANSION","WHIPSAW"],"report_url":"https://crashtestyourstrategy.com/s/rsi-30-70-btc","api_url":"https://crashtestyourstrategy.com/api/v1/strategies/rsi-30-70-btc","description":"Buy when RSI(14) drops below 30 (oversold). Sell when RSI(14) rises above 70 (overbought)."}],"total":1,"query_echo":{"indicator":"RSI","asset":"BTC"},"schema_family":"ctys-agent","schema_version":"ctys-catalog-v1"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/contact/submit":{"post":{"tags":["Contact"],"summary":"Submit Contact","description":"Accept an open contact / commission inquiry: store it + best-effort notify the operator.\nDescriptive intake only — no computation is triggered.","operationId":"submit_contact_api_v1_contact_submit_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactMessageCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactMessageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"summary":"Health Check","operationId":"health_check_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/account/tier":{"get":{"summary":"Get Tier Info","description":"Get current tier information (free tier for unauthenticated users).","operationId":"get_tier_info_api_v1_account_tier_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"AdhocCasesRequest":{"properties":{"strategyJson":{"type":"object","title":"Strategyjson"},"asset":{"type":"string","title":"Asset","default":"SPY"}},"additionalProperties":false,"type":"object","required":["strategyJson"],"title":"AdhocCasesRequest","description":"Request body for ad-hoc case-study run with inline strategy."},"AgentAnalyzeResponse":{"properties":{"robustness_score":{"type":"number","maximum":100.0,"minimum":0.0,"title":"Robustness Score","description":"V2 composite robustness score on the 0..100 scale. Equal-weight mean across populated FM-buckets with shrinkage. Higher = more uniform behaviour across the curated regimes.","examples":[53.2]},"robustness_class":{"type":"string","enum":["fragile","moderate","robust"],"title":"Robustness Class","description":"Monotonic class derived from robustness_score. 'fragile' (<50) | 'moderate' (50–70) | 'robust' (≥70).","examples":["moderate"]},"evaluation_confidence":{"allOf":[{"$ref":"#/components/schemas/EvaluationConfidence"}],"description":"Epistemic uncertainty of the evaluation itself — agent should weight conclusions accordingly."},"summary":{"type":"string","title":"Summary","description":"Short deterministic machine-friendly summary (≤200 chars). Names the score, class, strongest and weakest regimes. Use for one-line citations.","examples":["Robustness 53/100 (moderate). Strong in TREND_UP, SLOW_BEAR. Weak in LIQUIDITY_STRESS, SHARP_CRASH."]},"interpretation_text":{"type":"string","title":"Interpretation Text","description":"Longer narrative, LLM-citable. Use for human-readable answers / generated reports / agent reasoning chains. Descriptive, not advisory.","examples":["Returns vary substantially across the curated regimes — the model shows very different outcomes in bull versus bear and stress scenarios."]},"headline_metrics":{"allOf":[{"$ref":"#/components/schemas/HeadlineMetrics"}],"description":"Single-asset quantitative summary: median/p5 returns, WCDD, failure rate."},"per_regime":{"items":{"$ref":"#/components/schemas/PerRegimeEntry"},"type":"array","title":"Per Regime","description":"One entry per populated FM-bucket. Sorted by score descending (strengths first)."},"top_failure_modes":{"items":{"$ref":"#/components/schemas/TopFailureMode"},"type":"array","title":"Top Failure Modes","description":"Up to 3 weakest buckets where bucket_score < pool_score. May be empty — check top_failure_modes_status for the reason."},"top_failure_modes_status":{"type":"string","enum":["present","no_underperforming_buckets","barely_active"],"title":"Top Failure Modes Status","description":"Disambiguates an empty top_failure_modes list. 'present' — list contains entries. 'no_underperforming_buckets' — every FM-bucket score is at or above the overall pool baseline; no regime-specific weakness identified. 'barely_active' — strategy rarely takes positions or holds minimal exposure across cases, so bucket scores are uniform and not informative. An empty list does NOT mean 'no risk'.","examples":["present"]},"regime_class_summary":{"additionalProperties":{"$ref":"#/components/schemas/RegimeClassEntry"},"type":"object","title":"Regime Class Summary","description":"Aggregation into 4 regime classes: trend_regimes | mean_reverting_regimes | volatility_regimes | tail_event_regimes. Descriptive only — does NOT imply suitability or recommendation for any regime."},"caveats":{"items":{"type":"string"},"type":"array","title":"Caveats","description":"Inline trust caveats — always include the BaFin/WpHG framing and the curated-case-set qualifier.","examples":[["Scenario-simulation across 63 curated cases (31 empirical + 32 synthetic), not predictions.","BaFin/WpHG framing: descriptive output, not investment advice or suitability assessment.","Per-FM-bucket scores use a-priori augmentation when ex-post classification is sparse (Phase 18d)."]]},"methodological_limitations":{"items":{"type":"string"},"type":"array","title":"Methodological Limitations","description":"Explicit model boundaries — agents should not infer beyond these.","examples":[["Synthetic stress probes are not probabilistic forecasts.","Intraday liquidity and execution slippage simplified to a single per-bar assumption.","WCDD₉₅ is descriptive, not a true out-of-sample tail estimate."]]},"report_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Report Url","description":"Persistent citable URL. /s/{slug} when the input matched a catalog strategy; /r/{hash} for ad-hoc inputs (DB-persisted).","examples":["https://crashtestyourstrategy.com/r/H0Qc46MTgm9_R2_w"]},"methodology_url":{"type":"string","title":"Methodology Url","description":"Link to the full methodology page describing case catalog, simulator, and scoring architecture.","examples":["https://crashtestyourstrategy.com/methodology"]},"catalog_match_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Catalog Match Slug","description":"Slug of the matching catalog strategy if entry/exit conditions are an exact match. Null for ad-hoc inputs.","examples":["rsi-30-70-btc"]},"schema_family":{"type":"string","title":"Schema Family","description":"Schema family name. Stable across versions within the family.","default":"ctys-agent","examples":["ctys-agent"]},"schema_version":{"type":"string","title":"Schema Version","description":"Specific schema version within the family. Bump for breaking changes; additive changes keep this stable.","default":"ctys-agent-v1","examples":["ctys-agent-v1"]},"generated_utc":{"type":"string","title":"Generated Utc","description":"ISO-8601 UTC timestamp when the response was produced. Use for cache invalidation.","examples":["2026-05-15T14:32:11.123456+00:00"]}},"type":"object","required":["robustness_score","robustness_class","evaluation_confidence","summary","interpretation_text","headline_metrics","per_regime","top_failure_modes","top_failure_modes_status","regime_class_summary","caveats","methodological_limitations","methodology_url","generated_utc"],"title":"AgentAnalyzeResponse"},"AnalyzeJSONRequest":{"properties":{"input_type":{"const":"strategy_json","title":"Input Type","description":"Discriminator: skip the LLM parse step and use the provided canonical strategy JSON directly.","examples":["strategy_json"]},"strategy":{"type":"object","title":"Strategy","description":"Canonical strategy JSON, same shape as POST /api/v1/backtest/robustness/quick. Required fields: entry_conditions, exit_conditions, direction, position_sizing, position_size. Optional: stop_loss (percent), take_profit, max_positions.","examples":[{"direction":"long_only","entry_conditions":[{"indicator":"rsi_14","operator":"less_than","value":30}],"exit_conditions":[{"indicator":"rsi_14","operator":"greater_than","value":70}],"max_positions":1,"position_size":95,"position_sizing":"percent","stop_loss":5.0}]},"asset":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Asset","description":"Asset symbol: SPY | QQQ | BTC | ETH | GOLD | WTI | VIX. Defaults to SPY if absent.","examples":["SPY"]},"num_runs":{"type":"integer","maximum":100.0,"minimum":10.0,"title":"Num Runs","description":"Replicas per synthetic case (empirical anchors are always n=1). Higher = more stable but slower.","default":30,"examples":[30]}},"type":"object","required":["input_type","strategy"],"title":"AnalyzeJSONRequest","examples":[{"asset":"SPY","input_type":"strategy_json","num_runs":30,"strategy":{"direction":"long_only","entry_conditions":[{"indicator":"rsi_14","operator":"less_than","value":30}],"exit_conditions":[{"indicator":"rsi_14","operator":"greater_than","value":70}],"max_positions":1,"position_size":95,"position_sizing":"percent","stop_loss":5.0}}]},"AnalyzeNLRequest":{"properties":{"input_type":{"const":"natural_language","title":"Input Type","description":"Discriminator: tells the endpoint to LLM-parse `strategy_text` first.","examples":["natural_language"]},"strategy_text":{"type":"string","maxLength":4000,"minLength":4,"title":"Strategy Text","description":"Plain-English (or German) strategy description. The LLM parser converts this to canonical strategy JSON before the backtest. Be specific about entry/exit triggers, indicators, and stop levels — vague text reduces parse confidence.","examples":["Buy BTC when RSI(14) falls below 30, sell when RSI(14) rises above 70. Use a 5% stop loss."]},"asset":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Asset","description":"Asset symbol: SPY | QQQ | BTC | ETH | GOLD | WTI | VIX. If absent, inferred from the parsed strategy or defaults to SPY.","examples":["BTC"]},"num_runs":{"type":"integer","maximum":100.0,"minimum":10.0,"title":"Num Runs","description":"Replicas per synthetic case (empirical anchors are always n=1). Higher = more stable confidence but slower.","default":30,"examples":[30]}},"type":"object","required":["input_type","strategy_text"],"title":"AnalyzeNLRequest","examples":[{"asset":"BTC","input_type":"natural_language","num_runs":30,"strategy_text":"Buy BTC when RSI(14) falls below 30, sell when RSI(14) rises above 70. Use a 5% stop loss."}]},"CatalogMatch":{"properties":{"slug":{"type":"string","title":"Slug"},"name":{"type":"string","title":"Name","description":"Human-readable strategy name.","examples":["RSI 30/70 Mean Reversion (BTC)"]},"robustness_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Robustness Score","description":"V2 composite robustness score (0..100). Null if no cached result.","examples":[50.6]},"robustness_class":{"anyOf":[{"type":"string","enum":["fragile","moderate","robust"]},{"type":"null"}],"title":"Robustness Class","description":"Monotonic class: fragile (<50) | moderate (50–70) | robust (≥70).","examples":["moderate"]},"fragility_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fragility Grade","description":"Legacy fragility curve grade. Not directly comparable to robustness_class — see /interop.","examples":["moderate"]},"asset":{"type":"string","title":"Asset","description":"Asset symbol the strategy is scored on.","examples":["BTC"]},"indicators":{"items":{"type":"string"},"type":"array","title":"Indicators","description":"Indicator family names extracted from entry/exit conditions.","examples":[["RSI"]]},"failure_modes_covered":{"items":{"type":"string"},"type":"array","title":"Failure Modes Covered","description":"FM termCodes where this strategy was scored (subset of the 10-axis taxonomy).","examples":[["TREND_UP","TREND_DOWN","SLOW_BEAR","SHARP_CRASH","WHIPSAW","SIDEWAYS","LIQUIDITY_STRESS","VOL_EXPANSION","VOL_COMPRESSION"]]},"bucket_scores":{"anyOf":[{"additionalProperties":{"type":"number"},"type":"object"},{"type":"null"}],"title":"Bucket Scores","description":"Per-FM-bucket score (0..100). Only populated when sort_by_bucket is used; null otherwise to keep responses lean.","examples":[{"LIQUIDITY_STRESS":37.0,"SHARP_CRASH":45.8}]},"report_url":{"type":"string","title":"Report Url","description":"Human-readable strategy report URL (/s/{slug}).","examples":["https://crashtestyourstrategy.com/s/rsi-30-70-btc"]},"api_url":{"type":"string","title":"Api Url","description":"Machine-readable strategy report URL (full cached JSON).","examples":["https://crashtestyourstrategy.com/api/v1/strategies/rsi-30-70-btc"]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Short marketing-free description of the strategy.","examples":["Buy when RSI(14) drops below 30 (oversold). Sell when RSI(14) rises above 70 (overbought)."]}},"type":"object","required":["slug","name","asset","indicators","report_url","api_url"],"title":"CatalogMatch"},"CatalogQueryResponse":{"properties":{"matches":{"items":{"$ref":"#/components/schemas/CatalogMatch"},"type":"array","title":"Matches","description":"Strategies passing all AND-combined filters; sorted by score desc, slug asc."},"total":{"type":"integer","title":"Total","description":"Number of matches.","examples":[1]},"query_echo":{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"null"}]},"type":"object","title":"Query Echo","description":"Echo of the parsed filter parameters (after normalisation)."},"schema_family":{"type":"string","title":"Schema Family","description":"Schema family — stable across versions.","default":"ctys-agent","examples":["ctys-agent"]},"schema_version":{"type":"string","title":"Schema Version","description":"Schema version — bump for breaking changes.","default":"ctys-catalog-v1","examples":["ctys-catalog-v1"]}},"type":"object","required":["matches","total","query_echo"],"title":"CatalogQueryResponse"},"ContactMessageCreate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Name","description":"Optional name."},"email":{"type":"string","maxLength":255,"minLength":4,"title":"Email","description":"Contact email (required to reply)."},"message":{"type":"string","maxLength":4000,"minLength":10,"title":"Message","description":"Your inquiry."},"context":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Context","description":"Optional: which thesis/page prompted this."},"website":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Website"}},"type":"object","required":["email","message"],"title":"ContactMessageCreate","description":"An open contact / commission inquiry — the general 'work with me' channel. Descriptive\nintake only: nothing runs automatically; the operator reads it and replies by email."},"ContactMessageResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"}},"type":"object","required":["success","message"],"title":"ContactMessageResponse"},"EvaluationConfidence":{"properties":{"level":{"type":"string","enum":["low","moderate","high"],"title":"Level","description":"Coarse confidence label. high | moderate | low.","examples":["moderate"]},"classified_ratio":{"type":"number","title":"Classified Ratio","description":"Share (0..1) of replicas that met operational ex-post FM-classification gates without augmentation.","examples":[0.59]},"sparse_bucket_count":{"type":"integer","title":"Sparse Bucket Count","description":"Number of FM-buckets where ex-post classification produced < APRIORI_AUGMENT_THRESHOLD replicas and a-priori augmentation kicked in.","examples":[5]},"augmented_replicas_total":{"type":"integer","title":"Augmented Replicas Total","description":"Total replicas added via Phase 18d a-priori fallback across all sparse buckets.","examples":[305]},"rationale":{"type":"string","title":"Rationale","description":"Human-readable explanation of the confidence assignment — surfaces the dominant signal (low classification ratio, many sparse buckets, etc.).","examples":["59% of replicas classified ex-post; 5 bucket(s) augmented from a-priori tags."]}},"type":"object","required":["level","classified_ratio","sparse_bucket_count","augmented_replicas_total","rationale"],"title":"EvaluationConfidence"},"FeatureRequestCreate":{"properties":{"feature":{"type":"string","maxLength":50,"minLength":1,"title":"Feature"},"sessionId":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Sessionid"},"context":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Context","description":"Where the request originated: 'timeframe_selector', 'strategy_parse_detected', 'pricing_page'"},"email":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Email"},"detectedText":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Detectedtext","description":"Strategy text snippet if detected from input"}},"type":"object","required":["feature"],"title":"FeatureRequestCreate","description":"Request to log a feature request (low-friction)."},"FeatureRequestResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"feature":{"type":"string","title":"Feature"},"voteCount":{"type":"integer","title":"Votecount","description":"Total votes for this feature"},"isPrimaryVote":{"type":"boolean","title":"Isprimaryvote","description":"True if this was first vote from this session"},"message":{"type":"string","title":"Message"}},"type":"object","required":["success","feature","voteCount","isPrimaryVote","message"],"title":"FeatureRequestResponse","description":"Response after logging a feature request."},"FeatureRequestStats":{"properties":{"features":{"items":{"$ref":"#/components/schemas/FeatureVoteSummary"},"type":"array","title":"Features"},"totalRequests":{"type":"integer","title":"Totalrequests"},"updatedAt":{"type":"string","format":"date-time","title":"Updatedat"}},"type":"object","required":["features","totalRequests","updatedAt"],"title":"FeatureRequestStats","description":"Aggregated statistics for all feature requests."},"FeatureVoteSummary":{"properties":{"feature":{"type":"string","title":"Feature"},"totalVotes":{"type":"integer","title":"Totalvotes"},"primaryVotes":{"type":"integer","title":"Primaryvotes"},"uniqueSessions":{"type":"integer","title":"Uniquesessions"},"emailsCollected":{"type":"integer","title":"Emailscollected"}},"type":"object","required":["feature","totalVotes","primaryVotes","uniqueSessions","emailsCollected"],"title":"FeatureVoteSummary","description":"Summary of votes for a single feature."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HeadlineMetrics":{"properties":{"median_return":{"type":"number","title":"Median Return","description":"Median total return across replicas, as a fraction (-1..+∞). 0.05 = +5%.","examples":[0.05]},"p5_return":{"type":"number","title":"P5 Return","description":"5th-percentile total return across replicas. The 'worst case' return floor at the 5% tail.","examples":[-0.541]},"wcdd_95":{"type":"number","title":"Wcdd 95","description":"95th-percentile worst-case drawdown MAGNITUDE (0..1, positive). 5% of cases produced drawdowns deeper than this.","examples":[0.57]},"median_drawdown":{"type":"number","title":"Median Drawdown","description":"Median drawdown magnitude across replicas (0..1, positive).","examples":[0.19]},"failure_rate_pct":{"type":"number","title":"Failure Rate Pct","description":"Percentage (0..100) of cases that breached the failure-drawdown threshold (default 50% magnitude).","examples":[12.0]},"n_replicas":{"type":"integer","title":"N Replicas","description":"Total replica count across the curated case set for this asset.","examples":[255]},"asset":{"type":"string","title":"Asset","description":"Asset symbol the strategy was evaluated against.","examples":["BTC"]}},"type":"object","required":["median_return","p5_return","wcdd_95","median_drawdown","failure_rate_pct","n_replicas","asset"],"title":"HeadlineMetrics"},"NLParseRequest":{"properties":{"text":{"type":"string","maxLength":2000,"minLength":10,"title":"Text"},"debug":{"type":"boolean","title":"Debug","description":"Include detailed debug information in response","default":false}},"type":"object","required":["text"],"title":"NLParseRequest","description":"Request to parse natural language strategy."},"NLParseResponse":{"properties":{"strategy_json":{"type":"object","title":"Strategy Json"},"explanation":{"type":"string","title":"Explanation"},"confidence":{"type":"number","title":"Confidence"},"formalizable_percentage":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Formalizable Percentage","description":"Percentage of conditions that were legally formalizable (0-100)"},"parse_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parse Status","description":"Parse status: 'full', 'partial', or 'failed'"},"unparseable_concepts":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Unparseable Concepts","description":"Concepts detected in input that could not be formalized"},"assumptions":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Assumptions","description":"Interpretive decisions made by the parser (shown to user in report)"},"debug":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Debug","description":"Debug info (only present if debug=True in request)"}},"type":"object","required":["strategy_json","explanation","confidence"],"title":"NLParseResponse","description":"Response from NL parsing."},"OptimizedVariation":{"properties":{"rank":{"type":"integer","title":"Rank"},"score":{"type":"number","title":"Score"},"wcdd95":{"type":"number","title":"Wcdd95"},"improvement":{"type":"number","title":"Improvement"},"parameterChanges":{"items":{"$ref":"#/components/schemas/ParameterChange"},"type":"array","title":"Parameterchanges"},"strategyJson":{"type":"object","title":"Strategyjson"},"phase":{"type":"string","title":"Phase"}},"type":"object","required":["rank","score","wcdd95","improvement","parameterChanges","strategyJson","phase"],"title":"OptimizedVariation","description":"A single optimized variation result."},"ParameterChange":{"properties":{"name":{"type":"string","title":"Name"},"oldValue":{"type":"number","title":"Oldvalue"},"newValue":{"type":"number","title":"Newvalue"},"change":{"type":"string","title":"Change"}},"type":"object","required":["name","oldValue","newValue","change"],"title":"ParameterChange","description":"A single parameter change from optimization."},"ParameterOptimizeRequest":{"properties":{"strategyJson":{"type":"object","title":"Strategyjson"},"params":{"type":"object","title":"Params"},"budget":{"type":"integer","maximum":200.0,"minimum":10.0,"title":"Budget","default":50},"asset":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Asset","default":"SPY"},"useCalibration":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Usecalibration","default":true}},"type":"object","required":["strategyJson","params"],"title":"ParameterOptimizeRequest","description":"Request for parameter optimization sweep."},"ParameterOptimizeResponse":{"properties":{"originalScore":{"type":"number","title":"Originalscore"},"originalWcdd95":{"type":"number","title":"Originalwcdd95"},"variations":{"items":{"$ref":"#/components/schemas/OptimizedVariation"},"type":"array","title":"Variations"},"totalVariationsTested":{"type":"integer","title":"Totalvariationstested"},"bestImprovement":{"type":"number","title":"Bestimprovement"},"optimizationTimeSeconds":{"type":"number","title":"Optimizationtimeseconds"}},"type":"object","required":["originalScore","originalWcdd95","variations","totalVariationsTested","bestImprovement","optimizationTimeSeconds"],"title":"ParameterOptimizeResponse","description":"Response from parameter optimization."},"PerRegimeEntry":{"properties":{"regime":{"type":"string","title":"Regime","description":"Failure-mode termCode from the 10-axis taxonomy. See /ontology for canonical definitions.","examples":["TREND_UP"]},"label":{"type":"string","title":"Label","description":"Human-readable semantic label for the regime (matches /ontology/{slug} term descriptions).","examples":["persistent directional uptrend"]},"behavior":{"type":"string","enum":["stable","sensitive","degrading","inactive"],"title":"Behavior","description":"Qualitative regime behaviour. Controlled enum: 'stable' (score ≥ pool baseline), 'sensitive' (within 10 points below pool), 'degrading' (>10 points below pool), 'inactive' (bucket has < 3 replicas after augmentation).","examples":["stable"]},"score":{"type":"number","maximum":100.0,"minimum":0.0,"title":"Score","description":"Per-FM-bucket score on the V2 0..100 scale. Higher = better behaviour under this regime.","examples":[81.6]},"n_replicas":{"type":"integer","title":"N Replicas","description":"Replicas in this bucket (ex-post + a-priori-augmented combined).","examples":[39]},"shrinkage_alpha":{"type":"number","title":"Shrinkage Alpha","description":"Per-bucket shrinkage weight (1.0 = no shrinkage; <1.0 = bucket partially pooled toward overall).","examples":[1.0]},"n_augmented":{"type":"integer","title":"N Augmented","description":"Replicas added via Phase 18d a-priori augmentation (subset of n_replicas).","examples":[0]}},"type":"object","required":["regime","label","behavior","score","n_replicas","shrinkage_alpha","n_augmented"],"title":"PerRegimeEntry"},"PublicReportResponse":{"properties":{"shareHash":{"type":"string","title":"Sharehash"},"strategyName":{"type":"string","title":"Strategyname"},"robustness":{"type":"object","title":"Robustness"},"createdAt":{"type":"string","format":"date-time","title":"Createdat"},"numRuns":{"type":"integer","title":"Numruns"},"wcdd95":{"type":"number","title":"Wcdd95"},"robustnessScore":{"type":"number","title":"Robustnessscore"}},"type":"object","required":["shareHash","strategyName","robustness","createdAt","numRuns","wcdd95","robustnessScore"],"title":"PublicReportResponse","description":"Response for public shared report."},"QuickRobustnessRequest":{"properties":{"strategyJson":{"type":"object","title":"Strategyjson"},"params":{"type":"object","title":"Params"},"numRuns":{"type":"integer","maximum":1000.0,"minimum":10.0,"title":"Numruns","default":50},"scenarioTypes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Scenariotypes"},"asset":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Asset","default":"SPY"},"timeframe":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timeframe","default":"1D"},"useCalibration":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Usecalibration","default":true}},"type":"object","required":["strategyJson","params"],"title":"QuickRobustnessRequest","description":"Request for quick robustness check with inline strategy."},"QuickShareRequest":{"properties":{"robustness_data":{"type":"object","title":"Robustness Data"},"strategy_name":{"type":"string","title":"Strategy Name","default":"User Strategy"}},"additionalProperties":false,"type":"object","required":["robustness_data"],"title":"QuickShareRequest","description":"Request body for sharing quick robustness results."},"RegimeClassEntry":{"properties":{"avg_score":{"type":"number","title":"Avg Score","description":"Mean of bucket scores in this regime class.","examples":[44.0]},"behavior":{"type":"string","enum":["stable","sensitive","degrading","inactive"],"title":"Behavior","description":"Class-level behaviour — dominated by the most-degraded member.","examples":["degrading"]},"buckets":{"items":{"type":"string"},"type":"array","title":"Buckets","description":"FM termCodes grouped into this regime class.","examples":[["SHARP_CRASH","LIQUIDITY_STRESS"]]}},"type":"object","required":["avg_score","behavior","buckets"],"title":"RegimeClassEntry"},"StrategyExplainRequest":{"properties":{"indicators":{"items":{"type":"object"},"type":"array","title":"Indicators","default":[]},"entry_conditions":{"items":{"type":"object"},"type":"array","title":"Entry Conditions","default":[]},"exit_conditions":{"items":{"type":"object"},"type":"array","title":"Exit Conditions","default":[]},"stop_loss":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Stop Loss"},"take_profit":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Take Profit"}},"type":"object","title":"StrategyExplainRequest","description":"Request body for strategy explanation."},"TopFailureMode":{"properties":{"mode":{"type":"string","title":"Mode","description":"Failure-mode termCode where the strategy degrades most. See /ontology.","examples":["LIQUIDITY_STRESS"]},"severity":{"type":"string","enum":["low","moderate","high","critical"],"title":"Severity","description":"Qualitative severity. Controlled enum: 'low' (within 5 pts of pool), 'moderate' (5–15 pts below), 'high' (15–25 pts below), 'critical' (>25 pts below pool baseline).","examples":["high"]},"impact_type":{"type":"string","enum":["drawdown_expansion","return_instability","volatility_amplification","whipsaw_sensitivity","trend_dependency","tail_loss_acceleration"],"title":"Impact Type","description":"Failure-mechanism ontology. Controlled enum: drawdown_expansion | return_instability | volatility_amplification | whipsaw_sensitivity | trend_dependency | tail_loss_acceleration.","examples":["drawdown_expansion"]},"expected_behavior":{"type":"string","title":"Expected Behavior","description":"Plain-language phrase describing how the strategy degrades in this regime.","examples":["drawdowns deeper than the pool baseline in these scenarios"]},"bucket_score":{"type":"number","title":"Bucket Score","description":"The bucket's 0..100 score (mirrors the per_regime entry's score field).","examples":[37.0]},"delta_from_pool":{"type":"number","title":"Delta From Pool","description":"bucket_score minus overall_pool_score. Negative = regime-specific weakness vs the pool baseline.","examples":[-16.3]}},"type":"object","required":["mode","severity","impact_type","expected_behavior","bucket_score","delta_from_pool"],"title":"TopFailureMode"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}