Skip to content

Metrics and conformance

Most performance metrics have several published estimators. A library that disagrees with one formula is not wrong; one whose output matches no published estimator, or one its documentation does not state, is.

Named conventions (vetted.metrics)

40 conventions for 15 metrics: annual volatility and return, Sharpe, Sortino and downside deviation, maximum drawdown, Calmar, 95% VaR and ES, Omega, Ulcer and Pain indices, skewness and kurtosis.

from vetted import metrics
metrics.metrics()                                  # metric names
[c.name for c in metrics.conventions_for("var_95")]
metrics.compute("sharpe_annual", "arithmetic_ddof1", returns, 252)

The 24 conventions R PerformanceAnalytics implements reproduce it to 1e-10; the rest are checked against numpy, scipy or a brute-force definition.

Pinning a library to the reference values

import pytest
from vetted.testing import cases

@pytest.mark.parametrize("returns, periods, expected", cases("sortino_annual", "full_ddof0"))
def test_sortino(returns, periods, expected):
    assert my_sortino(returns, periods) == pytest.approx(expected, rel=1e-9)

Or copy the relevant block of src/vetted/data/expected.json into your own test data, with no dependency on vetted. quantstats, ffn and skfolio test suites built this way are in review upstream.

Conformance report

python -m vetted.conformance calls each installed library through its public API, names the convention it matches, and checks that missing observations are not treated as data and that distributional metrics do not depend on the order of the returns. The current report is in CONFORMANCE.md.