--- name: fi-attribution-campisi description: > Runs Fixed Income Manager Attribution using the Campisi Model. Decomposes bond returns into Income, Treasury, Spread, and Security-Specific effects. Accepts an xlsx file with Holdings, Yield Curve, and Spread Curves, validates inputs, prompts for missing data, and generates a comprehensive attribution report. metadata: display_name: "Fixed Income Attribution (Campisi)" short_description: "Decompose active fixed income return into income, treasury, spread, and specific effects." default_prompt: "Run Campisi attribution on my fixed income portfolio." icon_path: "assets/icon.png" --- # Fixed Income Attribution — Campisi Skill ## Purpose Decompose a fixed income portfolio's active return versus its benchmark into four additive effects per bond: | Effect | Formula | What it measures | |---|---|---| | **Income** | `coupon_rate × (days / 365)` | Carry/coupon income | | **Treasury** | `−ModDur × ΔYield_Treasury` | Interest rate sensitivity | | **Spread** | `−ModDur × ΔSpread_Average_Class` | Sector credit risk | | **Specific** | `Total_Return − Income − Treasury − Spread` | Idiosyncratic / issuer-specific | --- ## Invocation ``` /fi-attribution-campisi ``` Examples: - `/fi-attribution-campisi Here is my fixed income portfolio xlsx` - `/fi-attribution-campisi Run Campisi attribution on the uploaded file` --- ## Input Schema The skill accepts input in **two forms**: ### Form 1 — Spec-compliant xlsx (preferred) An Excel file containing three sheets: 1. **Holdings**: `period_id`, `security_id`, `security_name`, `bond_class`, `rating_category`, `portfolio_weight`, `benchmark_weight`, `total_return`, `coupon_rate`, `modified_duration_start` 2. **Yield_Curve**: `tenor_years`, `rate_start`, `rate_end` 3. **Spread_Curves**: `bond_class`, `rating_category`, `avg_spread_start`, `avg_spread_end` ### Form 2 — Natural language + prompted collection If no file is provided, the skill prompts for the required data. --- ## Step-by-Step Workflow The skill MUST execute these steps in order: ### Step 1 — Detect input form 1. Check whether the user uploaded an xlsx file. 2. Otherwise, enter **prompted collection mode**. ### Step 2 — Validate inputs (`scripts/validate_inputs.py`) Run the validator against the detected input. The validator checks: - `portfolio_weight` sums to 1.0 ± 1e-4 - `benchmark_weight` sums to 1.0 ± 1e-4 - Required columns exist in Holdings, Yield_Curve, and Spread_Curves. If validation **passes** → proceed to Step 3. If validation **fails** → display a clear error table and prompt the user to fix it. ### Step 3 — Run attribution (`scripts/run_attribution.py`) 1. Instantiate `FixedIncomeCampisiAttribution` from `FixedIncomeCampisiAttribution.py` 2. Call `generate_report()` -> `campisi_attribution_report.xlsx` ### Step 4 — Deliver results Present a structured summary of the Active Effects and attach `campisi_attribution_report.xlsx`. --- ## Prompt Rules (Prompted Collection Mode) When inputs are missing or incomplete, prompt for them: > "I need the portfolio data to run the Campisi attribution. Please provide an Excel file with three sheets: > 1. **Holdings**: Security-level data including weights, returns, coupon, duration, bond class, and rating. > 2. **Yield_Curve**: Treasury yield curve rates at the start and end of the period. > 3. **Spread_Curves**: Average OAS spreads by bond class and rating at the start and end of the period." --- ## Files in This Skill Package ``` fi-attribution-campisi/ ├── SKILL.md ← This file ├── assets/ │ └── icon.png ← Skill icon └── scripts/ ├── validate_inputs.py ← Input validator ├── run_attribution.py ← Attribution runner └── FixedIncomeCampisiAttribution.py ← Core engine ```