Methodology

Every formula, written down

Atlas’s outputs are mechanical computations on the data you upload. This page is the reference for every metric — what the math actually is, what assumptions it bakes in, and where it falls short. If a number Atlas shows you doesn’t match a definition here, it’s a bug.

Returns

Period return is computed as (end_value - start_value + cashflows) / start_value, where cashflows are external deposits or withdrawals over the window. Atlas reports daily, MTD, QTD, YTD, 1Y, 3Y, 5Y, and inception-to-date returns when the underlying price history covers the window.

Time-weighted return (TWR) chains daily sub-period returns to neutralize the timing of contributions: TWR = ∏ (1 + r_i) - 1. This is the comparable return metric for benchmarking against an index. Atlas uses TWR for the equity curve and benchmark comparisons.

Money-weighted (IRR)answers the personal question “what was my realized rate of return given when I actually contributed money?” — the IRR of all cashflows plus the current market value as a terminal flow. Solved by Newton-Raphson with bisection fallback. Atlas reports IRR for private-asset positions where the contribution timing is everything; for public securities IRR is available but TWR is the lead metric.

Risk metrics

All risk metrics use daily log returns over a rolling 252-day window unless otherwise noted. The risk-free rate defaults to the trailing 3-month Treasury yield (FRED series DGS3MO), updated daily.

  • Sharpe ratio = (annualized excess return) / (annualized volatility). Daily excess returns are annualized by ×252; daily volatility is annualized by ×√252.
  • Sortino ratio uses only the standard deviation of returns below the minimum-acceptable-return (which Atlas sets to the risk-free rate). Penalizes downside, ignores upside.
  • Calmar ratio = annualized return / |max-drawdown|. The risk-adjusted-return metric for long-horizon investors who care more about peak-to-trough pain than day-to-day vol.
  • Beta = covariance(portfolio, benchmark) / variance(benchmark). Computed against SPY by default. Beta of 1.0 means moves 1:1 with the market on average.
  • Jensen’s alpha is the intercept from the daily-return regression r_p - r_f = α + β (r_b - r_f) + ε, annualized.
  • Tracking error = annualized standard deviation of (r_p - r_b). Information ratio = (annualized active return) / tracking error.
  • Upside / downside capture= average portfolio return on benchmark-positive (negative) days, divided by the benchmark’s average on those days. 1.10 / 0.85 means you capture 110% of the upside and 85% of the downside.

VaR & CVaR

Atlas reports both methods at the 95% and 99% confidence levels.

  • Historical VaR at 95% = the 5th-percentile daily loss observed over the lookback window. Non-parametric; captures fat tails actually present in your history.
  • Parametric VaR at 95% = μ - 1.645σ, assuming daily returns are normally distributed. Underestimates tail risk in real markets — use historical when in doubt.
  • CVaR (expected shortfall)= the average loss on the days that exceed the VaR threshold. Answers “when it’s a bad day, how bad on average?”

Both are reported in dollars (NAV × percentile loss) and as a percent of NAV. They are daily measures; multiplying by √N to scale to longer horizons assumes IID normality and is not done by Atlas without a horizon parameter.

Stress tests

The stress engine runs each scenario by applying a closed-form shock to every position:

  • Equities: P&L_i = value_i × β_i × spy_shock. Beta defaults to 1.0 when unknown.
  • Sector overlays(custom sandbox only): added to the broad-equity shock if the position’s sector classification matches the overlay (Tech, Financials, Energy, Healthcare, Consumer Discretionary, Real Estate).
  • Bonds: P&L_i = -duration_i × yield_change × value_i. Duration is looked up from a per-symbol table (e.g., AGG: 6.0y, TLT: 16.5y, SHY: 1.8y); unknowns default to 5.5y. High-yield bonds add a credit-spread leg using the same duration.
  • International equity: applies a 0.5 USD-beta on top of the broad equity shock to capture the foreign-FX adjustment.
  • Gold / oil / crypto: 1:1 with their respective shocks. Cash is cash.

Historical scenarios (1987, 1998 LTCM, 2000 dot-com, 2008 GFC, March 2020 COVID, etc.) hardcode the SPY drop and 10Y yield move that actually occurred during the worst N-day window. Parametric scenarios are user-defined point shocks. The custom sandbox lets you dial in eight macro shocks plus six sector overlays.

What stress tests do not capture: liquidity risk, gap risk on weekends, model risk in your beta/duration estimates, leverage in derivatives positions, and the correlation breakdown that historically accompanies real crises. Treat outputs as a sensitivity check, not a forecast.

Factor regression

Atlas runs a Fama-French 3-factor + Momentum (FFCM) regression on your daily returns:

