Skip to content

About

Quantitative Risk and Return Analysis for Stock & ETF Portfolios

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

68 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GitHub code size in bytes GitHub issues GitHub pull requests

Portfolio Analyzer

Quantitative Risk and Return Analysis for Stock & ETF Portfolios

Portfolio Analyzer Demo Page

Return & Risk Measures

Total Return

The overall % gain/loss from start to end date. Simple and intuitive, but tells you nothing about the path taken to get there — two portfolios can have identical total returns while one endured a 40% drawdown and the other barely dipped.

CAGR (Compound Annual Growth Rate)

Total return annualized, i.e. "what constant yearly rate would get you the same result." Important because it makes returns comparable across different time periods — a 3-year backtest and a 7-year backtest can't be compared on total return alone, but their CAGRs can.

Annualized Volatility

The standard deviation of returns, scaled to a yearly figure. This is the standard proxy for risk/uncertainty: how much the portfolio's value swings around its average path. Two portfolios with the same CAGR but very different volatility are not equally desirable — lower volatility for the same return is strictly better from a risk-adjusted standpoint.

Sharpe Ratio

Return earned per unit of risk taken - (CAGR − risk-free rate) ÷ volatility. This is the metric that actually lets you compare "was this return worth the ride" — a portfolio returning 15% with wild swings can have a worse Sharpe than one returning 9% smoothly. It's the closest thing to a single-number risk-adjusted performance score.

Sortino Ratio

The same excess-return-per-unit-of-risk idea as Sharpe, but the denominator only counts downside deviation — the spread of days that lost money — rather than volatility in both directions. Sharpe penalizes a portfolio equally for a great week and a terrible one, since both add to the standard deviation; Sortino argues that's the wrong thing to call "risk," since nobody panics about upside surprises. Two portfolios with identical Sharpe ratios can have very different Sortino ratios if one earns its volatility mostly from big up days — that portfolio would look riskier than it is under Sharpe alone.

Max Drawdown

The largest peak-to-trough decline the portfolio experienced. This matters because volatility (an average measure) can hide the worst single episode — max drawdown answers "what's the deepest hole this portfolio dug itself into," which is often what actually determines whether a real investor panic-sells. It's a tail-risk measure, not a central-tendency one.

Beta (vs. benchmark)

How much the portfolio moves for each 1% move in the benchmark. Beta > 1 means amplified market moves (more aggressive/leveraged-feeling); beta < 1 means dampened moves (more defensive). This tells you how much of your portfolio's risk is just "the market," versus something else.

Alpha (annualized)

Return earned above what beta and the risk-free rate alone would predict (Jensen's alpha). This is the metric that answers "did the specific stock-picking/weighting actually add value, or did this portfolio just ride the market at some leverage level." Alpha near zero means you got exactly what your market exposure implied — no more, no less.

Correlation Matrix

Pairwise co-movement between holdings' daily returns. Critical for diversification: a portfolio can look diversified by name (different sectors, different companies) while still being highly correlated in behavior (e.g., two high-beta tech names that both crash together). Low/negative correlations are what actually reduce portfolio-level volatility below the average of the individual holdings' volatilities — that's the entire mathematical basis for diversification.

Monte Carlo Simulation

Bootstraps thousands of alternate paths by reshuffling the portfolio's historical daily returns, then tracks how deep each shuffled path's drawdown gets along the way. Because reordering a fixed set of returns doesn't change their product, every simulated path lands on the same terminal value as the actual history — this isn't a price forecaster. What it answers is sequence-of-returns risk: given the same overall return, how much pain could the ride have involved, and how often does the portfolio breach a "bust" drawdown threshold. Reported as a percentile fan chart (5th/25th/50th/75th/95th) alongside a max-drawdown distribution and bust probability.

Value at Risk (VaR)

Estimates the loss a portfolio could face over a chosen horizon (e.g. 1 day, 1 week) at a chosen confidence level (e.g. 95%), computed three independent ways so no single assumption is taken on faith:

  • Historical VaR — the empirical quantile of the portfolio's own overlapping historical return blocks; assumption-free, but only as good as whatever the historical sample happened to contain.
  • Parametric (variance-covariance) VaR — assumes normally distributed returns and derives the loss in closed form via the normal z-score, scaled to the horizon by the square-root-of-time rule.
  • Monte Carlo VaR — fits a multivariate normal to the underlying assets (preserving cross-asset correlation), simulates thousands of compounded paths, and takes the empirical quantile of the result — capturing the effects of compounding that the parametric method only approximates.

Paired with Expected Shortfall (CVaR), the average loss beyond the VaR cutoff, which answers "how bad, on average, is a bad day" — something VaR alone can't, since it only marks a threshold and says nothing about severity past it.

Dividend Analysis

Historical per-share dividend payouts pulled straight from each holding's actual payment record, broken down by year and by month so both the long-run trend and the real lumpiness of the cash flow are visible — a quarterly payer shows up as three empty months and one spike, not a smoothed average. Reported as trailing-twelve-month income and yield (actual $/share paid), alongside a forward estimate — the last-declared indicated annual rate held constant. That forward figure is a naive projection, not a forecast: yfinance has no real one, and a company can raise, cut, or suspend its dividend at any time, so it's flagged per holding whenever even that indicated rate isn't available.

Tech Stack

  • Frontend: React, TypeScript
  • Backend: FastAPI, yfinance
  • Deployment: Docker, Railway

About

Quantitative Risk and Return Analysis for Stock & ETF Portfolios

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages