Source code for fynance.metrics.summary

#!/usr/bin/env python3
# coding: utf-8

""" Aggregated performance summary and a metric registry.

A single :func:`summary` reduces an equity/price curve to the standard panel of
risk-adjusted metrics, and :data:`METRICS` exposes them by name.

"""

from __future__ import annotations

# Built-in packages
from typing import Callable

# Third-party packages
import numpy as np
from numpy.typing import NDArray

# Local packages
from fynance.metrics.drawdown import mdd
from fynance.metrics.ratios import (
    annual_volatility,
    calmar,
    sharpe,
    sortino,
)
from fynance.metrics.returns import annual_return

__all__ = ['METRICS', 'summary']

# Registry of scalar metrics taking an equity/price curve -> float.
METRICS: dict[str, Callable[..., NDArray]] = {
    'annual_return': annual_return,
    'annual_volatility': annual_volatility,
    'sharpe': sharpe,
    'sortino': sortino,
    'calmar': calmar,
    'max_drawdown': mdd,
}


[docs] def summary(prices: NDArray, period: int = 252, rf: float = 0.0) -> dict[str, float]: """ Standard performance summary of an equity/price curve. Parameters ---------- prices : array-like Equity or price curve (not returns). period : int Annualization factor (252 for daily data). rf : float Risk-free rate passed to the Sharpe ratio. Returns ------- dict of str to float ``annual_return``, ``annual_volatility``, ``sharpe``, ``sortino``, ``calmar`` and ``max_drawdown``. Examples -------- >>> import numpy as np >>> eq = np.array([100., 101., 103., 102., 105., 107.]) >>> s = summary(eq) >>> sorted(s) ['annual_return', 'annual_volatility', 'calmar', 'max_drawdown', 'sharpe', 'sortino'] """ p = np.asarray(prices, dtype=np.float64) return { 'annual_return': float(annual_return(p, period=period)), 'annual_volatility': float(annual_volatility(p, period=period)), 'sharpe': float(sharpe(p, period=period, rf=rf)), 'sortino': float(sortino(p, period=period)), 'calmar': float(calmar(p, period=period)), 'max_drawdown': float(mdd(p)), }