When to Use
Use this skill when a multi-strategy book needs the retirement rule written down before the drawdown, and applied identically to every strategy. The failure mode it exists to prevent is not analytical — it is the researcher who built the strategy arguing that this quarter is unrepresentative, every quarter.
The engine measures nothing. It adjudicates: you supply already-computed live and backtest statistics, and it applies four pre-declared guardrails, a fixed escalation ladder, and produces a record of which criteria fired, which could not be evaluated, and which thresholds were in force. Feed it at your governance cadence (monthly or quarterly is typical), and route its output to the capital-allocation committee.
Its second job is to refuse. A payload with a NaN metric, a sign-inverted drawdown, or an unevaluable criterion does not come back ACTIVE_HEALTHY — it raises or downgrades. An engine that certifies a strategy on the absence of data is worse than no engine.
When NOT to Use
- On a short live track record. The engine cannot tell 10 live days from 10 years. An IR or an IC t-stat over a few weeks is noise, and retiring a good strategy on noise destroys capital as surely as never retiring a bad one. Supply
live_observation_countand setmin_live_observations; without both, no sample-size gate exists and the ladder will happily retire a three-week-old strategy. - To diagnose why performance decayed. A market-wide regime shift and a strategy-specific alpha decay produce identical output here. Attribution belongs to
strategy-performance-decay-detection-vs-market-wide-decay; without it, you will retire a perfectly good strategy in the middle of an unfavourable regime. - As a live risk control. This runs on a governance cadence against aggregated statistics; it will not stop an intraday blow-up. The out-of-band control is
kill-switch-and-drawdown-circuit-breakersandportfolio-level-stop-loss-independent-of-strategy-stops. - As the unwind mechanism.
MANDATORY_RETIREMENTis a decision, not an action. Blocking order entry and liquidating the book isstrategy-decommissioning-and-position-unwind-procedure. - With the default thresholds unexamined. All four are house heuristics.
min_live_information_ratio=0.50sits at the 75th percentile of Grinold & Kahn's active-manager table — the default retires anything below top-quartile. That may be exactly right for your book, or absurd; it is not a standard. Seereferences/standards.md.
Prerequisites
- A
StrategyPerformanceMetricspayload:strategy_id,backtest_sharpe,backtest_max_drawdown_pct,live_sharpe,live_max_drawdown_pct,live_information_ratio,live_ic_t_stat,live_realized_annual_return_pct,backtest_annual_return_pct, and optionallylive_observation_count. - Drawdowns as positive magnitudes. A 20% peak-to-trough decline is
20.0, never-20.0. Enforced, not inferred — see the pitfall below for why guessing is unsafe.backtest_max_drawdown_pctmust be strictly positive;0.0is rejected as an unpopulated field. - All metrics finite. Non-finite values raise; they do not degrade gracefully.
- An IR and an IC t-stat you can explain. The engine consumes both as opaque numbers. Whether the t-stat came from a one-sided or two-sided test, whether it was computed on overlapping windows without an autocorrelation adjustment, and how many observations sit behind it are all invisible here and all change what the 1.96 threshold means.
backtest_sharpeandlive_sharpeare carried as context only — no criterion reads them.- Thresholds you are prepared to defend to a committee, and a change-control process around them: changing a retirement threshold is itself a material change under ESMA's supervisory expectations (
references/standards.md).
Workflow
-
Validate the payload before adjudicating anything.
- Reject non-finite metrics. Decision point —
NaNis not a neutral value.nan < 0.50isFalse, as is every other comparison, so a fully corrupt payload scores zero breaches and readsACTIVE_HEALTHY. The engine raises instead. - Reject negative drawdowns and a zero backtested drawdown. Decision point — do not "helpfully" take the absolute value. Both sign conventions are common; guessing wrong is silent. Fail loudly and make the caller declare the convention.
- Reject non-finite metrics. Decision point —
-
Gate on sample size before running the ladder.
- If
min_live_observationsis configured and the payload'slive_observation_countfalls short, returnINSUFFICIENT_LIVE_HISTORY. Breaches are still computed and reported, for information only. - Decision point — a short track record is not evidence of decay, and it is not evidence of health either. The correct action is
EXTEND_OBSERVATIONat reduced size, not retirement and not full allocation.
- If
-
Evaluate the four criteria. Comparisons are strict — a value sitting exactly on a threshold does not breach.
- $\text{IR}_{\text{live}} < 0.50$ →
ALPHA_DECAY_IR. - $\text{DD}{\text{live}} > 1.5 \times \text{DD}{\text{backtest}}$ →
DRAWDOWN_BREACH. - IC t-stat $< 1.96$ →
IC_STATISTICAL_DECAY. - $\text{Drift} = (R_{\text{live}} - R_{\text{backtest}}) / R_{\text{backtest}} \times 100 < -40%$ →
PERFORMANCE_DRIFT. - Decision point — the drift ratio is not always computable. It is undefined when the backtested return is non-positive and numerically meaningless when it is near zero (0.1% backtest vs 0.05% live is a 5 bp miss that reads as $-50%$ drift). In both cases
performance_drift_pctisNone, the criterion is named inskipped_criteria, andreturn_gap_pct_points— the plain percentage-point difference, always defined — is reported instead. It is never substituted with0.0.
- $\text{IR}_{\text{live}} < 0.50$ →
-
Apply the escalation ladder.
- 0 breaches, all four criteria evaluated →
ACTIVE_HEALTHY. - 0 breaches, any criterion not evaluated →
NEEDS_REVIEW. Decision point —ACTIVE_HEALTHYasserts that all four guardrails passed. A consumer reading onlydecisionmust never be told that on the strength of three. - 1 breach →
NEEDS_REVIEW(watchlist). - 2 breaches →
REDUCE_ALLOCATION(cut capital 50%, pending committee review). - $\ge 3$ breaches →
MANDATORY_RETIREMENT. - Override — a drawdown breach with a live IR below zero retires at two breaches. A strategy simultaneously losing against its benchmark and exceeding its backtested worst case has failed on both axes that matter, and waiting for a third confirmation costs capital. The override is reported in
escalation_reason, so a two-breach retirement is never unexplained. Disable it withescalate_on_negative_ir_with_drawdown_breach=False.
- 0 breaches, all four criteria evaluated →
-
Archive the report, then hand off.
thresholds_appliedechoes every parameter in force — a threshold-dependent decision is not reproducible without it.MANDATORY_RETIREMENTis a decision; the actual order-entry block and position unwind arestrategy-decommissioning-and-position-unwind-procedure.
Full procedure: see
references/workflows.md. Standards reference: seereferences/standards.md. Printable pre-flight checklist: seeassets/checklist.md.
Common Pitfalls
- Passing drawdowns as negative numbers. Under the negative convention, criterion 2 inverts:
-30.0 > -15.0isFalse, so a live drawdown three times the backtested worst case compares as within limits and the strategy is certified healthy. This is the highest-severity failure the skill has, and it is invisible — the report looks perfect. The engine now raises; do not "fix" it by takingabs()at the call site without first confirming which convention your data warehouse actually uses. - Treating a missing measurement as a passing one. A drift of
0.0returned because the backtested return was negative reads exactly like a strategy tracking its backtest perfectly. Any report whereevaluated_criteria_count < 4has an un-run guardrail, whateverbreached_criteriasays. - Reading
1.96as "95% confidence" in the decay question you are actually asking. 1.96 is the two-tailed 5% critical value of the standard normal; the one-sided 5% value is 1.645. "Has the IC decayed to non-positive?" is a one-sided question. Separately, an IC t-stat computed on overlapping forecast windows without a Newey-West correction is inflated, so the same 1.96 is a materially weaker test than it appears. - Counting four breaches as four independent findings. IR, IC t-stat and return drift all degrade together when a signal stops working. "3 of 4 breached" is closer to one finding confirmed three ways. The ladder is a severity heuristic, not a statistical test, and the criteria are equally weighted by fiat.
- Retiring on a track record too short to mean anything. The most expensive misuse of this engine: a strategy three weeks into live trading breaches all four criteria on noise and gets decommissioned. If
live_observation_countisNonethe gate silently does not run. - Re-tuning the thresholds until the strategy passes. The engine's only real value is that the rule pre-dates the drawdown. Changing
min_live_information_ratiofrom 0.50 to 0.30 because a favourite strategy is at 0.35 is the exact behaviour the skill exists to prevent — and under ESMA's supervisory briefing, changing risk-control thresholds is a material change requiring approval and a record. - Emotional parameter tweaking on the strategy instead of the process. Repeatedly recalibrating a decaying strategy resets its live track record to zero each time, which conveniently makes every criterion unevaluable.
- Citing a regulator in support of these numbers. No regulator prescribes an IR floor, a drawdown multiple, or a t-stat cut-off for withdrawing a strategy. Retirement for economic underperformance is a business decision. What is regulated is different — see
references/standards.md.
Verification
- Healthy baseline.
StrategyLifecycleRetirementEngine()with IR $1.2$, IC t-stat $2.5$, live DD $11.0$ against backtest DD $10.0$, live return $18.0$ vs backtest $20.0$ →ACTIVE_HEALTHY,is_retired False,breached_criteria == [],evaluated_criteria_count == 4,performance_drift_pct == -10.0(from $(18-20)/20 \times 100$),return_gap_pct_points == -2.0. - Full decay. Backtest DD $8.0$ (allowed $12.0$), live DD $20.0$, IR $-0.2$, t-stat $0.4$, live return $-5.0$ vs backtest $25.0$ →
MANDATORY_RETIREMENT, 4 breaches, drift $-120.0$. - Boundaries — exactly on a threshold must pass. IR exactly $0.50$, t-stat exactly $1.96$, live DD exactly $15.0$ (= $1.5 \times 10.0$), and drift exactly $-40.0$ (live $12.0$ vs backtest $20.0$) all produce
ACTIVE_HEALTHY. One tick past each must breach. - Sign-convention regression. A live DD of $-30.0$ against a backtest DD of $-10.0$ must raise
ValueError, not reportACTIVE_HEALTHY. Abacktest_max_drawdown_pctof $0.0$ must raise. - Corrupt-data regression. A
NaNorInfin any of the eight numeric fields must raiseValueError; a non-numeric value must raiseTypeError. - Unevaluable drift regression. Backtest return $-3.0$ with live return $-40.0$ →
performance_drift_pct is None,evaluated_criteria_count == 3,NEEDS_REVIEW(notACTIVE_HEALTHY),return_gap_pct_points == -37.0. Backtest $0.1$ vs live $0.05$ → driftNoneand no manufactured breach. Backtest exactly $1.0$ vs live $0.5$ → drift $-50.0$, evaluated normally. - Escalation override. Live DD $20.0$ with IR $-0.2$ →
MANDATORY_RETIREMENTat 2 breaches,escalation_reasoncontainingOVERRIDE_DD_AND_NEGATIVE_IR. Withescalate_on_negative_ir_with_drawdown_breach=Falsethe same payload →REDUCE_ALLOCATION. - Sample-size gate. With
min_live_observations=126, a payload breaching all four criteria atlive_observation_count=15→INSUFFICIENT_LIVE_HISTORY,is_retired False, four breaches still listed. At $126$ observations the same payload →MANDATORY_RETIREMENT. - Constructor validation. A non-positive
max_drawdown_multiplier, a non-finite threshold, amandatory_retirement_breach_countoutside $1..4$, and a non-positivemin_live_observationsmust each raiseValueError. - Run
python -m unittest discover -s skills/strategy-lifecycle-retirement-criteria/scripts— 45 tests, 100% pass rate.
Related Skills
strategy-performance-decay-detection-vs-market-wide-decaystrategy-decommissioning-and-position-unwind-procedurestrategy-underperformance-remediation-decision-treestrategy-committee-governance-for-capital-allocation-decisionsbacktest-vs-live-performance-divergence-trackingcapital-reallocation-based-on-live-performance