Performance · Endpoint
Metrics
Overall, yearly or monthly performance metrics for the signal and its books — measured on the window only.
/v1/alphas/{alpha}/metricsParameters
Path parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
alpha | string | required | — | alpha_id (e.g. CausalHaarActivityDisplacement_0de63b8678a2_sp500pit_weekly_20260730t000858z_f358d1480d42). Use the value returned by GET /v1/alphas. |
Query parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
from | YYYY-MM-DD | optional | window start | First trading day, inclusive. |
to | YYYY-MM-DD | optional | window end | Last trading day, inclusive. |
granularity | overall | yearly | monthly | optional | overall | overall reports window-level core statistics; yearly / monthly add a periods list with per-period core statistics. |
doc | boolean | optional | false | doc=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
https://api.simicx.com/v1/alphas/{alpha}/metrics?granularity=overall&doc=falseExample 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.granularitywindowcore.icicircore.information_ratioexcess_sharpepnlmax_drawdownmax_drawdown_pctturnovercore.tenurerank_icsignal_processingperiodsic_deciles.buckets[]ic_deciles.monotonicityforward_returnsweeks_skippedsignalcore.*.signalcore.*.annualisationnwt.icnwt.ic_score_panelnwt.irdoc_urlalphaalpha_idmeta.warningsdata.granularitywindowstring / objectWhat 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 | nullMean 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 | nullBook-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 | nullHow 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 | nullSealed 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[] | nullPer-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 | nullNewey–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 | nullNewey–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 | nullNewey–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_urlpathWhere 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_idstringCollection 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[] | absentEvery 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)
icHow 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)
icirStability 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_ratioRisk-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_sharpeThe 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)
pnlWhat 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_drawdownThe 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
turnoverHow 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
tenureLength 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_decilesMean 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
nwtSignificance 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
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.

