Skip to content
SimicX

Performance · Endpoint

Metrics

Overall, yearly or monthly performance metrics for the signal and its books — measured on the window only.

GET/v1/alphas/{alpha}/metrics

Parameters

Path parameters

NameTypeRequiredDefaultDescription
alphastringrequiredalpha_id (e.g. CausalHaarActivityDisplacement_0de63b8678a2_sp500pit_weekly_20260730t000858z_f358d1480d42). Use the value returned by GET /v1/alphas.

Query parameters

NameTypeRequiredDefaultDescription
fromYYYY-MM-DDoptionalwindow startFirst trading day, inclusive.
toYYYY-MM-DDoptionalwindow endLast trading day, inclusive.
granularityoverall | yearly | monthlyoptionaloveralloverall reports window-level core statistics; yearly / monthly add a periods list with per-period core statistics.
docbooleanoptionalfalsedoc=1 embeds the machine-readable documentation block in the response. The same block is served standalone, cacheable for a day, at /v1/alphas/{alpha}/metrics/_doc.

Example request

curl

curl -H "Authorization: Bearer sxk_live_4f9c…" \
  "https://api.simicx.com/v1/alphas/CausalHaarActivityDisplacement_0de63b8678a2_sp500pit_weekly_20260730t000858z_f358d1480d42/metrics?granularity=overall"

Try it

Execute GET /v1/alphas/{alpha}/metrics against the live API using your key. Paste a key below to send without signing in, or sign in to auto-fill from your profile — either way, the call counts towards your rate limits. Whether the route answers depends on your key's endpoint allow-list — /v1/me lists what is in force; a new key starts with only the self-service routes until an administrator grants more.

Sent server-side via a same-origin proxy; only the documented host(s) are allowed.

Paste an API key above to list alphas your key may access.

Request

GEThttps://api.simicx.com/v1/alphas/{alpha}/metrics?granularity=overall&doc=false

Example response

JSON · synthetic values, real schema

{
  "data": {
    "granularity": "overall",
    "window": { "from": null, "to": null },
    "core": {
      "ic":     { "value": 0.041,  "unit": "ratio", "status": "available", "source": "research.rank_ic.mean_ic", "source_kind": "fact", "signal": "conditioned", "annualisation": "per_period" },
      "icir":   { "value": 4.47,   "unit": "ratio", "status": "available", "source": "research.rank_ic.annualized_icir", "source_kind": "fact", "signal": "conditioned", "annualisation": "annualised" },
      "information_ratio": { "value": 1.83, "unit": "ratio", "status": "available", "source": "performance.information_ratio", "source_kind": "metric", "annualisation": "annualised" },
      "excess_sharpe": { "value": 1.51, "unit": "ratio", "status": "available", "source": "performance.excess_sharpe", "source_kind": "metric", "annualisation": "annualised", "risk_free_rate": 0.03, "risk_free_rate_source": "performance.risk_free_rate" },
      "sharpe": { "value": 1.83, "unit": "ratio", "status": "available", "source": "performance.information_ratio", "source_kind": "metric", "annualisation": "annualised", "deprecated": true, "superseded_by": "core.information_ratio" },
      "pnl":    { "value": 28670.0, "unit": "base_currency_units", "status": "available", "source": "performance.net_pnl", "source_kind": "metric", "annualisation": "not_annualisable" },
      "max_drawdown":     { "value": -0.0821, "unit": "ratio", "status": "available", "source": "performance.max_drawdown", "source_kind": "metric", "annualisation": "not_annualisable" },
      "max_drawdown_pct": { "value": -8.21,   "unit": "percentage_points", "status": "available", "source": "performance.max_drawdown_pct", "source_kind": "metric", "annualisation": "not_annualisable" },
      "turnover": { "value": 5.7, "unit": "per_year", "status": "available", "source": "performance.annualized_turnover", "source_kind": "metric", "annualisation": "annualised" },
      "tenure": { "weeks": 291, "traded_weeks": 291, "first_rebalance": "2020-12-31", "last_rebalance": "2026-07-24", "calendar_days": 2031, "years": 5.560575, "source": "rebalance" }
    },
    "rank_ic": {
      "conditioned": {
        "hit_rate": { "value": 0.572, "unit": "ratio", "status": "available", "source": "research.rank_ic.hit_rate", "source_kind": "fact", "signal": "conditioned", "annualisation": "not_annualisable" },
        "dispersion": { "value": 0.048, "unit": "ratio", "status": "available", "source": "research.rank_ic.sample_standard_deviation", "source_kind": "fact", "signal": "conditioned", "annualisation": "per_period" }
      },
      "raw": {
        "ic": { "value": 0.0097, "unit": "ratio", "status": "available", "source": "research.raw_signal_rank_ic.mean_ic", "source_kind": "fact", "signal": "raw", "annualisation": "per_period" },
        "icir": { "value": 0.71, "unit": "ratio", "status": "available", "source": "research.raw_signal_rank_ic.annualized_icir", "source_kind": "fact", "signal": "raw", "annualisation": "annualised" }
      }
    },
    "signal_processing": {
      "signal": "conditioned",
      "smoothing_applied": true,
      "smoothing_half_life_weeks": 4,
      "detail": "Every performance.* figure in this payload describes the book built from the conditioned score."
    },
    "periods": null,
    "ic_deciles": {
      "score_field": "pre_smoothing_score",
      "signal": "raw",
      "bucket_count": 10,
      "weeks": 291,
      "buckets": [
        { "bucket": "Q1",  "rank": 1,  "weeks": 291, "mean_n_symbols": 49.6, "mean_score": -0.112, "mean_score_z": -1.31, "mean_long_short_weight": -0.0038, "mean_long_only_weight": 0.0,    "mean_forward_return": -0.0041, "ic": -0.018, "n_return_obs": 14440 },
        { "bucket": "Q2",  "rank": 2,  "weeks": 291, "mean_n_symbols": 49.6, "mean_score": -0.058, "mean_score_z": -0.72, "mean_long_short_weight": -0.0019, "mean_long_only_weight": 0.0,    "mean_forward_return": -0.0022, "ic": -0.009, "n_return_obs": 14440 },
        { "bucket": "Q3",  "rank": 3,  "weeks": 291, "mean_n_symbols": 49.6, "mean_score": -0.031, "mean_score_z": -0.41, "mean_long_short_weight": 0.0,     "mean_long_only_weight": 0.0,    "mean_forward_return": -0.0008, "ic": -0.003, "n_return_obs": 14440 },
        { "bucket": "Q4",  "rank": 4,  "weeks": 291, "mean_n_symbols": 49.6, "mean_score": -0.014, "mean_score_z": -0.19, "mean_long_short_weight": 0.0,     "mean_long_only_weight": 0.0,    "mean_forward_return": 0.0001,  "ic": 0.001,  "n_return_obs": 14440 },
        { "bucket": "Q5",  "rank": 5,  "weeks": 291, "mean_n_symbols": 49.6, "mean_score": -0.002, "mean_score_z": -0.03, "mean_long_short_weight": 0.0,     "mean_long_only_weight": 0.0,    "mean_forward_return": 0.0009,  "ic": 0.004,  "n_return_obs": 14440 },
        { "bucket": "Q6",  "rank": 6,  "weeks": 291, "mean_n_symbols": 49.6, "mean_score": 0.009,  "mean_score_z": 0.13,  "mean_long_short_weight": 0.0,     "mean_long_only_weight": 0.0,    "mean_forward_return": 0.0017,  "ic": 0.007,  "n_return_obs": 14440 },
        { "bucket": "Q7",  "rank": 7,  "weeks": 291, "mean_n_symbols": 49.6, "mean_score": 0.024,  "mean_score_z": 0.34,  "mean_long_short_weight": 0.0,     "mean_long_only_weight": 0.0,    "mean_forward_return": 0.0026,  "ic": 0.011,  "n_return_obs": 14440 },
        { "bucket": "Q8",  "rank": 8,  "weeks": 291, "mean_n_symbols": 49.6, "mean_score": 0.044,  "mean_score_z": 0.61,  "mean_long_short_weight": 0.0,     "mean_long_only_weight": 0.0011, "mean_forward_return": 0.0034,  "ic": 0.014,  "n_return_obs": 14440 },
        { "bucket": "Q9",  "rank": 9,  "weeks": 291, "mean_n_symbols": 49.6, "mean_score": 0.071,  "mean_score_z": 0.96,  "mean_long_short_weight": 0.0021,  "mean_long_only_weight": 0.0029, "mean_forward_return": 0.0046,  "ic": 0.019,  "n_return_obs": 14440 },
        { "bucket": "Q10", "rank": 10, "weeks": 291, "mean_n_symbols": 49.6, "mean_score": 0.118,  "mean_score_z": 1.42,  "mean_long_short_weight": 0.0041,  "mean_long_only_weight": 0.0052, "mean_forward_return": 0.0061,  "ic": 0.024,  "n_return_obs": 14440 }
      ],
      "monotonicity": { "spearman_bucket_vs_mean_forward_return": 1.0, "top_minus_bottom": 0.0102 },
      "forward_returns": "present",
      "weeks_skipped": 0
    },
    "nwt": {
      "ic": { "t_stat": 6.12, "p_value": 0.0000, "lag": 5, "n": 290, "mean": 0.041, "standard_error": 0.0067, "source": "computed", "source_kind": "derived", "signal": "conditioned" },
      "ic_score_panel": { "t_stat": 3.31, "p_value": 0.0011, "lag": 5, "n": 290, "mean": 0.0097, "standard_error": 0.0029, "source": "score_panel", "source_kind": "derived", "signal": "raw" },
      "ir": { "t_stat": 2.94, "p_value": 0.0038, "lag": 4, "n": 290, "mean": 0.0011, "standard_error": 0.0004, "source": "computed", "frequency": "weekly" }
    },
    "doc_url": "/v1/alphas/CausalHaarActivityDisplacement_0de63b8678a2_sp500pit_weekly_20260730t000858z_f358d1480d42/metrics/_doc",
    "alpha": "CausalHaarActivityDisplacement_0de63b8678a2_sp500pit_weekly_20260730t000858z_f358d1480d42",
    "alpha_id": "causal_haar_activity_displacement_reversal_b3874c9db78d"
  },
  "meta": {
    "request_id": "req_7f3a2c",
    "generated_at": "2026-07-28T14:03:12Z",
    "source": "alpha_research",
    "run": "CausalHaarActivityDisplacement_0de63b8678a2_sp500pit_weekly_20260730t000858z_f358d1480d42",
    "alpha_id": "CausalHaarActivityDisplacement_0de63b8678a2_sp500pit_weekly_20260730t000858z_f358d1480d42",
    "source_alpha_id": "causal_haar_activity_displacement_reversal_b3874c9db78d"
  }
}

