plugins/wealth-management/skills/performance-reporting/SKILL.md
Generate clear, accurate performance reports for investment portfolios with benchmarks, attribution, and risk dashboards. Use when the user asks about portfolio performance reports, return summaries, benchmark comparison, risk dashboards, goal progress tracking, or GIPS-compliant reporting. Also trigger when users mention 'quarterly report', 'how did my portfolio do', 'time-weighted vs money-weighted return', 'annualized returns', 'net-of-fee performance', 'rolling Sharpe', or ask how to present investment results to clients.
npx skillsauth add joellewis/finance_skills performance-reportingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Accurate and consistent return calculation is the foundation of all performance reporting.
Period returns: Report standard time periods — MTD (month-to-date), QTD (quarter-to-date), YTD (year-to-date), 1Y, 3Y, 5Y, 10Y, and since inception. Always state the exact inception date.
Cumulative vs annualized: Annualize returns only for periods greater than 1 year. Annualizing a 3-month return is misleading because it implies the rate is sustainable for a full year. For periods under 1 year, report cumulative (total) returns only.
(1 + cumulative_return)^(1/years) - 1Gross vs net of fees: Always specify whether returns are gross or net of management fees, advisory fees, and transaction costs. Net-of-fee returns are what the investor actually experiences and should be the primary presentation. If showing gross returns, also show the fee drag.
GIPS (Global Investment Performance Standards): For institutional reporting, follow GIPS requirements — composite construction, full disclosure, verified calculations, and standardized presentation. Even for non-GIPS reports, the principles of fair representation and full disclosure apply.
Time-weighted vs money-weighted returns:
scripts/performance_reporting.py implements the return calculations behind these reports:
ModifiedDietz): approximates TWR by weighting each external cash flow by the fraction of the period it was invested: R = (V_end - V_start - sum(CF)) / (V_start + sum(w_i * CF_i)), with w_i = (D - d_i)/D. A GIPS-acceptable approximation when daily valuations are unavailable.TimeWeightedReturn): chain-links sub-period returns, prod(1 + r_t) - 1, with an annualization helper that refuses periods under 1 year.MoneyWeightedReturn): solves NPV(rate) = 0 numerically using Brent's root-finding method (scipy.optimize.brentq) over a bracketing interval, returning the annual money-weighted return.CompositeReturn): asset-weighted composite return using beginning-of-period values as weights, plus equal-weighted return and the asset-weighted internal dispersion GIPS requires for composites with 6+ portfolios.PeriodReturns): MTD/QTD/YTD-style trailing windows (1M through 10Y) and inception-to-date from a daily return series, annualizing only periods of 1 year or more.A return number in isolation is meaningless. Context requires a benchmark.
Appropriate benchmark selection: The benchmark must match the portfolio's investment style, geography, capitalization, and asset class mix. A US large-cap equity portfolio should be compared to the S&P 500 or Russell 1000, not the MSCI Emerging Markets Index.
Active return (alpha): Portfolio return minus benchmark return. Positive alpha indicates outperformance; negative alpha indicates underperformance.
Tracking error and information ratio: For definitions and computation, see performance-metrics. In reports, present these alongside active return so the reader can judge how consistently outperformance was achieved.
Complement return reporting with risk metrics to give a complete picture. For definitions and computation of these metrics (volatility, VaR, drawdown, etc.), see historical-risk.
Current snapshot metrics:
Rolling metrics: Show how risk evolves over time, not just a point-in-time estimate.
Risk exposure breakdown:
Explain why the portfolio outperformed or underperformed.
Brinson attribution (allocation, selection, interaction) and factor decomposition: For methodology and formulas, see performance-attribution. In a report, summarize each effect in one plain-language sentence (e.g., "sector weighting added 0.2%, stock selection added 0.4%").
Top/bottom contributors (holdings-level):
For goal-based investors, frame performance in terms of progress toward their specific objectives.
On-track assessment: Is the portfolio on track, behind, or ahead relative to the financial plan?
Probability of success: Use Monte Carlo simulation to estimate the probability of reaching the goal given current assets, savings rate, time horizon, and expected return/risk assumptions. Express as a percentage (e.g., "82% probability of funding retirement at age 65").
Projected vs required return: Compare the return needed to reach the goal with the expected return of the current portfolio. If the required return exceeds what is reasonable, flag this as a planning gap.
Milestone tracking: Express progress as percentage of goal funded. For example: "Retirement goal: $2,000,000. Current portfolio: $850,000. 42.5% funded with 15 years remaining."
Charts communicate faster than tables. Choose the right chart for the message.
Growth of $10,000 chart: Shows cumulative wealth growth of portfolio vs benchmark over time. Intuitive for all audiences. Use log scale for long time periods to avoid visual distortion from compounding.
Rolling return chart: Shows trailing 12-month or 36-month returns over time. Reveals consistency and regime changes. More informative than a single annualized number.
Drawdown chart: Shows peak-to-trough declines over time. Viscerally communicates risk in a way that volatility numbers cannot.
Asset allocation pie/bar chart: Current allocation vs target/benchmark. Use a grouped bar chart to show both side by side.
Risk-return scatter plot: Plot portfolio and benchmark (and possibly peer group) on an annualized return vs annualized volatility plane. Positions in the upper-left (high return, low risk) are desirable.
The most important reporting skill is translating numbers into meaning.
Given: A balanced portfolio (60% equity / 40% fixed income) returned 3.2% in Q3 (benchmark: 2.8%). YTD the portfolio returned 8.1% vs 7.5% for the benchmark. The portfolio Sharpe ratio is 0.85 over the trailing 12 months. Equity selection in technology (+0.3%) and an underweight in energy (-0.1%) were the main attribution drivers.
Analysis:
Headline: The portfolio outperformed its benchmark by 0.4 percentage points in Q3 and 0.6 percentage points YTD, driven by strong stock selection in technology.
Return summary table:
| Period | Portfolio | Benchmark | Active Return | |--------|-----------|-----------|---------------| | Q3 | +3.2% | +2.8% | +0.4% | | YTD | +8.1% | +7.5% | +0.6% |
Attribution highlights:
Risk context:
Plain-language summary for the client: "Your portfolio gained 3.2% this quarter, beating the benchmark by about half a percent. Year-to-date, you are ahead of the benchmark by a similar margin. The main driver was our technology stock picks, which outperformed the broader tech sector. We remain on track relative to your long-term financial plan."
Given: A client has a retirement goal of $2,000,000 in today's dollars. Current portfolio value is $850,000. Time horizon is 15 years. Current annual contribution is $30,000 (increasing 3% per year). Portfolio expected return is 7% nominal, expected volatility is 12%. Inflation assumption is 2.5%.
Analysis:
Current status:
Projection (deterministic):
Projection (Monte Carlo, 10,000 simulations):
Interpretation: While the deterministic projection shows the client is on track, the Monte Carlo analysis reveals a 68% probability of success — reasonable but not highly confident. The gap between the deterministic and probabilistic views is driven by sequence-of-returns risk and volatility drag.
Recommendations to improve probability of success:
Client-facing summary: "You have $850,000 saved toward your $2,000,000 retirement goal, which is 42.5% of the way there with 15 years to go. Based on our projections, you have roughly a 68% chance of reaching your goal with your current savings plan. This is a reasonable position, but we can improve your odds by increasing your annual contribution or building in some flexibility on your retirement date."
Run with uv run scripts/performance_reporting.py (the PEP 723 header resolves numpy/scipy automatically) or with python3 scripts/performance_reporting.py after pip install numpy scipy. A bare run prints five demos: a Modified Dietz return, chain-linked TWR, an IRR solved via Brent's method, a GIPS composite summary, and a standard-period return table. Use --verify to assert the demo outputs match expected values (exit code 0 on PASS) and --help for an overview of the classes. The file is primarily meant to be imported as a module (e.g., from performance_reporting import ModifiedDietz, MoneyWeightedReturn).
testing
Model, forecast, and interpret volatility using time-series models and options-implied measures. Use when the user asks about EWMA, GARCH models, implied volatility, volatility surfaces, volatility term structure, or the VIX. Also trigger when users mention 'volatility smile', 'volatility skew', 'realized vs implied vol', 'volatility risk premium', 'vol clustering', 'mean-reverting volatility', 'options pricing inputs', 'RiskMetrics', 'decay factor', or ask how to forecast future volatility for risk management.
testing
Execute a complete tax-loss harvesting workflow from candidate identification through post-harvest monitoring. Use when the user asks about finding TLH candidates, gain/loss budgeting, replacement security selection, wash-sale compliance, or harvest execution planning. Also trigger when users mention 'unrealized losses in my portfolio', 'swap ETFs for tax purposes', 'harvest losses before year-end', 'substantially identical security', 'wash-sale window', 'NIIT offset', 'loss carryforward', or ask how much tax they can save by harvesting.
testing
Maximizes after-tax returns through strategic asset location, gain/loss management, and withdrawal sequencing. Use when the user asks about asset location, Roth conversions, tax-efficient withdrawals, tax lot selection, or charitable giving with appreciated securities. Also trigger when users mention 'which account should I hold bonds in', 'tax drag', 'Roth vs Traditional', 'RMD planning', 'bracket stuffing', 'HIFO vs FIFO', or ask how to minimize taxes on investments. For tax-loss harvesting execution and wash-sale mechanics, see the tax-loss-harvesting skill.
development
Plan and track savings for specific financial goals including retirement, education, and home purchase. Use when the user asks about required savings rates, 529 plans, retirement accumulation targets, down payment planning, or goal prioritization. Also trigger when users mention 'how much do I need to save each month', 'am I on track for retirement', 'college savings', 'safe withdrawal rate', '4% rule', 'FIRE savings rate', 'catch-up contributions', 'employer match', or ask how to balance competing savings goals.