A professional, fully client-side Quantitative Portfolio Designer, Historical Backtester, and Advanced Monte Carlo Simulation Engine. Designed with modern finance frameworks, high-performance web-threading, and state-of-the-art stochastic models, this web application helps investors, quantitative analysts, and students model future asset returns, simulate realistic wealth accumulation schedules, and analyze portfolio tail risk with extreme responsiveness.
Live demo: jsonfm.github.io/monte-carlo-portfolio
- π οΈ Interactive Portfolio Designer: Custom-design portfolios by adding assets with arbitrary tickers/names, custom categories (ETF, Stock, Bond, Crypto), and dynamic weight distributions. Includes interactive weight visualizers, total allocation validation (must sum to exactly 100%), and preloaded template presets.
-
πΆ Real-time Market Data & Backtesting: Integrates with Yahoo Finance using robust, multi-fallback, client-side CORS proxies (
corsproxy.ioandallorigins) to fetch real-time and historical daily asset prices across custom timeframes with zero server-side storage required, keeping all data 100% private. -
π² Advanced Stochastic Simulation Engines:
-
Geometric Brownian Motion (GBM) with Correlation: Annualizes daily asset drifts (
$\mu$ ) and volatilities ($\sigma$ ), correlating returns across assets via Cholesky Decomposition of the historical covariance matrix. - GARCH(1,1) Volatility Clustering: Extends standard GBM by modeling time-varying conditional variance. Captures realistic market "calm" and "panic" phases where large shocks lead to sustained high-volatility regimes.
- Merton Jump-Diffusion (Black Swans): Incorporates Poisson-distributed, randomized systemic shocks ("jumps") representing sudden crash events or flash crashes. Includes asset-class specific jump reactions (e.g., severe stock/crypto crashes paired with flight-to-safety bond gains) and a mathematical compensator to prevent drift bias.
- Moving Block Bootstrap: A non-parametric engine that samples contiguous historical daily return blocks (e.g., 10-day blocks). This preserves joint-asset covariance while naturally capturing momentum, short-term trends, and serial autocorrelation directly from market history.
-
Geometric Brownian Motion (GBM) with Correlation: Annualizes daily asset drifts (
-
π Pro-Grade Executive Report & Analytics: Synthesizes simulation results into an extensive, highly visual, multi-dimension analytical report:
- Executive Summary: Consolidates simulation constraints, cash flow parameters, and core health scores.
- Portfolio Composition & Diversification Audit: Calculates the Herfindahl-Hirschman Index (HHI) to classify and grade overall portfolio diversification (from Grade A Excellent to Grade F Extreme Concentration).
- Downside Protection & Tail Risk Assessment: Provides deep insight into Value at Risk (VaR), Conditional Value at Risk (CVaR / Expected Shortfall), capital loss probabilities, and transaction/tax friction drag.
- Custom Goal Probability Solver: Input any custom dollar target and the engine reverse-solves the exact probability of achievement, suggesting starting capital and tracking the target crossing year.
- Strategic Portfolio Analysis & Considerations: Dynamic, rules-based portfolio advisor suggesting recommendations for asset concentration, inflation risk, safe withdrawal rates, and Merton jump impacts.
-
Export & Share Utility: One-click copy for clean markdown/text memo reporting, single-button
.txtfile downloading, and print-optimized CSS overrides to save the complete report as a publication-ready PDF.
-
π° Comprehensive Wealth Accumulation & Cash Flow Controls:
- Monthly Deposits & Withdrawals: Model realistic, long-term accumulation plans (savings) or decumulation paths (retirement income distributions) processed on a monthly cycle.
- Inflation-Adjusted Projections: Toggle inflation discounting to view all future value percentiles in inflation-adjusted, real-purchasing-power dollars.
- Capital Gains Taxes & Tax Drag: Simulates realized capital gains tax liabilities on sold assets during periodic rebalances or withdrawals, tracking the cost basis of each asset. Toggle taxable vs. tax-sheltered accounts (0% tax drag).
- Transaction Fees: Model percentage-based brokerage commissions and trade fees that drag down growth during rebalances, deposits, and withdrawals.
- π Dynamic Portfolio Rebalancing Simulator: Run simulations with different rebalancing frequencies (None, Monthly, Annually) or dynamic Tolerance Bands (e.g., rebalance only when an asset's weight drifts by more than 5% absolute from its target allocation) to study how transaction friction and tax drag affect compound growth.
-
π Institutional-Grade Performance & Risk Metrics:
- CAGR: (Compound Annual Growth Rate) computed across the median path.
- Sharpe Ratio: Reward-to-volatility index (using a 0% baseline risk-free rate).
- Sortino Ratio: Downside-adjusted reward index utilizing downside semi-standard deviation.
- Maximum Drawdown: Peak-to-trough historical paper loss.
- 95% Value at Risk (VaR): The worst-case capital loss threshold at a 95% confidence interval.
- 95% Conditional Value at Risk (CVaR / Expected Shortfall): The average expected portfolio loss if outcomes land in the worst 5% tail.
-
π Rich Interactive Charting (Recharts):
- Monte Carlo Projections: Displays a clean statistical "cone" (10th percentile downside, 50th percentile median, 90th percentile upside), overlaid with 30 randomly selected simulated asset paths.
- Historical Backtester: Models historical portfolio growth alongside a customizable benchmark index (e.g., SPY, QQQ, IWM, BTC-USD) over the historical range.
- Asset Allocation: A beautiful, responsive Pie Chart visualizing portfolio composition.
-
π Optimized Search Engine Visibility (SEO): Fully indexed and optimized with custom Open Graph & Twitter Cards metadata, search engine structured data JSON-LD schemas, automated XML sitemaps, crawler instructions (
robots.txt), and rich accessibility fallbacks for non-JavaScript search crawlers. - β‘ High-Performance Web Workers: The intensive statistical simulation loop is executed entirely in a separate background thread via HTML5 ESM Web Workers. Computes thousands of years of simulated paths with full cash flow and tax histories in milliseconds without blocking the browser UI, ensuring a consistent 60 FPS.
- π Adaptive Dark Mode & Tailwind v4 UI: Beautiful, modern, dark-first UI optimized with Tailwind CSS v4, smooth Framer Motion transitions, responsive layouts, unified light/dark styling, and intuitive informational tooltips for all settings.
To model asset prices under continuous-time assumptions, we model the spot price
In a discrete simulation step over interval
Where:
-
$\mu_i$ is the annualized expected return (historical CAGR) of asset$i$ . -
$\sigma_i$ is the annualized volatility of asset$i$ . -
$X_i$ is a correlated standard normal variable.
To preserve historical cross-asset relationships, we compute the covariance matrix
Where
Note: The math engine applies diagonal regularization ($10^{-8}$) to ensure strict positive-definiteness on highly correlated asset matrices.
In reality, market volatility is time-varying and exhibits "volatility clustering" (quiet periods follow quiet periods, and high-volatility shocks trigger sustained high volatility). We implement a discrete GARCH(1,1) recurrence model:
Where:
-
$h_t$ is the conditional daily variance of return on day$t$ . -
$\omega$ is the baseline variance constant, calibrated dynamically from historical annualized volatility:$$\omega = V_L \cdot (1 - \alpha - beta)$$ where$V_L = \frac{\sigma^2}{252}$ is the daily unconditional historical variance, and we set standard financial coefficients$\alpha = 0.08$ and$\beta = 0.90$ . -
$\varepsilon_{t-1} = R_{t-1} - \mathbb{E}[R]$ is the return shock residual on the previous day. -
$h_{t-1}$ is the prior day's conditional daily variance.
Under GARCH, the diffusion step is modeled using the time-varying daily volatility
To incorporate realistic tail risk and discontinuous "black swan" market crashes, we extend Geometric Brownian Motion by adding a Poisson-driven jump-diffusion process:
Where:
-
$\lambda$ is the jump intensity (expected number of shocks per year, set to 1.0). -
$dN_t$ is a Poisson process ($dN_t = 1$ with probability$\lambda dt$ , and$0$ otherwise). -
$Y_t - 1$ is the random percentage jump size. The log-return of the jump follows a normal distribution:$$\ln(Y_t) \sim \mathcal{N}(\mu_J, \sigma_J^2)$$ The model employs category-specific parameters to simulate realistic asset behaviors:-
Bonds (Flight-to-Safety):
$\mu_J = +0.015$ ,$\sigma_J = 0.01$ (Bonds jump upward during market shocks). -
Stocks / ETFs:
$\mu_J = -0.05$ ,$\sigma_J = 0.06$ (Equities crash during market shocks). -
Cryptocurrency:
$\mu_J = -0.10$ ,$\sigma_J = 0.18$ (Crypto suffers severe capitulations).
-
Bonds (Flight-to-Safety):
-
$k = \mathbb{E}[Y_t - 1] = \exp\left(\mu_J + \frac{1}{2}\sigma_J^2\right) - 1$ is the expected relative jump size. Subtracting the Merton compensator term$\lambda k dt$ from the drift prevents the addition of jumps from biasing the long-term expected rate of return$\mu$ .
Under the non-parametric Historical Bootstrapping model, we do not assume returns are normally distributed, which is critical for assets like Crypto with high skewness and kurtosis.
To avoid destroying short-term trends, momentum, and serial autocorrelation, we implement a Moving Block Bootstrap. Rather than sampling individual days independently:
- The engine divides the historical dataset into contiguous, overlapping blocks of size
$b$ (default$b = 10$ trading days). - The engine randomly selects a block starting day
$s$ and samples$b$ consecutive daily returns: $$B = [\mathbf{R}{s}, \mathbf{R}{s+1}, \dots, \mathbf{R}_{s+b-1}]$$ - We sample the entire row (returns of all assets on the same day) simultaneously, perfectly preserving cross-asset covariance structures while capturing local autocorrelation and momentum.
The engine runs a full, step-by-step balance ledger for each simulated path, managing cash additions, withdrawals, fees, and capital gains taxes.
-
Monthly Deposits (
$C$ ) / Withdrawals ($W$ ): Adjusted dynamically for compounding inflation over time:$$C_t = C_0 \cdot (1 + I)^{t}$$ where$I$ is the annual inflation rate, and$t$ is the elapsed fraction of a year. -
Real purchasing power: If inflation adjustment is enabled, final portfolio values and yearly snapshots are discounted back to "Year 0" real dollars:
$$V_{\text{real}, t} = \frac{V_{\text{nominal}, t}}{(1 + I)^{t}}$$
When a portfolio is rebalanced (either on a calendar schedule or when any asset's weight drifts beyond the absolute Rebalancing Threshold
-
Sells are processed first: For any asset
$i$ whose current value exceeds its target value ($V_i > V_{\text{target}, i}$ ), the engine sells the excess amount:$$A_{\text{sold}, i} = V_i - V_{\text{target}, i}$$ -
Cost Basis realization: The cost basis
$B_i$ of the asset is adjusted proportionally. The sold fraction is$f_i = \frac{A_{\text{sold}, i}}{V_i}$ , which realizes a taxable gain:$$G_{\text{realized}, i} = \max\left(0, A_{\text{sold}, i} - f_i \cdot B_i\right)$$ -
Tax realization: If the account is taxable, a capital gains tax liability is incurred:
$$\text{Tax}i = G{\text{realized}, i} \cdot \tau$$
where
$\tau$ is the capital gains tax rate. The asset's cost basis is decremented by$f_i \cdot B_i$ . -
Buys are processed next: The proceeds are allocated to underweighted assets (
$V_i < V_{\text{target}, i}$ ), increasing their cost basis dollar-for-dollar. -
Transaction Fees: A transaction fee drag is calculated on the total volume traded (the sum of all sells and buys):
$$\text{Fee} = \left( \sum A_{\text{sold}, i} + \sum A_{\text{bought}, j} \right) \cdot \theta$$ where$\theta$ is the transaction fee percentage. -
Drag deduction: The total drag (
$\text{Fee} + \sum \text{Tax}_i$ ) is subtracted proportionally from all asset allocations, capturing the realistic drag on long-term compound growth.
The codebase is highly modular, separating state management, side effects, statistical calculations, and rendering.
monte-carlo-portfolio/
βββ .github/workflows/ # GitHub Actions deployment pipelines
βββ src/
β βββ assets/ # Static media and SVG assets (Vite/React icons)
β βββ components/ # React Presentation & Chart Components
β β βββ report/ # Modular simulation executive report subcomponents
β β β βββ BenchmarkComparison.tsx # Historical asset backtester vs. customizable benchmark
β β β βββ CompositionAnalysis.tsx # Portfolio diversification audit & HHI index calculations
β β β βββ DistributionHistogram.tsx # Final wealth terminal value density distribution histogram
β β β βββ ExecutiveSummary.tsx # Quick view of simulation parameters & health scorecard
β β β βββ ExportBar.tsx # Copy text memo & file download (.txt) helper
β β β βββ GoalSolver.tsx # Interactive forward target-wealth probability solver
β β β βββ MethodologySettings.tsx # Transparent math modeling and configuration values
β β β βββ PerformanceProjection.tsx # Statistical trajectory bands and outcome percentiles
β β β βββ RiskAssessment.tsx # Downside metrics & tail-risk calculations (95% VaR & CVaR)
β β β βββ SimulationReportSkeleton.tsx # Shimmering skeleton loading placeholder
β β β βββ StrategicRecommendations.tsx # Custom, rule-based portfolio optimizations & alerts
β β βββ AllocationPieChart.tsx # Allocation weight layout
β β βββ AssetInput.tsx # Portfolio custom setup panel
β β βββ DashboardCharts.tsx # Charts parent wrapper
β β βββ HistoricalChart.tsx # Recharts historical comparison
β β βββ InfoTooltip.tsx # Contextual explanatory tooltips
β β βββ MethodologyDocs.tsx # MathJax mathematical methodology documentation
β β βββ MetricsDisplay.tsx # KPI stats (Sharpe, Sortino, VaR, CVaR, Taxes)
β β βββ MonteCarloChart.tsx # Percentile cone and sample paths
β β βββ Navbar.tsx # Header and Dark Mode controls
β β βββ SimulationControls.tsx # Sliders (years, runs, deposits, inflation, taxes)
β β βββ SimulationReport.tsx # Comprehensive, exportable analytical report parent
β βββ data/
β β βββ commonAssets.json # Built-in fallback template metadata
β βββ hooks/ # Custom React state and side-effect hooks
β β βββ useHistoricalBacktest.ts # Debounced historical backtesting hook
β β βββ usePortfolioState.ts # User designer form and model states
β β βββ useSimulation.ts # Worker orchestration and thread safety
β βββ services/
β β βββ dataService.ts # Yahoo Finance CORS fetcher & search APIs
β βββ types/ # TypeScript interfaces & types
β β βββ index.ts # Shared TypeScript type definitions
β βββ utils/
β β βββ colors.ts # Dynamic tailwind color generation
β β βββ mathEngine.ts # Core quantitative mathematical algorithms
β βββ workers/
β β βββ simulationWorker.ts # Web Worker thread background simulation loops
β βββ index.css # Tailwind directives and custom variables
β βββ main.tsx # Application entry-point
β βββ App.tsx # Primary layout orchestrator
βββ index.html # Main index file
βββ package.json # NPM dependencies & task configurations
βββ vite.config.ts # Bundler config (supports ESM workers)
Make sure you have Node.js (v18+) and npm installed on your machine.
-
Clone the repository:
git clone https://github.com/jsonfm/monte-carlo-portfolio.git cd monte-carlo-portfolio -
Install dependencies:
npm install
-
Start the local development server:
npm run dev
The application will be running locally at http://localhost:5173.
-
Build for production:
npm run build
This bundles and compiles the application into highly optimized assets in the
./distfolder. -
Preview production build locally:
npm run preview
- React 19 - Declarative UI development
- Vite 8 - Super-fast frontend bundler
- Tailwind CSS v4 - Utility-first styling with advanced CSS variable engines
- Recharts - Beautiful, interactive charting
- better-react-mathjax - High-performance client-side MathJax equation rendering
- Framer Motion - Fluent UI transitions and micro-interactions
- Lucide React - Clean and consistent modern vector icons
This project includes a fully automated GitHub Actions pipeline (.github/workflows/deploy.yml) that builds and deploys the application to GitHub Pages on every push to the main or master branch.
To configure GitHub Pages manually for your fork:
- Go to your repository settings on GitHub.
- Navigate to Pages in the left sidebar.
- Set the Source under Build and deployment to GitHub Actions.
- Once you push changes to
main, the deployment job will run and compile your static app, outputting it directly to the designated static site URL.
This project is open-source and licensed under the MIT License. Feel free to use, modify, and distribute it as needed.