Response fields

Every field the response can carry, what it means, and how it is computed.

  • data.granularitywindowstring / object

    What was measured.

    How it is computed

    Echoes the request; window nulls mean the full window. from/to narrows the derived blocks but never restates stored aggregates (a window_lifetime_only warning says so).

  • core.icicirstat | null

    Mean weekly rank IC and its information ratio.

    How it is computed

    Fact first (research.rank_ic.*), the stored metrics dataset second — see source/source_kind on each entry.

  • core.information_ratioexcess_sharpepnlmax_drawdownmax_drawdown_pctturnoverstat | null

    Book-level statistics.

    How it is computed

    Always measured on the long/short book — there is no book parameter. Each entry is { value, unit, status, source, source_kind }; core.information_ratio is the sealed risk-adjusted return and core.excess_sharpe the same figure net of the sealed risk-free rate; core.sharpe is a deprecated alias of the former and carries deprecated: true. Read unit per entry — pnl is base_currency_units, max_drawdown is a ratio of the peak, max_drawdown_pct percentage_points, turnover per year or per session as sealed. A stat that is neither stored nor derivable is null and named in a missing_core_metrics warning.

  • core.tenureobject | null

    How much evaluation the alpha has behind it.

    How it is computed

    { weeks, traded_weeks, first_rebalance, last_rebalance, calendar_days, years, source } — every rebalance date inside the window, including pending; traded_weeks counts only week_status == traded. A trailing pending week can be last_rebalance while remaining outside traded_weeks and outside IC (no forward_return yet). Falls back to the ledger's session span (source: portfolio, week counts null) when no rebalance dataset exists.

  • rank_icsignal_processingobject | null

    Sealed rank-IC extras for both signal families, and whether the traded score was smoothed.

    How it is computed

    rank_ic.conditioned carries hit_rate / dispersion / coverage beside core.ic; rank_ic.raw is the only place the API serves the unconditioned mean IC and ICIR. signal_processing reports smoothing_applied and smoothing_half_life_weeks from research.score_tape.*

  • periodsobject[] | null

    Per-period core statistics.

    How it is computed

    granularity=yearly / monthly adds [{ period, core }]; null at overall. Sealed keys are performance.annual.<YYYY>.long_short_<metric> (and ic_<metric> for rank IC); the API classifies the long_short_ prefix away and serves the same unprefixed field names as overall — information_ratio, excess_sharpe, turnover (from long_short_total_turnover), pnl, … — with annualisation set from the sealed name.

  • ic_deciles.buckets[]object[]

    The weekly cross-section in ten score buckets — Q1 lowest scores, Q10 highest — of the RAW signal.

    How it is computed

    Per bucket { bucket, rank, weeks, mean_n_symbols, mean_score, mean_score_z, mean_long_short_weight, mean_long_only_weight, mean_forward_return, ic, n_return_obs }: means of weekly means, so a 496-name week and a 120-name week count equally.

  • ic_deciles.monotonicityforward_returnsweeks_skippedsignal

    Whether the ladder is monotone, whether returns were seen at all, and which signal it buckets.

    How it is computed

    When forward returns are available, return-bearing columns are populated; otherwise they are null and meta.warnings may include forward_returns_absent. Weeks with fewer than 20 scored symbols are skipped. The ladder buckets the unconditioned signal (the same measurement published as raw_score; sealed as pre_smoothing_score) and carries signal: "raw".

  • core.*.signal"conditioned" | "raw"

    WHICH SIGNAL the statistic measures. The engine seals two rank-IC families — the conditioned signal (research.rank_ic.*) and the raw one (research.raw_signal_rank_ic.*) — and they can differ in magnitude and even in sign, because conditioning does real work. Present on the IC family only.

    How it is computed

    Read from the sealed fact the value came from. Never inferred.

  • core.*.annualisation"annualised" | "per_period" | "not_annualisable"

    The TIME BASIS of the value, so a client never has to guess whether to scale by √52.

    How it is computed

    core.ic is per_period; core.icir is annualised when the run seals annualized_icir; core.information_ratio and core.excess_sharpe are always annualised; pnl and both drawdowns are not_annualisable — a drawdown is a path statistic with no annual form. Absent on tenure, ic_deciles and nwt, where the concept does not apply.

  • nwt.icobject | null

    Newey–West significance of the CONDITIONED signal's mean weekly IC — the family core.ic belongs to.

    How it is computed

    { t_stat, p_value, lag, n, mean, standard_error, signal: "conditioned" }. Served from a sealed fact when one exists; no run seals one, so it is rebuilt from that run's own rebalance cross-sections (source: computed, source_kind: derived) and published ONLY when the rebuilt series reproduces the run's own sealed research.rank_ic.mean_ic. It covers the whole evaluation window even when from/to is set, because the sealed mean it tests is a lifetime figure. Null with ic_reproduction_mismatch if the rebuild disagrees, and with ic_family_mismatch when the run has no rebalance cross-sections at all.

  • nwt.ic_score_panelobject | null

    Newey–West significance of the RAW signal's mean weekly IC, recomputed from the score panel this API publishes. It describes the panel you can download; it does NOT test core.ic.

    How it is computed

    Weekly Spearman of raw_score vs forward_return over the rebalance cross-sections, then HAC. signal: "raw", source_kind: "derived".

  • nwt.irobject | null

    Newey–West significance of the mean long/short return.

    How it is computed

    { t_stat, p_value, lag, n, mean, standard_error, source, frequency } computed from the ledger; frequency is weekly | daily.

  • doc_urlpath

    Where the machine-readable field documentation lives.

    How it is computed

    GET it (or pass doc=1 here) for meanings, formulas, horizons and the full warning vocabulary.

  • alphaalpha_idstring

    Collection and source id of what was measured.

    How it is computed

    alpha is the collection served (== meta.run); alpha_id is the run index's source id.

  • meta.warningsobject[] | absent

    Every block that degraded or needs careful reading, machine-readably.

    How it is computed

    missing_kind / missing_core_metrics / access_limited / forward_returns_absent / insufficient_data / nonpositive_variance / window_lifetime_only / block_error / ic_family_mismatch / ic_reproduction_mismatch — partial data is a 200, never a 500.

  • ic_deciles, nwt.ic and nwt.ic_score_panel additionally read rebalance cross-sections and nwt.ir the ledger; a key barred from either endpoint still gets the remaining blocks, plus an access_limited warning.
  • granularity=yearly / monthly add a periods list per calendar year / month; the decile ladder, Newey-West and tenure stay window-level. Per-period core fields are unprefixed even though the seal writes long_short_* names.
  • The glossary below defines each metric; the same definitions are served machine-readably at /v1/alphas/{alpha}/metrics/_doc (cacheable for a day).

