portfolios.implement_portfolio_sort()

Implement a portfolio sort.

Usage

Source

portfolios.implement_portfolio_sort(
    data,
    sorting_variables,
    sorting_method,
    portfolio_sort_options,
    rebalancing_month=None,
    breakpoint_function_main=None,
    breakpoint_function_secondary=None,
    min_portfolio_size=1,
    cap_weight=0.8,
    data_options=None,
    quiet=False
)

A convenience wrapper that combines sample construction filtering and portfolio return computation into a single call. Equivalent to calling ‘filter_sorting_data’ followed by ‘compute_portfolio_returns’ with the filter and breakpoint specifications bundled in ‘portfolio_sort_options’.

Parameters

data: pl.DataFrame

Data frame containing the stock-level panel data.

sorting_variables: str or list of str

One or two column names to sort portfolios on.

sorting_method: str

Sorting method to use. One of ‘univariate’, ‘bivariate-dependent’, or ‘bivariate-independent’.

portfolio_sort_options: dict

Dict produced by ‘portfolio_sort_options’, bundling filter and breakpoint specifications. The accepted entries include ‘filter_options’, ‘breakpoint_options_main’, and ‘breakpoint_options_secondary’.

rebalancing_month: int = None

Month in which portfolios are rebalanced annually. None (the default) means monthly rebalancing.

breakpoint_function_main: callable = None

Function used to compute breakpoints for the main sorting variable. Defaults to ‘compute_breakpoints’.

breakpoint_function_secondary: callable = None

Function used to compute breakpoints for the secondary sorting variable. Defaults to ‘compute_breakpoints’.

min_portfolio_size: int = 1

Minimum number of firms in the reported portfolio cross-section on a given date. For univariate sorts that is firms per portfolio-date; for bivariate sorts that is firms per main-portfolio-date summed across the secondary buckets. Cross-sections below the threshold have their returns set to null. Set to 0 to deactivate the check.

cap_weight: float = 0.8

Quantile of the cross-sectional ‘mktcap_lag’ distribution at which market capitalizations are capped per date when computing the capped value-weighted excess return (‘ret_excess_vw_capped’). Must be in [0, 1].

data_options: dict = None

Column-name mapping (see ‘data_options’). All elements are forwarded to ‘filter_sorting_data’ and ‘compute_portfolio_returns’. Uses the ‘data_options’ defaults when None.

quiet: bool = False
Whether informational messages should be suppressed.

Returns

pl.DataFrame
Data frame of portfolio returns as returned by ‘compute_portfolio_returns’.

Examples

import datetime as dt
import numpy as np
import polars as pl
from tidyfinance import (
    implement_portfolio_sort,
    portfolio_sort_options,
    filter_options,
    breakpoint_options,
)
rng = np.random.default_rng(123)
dates = pl.date_range(
    dt.date(2020, 1, 1), dt.date(2028, 4, 1), '1mo', eager=True
)
data = pl.DataFrame({
    'permno': range(1, 501),
    'date': dates.to_numpy().repeat(5),
    'mktcap_lag': rng.uniform(100, 1000, 500),
    'ret_excess': rng.standard_normal(500),
    'prc_adj': rng.uniform(0.5, 50, 500),
    'size': rng.uniform(50, 150, 500),
})
implement_portfolio_sort(
    data=data,
    sorting_variables='size',
    sorting_method='univariate',
    portfolio_sort_options=portfolio_sort_options(
        filter_options=filter_options(min_stock_price=1),
        breakpoint_options_main=breakpoint_options(n_portfolios=5),
    ),
)