skfolio.descriptor.DaysToCover#
- class skfolio.descriptor.DaysToCover(half_life=21.0, min_periods=None)[source]#
Exponentially weighted days-to-cover descriptor.
Computes the ratio of shares sold short to exponentially weighted average daily volume:
\[ \begin{aligned} \text{EWMA\_volume}(t) &= \lambda \cdot \text{EWMA\_volume}(t-1) + (1 - \lambda) \cdot \text{adj\_volume}(t) \\[0.75em] \text{days\_to\_cover}(t) &= \frac{\text{short\_interest}(t)}{\text{EWMA\_volume}(t)} \end{aligned} \]where \(\lambda = \exp(-\ln(2) / \text{half\_life})\) is the EWMA decay factor.
Days to cover measures how many trading days it would take short sellers to buy back their positions at the current trading rate. High values indicate crowded short positions relative to liquidity [1] [2].
EWMA smoothing is preferred over a fixed rolling average because daily volume can spike around earnings, index rebalances or news events. EWMA dampens these spikes gradually, producing more stable factor exposures.
- Parameters:
- half_lifefloat, default=21.0
EWMA half-life in observations for volume smoothing. With daily data, common choices are:
half_life=21: ~1 monthhalf_life=63: ~3 monthshalf_life=252: ~1 year
- min_periodsint, optional
Minimum number of valid positive-volume observations required for each asset. Until an asset reaches this count, its output is NaN. This warm-up period avoids exposing early EWMA values before the volume estimate has sufficiently converged from its zero initialization. If
None, defaults to \(\lceil\text{half\_life}\rceil\), with a minimum of 1.
- Attributes:
- n_assets_int
Number of assets seen during fitting.
- asset_names_ndarray of shape (n_assets,)
Asset names seen during fitting.
- days_to_cover_ndarray of shape (n_assets,)
Last days-to-cover value for each asset.
Methods
fit_transform(X[, y])Compute exponentially weighted days to cover.
Get metadata routing of this object.
get_params([deep])Get parameters for this estimator.
partial_fit_transform(X[, y])Update state and return days to cover for this batch.
set_params(**params)Set the parameters of this estimator.
See also
ShortInterestShort interest as fraction of shares outstanding.
EWShareTurnoverEWMA share turnover (volume / shares outstanding).
Notes
short_interestis the number of shares held short. Non-missing values must be finite and non-negative.adj_volumeis split-adjusted trading volume. Non-missing values must be finite and non-negative.The EWMA state is updated only for positive-volume observations. NaN or zero
adj_volumeholds the EWMA state and does not increment the valid-observation count. NaNshort_interestpropagates to the output but does not prevent the volume state from updating.The
active_maskproperty of theAssetPaneldistinguishes holidays from delistings.References
[1]“An investigation of the informational role of short interest in the Nasdaq market” The Journal of Finance. Desai, H., Ramesh, K., Thiagarajan, S. R., & Balachandran, B. V. (2002).
[2]“Short interest, institutional ownership, and stock returns” Journal of Financial Economics. Asquith, P., Pathak, P. A., & Ritter, J. R. (2005).
Examples
>>> from skfolio.datasets import make_synthetic_characteristics >>> from skfolio.descriptor import DaysToCover >>> >>> X = make_synthetic_characteristics() >>> >>> # 1-month EWMA volume smoothing (default) >>> descriptor = DaysToCover() >>> days_to_cover = descriptor.fit_transform(X) >>> >>> # 3-month EWMA volume smoothing >>> descriptor = DaysToCover(half_life=63) >>> days_to_cover = descriptor.fit_transform(X)
- fit_transform(X, y=None, **fit_params)[source]#
Compute exponentially weighted days to cover.
- Parameters:
- XAssetPanel
Input panel containing
short_interestandadj_volume.- yNone
Ignored. Present for compatibility with scikit-learn’s API.
- **fit_paramsdict
Additional fit parameters. Ignored.
- Returns:
- days_to_coverndarray of shape (n_observations, n_assets)
Short interest divided by EWMA-smoothed daily volume for each observation and asset.
- get_metadata_routing()#
Get metadata routing of this object.
Please check User Guide on how the routing mechanism works.
- Returns:
- routingMetadataRequest
A
MetadataRequestencapsulating routing information.
- get_params(deep=True)#
Get parameters for this estimator.
- Parameters:
- deepbool, default=True
If True, will return the parameters for this estimator and contained subobjects that are estimators.
- Returns:
- paramsdict
Parameter names mapped to their values.
- partial_fit_transform(X, y=None, **fit_params)[source]#
Update state and return days to cover for this batch.
This method supports online updates by continuing from the current fitted state. Use
fit_transformto start from a clean state.- Parameters:
- XAssetPanel
Input panel containing
short_interestandadj_volume.- yNone
Ignored. Present for compatibility with scikit-learn’s API.
- **fit_paramsdict
Additional fit parameters. Ignored.
- Returns:
- days_to_coverndarray of shape (n_observations, n_assets)
Short interest divided by EWMA-smoothed daily volume for each observation and asset.
- set_params(**params)#
Set the parameters of this estimator.
The method works on simple estimators as well as on nested objects (such as
Pipeline). The latter have parameters of the form<component>__<parameter>so that it’s possible to update each component of a nested object.- Parameters:
- **paramsdict
Estimator parameters.
- Returns:
- selfestimator instance
Estimator instance.