Metric definitions

Signal metrics are measured on the weekly scores; book metrics on the daily ledger. All are computed on the evaluation window only.

Rank IC (information coefficient)

ic

How well the week's score ordering predicted the following week's return ordering. Positive is predictive; ~0.03–0.05 weekly is a strong cross-sectional signal.

Formula
Per rebalance week t: IC_t = Spearman ρ ( score_i,t , fwd_return_i,t→t+1 ) across the cohort. Reported value: mean of IC_t over the window.
Granularity & horizon
Computed per week (cross-section across ~500 names), aggregated to overall / yearly / monthly. Horizon: one rebalance period (weekly).

ICIR (IC information ratio)

icir

Stability of the IC — a high mean IC that whipsaws is worth less than a steady one. The signal analogue of a Sharpe ratio.

Formula
mean(IC_t) / stdev(IC_t) over the window's weekly IC series.
Granularity & horizon
From the weekly IC series; overall / yearly / monthly. Horizon: weekly observations.

Information ratio

information_ratio

Risk-adjusted return of the long/short book, gross of the risk-free rate. Net of modelled transaction costs, borrow and carry — but nothing is deducted for the risk-free hurdle. For the true Sharpe, read excess_sharpe.

Formula
As sealed by the engine (performance.information_ratio; legacy seals may use sharpe_ratio / sharpe). Per period the engine seals performance.annual.<YYYY>.long_short_information_ratio — the API maps that long_short_* name onto the unprefixed public field. Only when nothing is sealed does the API fall back to mean(r) / stdev(r) × √(periods per year) over the long/short ledger.
Granularity & horizon
Long/short book only (no book parameter); overall / yearly / monthly under periods[]. Always annualised.

