Skip to content

Compute on Your Own Data

POST /api/indicators/compute lets you run the engine's 60+ indicator pipelines against klines you supply yourself — independent of the engine's in-memory cache, not bound to any venue or symbol.

Good for:

  • Backtest: run indicators over OHLCV history pulled from your DB / CSV
  • Custom data sources: counterparty exchange, aggregated contracts, your own tick resamples
  • Offline analysis: validate indicator values for a specific window without being constrained by what the engine has cached

Not for:

  • Live data — use POST /api/indicators for lower latency, it reads from in-memory store
  • Multi-timeframe (MTF) indicators like SMC's fvg_timeframe — those need server-side prefetch of multiple timeframes; only the store-backed path supports them

30-second quickstart

bash
curl -X POST 'https://api.mobiusquant.ai/api/indicators/compute' \
  -H 'authorization: Bearer mq_xxx' \
  -H 'content-type: application/json' \
  -d '{
    "klines": [
      [1735689600000, 95000.0, 95500.0, 94800.0, 95200.0, 1234.5],
      [1735693200000, 95200.0, 95800.0, 95100.0, 95650.0, 1500.2]
    ],
    "interval": "1h",
    "calc": [{"name": "rsi", "params": {"period": 14}}]
  }'

Returns:

jsonc
{
  "count": 2,
  "interval": "1h",
  "klines": [[1735689600000, 95000.0, ...], ...],   // echoed
  "indicators": {
    "rsi:period=14": {
      "columns": ["open_time", "rsi"],
      "data":    [[1735689600000, null], [1735693200000, null]],
      "explain": { /* knowledge: summary_focus / signals / caveats */ }
    }
  }
}

RSI returns null for the first 14 bars — this is normal. All cumulative indicators need warmup. See Limits below.


Python example

python
import requests
import pandas as pd

# Load historical OHLCV from your own data source
df = pd.read_csv('btc_1h_history.csv')   # columns: open_time(ms), open, high, low, close, volume

klines = df[['open_time', 'open', 'high', 'low', 'close', 'volume']].values.tolist()

resp = requests.post(
    'https://api.mobiusquant.ai/api/indicators/compute',
    headers={'Authorization': 'Bearer mq_xxx'},
    json={
        'klines':   klines,
        'interval': '1h',
        'calc': [
            {'name': 'ema', 'params': {'period': 20}, 'id': 'ema20'},
            {'name': 'ema', 'params': {'period': 200}, 'id': 'ema200'},
            {'name': 'rsi', 'params': {'period': 14}},
        ],
    },
)
result = resp.json()
print(result['indicators']['ema20']['data'][-1])   # latest EMA20 value
print(result['indicators']['rsi:period=14']['data'][-1])

SMC and other "composite" indicators work too

Indicators like SMC (Smart Money Concepts) that produce non-numeric output also return per-bar columns + an objects sidecar:

bash
curl -X POST 'https://api.mobiusquant.ai/api/indicators/compute?explain=false' \
  -H 'content-type: application/json' \
  -d '{
    "klines": [/* ≥500 historical bars */],
    "calc": [{"id": "smc", "name": "smc",
              "params": {"show_swing_points": true, "show_premium_discount_zones": true}}]
  }'

The response includes indicators.smc.objects with structured shapes — swing_structures, order_blocks_swing, fair_value_gaps, premium_zone, etc. Feed them straight into a chart renderer or an LLM. See SMC indicator page.


Request schema

FieldTypeRequiredDescription
klinesarrayOHLCV bars; each row auto-detected as either list or object (see below)
calcarrayIndicators to compute, each {name, params, id?} — same shape as /api/indicators
intervalstringMetadata only, echoed back; some MTF indicators ignore it
echo_klinesboolDefault true — echoes input klines; set false to shrink the response

Two klines row formats (auto-detected):

jsonc
// Compact (Binance nested-list style): [open_time_ms, open, high, low, close, volume, quote_volume?]
[1735689600000, 95000.0, 95500.0, 94800.0, 95200.0, 1234.5, 117526200.0]

// Object (more explicit)
{
  "open_time":    1735689600000,
  "open":         95000.0,
  "high":         95500.0,
  "low":          94800.0,
  "close":        95200.0,
  "volume":       1234.5,
  "quote_volume": 117526200.0     // optional, used by some indicators (VWAP / CVD); defaults to 0
}

Response schema

FieldTypeDescription
countintNumber of klines processed
intervalstringEchoes request's interval (only when provided)
klinesarrayEcho of input klines (omitted when echo_klines=false)
indicatorsobjectkey = id or auto-generated name:p1=v1,..., value = single indicator's columns/data/objects/explain

Each indicators.<key> has the same shape as in POST /api/indicators:

jsonc
{
  "columns": ["open_time", "rsi"],
  "data":    [[1735689600000, null], [1735693200000, 67.4], ...],
  "objects": { /* present only for SMC and other non-numeric indicators */ },
  "explain": { /* knowledge: only when ?explain=true */ }
}

Limits

LimitValueOn violation
Kline count2000413
open_timestrictly monotonically increasing in ms400
OHLCVmust be finite (no NaN / inf)400
calc listnon-empty, all name in registry400
calc invalid paramsPydantic / signature mismatch422

Important: no warmup buffer

/api/indicators internally adds 1000 bars of warmup to feed accumulating indicators (EMA / RSI / ATR). /api/indicators/compute does not — it uses exactly the klines you supply.

So make sure you include enough history:

Indicator / usageMinimum bars
RSI(14) to stabilize≥ 50
EMA(200) / ATR(200) to stabilize≥ 200
Bollinger / Keltner / Donchian (default params)≥ 30
SMC internal structure + FVG≥ 50
SMC swing structure / OB / Strong-Weak / P/D zones≥ 100 (default swing_size=50, plus buffer)
SMC complete + EQH/EQL stable≥ 200 (ATR threshold converges)
Production-grade analysis500+

The first N bars returning null is normal — discard them and use the stable tail.


Auth & rate limits

Same as /api/indicators:

  • No Authorization header → anonymous IP bucket (low quota)
  • Valid Bearer mq_xxx → token bucket (higher quota)
  • Don't have a token yet? Apply for one — it's free.

Error codes

CodeMeaningWhat to do
400Validation failed (non-monotonic, NaN, unknown indicator, too few columns)Read detail, fix the request
401Authorization header present but token invalidRe-apply
413klines exceeds 2000Batch, or shorten the window
422Pydantic validation (missing field, wrong type, unknown field)Check detail.loc
429Rate limitedHonor Retry-After; token bucket has higher quota
500Indicator computation crashed (indicator bug)Report with the indicator name in detail

AI trading infrastructure