Source code for skfolio.descriptor._leverage._book_leverage
"""Book leverage descriptor."""
# Copyright (c) 2023-2026
# Author: Hugo Delatte <hugo.delatte@skfoliolabs.com>
# SPDX-License-Identifier: BSD-3-Clause
from __future__ import annotations
import numpy as np
from skfolio.containers import AssetPanel
from skfolio.descriptor._base import BaseDescriptor
from skfolio.typing import FloatArray
from skfolio.utils.stats import safe_divide
from skfolio.utils.validation import validate_asset_panel
[docs]
class BookLeverage(BaseDescriptor, stateless=True):
r"""Book leverage descriptor.
Computes the proportion of total book capital financed by debt:
.. math::
\text{book\_leverage}(t) =
\frac{\text{total\_debt}(t)}
{\text{total\_debt}(t) + \text{book\_equity}(t)}
Book leverage measures financial risk through the lens of the capital structure: the
fraction of a firm's total invested capital (debt plus common equity) that comes
from creditors rather than common shareholders [1]_.
NaNs are allowed as missing observations and propagate to the output.
Non-missing `total_debt` and `book_equity` values must be finite.
This form is preferred over the debt-to-equity ratio (:math:`D / E`) because the two
are monotonically related (:math:`D / E = \text{book\_leverage} / (1 - \text{book\_leverage})`)
but book leverage is bounded in :math:`[0, 1]` for healthy firms, producing
well-behaved cross-sectional distributions that do not require aggressive
winsorization.
`book_equity` is common shareholders' equity (excluding preferred stock and
minority interest). When it is negative (e.g., firms with accumulated losses
exceeding paid-in capital), the denominator `total_debt + book_equity` may remain
positive, become zero or turn negative:
- **Denominator > 0 and book_equity < 0**: the ratio exceeds 1. The firm is extremely
leveraged, with debt exceeding total book capital. The value is a valid distress
signal and is preserved in the output.
- **Denominator <= 0**: the ratio is undefined or negative, and no longer has its
intended interpretation as a measure of book leverage. These observations are
masked to NaN.
This differs from :class:`ReturnOnEquity`, where any negative equity makes the
concept meaningless. Here, a ratio above 1 carries real information about financial
risk.
Parameters
----------
None
Attributes
----------
n_assets_ : int
Number of assets seen during fitting.
asset_names_ : ndarray of shape (n_assets,)
Asset names seen during fitting.
References
----------
.. [1] "Capital structure decisions: which factors are reliably important?"
Financial Management. Frank, M. Z., & Goyal, V. K. (2009).
See Also
--------
DebtToAssets : Leverage relative to total assets.
MarketLeverage : Leverage as a fraction of total market capital.
Examples
--------
>>> from skfolio.datasets import make_synthetic_characteristics
>>> from skfolio.descriptor import BookLeverage
>>>
>>> X = make_synthetic_characteristics()
>>>
>>> descriptor = BookLeverage()
>>> book_leverage = descriptor.fit_transform(X)
"""