Experiments
The experiment API takes a strategy template plus a parameter space and the engine generates its own candidates — grid enumeration or random/Monte-Carlo sampling — backtests each, and ranks the results. Use it for hyperparameter sweeps, dataset comparisons, or signal-combination searches. You do not hand it a list of strategies; you describe the space and the engine searches it. (Screening a fixed candidate list is a different workflow — see SIEVE → bulk backtest.) Sweep size is bounded by your subscription tier’smax_backtests_per_sweep (enforced at validate), not a fixed limit — see Limits & caps.
All endpoints sit under /api/v1/oracle/ on the MangroveAI gateway and are forwarded to the Oracle backtest engine with your identity attached. Auth: API key or JWT (same as the rest of /api/v1/*).
Endpoints
| Method | Path | Purpose | Billable |
|---|---|---|---|
POST | /api/v1/oracle/experiments | Create an experiment (the parameter grid + strategy template) | oracle_experiment (1 unit; x402 $0.25) |
POST | /api/v1/oracle/experiments/{id}/validate | Validate a draft + return total_runs (required before launch; enforces the tier per-sweep cap) | free (metadata) |
POST | /api/v1/oracle/experiments/{id}/launch | Fan the validated parameter space out into backtests (async) | oracle_experiment |
GET | /api/v1/oracle/results | Read results as they materialize. Pass ?experiment_id=<id> to scope to a single sweep, or omit it for the cross-experiment view. | oracle_results_read (1 unit; x402 $0.01) |
POST | /api/v1/oracle/simulate/run | Simulate a single strategy run without persisting | oracle_simulate (1 unit; x402 $0.10) |
POST | /api/v1/oracle/simulate/generate | LLM-backed strategy candidate generation | oracle_simulate |
GET | /api/v1/oracle/simulate/presets | Ready-made simulate request templates | free (metadata) |
GET | /api/v1/oracle/simulate/history | List recent simulate runs (caller-scoped) | free (metadata) |
GET | /api/v1/oracle/datasets | List the datasets the engine can run against | free (metadata) |
GET | /api/v1/oracle/signals | List signals available to experiments | free (metadata) |
GET | /api/v1/oracle/exec-config/defaults | Execution-defaults metadata (fees, slippage, position sizing, risk limits) | free (metadata) |
GET | /api/v1/oracle/templates | Predefined strategy templates you can seed an experiment from | free (metadata) |
GET | /api/v1/oracle/leaderboard | Curated persona roster — wrappers for the deployed strategies on the public dashboard. See Deployed strategies for live execution state. | free (metadata) |
GET | /api/v1/oracle/deployed/strategies | List the live-running curated strategies with current account value, open positions, etc. | free (metadata) |
POST /experiments + subsequent /launch counts as ONE billable HTTP call against your tier, regardless of how many strategies the grid fans out to.
Typical flow
Create an experiment
Body is the Returns an
ExperimentConfig: a datasets array (whole dataset OBJECTS from /datasets, not filenames), entry_signals / exit_signals (each signal needs a signal_type; entry needs ≥1 filter), and a params_sweep on each signal defining the space (values: [...] or {min, max, step}). The binary SIEVE pre_filter skips configs predicted not to trade.experiment_id with status: "draft". Sweep size is controlled by grid_signals.n_param_combos (grid) or n_random (random) — the engine samples up to that many configs from the space.Validate
{ "valid": bool, "total_runs": int, "errors": [...], "warnings": [...] }. Required before launch. This is where the tier per-sweep cap is enforced: if total_runs exceeds your tier’s max_backtests_per_sweep, validate fails with HTTP 403 — shrink the size or upgrade. There is no fixed 99 limit.Launch
Costs
Per the developer pricing page, everyPOST /experiments + /launch HTTP call counts as 1 unit against your API quota. x402 callers pay $0.25 per kickoff. The engine fans out to many individual backtests internally; you are not charged per fanout child.
GET /results is billed separately at 1 unit per call ($0.01 x402). Polling efficiently matters — prefer larger paged reads to short-interval polling.
Limits & caps
Two tier-dependent caps govern sweeps (there is no fixed 99-strategy limit — that 99 is SIEVE’s per-call cap, a different feature):- Per-sweep size —
max_backtests_per_sweepfor your tier (e.g. Pro 5,000 / Startup 20,000 / Enterprise 100,000). Enforced at validate (HTTP 403 iftotal_runsexceeds it). Control your size withgrid_signals.n_param_combosorn_random. - Concurrent sweeps —
concurrent_sweep_cap(often 1 on lower tiers). Enforced at launch (HTTP 429). Wait for the in-flight sweep to finish, then launch the next.
Related
- SIEVE classifier — a separate workflow: cheaply score a fixed candidate shortlist (≤99 per call) and hand the survivors to a bulk backtest. It does NOT gate or feed a sweep. (A sweep’s own built-in binary SIEVE
pre_filteris a different mechanism — it skips dead configs during the search.) - Backtesting API — single-strategy synchronous and async backtests, useful when you already know the parameters you want to test.
- Deployed strategies — live execution state of curated paper-trading strategies (the surface formerly implied by “leaderboard”).
mangroveaiPython SDK —client.oracle.create_experiment(...),client.oracle.simulate_run(...),client.oracle.list_results(...), and the full deployed/leaderboard surface are typed wrappers as of SDK v1.4.0.