# Portfolio Attribution

> A Claude skill from brainbytes-dev/everything-claude-trading.

- **Type:** Skill
- **Install:** `agentstack add skill-brainbytes-dev-everything-claude-trading-portfolio-attribution`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [brainbytes-dev](https://agentstack.voostack.com/s/brainbytes-dev)
- **Installs:** 0
- **Category:** [Finance & Payments](https://agentstack.voostack.com/c/finance-and-payments)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [brainbytes-dev](https://github.com/brainbytes-dev)
- **Source:** https://github.com/brainbytes-dev/everything-claude-trading/tree/main/skills/portfolio/portfolio-attribution

## Install

```sh
agentstack add skill-brainbytes-dev-everything-claude-trading-portfolio-attribution
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Portfolio Performance Attribution

> Decomposing portfolio returns into allocation, selection, and factor contributions.

## When to Activate

- User needs to explain why a portfolio outperformed or underperformed its benchmark
- Implementing Brinson-Fachler attribution for equity portfolios
- Building factor-based attribution using regression or risk models
- Performing fixed income attribution (duration, credit, curve)
- Linking single-period attribution across multiple periods

## Core Concepts

### What Is Attribution?

Attribution decomposes the active return (portfolio return minus benchmark return) into components that explain *where* and *how* value was added or lost. Two major frameworks:

1. **Holdings-based (Brinson)**: uses portfolio and benchmark weights and returns by sector/region
2. **Returns-based (factor regression)**: regresses portfolio returns on factor returns to identify exposures
3. **Risk-model-based**: uses a multi-factor risk model to decompose returns into factor and specific components

### Brinson-Fachler Attribution

Decomposes active return into three effects for each sector s:

**Allocation Effect**: did the manager overweight sectors that outperformed?
```
AE_s = (w_p,s - w_b,s) * (R_b,s - R_b)
```

**Selection Effect**: did the manager pick better stocks within each sector?
```
SE_s = w_b,s * (R_p,s - R_b,s)
```

**Interaction Effect**: combined effect of overweighting sectors where stock picks were also good
```
IE_s = (w_p,s - w_b,s) * (R_p,s - R_b,s)
```

Total active return: R_p - R_b = ΣAE_s + ΣSE_s + ΣIE_s

Where:
- w_p,s, w_b,s: portfolio and benchmark weight in sector s
- R_p,s, R_b,s: portfolio and benchmark return in sector s
- R_b: total benchmark return

### Factor-Based Attribution

Uses a multi-factor risk model (e.g., Barra, Axioma, Northfield):

```
R_p - R_f = Σ (β_p,k - β_b,k) * f_k + α_specific
```

Where β_p,k is the portfolio's exposure to factor k, and f_k is the factor return. Decomposes into:
- **Factor timing**: return from active factor bets
- **Specific return**: stock-level alpha (idiosyncratic return)

## Methodology

### Step 1: Brinson Attribution Implementation

```python
import pandas as pd
import numpy as np

def brinson_fachler(portfolio_weights, benchmark_weights,
                     portfolio_returns, benchmark_returns):
    """
    Single-period Brinson-Fachler attribution by sector.

    All inputs are Series indexed by sector.
    """
    total_bench_return = (benchmark_weights * benchmark_returns).sum()

    allocation = (portfolio_weights - benchmark_weights) * (benchmark_returns - total_bench_return)
    selection = benchmark_weights * (portfolio_returns - benchmark_returns)
    interaction = (portfolio_weights - benchmark_weights) * (portfolio_returns - benchmark_returns)

    result = pd.DataFrame({
        'port_weight': portfolio_weights,
        'bench_weight': benchmark_weights,
        'port_return': portfolio_returns,
        'bench_return': benchmark_returns,
        'allocation': allocation,
        'selection': selection,
        'interaction': interaction,
        'total_active': allocation + selection + interaction
    })

    # Verify: sum of total_active should equal portfolio return - benchmark return
    port_return = (portfolio_weights * portfolio_returns).sum()
    bench_return = (benchmark_weights * benchmark_returns).sum()
    assert abs(result['total_active'].sum() - (port_return - bench_return)) 8.2%}
    Benchmark Return:     {bench_ret:>8.2%}
    Active Return:        {active_ret:>8.2%}

    --- Decomposition by Sector ---
    {'Sector':8} {'Select':>8} {'Inter':>8} {'Total':>8}
    {'-'*60}
    """
    for sector, row in attribution_df.iterrows():
        report += f"    {sector:8.2%} {row['selection']:>8.2%} "
        report += f"{row['interaction']:>8.2%} {row['total_active']:>8.2%}\n"

    report += f"    {'-'*60}\n"
    report += f"    {'TOTAL':8.2%} "
    report += f"{attribution_df['selection'].sum():>8.2%} "
    report += f"{attribution_df['interaction'].sum():>8.2%} "
    report += f"{attribution_df['total_active'].sum():>8.2%}\n"

    return report
```

## Examples

### Equity Attribution by Sector

```python
# Sector weights and returns
sectors = ['Technology', 'Healthcare', 'Financials', 'Energy', 'Consumer']
port_w = pd.Series([0.35, 0.20, 0.15, 0.10, 0.20], index=sectors)
bench_w = pd.Series([0.28, 0.15, 0.18, 0.12, 0.27], index=sectors)
port_r = pd.Series([0.08, 0.05, 0.03, -0.02, 0.04], index=sectors)
bench_r = pd.Series([0.06, 0.04, 0.04, -0.01, 0.03], index=sectors)

result = brinson_fachler(port_w, bench_w, port_r, bench_r)
# Allocation to Tech (overweight in strong sector) = positive
# Selection in Tech (8% vs 6%) = positive
```

### Interpreting Results

Key insights to surface:
- Was alpha from sector allocation (top-down) or stock selection (bottom-up)?
- Which sectors had the largest attribution? Is it consistent over time or a one-off?
- Is the interaction effect large? If so, the manager may be making correlated allocation and selection bets
- Does attribution match the stated investment process? (A bottom-up manager should show selection, not allocation)

## Quality Gate

- [ ] Attribution sums exactly to total active return (no residual beyond rounding)
- [ ] Multi-period attribution uses a proper linking method (Carino, GRAP, or Menchero)
- [ ] Sector/region classification is consistent between portfolio and benchmark
- [ ] Transaction effects excluded from holdings-based attribution (or accounted for separately)
- [ ] Currency effects separated from local returns for international portfolios
- [ ] Factor-based attribution uses a risk model consistent with the portfolio's universe
- [ ] Interaction effect interpreted correctly — not lumped into allocation or selection arbitrarily
- [ ] Reported at multiple levels: total, sector, country, and individual security
- [ ] For fixed income: duration, curve, and spread effects isolated before reporting selection
- [ ] Attribution is stable and explainable — large unexplained residuals indicate model problems

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [brainbytes-dev](https://github.com/brainbytes-dev)
- **Source:** [brainbytes-dev/everything-claude-trading](https://github.com/brainbytes-dev/everything-claude-trading)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-brainbytes-dev-everything-claude-trading-portfolio-attribution
- Seller: https://agentstack.voostack.com/s/brainbytes-dev
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
