/api/signal/backtest/:coin
GETAvailable

Signal backtest results

Signal backtest results (BTC / ETH only)

GET/api/signal/backtest/:coin

Request

Query parameters

NameTypeRequiredDefaultAllowed valuesDescription
coin pathstringRequired—BTC, ETHCoin; other values return 400. Example: BTC

Parameters marked “path” are part of the URL.

Example request

curl -s "https://www.coinboss.com/api/signal/backtest/BTC"

Response fields

The field table is generated from real responses, so it lists exactly what the endpoint returns. Paths use a[] for array items and {*} for objects keyed by a dynamic name such as a coin or an exchange.

FieldTypeUnitDescription
successboolean—true when the request succeeded. On failure the body is `{ success: false, code, error, request_id }`.
coinstring—Coin symbol, upper case (for example BTC).
backtest_basisstring—Coin the backtest statistics were measured on (`ETH`).
basis_note_codestring—`basis_native` when the requested coin is the backtested coin, `basis_borrowed` when ETH statistics are shown for another coin.
basisstring—Futures price minus spot price, or the basis block.
note_codestring—Fixed code `eth_only_basis`: every statistic in this response comes from ETHUSDT history.
dailyobject—Daily values.
daily.datasetobject—Size and date range of the daily candle history behind the daily statistics (full history and recent window).
daily.dataset.bars_fullnumbercountNumber of daily candles in the full history.
daily.dataset.range_fullstring—First and last date of the full history, as text.
daily.dataset.bars_recentnumbercountNumber of daily candles in the recent window.
daily.dataset.range_recentstring—First and last date of the recent window, as text.
daily.dataset.srcstring—Source.
daily.baselineobject—Reference result of buying on any day and holding 30 days, for the full history and the recent window.
daily.baseline.fullobject—Full-resolution data.
daily.baseline.full.nnumber—Number of items counted.
daily.baseline.full.hold30_winratenumber%Share of all 30-day holds in the full history that ended in profit.
daily.baseline.full.hold30_pfnumberratioProfit factor of all 30-day holds in the full history: sum of gains ÷ absolute sum of losses.
daily.baseline.recentobject—Most recent entries.
daily.baseline.recent.nnumber—Number of items counted.
daily.baseline.recent.hold30_winratenumber%Share of all 30-day holds in the recent window that ended in profit.
daily.baseline.recent.hold30_pfnumberratioProfit factor of all 30-day holds in the recent window: sum of gains ÷ absolute sum of losses.
daily.timingobject—Return of buy-and-hold compared with simple trend-filter rules, for the full history and the recent window.
daily.timing.fullobject—Full-resolution data.
daily.timing.full.buy_hold_pctnumber%Buy-and-hold return over the full history, measured from the 210th candle on.
daily.timing.full.above_ema200_pctnumber%Return over the full history when holding only on days the close is above the 200-day EMA.
daily.timing.full.below_ema200_pctnumber%Return over the full history when holding only on days the close is below the 200-day EMA.
daily.timing.full.ema20_gt_ema50_pctnumber%Return over the full history when holding only while the 20-day EMA is above the 50-day EMA.
daily.timing.full.days_abovestring—Text `days held/total days` for the close-above-EMA200 rule, full history.
daily.timing.full.days_faststring—Text `days held/total days` for the EMA20-above-EMA50 rule, full history.
daily.timing.recentobject—Most recent entries.
daily.timing.recent.buy_hold_pctnumber%Buy-and-hold return over the recent window.
daily.timing.recent.above_ema200_pctnumber%Return over the recent window when holding only on days the close is above the 200-day EMA.
daily.timing.recent.below_ema200_pctnumber%Return over the recent window when holding only on days the close is below the 200-day EMA.
daily.timing.recent.ema20_gt_ema50_pctnumber%Return over the recent window when holding only while the 20-day EMA is above the 50-day EMA.
daily.timing.recent.days_abovestring—Text `days held/total days` for the close-above-EMA200 rule, recent window.
daily.timing.recent.days_faststring—Text `days held/total days` for the EMA20-above-EMA50 rule, recent window.
daily.signalsobject—Signal entries. dynamic keys: bull_regime,bear_regime,multi_long,fast_filter,pullback_add,streak5_up
daily.signals.{*}object—Signal entries.
daily.signals.{*}.holdstring—Holding rule used in the backtest of the signal named by the map key, for example `30d`, `7d` or a take-profit / stop-loss rule in ATR multiples.
daily.signals.{*}.fullobject—Full-resolution data.
daily.signals.{*}.full.nnumber—Number of items counted.
daily.signals.{*}.full.winratenumber|null—Win rate.
daily.signals.{*}.full.pfnumber|null—Profit factor.
daily.signals.{*}.recentobject—Most recent entries.
daily.signals.{*}.recent.nnumber—Number of items counted.
daily.signals.{*}.recent.winratenumber|null—Win rate.
daily.signals.{*}.recent.pfnumber|null—Profit factor.
daily.signals.{*}.srcstring—Source.
daily.signals.{*}.full.total_pctnumber%Share of the total. may be absent
daily.signals.{*}.full.mdd_pctnumber%Maximum drawdown. may be absent
daily.signals.{*}.recent.total_pctnumber%Share of the total. may be absent
daily.signals.{*}.recent.mdd_pctnumber%Maximum drawdown. may be absent
m15object—Backtest on 15-minute ETHUSDT candles: exits in ATR(14) multiples, round-trip cost included.
m15.datasetobject—Size, date range and completeness of the 15-minute candle history used.
m15.dataset.barsnumber—Bars.
m15.dataset.rangestring—Window requested.
m15.dataset.completenessstring—Text giving candles present versus candles expected in the 15-minute history.
m15.dataset.srcstring—Source.
m15.signalsobject—Signal entries. dynamic keys: knife_25,knife_30,cum8_4,cum16_6
m15.signals.{*}object—Signal entries.
m15.signals.{*}.signalsnumber—Signal entries.
m15.signals.{*}.nnumber—Number of items counted.
m15.signals.{*}.winratenumber—Win rate.
m15.signals.{*}.pfnumber—Profit factor.
m15.signals.{*}.total_pctnumber%Share of the total.
m15.signals.{*}.mdd_pctnumber%Maximum drawdown.
m15.signals.{*}.tpnumberxTake-profit distance used for the signal named by the map key, as a multiple of ATR(14).
m15.signals.{*}.slnumberxStop-loss distance used for the signal named by the map key, as a multiple of ATR(14).
m15.signals.{*}.srcstring—Source.
m15.threshold_scanarray—Backtest results by size of the single-candle drop that triggers a buy.
m15.threshold_scan[]object—Result for one drop threshold.
m15.threshold_scan[].thnumber%Single-candle price change that triggers the entry (negative).
m15.threshold_scan[].signalsnumber—Signal entries.
m15.threshold_scan[].nnumber—Number of items counted.
m15.threshold_scan[].winratenumber—Win rate.
m15.threshold_scan[].pfnumber—Profit factor.
m15.threshold_scan[].total_pctnumber%Share of the total.
m15.filter_testarray—Results of the −2.0 % dip entry with one extra filter each (RSI, volume, EMA200).
m15.filter_test[]object—Result for one filter variant.
m15.filter_test[].codestring—Code.
m15.filter_test[].nnumber—Number of items counted.
m15.filter_test[].winratenumber—Win rate.
m15.filter_test[].pfnumber—Profit factor.
m15.filter_test[].total_pctnumber%Share of the total.
m15.confirm_testarray—Results by entry timing: immediately, or after waiting for one or two confirming candles.
m15.confirm_test[]object—Result for one entry-timing variant.
m15.confirm_test[].codestring—Code.
m15.confirm_test[].nnumber—Number of items counted.
m15.confirm_test[].winratenumber—Win rate.
m15.confirm_test[].pfnumber—Profit factor.
m15.confirm_test[].total_pctnumber%Share of the total.
m15.cost_testarray—Results under different assumed round-trip trading costs.
m15.cost_test[]object—Result for one cost assumption.
m15.cost_test[].cost_pctnumber%Round-trip trading cost assumed in this run, as a percentage of notional.
m15.cost_test[].pfnumber—Profit factor.
m15.cost_test[].total_pctnumber%Share of the total.
m15.hour_testarray—Results of the −1.5 % dip entry split by UTC hour window.
m15.hour_test[]object—Result for one UTC hour window.
m15.hour_test[].codestring—Code.
m15.hour_test[].nnumber—Number of items counted.
m15.hour_test[].winratenumber—Win rate.
m15.hour_test[].pfnumber—Profit factor.
m15.hour_test[].total_pctnumber%Share of the total.
m15.short_sidearray—Results of the mirror trade: shorting after a single-candle surge.
m15.short_side[]object—Result for one surge threshold.
m15.short_side[].codestring—Code.
m15.short_side[].nnumber—Number of items counted.
m15.short_side[].winratenumber—Win rate.
m15.short_side[].pfnumber—Profit factor.
m15.short_side[].total_pctnumber%Share of the total.
weekdayarray—Day of week.
weekday[]object—Day of week.
weekday[].dnumber—Calendar date (UTC).
weekday[].up_ratenumber—Share of periods that closed higher.
weekday[].mean_pctnumber%Mean daily price change on that weekday (`d` 1 = Monday … 7 = Sunday), full history.
montharray—Calendar month.
month[]object—Calendar month.
month[].mnumber—Calendar month number, 1–12.
month[].up_ratenumber—Share of periods that closed higher.
month[].median_pctnumber%Median cumulative price change of that calendar month across the years in the full history.

