macrosynergy.securities.index#

compute_daily_weights(constituents, returns, rebalance_freq='M', reconstitution_freq=None, blacklist=None)[source]#

Compute daily float-adjusted equal weights for an index constituent set.

Starting from an equal-weighted portfolio at the beginning of each rebalancing period, weights drift with realized returns within the period. At each rebalance date the portfolio is reset to equal weights over the current constituent set. Reconstitution (membership changes) can be snapped to a coarser frequency than rebalancing via reconstitution_freq.

Parameters:
  • constituents (pd.DataFrame or QuantamentalDataFrame) – Long-format DataFrame with columns “cid”, “real_date”, and “membership” (binary 0/1). Each row records whether a security was a constituent on a given date.

  • returns (pd.DataFrame or QuantamentalDataFrame) – Long-format DataFrame with columns “cid”, “real_date”, “xcat”, and “value” (daily return in percentage points). Must be filtered to a single xcat before passing.

  • rebalance_freq (str, default "M") – Pandas period alias controlling how often the portfolio is reset to equal weights. Must be one of {“B”, “W”, “M”, “Q”, “Y”}.

  • reconstitution_freq (str or None, default None) – Pandas period alias controlling how often membership changes take effect. If None, defaults to “rebalance_freq”.

  • blacklist (dict or None, default None) – Mapping of “cid” to (start, end) pd.Timestamp pairs identifying securities to exclude. Exclusions are snapped to rebalance period starts, matching the weight-reset cadence.

Returns:

Long-format DataFrame with columns [“real_date”, “cid”, “value”] containing the daily portfolio weight for each constituent, with zero-weight rows dropped.

Return type:

pd.DataFrame

compute_index_returns(constituents, returns, rebalance_freq='M', reconstitution_freq=None, blacklist=None)[source]#

Compute daily index-level returns from constituent weights and individual returns.

Wraps compute_daily_weights() to obtain daily float-adjusted weights, then computes the weighted-average return across constituents for each business day.

Parameters:
  • constituents (pd.DataFrame or QuantamentalDataFrame) – Long-format DataFrame with columns “cid”, “real_date”, and “membership” (binary 0/1).

  • returns (pd.DataFrame or QuantamentalDataFrame) – Long-format DataFrame with columns “cid”, “real_date”, “xcat”, and “value” (daily return in percentage points). Must be filtered to a single xcat before passing.

  • rebalance_freq (str, default "M") – Portfolio rebalancing frequency. Must be one of {“B”, “W”, “M”, “Q”, “Y”}.

  • reconstitution_freq (str or None, default None) – Membership reconstitution frequency. Defaults to “rebalance_freq” when None.

  • blacklist (dict or None, default None) – Mapping of “cid” to (start, end) pd.Timestamp pairs for securities to exclude.

Return type:

Tuple[DataFrame, DataFrame]

Returns:

  • daily_index (pd.DataFrame) – DataFrame with columns [“real_date”, “value”] containing the daily index return in percentage points.

  • weights_long (pd.DataFrame) – Long-format weight DataFrame as returned by “compute_daily_weights”.

compute_excess_returns(returns, index_returns, method='ratio', output_freq=None)[source]#

Compute per-stock excess (active) returns relative to a benchmark index.

Three excess-return formulations are supported:

  • “ratio” : (1 + r_stock) / (1 + r_bench) - 1

  • “log” : log(1 + r_stock) - log(1 + r_bench)

  • “diff” : r_stock - r_bench

Optionally compounds daily returns to a lower frequency before computing the excess return.

Parameters:
  • returns (pd.DataFrame or QuantamentalDataFrame) – Long-format DataFrame with columns “cid”, “real_date”, “xcat”, and “value” (daily return in percentage points).

  • index_returns (pd.DataFrame or QuantamentalDataFrame) – DataFrame with columns “real_date” and “value” (daily index return in percentage points). Must contain one row per date (no duplicates).

  • method (str, default "ratio") – Excess-return formula. One of {“ratio”, “log”, “diff”}.

  • output_freq (str or None, default None) – If provided, daily returns are compounded to this frequency before the excess-return formula is applied. Must be one of {“B”, “W”, “M”, “Q”, “Y”}. When None, excess returns are computed at daily frequency.

Returns:

Long-format DataFrame with columns [“real_date”, “cid”, “value”] containing excess returns in percentage points. Dates correspond to period-end timestamps when “output_freq” is set.

Return type:

pd.DataFrame