
Performance Attribution
Performance attribution analysis, Brinson sector/stock-selection attribution, factor...
Install
npx skills add HKUDS/Vibe-Trading --skill performance-attribution -g -a claude-code -y- Repository
- HKUDS/Vibe-Trading37.4k
- Category
- Engineering
- Updated
- 3d ago
- License
- MIT
- Context cost
- Mediumabout 3,000 tokens
- Runs scripts
- No, instructions only
What it does
Performance attribution analysis, Brinson sector/stock-selection attribution, factor alpha/beta decomposition, market-timing evaluation, and benchmark comparison framework.
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 raises rather than returning a decomposition
that does not tie out.
A residual is therefore never a property of the algebra, but it is a real and expected property of a reported attribution, because the inputs are a snapshot. Intra-period trading, cash drag, corporate actions and FX translation all move the actual portfolio return away from the one these weights and sector returns imply. So:
- residual inside the decomposition, given the inputs → impossible; if you see one, the arithmetic or the weight convention is wrong;
- residual between the decomposition and the reported fund return → normal;
quantify it and attribute it to its source rather than absorbing it silently
into selection. This is what the
/attribreconciliation gate asks for.
