Mangrove SIEVE API

Mangrove SIEVE (Strategy Indicator Embeddings with Value Estimation) is a learned classifier trained on millions of historical backtests. It produces two probability heads for any candidate strategy:
  • Binary headP(no_trades) vs P(trades). Use this to filter out strategies that will never fire entries given their signal mix and parameter ranges.
  • 4-class head — softmax over losing, no_trades, wash, winning. Use this to rank strategies by predicted outcome before spending compute on a full backtest.
A single request scores up to 99 strategies in one round-trip. Every response is provenance-stamped so you can reproduce predictions later.

Endpoint

MethodEndpointDescription
POST/api/v1/oracle/sieve/scoreScore 1–99 strategies through both heads

Score Strategies

POST /api/v1/oracle/sieve/score The request accepts exactly one of two input shapes:
FieldDescriptionWhen to use
strategiesMangroveAI-shaped Strategy objects (entry/exit arrays of signals + execution config)When you’re constructing strategies in code and want a friendly shape
runsRaw run dicts (entry_json / exit_json strings, asset, exec_config)When you’re scoring rows already in the Mangrove sweep corpus
Per-request cap: 99 items. Sending more returns HTTP 413.

Example: Score a Strategy object

curl -X POST https://api.mangrovedeveloper.ai/api/v1/oracle/sieve/score \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "strategies": [
      {
        "asset": "BTC",
        "entry": [
          {
            "name": "macd_bullish_cross",
            "signal_type": "TRIGGER",
            "timeframe": "1h",
            "params": {"window_fast": 12, "window_slow": 26, "window_sign": 9}
          },
          {
            "name": "is_above_sma",
            "signal_type": "FILTER",
            "timeframe": "1h",
            "params": {"window": 50}
          }
        ],
        "exit": [
          {
            "name": "macd_bearish_cross",
            "signal_type": "TRIGGER",
            "timeframe": "1h",
            "params": {"window_fast": 12, "window_slow": 26, "window_sign": 9}
          }
        ],
        "execution_config": {
          "reward_factor": 2.0,
          "max_risk_per_trade": 0.01
        }
      }
    ]
  }'

Example: Score raw runs

Use this shape when you’ve already extracted entry_json / exit_json strings from the sweep corpus.
curl -X POST https://api.mangrovedeveloper.ai/api/v1/oracle/sieve/score \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "runs": [
      {
        "entry_json": "[{\"name\":\"macd_bullish_cross\",\"signal_type\":\"TRIGGER\",\"params\":{\"window_fast\":12,\"window_slow\":26,\"window_sign\":9}}]",
        "exit_json": "[{\"name\":\"macd_bearish_cross\",\"signal_type\":\"TRIGGER\",\"params\":{\"window_fast\":12,\"window_slow\":26,\"window_sign\":9}}]",
        "asset": "BTC",
        "exec_config": {"reward_factor": 2.0, "max_risk_per_trade": 0.01}
      }
    ]
  }'

Response

{
  "predictions": [
    {
      "binary": {
        "p_no_trades": 0.082,
        "p_trades": 0.918
      },
      "four_class": {
        "losing": 0.110,
        "no_trades": 0.080,
        "wash": 0.314,
        "winning": 0.496
      }
    }
  ],
  "count": 1,
  "model_version": "mangrove-sieve:0b9a2da0d827",
  "code_version": "oracle:v0.12.0 ai:v3.9.5 kb:1.0.3 roots:v0.3.0"
}
FieldTypeDescription
predictions[].binary.p_no_tradesfloatProbability the strategy will not fire any entries on real data
predictions[].binary.p_tradesfloat1 − p_no_trades
predictions[].four_class.losingfloatProbability the strategy ends with a net loss
predictions[].four_class.no_tradesfloatProbability the strategy fires no trades
predictions[].four_class.washfloatProbability the strategy ends roughly break-even
predictions[].four_class.winningfloatProbability the strategy ends with a net profit
countintNumber of items scored in this request
model_versionstringContent hash of the bundled model artifacts. Format: mangrove-sieve:<12-char-hash>. Changes when the model is retrained.
code_versionstringFull Oracle + MangroveAI + KB + Roots provenance string. Format: oracle:<ref> ai:<ref> kb:<ref> roots:<ref>
Both heads return probabilities that sum to 1.0 within float32 tolerance.

Schema details

SignalSpec (inside strategies[].entry / strategies[].exit)

FieldTypeRequiredNotes
namestringyesMangrove Knowledge Base signal name (e.g. macd_bullish_cross, rsi_oversold)
signal_typestringyesTRIGGER or FILTER
timeframestringnoe.g. "1h", "4h", "1d". Omit for default
paramsobjectnoSignal parameters; shape varies per signal — see Signals reference

StrategyInput

FieldTypeRequired
assetstringyes — BTC, ETH, SOL, …
entrySignalSpec[]yes — at least one TRIGGER expected
exitSignalSpec[]yes (may be empty)
execution_config.reward_factorfloatno — defaults to 2.0
execution_config.max_risk_per_tradefloatno — defaults to 0.01

RunInput

FieldTypeRequiredNotes
entry_jsonstringyesJSON-encoded array of signal dicts
exit_jsonstringyesJSON-encoded array of signal dicts (use "[]" if none)
assetstringyes
exec_config.reward_factorfloatnodefaults to 2.0
exec_config.max_risk_per_tradefloatnodefaults to 0.01

Error responses

StatusWhenDetail
400Both strategies and runs provided, or neither, or empty list"Provide exactly one of \strategies` or `runs` (and not an empty list)“`
400Malformed payload (missing required keys, wrong types)"Invalid strategies payload: ..." / "Invalid runs payload: ..."
413More than 99 items in a single request"Max 99 items per request, got <n>"
503Model artifacts missing or load failed on the server"Mangrove SIEVE predictor unavailable"

Provenance + reproducibility

Every response carries model_version (a content hash of the bundled model artifacts: binary head, 4-class head, vocabulary) and code_version (the full Oracle dependency stack). Together they let you reproduce a prediction later — log them next to any decision you make based on a SIEVE score. When the model is retrained, model_version changes; the old probabilities remain a faithful record of what the prior model said. If you cache SIEVE scores in your own system, key the cache on (input_hash, model_version).

Rate limits + tiers

SIEVE calls are gated by your subscription tier. See your tier’s sieve_predictions_monthly allowance in the subscription docs. Per-request cap (99 items) is independent of tier.