Performance Attribution#
The top-level orchestration module. Its main() function coordinates the full attribution
workflow: loading market and portfolio data, aligning date ranges, executing Brinson-Fachler and/or
factor-model attribution, and optionally launching the interactive dashboard.
Performance Attribution Pipeline#
Main orchestration module for running multi-method portfolio performance attribution analysis.
This module provides the top-level main function that coordinates the
full attribution workflow: loading market and portfolio data, aligning date
ranges, executing Brinson-Fachler and/or factor-model attribution, and
optionally launching an interactive dashboard.
Notes
The pipeline currently supports two attribution methodologies that can be
enabled independently via the Configuration object:
Brinson-Fachler – decomposes active return into allocation and selection effects using sector/asset weights.
Factor Model – regresses portfolio returns against user-supplied factor return series and decomposes performance into factor exposures plus a residual (alpha).
All intermediate computations use PyArrow columnar tables for memory efficiency and vectorized operations.
Examples
>>> from kaxanuk.attribution_analysis.entities.configuration import Configuration
>>> from kaxanuk.attribution_analysis.performance_attribution import main
>>>
>>> config = Configuration(
... input_directory="data/input",
... weights_portfolio_directory="weights/portfolio",
... weights_benchmark_directory="weights/benchmark",
... benchmark_returns_directory="returns/benchmark",
... investable_assets_directory="data/prices",
... factor_returns_by_factor_directory="data/factors",
... portfolio_file_name="portfolio_weights.csv",
... benchmark_file_name="benchmark_weights.csv",
... benchmark_return_file_name="benchmark_returns.csv",
... user_column_date="date",
... user_column_price="close",
... market_data_input_format="csv",
... portfolio_input_format="csv",
... start_date="auto",
... end_date="auto",
... brinson_fachler_method=True,
... factor_model_method=True,
... )
>>> main(config, launch_dashboard=True, dashboard_port=8050)
- main(configuration: Configuration, *, launch_dashboard: bool = True, dashboard_port: int) None[source]#
Run the full performance attribution pipeline.
Orchestrates data loading, date-range alignment, attribution computation, and optional dashboard visualisation for a portfolio defined by
configuration.- Parameters:
configuration (Configuration) –
Frozen dataclass holding all runtime settings including:
Directory paths –
input_directory,weights_portfolio_directory,weights_benchmark_directory,benchmark_returns_directory,investable_assets_directory,factor_returns_by_factor_directory.File names –
portfolio_file_name,benchmark_file_name,benchmark_return_file_name.Column mappings –
user_column_date,user_column_price.Input formats –
market_data_input_format("csv"|"parquet"),portfolio_input_format("csv"|"excel").Date range –
start_date,end_date(datetime.date|"auto").Method flags –
brinson_fachler_method,factor_model_method(bothbool).
launch_dashboard (bool, default True) – If
Trueand the factor-model method is enabled, launch a Dash web application displaying interactive attribution charts and summary statistics. WhenFalse, static matplotlib plots are generated instead.dashboard_port (int) – TCP port on which the Dash server listens when
launch_dashboard=True. Required (no default); typically read from the configuration viaExcelConfigurator.get_dashboard_port().
- Returns:
All outputs are side-effects: log messages, plots, and/or a running Dash server.
- Return type:
None
- Raises:
LicenseError – Raised before anything is read when the license does not validate (
services.license_validator.validate_license()): one ofLicenseNotFoundError,LicenseValidationError,LicenseServerErrororLicenseConfigurationError.FileNotFoundError – If any configured data directory or file does not exist.
ConfigurationError – If
configurationcontains invalid field values (raised duringConfiguration.__post_init__).
Notes
The function aligns all input tables (asset returns, portfolio weights, benchmark weights, benchmark returns, and factor returns) to the intersection of their date ranges before running any attribution calculation. This prevents shape mismatches and ensures consistent time-series indexing across methods.
The pipeline proceeds in four stages:
Data loading – market prices, portfolio/benchmark weights, benchmark returns, and per-factor return series are read from disk using the appropriate input handlers.
Date alignment – the common start/end dates across all tables are computed and each table is filtered accordingly.
Attribution – enabled methods (Brinson-Fachler, Factor Model) are executed sequentially.
Visualisation – results are either plotted (matplotlib) or served via an interactive Dash dashboard.
Examples
Run attribution without the dashboard (useful in batch/CI contexts):
>>> main(config, launch_dashboard=False)
Run only the Brinson-Fachler method with the dashboard disabled:
>>> config = Configuration(..., brinson_fachler_method=True, ... factor_model_method=False) >>> main(config, launch_dashboard=False)