Performance Attribution Analysis
Overview
Decompose portfolio excess returns into explainable sources: sector allocation, stock selection, factor exposure, timing contribution, and more. This helps explain why a strategy made or lost money, rather than only how much it made or lost.
Brinson Attribution Model
Do not retype these formulas into throwaway Python. They are implemented and
tested in src/quantlib/attribution.py; import them.
Single-Period Brinson-Fachler Model
Let w_p,i = portfolio weight of sector i
w_b,i = benchmark weight of sector i
r_p,i = portfolio return of sector i
r_b,i = benchmark return of sector i
R_b = total benchmark return
Allocation_i = (w_p,i - w_b,i) × (r_b,i - R_b)
Selection_i = w_b,i × (r_p,i - r_b,i)
Interaction_i = (w_p,i - w_b,i) × (r_p,i - r_b,i)
Total active return = Σ(Allocation_i) + Σ(Selection_i) + Σ(Interaction_i)
The decomposition itself has no residual term. The three effects sum to
R_p - R_b identically, for any sector returns whatsoever, provided the
portfolio and benchmark weights carry the same total. brinson_fachler enforces
the weight-sum precondition and…