simulate_flow_scenario
Generate constrained what-if market scenarios from a trained Flow model, returning a job ID for polling results with check_flow_job.
Instructions
Start constrained what-if scenario generation from a trained Flow model. Returns immediately with a job_id — use check_flow_job(job_id, job_type='generate') to poll for results. PREREQ: Always run generate_flow_paths FIRST on the same day to establish a baseline.
REQUIRED for any scenario with ≥2 constraints: call check_scenario_probability FIRST and verify probability ≥0.1% before invoking this tool. Two constraints multiply joint probability (e.g. oil ≥155 alone ~2%, VIX ≥40 alone ~3% → joint ~0.06%, below the resolution floor). Skipping the pre-check wastes GPU credits on infeasible scenarios and surfaces 0% results that are confusing to the user. The pre-check is ~1-15s; the full scenario is minutes.
After this tool runs, scenario_probability comes back in get_flow_results — interpret it as: ≥5% within normal range | 1-5% rare | <1% outside training distribution | 0% below measurable (not necessarily impossible — could be rare-event paths from latent mode). When latent mode produced the paths, surface that to the user verbatim — those paths satisfy constraints by construction but represent rare-event distortions, not unconditional samples.
THREE WAYS TO GET 0% PROBABILITY — avoid all: (1) DURATION: mean-reverting features (VIX, spreads, rates) spike for days to weeks, not months. Always use t_start/t_end to window constraints (e.g. t_start=10, t_end=20), not the full horizon. (2) JUMP TOO ABRUPT: if today's value is far from the threshold, t_start must give enough time to get there. (3) MULTIPLE CONSTRAINTS: joint probability multiplies. With 2+ constraints, ALWAYS check_scenario_probability first.
Check last_price from generate_flow_paths first — if VIX is at 15 and you constrain it above 30 from day 5, that's a 2x move in 5 days (essentially never happens). Set t_start large enough for a realistic transition: the bigger the gap between current value and threshold, the later t_start should be. VIX all-time high ~89, never sustained above 30 for more than a few weeks.
feature_name in constraints must be the DISPLAY NAME from feature_names (e.g. 'Apple Inc.', 'SPDR S&P 500 ETF Trust'), NOT ticker symbols. Constraint types: 'level' (absolute price bounds), 'return' (per-step return bounds). Pass portfolio_id through so test_flow_risk can be called directly on results. Run scenarios SEQUENTIALLY (one at a time), not in parallel, to avoid GPU queue contention.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| horizon | No | Override horizon (defaults to training horizon). | |
| n_paths | No | Number of paths to generate. More = better diversity. 1000 default. | |
| constraints | Yes | List of constraints. Each MUST have 'lower' and/or 'upper' (NOT 'threshold'). Required keys: feature_name, lower and/or upper. Optional: type, t_start, t_end. Example: {'feature_name': 'Equity Volatility (VIX)', 'lower': 30, 't_start': 10, 't_end': 25} (VIX > 30 from day 10 to 25). For upper bound: {'feature_name': 'Apple Inc.', 'upper': 200, 't_start': 5, 't_end': 40} (AAPL < 200). Types: 'level' (default, absolute price) or 'return'. feature_name must be DISPLAY NAME from feature_names (not ticker). ALWAYS set t_start/t_end to window the constraint realistically. | |
| portfolio_id | No | UUID of the portfolio (from train_flow_model). Pass it through so test_flow_risk can be called directly on the results. | |
| model_group_id | Yes | UUID of the model group with a trained Flow model (from train_flow_model) | |
| skip_feasibility_gate | No | Bypass the backend's pre-flight feasibility gate. DEFAULT FALSE. The gate refuses scenarios whose natural probability is below ~0.5%, preventing latent-mode rare-event distortions that produce unusable summary stats (we shipped a real prod case where a 0% joint scenario fell through to latent and returned expected_return=-91%). Set True ONLY after running check_scenario_probability and consciously committing to a rare-event regime — and then frame the result to the user as conditional on the rare event, not as a marginal forecast. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |