Skip to main content

Get Backtest Result

Retrieve the status and (when ready) the full result of a backtest job.

Endpoint​

GET /v1/backtest/jobs/{id}

Weight: 2

Authentication: Required (signed)

Path parameters​

NameTypeMandatoryDescription
idstringYesJob identifier returned by Create Job, e.g. bt_3c91ef.

Response​

A successful response returns the full job object. The result payload is populated only when status is done.

{
"id": "bt_3c91ef",
"status": "done",
"config": {
"template_id": "tpl_grid",
"params": {
"grid_levels": 8,
"upper_price": "72000",
"lower_price": "60000"
},
"symbols": ["BTCUSDT"],
"timeframe": "1h",
"start": "2025-01-01T00:00:00Z",
"end": "2025-12-31T23:59:59Z",
"capital": "10000.00",
"leverage": 1,
"fee_model": "fixed_bps",
"fee_bps": "5"
},
"submitted_at": "2026-04-29T10:15:00Z",
"started_at": "2026-04-29T10:15:08Z",
"finished_at": "2026-04-29T10:17:42Z",
"progress": 1.0,
"result": {
"metrics": {
"sharpe": "1.84",
"sortino": "2.31",
"calmar": "1.12",
"max_drawdown": "-0.142",
"win_rate": "0.638",
"profit_factor": "1.92",
"cagr": "0.187",
"expected_value": "12.43",
"total_trades": 247,
"avg_trade_duration_seconds": 14820
},
"equity_curve": [
["2025-01-01T00:00:00Z", "10000.00"],
["2025-01-02T00:00:00Z", "10031.50"]
],
"trades": [
{
"id": 1,
"side": "buy",
"symbol": "BTCUSDT",
"entry_time": "2025-01-15T08:00:00Z",
"entry_price": "62100.00",
"exit_time": "2025-01-15T14:00:00Z",
"exit_price": "63250.00",
"qty": "0.0805",
"pnl": "92.58",
"fee": "10.18"
}
]
},
"error": null
}

While the job is queued or running, result is null and progress is fractional in [0, 1]. While failed, result is null and error carries the failure detail.

Response fields​

FieldTypeDescription
idstringJob identifier.
statusenumqueued, running, done, failed, or cancelled. The latter three are terminal.
configobjectResolved configuration the job is running with. See Create Job for field meanings.
submitted_atstring (ISO 8601)When the job was accepted.
started_atstring (ISO 8601) | nullWhen the worker began processing.
finished_atstring (ISO 8601) | nullWhen the job entered a terminal state.
progressnumberFractional progress in [0, 1]. 1.0 when complete.
resultobject | nullPopulated only when status = "done".
result.metricsobjectPerformance metrics. See Metrics for definitions.
result.equity_curvearray<[ISO 8601, decimal string]>Equity samples; one entry per simulated day.
result.tradesarray<object>Closed trades. Each trade has id, side, symbol, entry_time, entry_price, exit_time, exit_price, qty, pnl, fee.
errorobject | null{ "code", "message" } when status = "failed".

Polling guidance​

  • Poll at most once every 5 seconds per job. More aggressive polling is rate-limited.
  • Stop polling as soon as status reaches a terminal value (done, failed, cancelled).
  • For long-running jobs, prefer exponential backoff after the first few polls.

Pagination of large results​

For very long backtests, result.equity_curve and result.trades may eventually be paginated to keep responses manageable. In the initial release the full arrays are always returned in a single response.

Future: opt-in pagination via ?expand=equity_curve&cursor=... (and expand=trades). The default response will then return only metrics and the first page of each array.

Errors​

HTTPCodeCause
404NOT_FOUNDThe job ID does not exist or is not owned by the authenticated key.

See Errors for shared error semantics.

Example​

curl -X GET https://api.pipai.example/v1/backtest/jobs/bt_3c91ef \
-H "X-Primit-API-Key: $API_KEY" \
-H "X-Primit-Timestamp: $TS" \
-H "X-Primit-Signature: $SIG"