Excess Sharpe

excess_sharpe

The only true Sharpe this API publishes — the long/short book's return net of the sealed risk-free rate, divided by its volatility.

Formula
As sealed by the engine (performance.excess_sharpe; per period performance.annual.<YYYY>.long_short_excess_sharpe). The rate deducted rides on the same entry as risk_free_rate. Never derived — a run that seals none gets null.
Granularity & horizon
Long/short book only; overall / yearly / monthly under periods[]. Always annualised.

PNL (cumulative net profit & loss)

pnl

What the book made over the window, net of modelled costs — the bottom line the equity curve integrates to.

Formula
As sealed by the engine (performance.net_pnl preferred; pnl / total_pnl where sealed). Per period: performance.annual.<YYYY>.long_short_net_pnl. Unit is base_currency_units — read core.pnl.unit rather than assuming a ratio.
Granularity & horizon
Long/short book; overall / yearly / monthly. Horizon: cumulative over the window. Not annualisable.

Maximum drawdown

max_drawdown

The worst peak-to-trough decline of the equity curve over the evaluation window, as a fraction of the running peak.

Formula
As sealed by the engine. /metrics/_doc declares unit ratio for max_drawdown (e.g. −0.0821) and percentage_points for max_drawdown_pct (e.g. −8.21). Per period the sealed keys are long_short_max_drawdown / long_short_max_drawdown_pct.
Granularity & horizon
Long/short book; overall / yearly / monthly. Not annualisable.

