Foliolytic Methodology

Last updated:

Every metric Foliolytic computes, how it's computed, what data it uses, what edge cases the implementation handles, and where Foliolytic differs from typical online calculators. No black box.

Quick Answer

What's the most important methodological choice in Foliolytic?

Foliolytic uses actual daily U.S. Treasury bill yields from FRED as the risk-free rate, matched to each calendar day of your portfolio history. Most online calculators use a static 2% or 3% assumption, which can change Sharpe and Sortino ratios by 0.3–0.5 in environments where T-bill yields are 5%. Combined with daily-resolution drawdown reconstruction (not month-end snapshots) and Newton-Raphson XIRR with bisection fallback, this puts Foliolytic's numbers in line with institutional asset-management methodology.

Real Treasury yields · Daily granularity · Newton-Raphson XIRR
Metrics covered
  1. Sharpe Ratio
  2. Sortino Ratio
  3. XIRR (Money-Weighted Return)
  4. TWR (Time-Weighted Return)
  5. Beta
  6. Alpha (Jensen's)
  7. R-Squared
  8. Maximum Drawdown
  9. Value at Risk (VaR)
  10. CVaR (Expected Shortfall)
  11. Calmar Ratio
  12. Treynor Ratio
  13. Information Ratio
  14. Capture Ratio (Up/Down)
  15. Tracking Error
  16. Probabilistic Sharpe Ratio (PSR)
  17. Hurst Exponent
  18. Ulcer Index
  19. Batting Average
  20. Burke Ratio
  21. Martin Ratio
  22. Sterling Ratio
  23. Modigliani M²

Sharpe Ratio

Formula

Sharpe = (R̄_p - R_f) · √252 / (σ(r_d) · √252)
where r_d = daily log returns and R̄_p, σ are computed on those daily log returns.

Inputs

Daily portfolio value series reconstructed from your transactions. Daily 3-month U.S. Treasury bill yield from FRED, matched to each calendar day. 252 trading days per year for stock-only portfolios; 365 for crypto-only; appropriate per-asset blend for mixed.

Edge cases & numerical handling

If the portfolio history is shorter than 30 days, Sharpe is suppressed (sample size too small for meaningful inference). If σ < 1e-9 (effectively flat portfolio), Sharpe is reported as null rather than infinity.

Differences from common calculators

Most online calculators use a static 2% or 3% risk-free rate. Foliolytic uses actual daily T-bill yields. In high-rate environments (2023–2025), this changes Sharpe ratios by 0.3–0.5 vs. fixed-rate calculators.

Sortino Ratio

Formula

Sortino = (R̄_p - R_f) · √252 / DD
where DD = √( (1/n) · Σ min(r_d - r_f_d, 0)² ) · √252

Inputs

Same daily portfolio series and daily risk-free rates as Sharpe. Threshold for the 'downside' is the daily risk-free rate, not zero.

Edge cases & numerical handling

Downside deviation is computed using only days where r_d < r_f_d. Days where r_d ≥ r_f_d contribute zero to the sum but are counted in n. This matches Sortino's original 1980s specification.

Differences from common calculators

Some calculators use zero as the downside threshold, which is mathematically convenient but theoretically incorrect. The original Sortino paper specifies the minimum acceptable return (MAR), which is most naturally interpreted as the risk-free rate.

XIRR (Money-Weighted Return)

Formula

0 = Σᵢ CFᵢ / (1 + XIRR)^( (dᵢ - d₀) / 365 )
solved via Newton-Raphson with bisection fallback.

Inputs

Full transaction history with dated cash flows. Includes contributions (negative), withdrawals (positive), terminal portfolio value at the most recent date (positive), and any cash dividends received as separate flows.

Edge cases & numerical handling

Newton-Raphson iterates with an initial guess of 0.10. If the derivative goes to zero or the iteration diverges, the algorithm falls back to bisection on [-0.99, +5.0]. Convergence tolerance: 1e-10. Cash flows below $0.01 are ignored. Result is sanity-capped at [-0.99, +5.0] per year — values outside this range almost always indicate data errors (currency mix-ups, decimal point shifts, crypto reporting glitches).

Differences from common calculators

Excel's XIRR uses the same Newton-Raphson approach but doesn't sanity-cap, so it returns absurd values (multi-billion percent) for messy crypto data. Foliolytic's cap prevents these from contaminating the dashboard.

TWR (Time-Weighted Return)

Formula

TWR = Π_i (1 + R_i) - 1
where R_i is the return of period i computed between cash flow events.

Inputs

Daily portfolio values, dates of all external cash flows. The period between two consecutive flows is one return-window.

Edge cases & numerical handling

Sub-period returns are chained geometrically to remove the timing effect of contributions and withdrawals. Days with no flows produce single-day return periods. Multi-day periods between flows are compounded.

Differences from common calculators

TWR is the standard for evaluating asset-level performance (what fund managers report). Money-weighted return (XIRR) is the standard for evaluating an investor's actual experience. Foliolytic computes both — they often differ by several percentage points.

Beta

Formula

β = Cov(r_p, r_m) / Var(r_m)
computed via OLS regression of daily portfolio returns r_p on daily benchmark returns r_m, using excess-of-risk-free-rate returns.

Inputs

Daily portfolio returns. Daily benchmark returns (S&P 500 by default; configurable to QQQ, VT, or any custom benchmark). Daily 3-month T-bill yield to compute excess returns.

Edge cases & numerical handling

Minimum 30 days of overlap between portfolio and benchmark. Days where either has missing data are dropped. Outliers (>5σ) are flagged but not removed — beta is a robust statistic and removing outliers tends to bias it upward.

Differences from common calculators

Some calculators run beta on raw returns (not excess returns), which is mathematically equivalent only if the risk-free rate is constant. With time-varying T-bill rates, regressing on excess returns is more correct.

Alpha (Jensen's)

Formula

α = R̄_p - [R_f + β · (R̄_m - R_f)]
where all quantities are annualized.

Inputs

Same as beta, plus the regression intercept (the OLS constant term).

Edge cases & numerical handling

Alpha is reported in annualized percentage points. Statistical significance (t-stat) is computed alongside — alpha values without t-stat > 1.5 should be treated as noise, not skill.

Differences from common calculators

Many spreadsheet alphas are computed as a pure intercept of unscaled regression, missing the annualization step. Foliolytic always reports annualized alpha so the number is directly interpretable as 'extra return per year vs. benchmark-equivalent risk exposure.'

R-Squared

Formula

R² = 1 - SS_residual / SS_total
where SS_residual = Σ(r_p - r_p_predicted)² and SS_total = Σ(r_p - r̄_p)²

Inputs

Same regression as beta. R² is the coefficient of determination from that fit.

Edge cases & numerical handling

If R² < 0.05 against the chosen benchmark, the portfolio's beta and alpha estimates are flagged as statistically meaningless — there's no linear relationship to interpret.

Differences from common calculators

Foliolytic treats high R² (≥ 0.95 with low active share) as a 'closet indexer' signal — see Recent Major Updates in CLAUDE.md for the badge definition.

Maximum Drawdown

Formula

MaxDD = min over t of [V_t / max(V_s : s ≤ t) - 1]

Inputs

Daily portfolio value series across full history. Reconstruction uses transaction-by-transaction valuation, not period-end snapshots.

Edge cases & numerical handling

Daily granularity is used for stocks and crypto. Intraday peaks/troughs are not captured — Foliolytic's max drawdown is daily-resolution. Recovery time (days from peak to next day at or above peak) is reported alongside.

Differences from common calculators

Many trackers compute drawdown from monthly NAVs, which understates true peak-to-trough by an average of 20–30%. Daily reconstruction captures more of the path.

Value at Risk (VaR)

Formula

Historical: VaR_α = quantile(r_d, 1 - α)
Parametric (Gaussian): VaR_α = μ - z_α · σ
Monte Carlo: simulate from fitted distribution and take 1-α quantile.

Inputs

Full daily return history. Confidence level α (default: 95% and 99%). For parametric VaR, also requires sample mean and standard deviation. For Monte Carlo, fits a distribution (Gaussian by default; t-distribution for fat-tailed assets).

Edge cases & numerical handling

Historical VaR requires at least 60 days of returns (statistical minimum); 250+ days strongly preferred. Parametric VaR can be unreliable for non-Gaussian return distributions. Foliolytic reports all three side-by-side so the gap (or lack thereof) is visible.

Differences from common calculators

Most calculators only report parametric VaR. Foliolytic shows historical, parametric, and Monte Carlo. For fat-tailed assets (crypto, leveraged equity, single stocks), parametric VaR can underestimate true loss potential by 50%+.

CVaR (Expected Shortfall)

Formula

CVaR_α = E[Loss | Loss ≥ VaR_α]
empirically: mean of returns worse than VaR_α threshold.

Inputs

Same as historical VaR. CVaR uses only days where loss exceeded the VaR threshold.

Edge cases & numerical handling

Conditional on the tail being non-empty: requires at least 5 observations beyond the VaR threshold for a meaningful estimate. With 250 days of history at 95% VaR, this gives 12–13 tail observations — borderline.

Differences from common calculators

Many sources report only VaR. CVaR (also called Expected Shortfall) tells you not just the threshold but the average severity beyond it — more useful for capital planning. Basel III for banks now mandates CVaR over VaR for these reasons.

Calmar Ratio

Formula

Calmar = R_annual / |MaxDD|

Inputs

Annualized return (CAGR over the full history). Maximum drawdown over the full history.

Edge cases & numerical handling

Requires both inputs to be non-trivial. If MaxDD < 1% (essentially no drawdown), Calmar is reported as 'n/a' rather than infinity. If R_annual ≤ 0, Calmar can still be computed but is reported with explicit context (high Calmar from low drawdown is impressive only if return is also positive).

Differences from common calculators

Some implementations use 36-month rolling Calmar instead of full-period. Foliolytic computes full-period Calmar by default; rolling Calmar is available in the advanced metrics tab.

Treynor Ratio

Formula

Treynor = (R̄_p - R_f) / β

Inputs

Annualized excess return over the period. Beta from the same regression used for the beta metric.

Edge cases & numerical handling

If β is near zero or negative, Treynor becomes meaningless or counterintuitive. Foliolytic flags portfolios with |β| < 0.2 as 'low-beta' and shows Treynor with a warning indicator.

Differences from common calculators

Treynor is most useful for well-diversified portfolios where idiosyncratic risk has been diversified away. For single stocks or concentrated portfolios, Sharpe is the more appropriate metric — Treynor will overstate risk-adjusted return because firm-specific risk isn't captured by beta.

Information Ratio

Formula

IR = (R̄_p - R̄_b) / σ(r_p - r_b)
where the denominator is the tracking error.

Inputs

Daily portfolio returns and daily benchmark returns. Both annualized via √252.

Edge cases & numerical handling

Requires at least 60 days of paired data. If tracking error < 0.5% (essentially indexed), IR is suppressed because numerator divided by a near-zero denominator gives unstable estimates.

Differences from common calculators

Some implementations use monthly returns (the official GIPS standard). Foliolytic uses daily for higher resolution; the daily-vs-monthly difference is small for IR (typically within 5%).

Capture Ratio (Up/Down)

Formula

Up-Capture = R̄_p_up / R̄_b_up
(over months where R_b > 0)
Down-Capture = R̄_p_down / R̄_b_down
(over months where R_b < 0)

Inputs

Monthly portfolio and benchmark returns. Computed on monthly granularity to match the standard reporting convention.

Edge cases & numerical handling

Requires at least 12 months in each regime (up/down) for meaningful estimates. Months where benchmark return is exactly zero are dropped. The capture ratios are reported as percentages.

Differences from common calculators

Foliolytic also reports capture-ratio quality (the spread up_capture - down_capture) — the dream profile is high up, low down.

Tracking Error

Formula

TE = σ(r_p - r_b) · √252

Inputs

Daily portfolio and benchmark returns. Difference series is computed daily; TE is the annualized standard deviation.

Edge cases & numerical handling

Same minimum-data requirements as IR (≥ 60 days). For very tightly indexed portfolios (< 0.5% TE), the metric is reported but flagged because tracking error this low usually means closet indexing.

Differences from common calculators

Some calculators use ex-ante (forward-looking, factor-based) tracking error rather than ex-post (historical). Foliolytic always uses ex-post — the actual realized deviation from the benchmark.

Probabilistic Sharpe Ratio (PSR)

Formula

PSR(SR*) = Φ( (SR_obs - SR*) · √(n-1) / √(1 - γ_3·SR_obs + ((γ_4-1)/4)·SR_obs²) )
where γ_3 is sample skew and γ_4 is sample kurtosis.

Inputs

Observed Sharpe ratio, sample size n, sample skew, sample kurtosis. Benchmark SR* (defaults to 0).

Edge cases & numerical handling

Quantiles for PSR are bootstrapped from rolling 5-year SPY total-return windows (1101 windows from 1928–2025), so the score reflects sample-size-aware reference distributions. The PSR formula has √(n-1) in the numerator, so reference distributions must use windows matching the user's history length — see April 2026 metrics v6 fix in CLAUDE.md.

Differences from common calculators

Most online calculators don't report PSR at all. The few that do typically use a fixed reference distribution that doesn't account for sample size, leading to user portfolios with realistic 5-year histories scoring 'poor' even at the BLP credibility threshold.

Hurst Exponent

Formula

log(R/S)_n = H · log(n) + c
fit via OLS on log-window-size axis.

Inputs

Daily return series. Window sizes typically range from 10 to T/2 logarithmically.

Edge cases & numerical handling

Direction is treated as 'neutral' rather than 'higher-is-better' — H = 0.5 (random walk) is the conceptual midpoint, with deviations either way being informative. Quantiles bootstrapped from rolling 5-year SPY windows, same as PSR.

Differences from common calculators

Foliolytic uses the rescaled-range (R/S) method. Detrended fluctuation analysis (DFA) is available as an alternative in the advanced tab; both typically give very similar results for the equity returns most users hold.

Ulcer Index

Formula

UI = √( (1/n) · Σ DD_i² ) · 100

Inputs

Daily drawdown series (percentage off running maximum).

Edge cases & numerical handling

Reported as a percentage. Like all drawdown-based metrics, sensitive to the resolution of the underlying value series — daily reconstruction matters.

Differences from common calculators

Some implementations report UI as a fraction; Foliolytic uses Peter Martin's original convention of percentage * 100 for direct comparison with published research.

Batting Average

Formula

BA = (months where r_p > r_b) / (total months)

Inputs

Monthly portfolio and benchmark returns.

Edge cases & numerical handling

Months where r_p == r_b are split half-and-half. Minimum 12 months for meaningful estimate.

Differences from common calculators

Foliolytic also reports a paired metric, batting-average-vs-zero (months where r_p > 0 / total), useful for absolute-return strategies.

Burke Ratio

Formula

Burke = (R_annual - R_f) / √(Σ DD_i²)

Inputs

Annualized return, risk-free rate, all drawdown values over the period.

Edge cases & numerical handling

Similar to Calmar but penalizes the sum of squared drawdowns instead of just the maximum. Less sensitive to a single black-swan drawdown than Calmar.

Differences from common calculators

Foliolytic's Burke baselines were recalibrated to FF_100Y_BUFFETT_ANCHORED in v6.5 (April 2026) — see CLAUDE.md for the calibration story.

Martin Ratio

Formula

Martin = (R_annual - R_f) / UI

Inputs

Annualized excess return, Ulcer Index.

Edge cases & numerical handling

Direct cousin of Calmar and Burke; uses Ulcer Index as the path-risk denominator.

Differences from common calculators

Most calculators don't compute Martin Ratio. Foliolytic includes it because Ulcer-based metrics correlate well with subjective investor pain.

Sterling Ratio

Formula

Sterling = R_annual / (mean of N worst drawdowns - 10%)
N = 3, period = 36 months by default.

Inputs

Annualized return. List of all completed drawdowns within the lookback window, ranked by depth.

Edge cases & numerical handling

The -10% adjustment is a fixed offset from Sterling's original formulation. If fewer than N completed drawdowns exist, the metric is suppressed.

Differences from common calculators

Sterling is more sensitive than Calmar to a series of medium drawdowns. Foliolytic's baselines (FF_100Y_BUFFETT_ANCHORED) were recalibrated in v6.5.

Modigliani M²

Formula

M² = Sharpe · σ_market + R_f

Inputs

Portfolio Sharpe ratio, annualized standard deviation of the benchmark, annualized risk-free rate.

Edge cases & numerical handling

M² ≡ Sharpe rescaled to benchmark volatility. Whenever Sharpe bands change, M² bands MUST change identically — they are mathematically the same quantity.

Differences from common calculators

Many calculators compute Sharpe but skip M². M² is more interpretable for retail users because it's denominated in percentage points of return, not unit-less ratio.

General notes that apply across metrics

Daily granularity, not monthly

Every Foliolytic metric is computed from daily portfolio reconstruction, not month-end snapshots. This matters most for drawdown-based metrics (max drawdown, Calmar, Burke, Martin, Sterling, Ulcer): monthly NAVs typically understate true peak-to-trough drawdown by 20–30% because they miss intra-month dips. Daily granularity captures the path that actually happened.

Annualization conventions

Stock-only portfolios use 252 trading days. Crypto-only use 365 days (24/7 trading). Mixed portfolios use a per-asset blend, then recombine into a single annualized portfolio figure. Volatility scaling uses √n (variance scales linearly with time, so standard deviation scales with √time).

Log returns for compounding, arithmetic for display

Daily log returns are used internally for any metric requiring time-aggregation (variance, multi-period compounding, annualization). Arithmetic returns are used for display because they're more intuitive ('-30%' is more recognizable than 'log-return -0.357'). The two are equivalent at the daily level for typical equity returns; they diverge for extreme moves.

Outlier policy

Outliers are flagged but not removed. Removing outliers tends to bias variance and Sharpe estimates upward and is generally bad practice. The exception is where data clearly indicates an error — e.g., crypto trades misreported in cents instead of dollars, or currency-conversion glitches yielding 1000x price spikes. These are caught by the parser layer (see /about) and corrected before metrics computation.

Minimum sample sizes

Foliolytic suppresses metrics that require more data than is available. Sharpe and Sortino require ≥ 30 days. Beta, alpha, IR, tracking error require ≥ 60 days of paired data. Capture ratios require ≥ 12 months in each regime. PSR and Hurst require enough history to bootstrap reference distributions. When the minimum is not met, the metric shows '—' rather than a meaningless number.

Risk-free rate matching

For every metric that uses R_f (Sharpe, Sortino, Treynor, M², alpha, beta on excess returns), the daily 3-month T-bill yield is used and matched to each calendar day of the portfolio's history. The annualized R_f used in display is the time-weighted average of daily R_f over the portfolio's history. Most calculators use a single fixed R_f figure, which is wrong whenever rates moved.

Benchmark choice

S&P 500 (SPY total-return) by default. User-configurable to QQQ, VT, or any custom ticker. Beta, alpha, R², capture ratios, batting average, IR, and tracking error all recompute against the chosen benchmark. Crypto portfolios default to BTC for benchmark-relative metrics.

Updates and recalibration

Reference distributions for percentile-based scoring (PSR, Hurst, Sharpe quantiles, etc.) are recalibrated periodically as new market data arrives. The current calibration set is documented in the metricBaselines.js source file. Major recalibration events are logged with version tags (v6.4, v6.5) for transparency — see CLAUDE.md and the changelog at the top of metricBaselines.js.

All Foliolytic Calculators

Every metric below has its own dedicated calculator with worked examples, interpretation tables, and a free CSV upload tool.

Frequently Asked Questions

What's the difference between log returns and arithmetic returns?

Arithmetic returns ((P_t - P_(t-1)) / P_(t-1)) are intuitive and what investors usually mean by 'return'. Log returns (ln(P_t / P_(t-1))) have a critical mathematical property: they are additive across time. The 90-day log return equals the sum of 90 daily log returns. Arithmetic returns don't have this property — they compound geometrically. Foliolytic uses log returns internally for any time-aggregation and arithmetic returns for display.

Why is Foliolytic's Sharpe ratio different from my broker's?

Almost certainly because of the risk-free rate. Foliolytic uses actual daily 3-month T-bill yields from FRED. Most brokers and online calculators use a fixed assumption (often 2% or 0%). In an environment where T-bill yields are 5%, this can change Sharpe by 0.3–0.5 — a substantial difference.

How does Foliolytic handle stock splits?

Splits are applied retroactively to historical share counts and prices. A 4-for-1 split on AAPL in August 2020 retroactively quadruples your share count and quarters the historical price for all dates before the split. Portfolio value series remains continuous across the split — there is no jump in value, only in cosmetic per-share figures.

How are dividends handled?

Cash dividends are added to the portfolio cash balance on the ex-dividend date. They are not auto-reinvested. If your broker auto-reinvests, the resulting share purchases will appear in your transaction history and will be processed normally. Special dividends are handled the same way as regular cash dividends.

What benchmark does Foliolytic use?

S&P 500 (SPY total return) by default. The benchmark is configurable in the dashboard — you can pick any major index, ETF, or even a custom ticker. Beta, alpha, R², capture ratio, batting average, and tracking error all recompute against the chosen benchmark.

Are returns gross or net of fees?

Foliolytic computes returns from your transaction history as-is. If your broker deducts fees from positions or charges them as separate transactions, those flows are reflected. If fees are paid out of a separate cash account that's not in your CSV, they aren't captured. For most retail brokerage accounts (Fidelity, Schwab, Robinhood, IBKR), the on-platform fees are already reflected in transaction prices.

Try Foliolytic — Free, no signup

Run all the calculations described above against your own portfolio in seconds.

Analyze Your Portfolio Free →