r_p - r_f = α + β_M (Mkt-RF) + β_S SMB + β_V HML + β_W WML + ε

  • Mkt-RF: market excess return.
  • SMB (size): small-minus-big — positive loading = small-cap tilt.
  • HML (value): high-minus-low book/market — positive loading = value tilt.
  • WML (momentum): winners-minus-losers — positive loading = momentum tilt.

Loadings are reported with their t-statistic and a significance badge when |t| ≥ 2 (~95% confidence). Factor time series come from Ken French’s research data library.

Monte Carlo

The Monte Carlo simulator uses geometric Brownian motion (GBM) with constant drift and volatility:

V(t+dt) = V(t) × exp((μ - ½σ²) dt + σ √dt × Z) + contribution

where Z ~ N(0,1). Default 10,000 paths over the user-supplied horizon, monthly time steps. The fan-chart percentiles (10/50/90) come from sorting the terminal distribution. The probability of reaching a target equals the fraction of paths that finish above the target.

The Goals page uses 2,000 paths (smaller portfolio of paths is plenty for stable funded-probability estimates) with monthly steps and end-of-month contributions.

Limitations:GBM doesn’t model fat tails, regime shifts, mean reversion, or correlation breakdown. Real markets exhibit all four. The funded probability is a useful sanity check; calling it a guarantee would be malpractice.

Concentration

Atlas reports five concentration metrics on the Allocation tab:

  • HHI (Herfindahl-Hirschman Index) = Σ (w_i × 100)². Computed on percentage weights so the absolute scale is 0-10,000. Below 1,500 = unconcentrated; 1,500-2,500 = moderately concentrated; above 2,500 = highly concentrated (DOJ antitrust thresholds, applied here as a portfolio equivalent).
  • Top 1, Top 5, Top 10: simple sums of the largest position weights.
  • Effective N = 1 / Σ w_i². The diversification-equivalent count: a perfectly equal-weighted book of 30 stocks has effective N = 30; one with one 50% position and 29 of 1.7% each has effective N ≈ 4.

Tax lots & wash-sale screening

Atlas matches sells to opens using FIFO by default. Other methods (LIFO, HIFO, Lowest-cost-first) are available in the Sale Tax Projection tool. Realized gain is (proceeds - cost_basis), classified as ST if held ≤365 days and LT otherwise.

TLH candidate detection:any open lot in a taxable account with unrealized loss ≥ $500 is flagged. Wash-sale screening checks for any same-symbol BUY in the past 30 days within the visible ledger — and only within the visible ledger. Atlas cannot see trades at other brokerages, in your spouse’s accounts, or in IRAs (where the IRS still applies wash-sale rules per Rev. Rul. 2008-5). If the screen says “clear” it means clear within Atlas’s view; the actual rule is broader.

Asset location

Each (account category, asset class) pair gets an affinity scorein [0, 1] where 1 means “textbook home.” The score reflects the conventional tax-efficiency framework from the Bogleheads / CFA Institute / practitioner literature — for instance, high-yield bonds in a taxable account score low because their ordinary-income interest is taxed at marginal rates, while the same fund in a tax-deferred account defers the entire bill.

Categories are bucketed by their tax structure: taxable, tax-deferred, tax-free (Roth), medical (HSA), education (529), custodial (UGMA/UTMA), trust, and other (annuity / DAF). The per-pair commentary is curated for ~40 high-value (category, class) combinations and falls back to a category-level template otherwise.

The score is positional (where would the literature put this?) — it is nota rating of your investment decisions. Holding broad US equity in taxable scores high because that’s where it conventionally goes; that doesn’t mean Atlas is recommending you buy more.

Drawdown analysis

A drawdown episodebegins on the day the equity curve crosses below a new high-water mark and ends on the day it recovers above the prior peak. Atlas reports per episode: peak date, trough date, recovery date (or “ongoing”), depth (% from peak), duration (peak to trough, days), and recovery time (trough to recovery, days). Compared in the same window against the benchmark. The underwater curve is (value(t) - rolling_max(value, t)) / rolling_max.

Data sources & caveats

  • Prices: Polygon.io (primary) with Yahoo Finance via yfinanceas a fallback for symbols Polygon doesn’t cover. Daily adjusted close.
  • Macro: FRED (Federal Reserve Bank of St. Louis) for Treasury yields, CPI, unemployment, and the risk-free rate.
  • Factor data:Ken French’s research library (Fama-French 3-factor + momentum daily returns).
  • AI:Anthropic Claude (Opus 4.7 and Sonnet 4.6) for the Atlas Brief, What-If commentary, and Devil’s Advocate. Prompts and JSON contracts are versioned in the codebase. Anthropic does not train on your data.
  • What we do not have:real-time prices, level 2 quotes, options chains beyond the user’s position data, intraday tick data, hedge-fund return series, private equity NAV marks beyond what you upload.

Last reviewed May 2026. If a calculation changes, this page changes too. Found a number that doesn’t match? Report it via the contact form.