Turnover

turnover

How much of the book is traded each period — the driver of transaction costs and capacity.

Formula
As sealed by the engine — performance.annualized_turnover preferred, then turnover, mean_turnover, then total_turnover. Per period the engine seals only the sum: performance.annual.<YYYY>.long_short_total_turnover — served under the unprefixed public field with annualisation: not_annualisable.
Granularity & horizon
Long/short book; overall, and per period under periods[]. Read annualisation and unit on the value — ratio per year when annualised, a period sum when total_turnover.

Tenure

tenure

Length of the evaluation track record — how much evidence the other metrics rest on.

Formula
Count of rebalance weeks from first to last (with the calendar span alongside).
Granularity & horizon
Per run; overall only.

IC deciles (Q1…Q10)

ic_deciles

Mean forward return of score-sorted decile portfolios of the RAW (unconditioned) signal. A healthy signal is monotonic: Q1 (lowest scores) worst through Q10 (highest) best, with the spread Q10 − Q1 the tradeable edge. Carries signal: "raw".

Formula
Each week, sort the cohort into deciles by the unconditioned score (raw_score / sealed pre_smoothing_score); average the next-period forward returns within each decile; average those means across weeks. score_field names the sealed column that was read.
Granularity & horizon
Weekly cross-section, pooled across the window. Window-level only — the ladder is not restated at granularity=yearly / monthly. Horizon: one rebalance period (weekly forward returns).

Newey–West t-statistic

nwt

Significance of a mean with autocorrelation- and heteroskedasticity-robust standard errors. nwt.ic tests the CONDITIONED mean weekly IC (core.ic's family); nwt.ic_score_panel tests the RAW mean weekly IC from the published score panel — it does NOT test core.ic; nwt.ir tests mean long/short book return.

Formula
t = mean(x) / SE_NW(x), with SE_NW the Newey–West HAC standard error at the stated lag; p_value two-sided from the t distribution; lag the Bartlett HAC lag length L = floor( 4 · (n/100)^(2/9) ), capped at n − 1 and reported in the payload.
Granularity & horizon
Window-level only. nwt.ic is lifetime-scoped even when from/to is set; nwt.ic_score_panel and nwt.ir follow the window.

Illustration

mean next-week forward return by score decile-0.89%Q1-0.51%Q2-0.27%Q3-0.08%Q4+0.06%Q5+0.19%Q6+0.34%Q7+0.52%Q8+0.71%Q9+0.96%Q10Q10 − Q1 = +1.85% / week

Illustrative synthetic data — the ic_deciles payload of GET /v1/alphas/{alpha}/metrics. Monotonic ladders are what a healthy ranker looks like: the edge is the low-to-high ordering, not one lucky bucket.