Generated 2026-11-11 23:01 UTC from 1 real responses.

Example response

/api/signal/backtest/BTC · Real response captured 2026-11-13 03:59:07 UTC. Long arrays and maps are shortened for display: month had 12 items; weekday had 7 items; m15.signals had 4 items; daily.signals had 12 items; m15.cost_test had 5 items; m15.hour_test had 3 items.

  • {
    • "success": true,
    • "coin": "BTC",
    • "backtest_basis": "ETH",
    • "basis_note_code": "basis_borrowed",
    • "basis": "ETHUSDT",
    • "note_code": "eth_only_basis",
    • "daily": {
      • "dataset": { … 5 },
      • "baseline": { … 2 },
      • "timing": { … 2 },
      • "signals": { … 2 }
      },
    • "m15": {
      • "dataset": { … 4 },
      • "signals": { … 2 },
      • "threshold_scan": [ … 2 ],
      • "filter_test": [ … 2 ],
      • "confirm_test": [ … 2 ],
      • "cost_test": [ … 2 ],
      • "hour_test": [ … 2 ],
      • "short_side": [ … 1 ]
      },
    • "weekday": [
      • { … 3 },
      • { … 3 }
      ],
    • "month": [
      • { … 3 },
      • { … 3 }
      ]
    }

Details

