Source code for kaxanuk.attribution_analysis.interfaces.brinston_fachler_arrow_interface
"""
Abstract interface for Brinson-Fachler return attribution using PyArrow Tables.
Defines the contract that concrete Brinson-Fachler implementations must
satisfy: computing single-period attribution for a given date and
aggregating single-period results into a time series.
"""
import abc
import pyarrow as pa
[docs]
class BrinstonFachlerArrowInterface(metaclass=abc.ABCMeta):
"""
Abstract interface for Brinson-Fachler attribution using PyArrow Tables.
Defines the contract for computing single-period and multi-period
Brinson-Fachler return attribution, decomposing active return into
allocation, selection, and interaction effects.
Parameters
----------
returns_investible_assets : pa.Table
Asset returns table with a date column and one column per asset
containing period returns as float64.
portfolio_weights : pa.Table
Portfolio weight table with a date column and one column per asset
containing portfolio weights as float64.
benchmark_weights : pa.Table
Benchmark weight table with a date column and one column per asset
containing benchmark weights as float64.
"""
def __init__(
self,
returns_investible_assets: pa.Table,
portfolio_weights: pa.Table,
benchmark_weights: pa.Table
) -> None:
self.returns_investible_assets = returns_investible_assets
self.portfolio_weights = portfolio_weights
self.benchmark_weights = benchmark_weights
[docs]
@abc.abstractmethod
def brinson_fachler_model(
self,
date: str
) -> tuple[pa.Table, pa.Table]:
"""
Calculate the Brinson-Fachler attribution model for a single date.
Decomposes the active return (portfolio minus benchmark) into
allocation, selection, and interaction effects for each asset.
Parameters
----------
date : scalar
The date for which to calculate the attribution. Must match
a value present in the date column of the input tables.
Returns
-------
detail_table : pa.Table
Per-asset attribution with columns: ``asset``, ``portfolio_weights``,
``benchmark_weights``, ``returns_data``, ``portfolio_returns``,
``benchmark_returns``, ``alpha``, ``allocation``, ``selection``,
``interaction``.
totals_table : pa.Table
Single-row summary with columns: ``date``, ``portfolio_returns``,
``benchmark_returns``, ``alpha``, ``allocation``, ``selection``,
``interaction``.
"""
...
[docs]
@abc.abstractmethod
def time_series_calculation(
self
) -> None:
"""
Calculate the Brinson-Fachler attribution across all available dates.
Iterates over dates common to portfolio weights and benchmark weights,
computing the single-period model for each, and concatenates the
totals into a time-series table.
Returns
-------
detail_dict : dict
Mapping of each date to its per-asset ``pa.Table`` detail breakdown.
totals_table : pa.Table
Concatenated totals across all dates with columns: ``date``,
``portfolio_returns``, ``benchmark_returns``, ``alpha``,
``allocation``, ``selection``, ``interaction``.
"""
...