def tearsheet_custom_metrics¶
tearsheet_custom_metrics is a strategy lifecycle hook that runs during backtest
analysis, immediately before LumiBot writes:
*_tearsheet.html*_tearsheet_metrics.json
Use this hook when you want strategy-defined metrics in both artifacts.
When it runs¶
Backtest trading completes.
LumiBot computes strategy/benchmark return series and drawdown context.
LumiBot calls
tearsheet_custom_metrics(...).Returned metrics are appended to the tearsheet metrics table and JSON scalar metrics.
Method signature¶
def tearsheet_custom_metrics(
self,
stats_df: pd.DataFrame | None,
strategy_returns: pd.Series,
benchmark_returns: pd.Series | None,
drawdown: pd.Series,
drawdown_details: pd.DataFrame,
risk_free_rate: float,
) -> dict:
...
Parameter structure¶
stats_df(pd.DataFrame | None)Backtest stats dataframe (same data used for
*_stats.csv/parquet).strategy_returns(pd.Series)Strategy return series used for tearsheet metric calculations.
benchmark_returns(pd.Series | None)Benchmark return series when a benchmark is available; otherwise
None.drawdown(pd.Series)Strategy drawdown series derived from cumulative returns.
drawdown_details(pd.DataFrame)Drawdown periods table (columns such as start/end/valley/days/max drawdown when available).
risk_free_rate(float)Effective risk-free rate used by tearsheet metrics.
Return format¶
Return a dict mapping metric names to values.
Supported formats:
{"Custom Metric A": 1.23}
{"Custom Metric B": {"strategy": 1.23, "benchmark": 0.91}}
Behavior rules:
Return
{}if no custom metrics apply.Returning
Noneis treated as no custom metrics.Returning a non-dict is ignored (with a warning).
Exceptions inside the hook are caught; tearsheet generation continues.
Example¶
class MyStrategy(Strategy):
def tearsheet_custom_metrics(
self,
stats_df,
strategy_returns,
benchmark_returns,
drawdown,
drawdown_details,
risk_free_rate,
):
if strategy_returns.empty:
return {}
p95 = float(strategy_returns.quantile(0.95))
avg_dd_days = (
float(drawdown_details["days"].mean())
if not drawdown_details.empty and "days" in drawdown_details.columns
else 0.0
)
return {
"95th Percentile Daily Return": p95,
"Average Drawdown Days": avg_dd_days,
}
API reference (source of truth)¶
The method docstring below is auto-loaded from the Strategy class and should be treated as the canonical API reference.
- Strategy.tearsheet_custom_metrics(stats_df: DataFrame | None, strategy_returns: Series, benchmark_returns: Series | None, drawdown: Series, drawdown_details: DataFrame, risk_free_rate: float)¶
Lifecycle hook to append strategy-defined metrics to the tearsheet.
This hook runs during backtest analysis immediately before the tearsheet HTML and
*_tearsheet_metrics.jsonartifacts are generated.- Parameters:
stats_df (pd.DataFrame or None) – Full backtest stats DataFrame (same data used for
*_stats.csv/parquet).strategy_returns (pd.Series) – Strategy return series used for QuantStats metrics.
benchmark_returns (pd.Series or None) – Benchmark return series if a benchmark is available.
drawdown (pd.Series) – Drawdown series computed from
strategy_returns.drawdown_details (pd.DataFrame) – Drawdown period table (start/end/valley/days/max drawdown when available).
risk_free_rate (float) – Effective risk-free rate used for tearsheet calculations.
- Returns:
Mapping of metric name to value. Supported values: -
{"My Metric": 1.23}-{"My Metric": {"strategy": 1.23, "benchmark": 0.87}}- Return type:
dict
Example
>>> def tearsheet_custom_metrics( >>> self, >>> stats_df, >>> strategy_returns, >>> benchmark_returns, >>> drawdown, >>> drawdown_details, >>> risk_free_rate, >>> ): >>> avg_abs_return = float(strategy_returns.abs().mean()) if not strategy_returns.empty else 0.0 >>> return {"Avg Absolute Daily Return %": avg_abs_return * 100.0}