Authentication
None. Public endpoint.
Rate limit
1200 requests per minute per IP
Server cache
60m
Edge micro-cache
10s
Window
fixed: daily bars 2017-08-17 to 2026-07-30, 15-minute bars 2023-01 to 2026-07
Data sources
Static summary of an offline backtest on exchange ETHUSDT klines; not recomputed.
Exchange coverage
ETH backtest only; BTC returns the same ETH-based numbers.
Units
win rate in percent, profit factor, sample counts
Timestamps
Unix epoch milliseconds (UTC) unless the field description says otherwise
Response format
json
Stability
Stable

Live status

AvailableChecked 2026-11-13 03:59:07 UTCHTTP 2008 msSchema matches

Availability, last 30 days

100% of 408 checks passed

Errors

Failed calls share one shape on every endpoint. The full list is on the errors page. Errors and rate limits →

CodeHTTPMeaningWhat to do
INVALID_PARAM400A required parameter is missing or a value is not accepted. `param` names the parameter when it is known.Do not retry unchanged; fix the request.
UNAUTHORIZED401The `CB-API-KEY` header was sent but the key is unknown or revoked. Public data needs no key — drop the header or use a valid key.Do not retry unchanged.
FORBIDDEN403The route is not part of the public API (internal or account-only).Do not retry.
NOT_FOUND404Unknown route, or the requested coin / exchange / fund does not exist.Do not retry; check the path and identifiers against the catalog.
RATE_LIMITED429More requests than the per-minute limit. `Retry-After` gives the seconds to wait.Wait for `Retry-After`, then retry with backoff.
INTERNAL500Unexpected server error. The message is generic by design; quote `request_id` when reporting it.Retry once after a few seconds; report it with the request id if it persists.
UPSTREAM_FAILED503The data source behind this endpoint did not answer in time. No stale or substitute numbers are returned in its place.Retry with backoff; check the status page.
UNAVAILABLE501 / 503The dataset is temporarily not ready (cache warming) or the endpoint has no lawful public source yet.Retry later; the catalog marks endpoints that are unavailable by design.
REQUEST_FAILED200Some older endpoints answer HTTP 200 with `success: false`. Always check `success`, not only the HTTP status.Depends on the message; treat as a failed request.

Try it

GET/api/signal/backtest/:coinAvailable
Parameters

string — Coin; other values return 400.

Request URLhttps://www.coinboss.com/api/signal/backtest/BTC
Choose an endpoint and press “Send request”. The response, headers and timing will appear here.