Metrics Conventions & Definitions¶
Purpose & Scope¶
This document serves as the authoritative reference for all financial and risk metrics implemented in progridpy.metrics. It defines sign conventions, formulas, edge-case behaviors, and testing requirements to ensure industry-correct financial risk analytics.
Input Assumptions¶
- Cleared Trades Only: Metrics are computed only on "cleared" trades (
cleared == True). - Active Nodes Only: Metrics exclude "dead" nodes (
dead_node == False). - Daily Scope: The base unit of analysis is the canonical daily gain time series.
Canonical Series¶
metrics are derived from the Canonical Series:
* daily_gains: Sum of net gains per day.
* cumulative_gains: Cumulative sum of daily_gains.
* drawdowns: cumulative_gains - continuously_updating_max(cumulative_gains).
Sign Conventions (MANDATORY)¶
| Metric Type | Sign Convention | Example | Meaning |
|---|---|---|---|
| Gains / P&L | Positive (+) | +100 |
Profit |
| Negative (-) | -100 |
Loss | |
| Losses | Negative (-) | -500 |
A loss of $500 |
| Drawdowns | Negative (≤ 0) | -20% or -500 |
Distance from peak |
| Rolling Period P&L | Any value | -50 or +30 |
Net P&L over rolling period (negative=loss, positive=profit) |
| VaR / CVaR | Negative (≤ 0) | -1000 |
Estimated loss threshold |
| Estimated Risk | Any value | -1000 or +500 |
Composite risk estimate (typically negative) |
[!NOTE] Rolling period metrics and Estimated Risk are not clamped. If a rolling period has a net profit, that positive value is preserved. This allows accurate reporting of best/worst periods regardless of whether they resulted in profit or loss.
Metric Formulas¶
Estimated Risk¶
A composite risk metric estimating the tail risk of the strategy. Defined as the 0.05th percentile (0.0005 quantile) of daily, 90-day, and 180-day returns.
Let \(Q_q(X)\) be the q-quantile of series \(X\). $$ \text{Estimated Risk} = 2 \cdot Q_{0.0005}(\text{daily}) + Q_{0.0005}(\text{90d}) + Q_{0.0005}(\text{180d}) $$ * Typically negative (representing potential loss), but can be positive in edge cases. * The sum is computed as-is without clamping.
Drawdown¶
$$ \text{drawdown}t = \text{cumulative_gain}_t - \max_s) $$ * Always }(\text{cumulative_gain\(\le 0\). * At a new equity high, drawdown is 0. * Max Drawdown is the minimum (most negative) value of the drawdown series.
Risk-Adjusted Ratios (Sharpe / Sortino)¶
Ratios measure return per unit of risk. To maintain the intuition that "higher is better": $$ \text{Ratio} = \frac{\text{Mean Return}}{|\text{Risk Proxy}|} $$ * Sharpe: \(\mu / \sigma\) (standard deviation of daily gains). * Sortino: \(\mu / \sigma_{down}\) (standard deviation of negative daily gains). * Return / Estimated Risk: \(\text{Return} / |\text{Estimated Risk}|\).
Edge Cases¶
No Drawdown¶
If the strategy never has a losing period relative to the peak:
* Drawdown series is all 0.
* Max Drawdown is 0.
No Loss (Perfect Strategy)¶
If daily_gains are always \(\ge 0\):
* Rolling period metrics (worst_Xd_loss) will be positive (best period is still a profit).
* VaR / CVaR are 0 (clamped).
* Estimated Risk can be positive (sum of positive quantiles).
* Drawdowns are 0.
* Ratios:
* If risk (denominator) is 0, ratios return NaN.
* This is explicitly handled to avoid DivisionByZero errors.
Testing Philosophy & Invariants¶
All metrics code must be verified against these invariants:
1. drawdowns <= 0 (by mathematical definition)
2. max_drawdown <= 0
3. cvar <= 0 and var <= 0
4. If returns > 0, then ratios > 0 (unless risk is 0 -> NaN).
Note: estimated_risk and rolling period metrics (worst_Xd_loss) are NOT clamped and can be positive or negative.
New tests must confirm these properties using tests/metrics/test_invariants.py.
Guidance for Developers¶
- NEVER silently flip signs in the UI layer. The calculation layer is the source of truth.
- ALWAYS use
abs(risk)when computing ratios (to ensure positive denominator). - Rolling period metrics report actual P&L (can be positive or negative).
Last Updated: 2025-12-22