← Back to site

Methodology

How every number in Kuantura is computed, in plain English.

Kuantura is built around the idea that you should always be able to see why a number is what it is. This page documents the math behind every figure the app shows. If a calculation differs from what your broker reports, it's almost always one of the deliberate methodology choices below — not a bug.

Contents
  1. Cost basis & invested capital
  2. Unrealized gain
  3. Fees
  4. Dividends & income
  5. Foreign exchange (FX)
  6. Stock splits
  7. Performance curve
  8. TWR vs IRR
  9. Risk metrics
  10. Monte Carlo projection
  11. Known limitations

Cost basis & invested capital

Kuantura uses a net-invested method, not lot-based (FIFO/LIFO) tracking. For each holding:

cost_basis = Σ (buy_qty × buy_price × FX_at_buy_date)
            − Σ (sell_qty × sell_price × FX_at_sell_date)

That is, every buy adds the buy's value (in your base currency at that day's FX rate), every sell subtracts the sell's value (same way). The remainder is the capital still working in the position.

This matches what most personal-tracker tools do and is the simplest model that handles partial sells consistently. It does not match how most brokers report cost basis — brokers usually attach a specific buy lot to each sell (FIFO by default, sometimes user-selectable). The two methods agree when you hold a position continuously and only diverge during partial sells.

Unrealized gain

unrealized = current_market_value − cost_basis

Current market value uses the latest available close (or live quote where supported) converted at today's FX rate. The number you see is the gain you'd lock in if you sold today at the displayed price, less the capital still attributed to the position.

Kuantura does not separately split realized vs unrealized. If you've sold some lots, the realized portion is folded into the reduced cost basis. This is a deliberate simplification — full lot-based realized P&L tracking is on the roadmap for a future version.

Fees

Trading fees, FX conversion costs, and management charges entered as transactions of type Fee are tracked separately and do not change cost basis. They are subtracted from total return so the headline figure is honest about friction.

total_return = (price_change + dividends_received) − fees

Dividends & income

Income from Dividend, Interest, and Coupon transactions is summed at the FX rate of the receipt date and shown on the Dividends page.

If you haven't recorded dividends manually, Kuantura auto-detects them from Yahoo Finance's historical dividend stream and multiplies by the split-adjusted shares you held on each ex-date. Manually recorded dividends take precedence per holding to avoid double-counting.

Forward run-rate uses the last 12 months of income annualised — an honest projection from your own history, not an external yield estimate.

Foreign exchange (FX)

Kuantura supports NOK, USD, EUR, GBP, SEK, DKK, JPY, CAD, CHF and 25+ others, sourced from Norges Bank (official Norwegian central bank rates).

When Norges Bank has no rate for a given date (weekends, holidays), the most recent prior business day is used.

Stock splits

Kuantura applies a split-adjusted-share view to every metric: when a position has split N-for-1, the share count for all prior dates is multiplied by N and the price is divided by N.

The major recent splits — AMZN 20:1 (2022), GOOGL 20:1 (2022), TSLA 3:1 (2022), NVDA 10:1 (2024) — are pre-loaded so existing accounts don't need to re-edit history. For any other split, add a Split transaction manually (Transactions → New → Stock split) with the ratio and date; the split-adjusted view then applies everywhere. Automatic detection of arbitrary splits from price series is on the roadmap but not implemented yet — if a holding's share count looks wrong after a corporate action, a missing Split entry is the likely cause.

Performance curve

This is the most subtle calculation in the app. The curve on the Performance page shows portfolio value over time, but it's not a tick-by-tick mark-to-market.

Instead, every month we:

  1. Replay your transaction ledger to determine which shares of each holding you owned on the last day of that month, with stock splits and corporate actions applied.
  2. Price each of those holdings at the last cached daily close on or before that month's end date — using Yahoo Finance's split- and dividend-adjusted close series. When the price series for a ticker isn't available (a long-tail symbol Yahoo doesn't cover), that month's value uses the last available close instead.
  3. Compute monthly returns from the resulting value series, with dividends and interest added back into the numerator (so a dividend-paying holding's return is total return, not price return).
  4. Cash flows (buys, sells, dividends, fees) keep their original dates and amounts.

Known limits:

What it means in practice: the curve will closely track your broker's mark-to-market for any ticker Yahoo covers. It may diverge for long-tail or recently-IPO'd securities where the historical price series is incomplete, and for holdings with corporate actions Yahoo hasn't back-applied yet. We surface that gap as a per-row warning in the holdings table where we know about it.

TWR vs IRR

The Performance page shows two return numbers because they answer different questions:

Both are computed from the same underlying ledger and price series. They differ for any portfolio with contributions — the bigger the contributions, the bigger the gap.

Implementation honesty

Both numbers in Kuantura are monthly approximations rather than the textbook continuous-time definitions, and we think you should know what that means:

We validate every release of the math against a scipy.optimize.brentq XIRR reference on ten canonical portfolios (single buy, DCA, partial sell, round-trip, multi-currency, dividends, splits, fees, decumulation, single-month). In the latest run, seven of the ten agree within 0.13 pp annualised; the dollar-cost-averaging case differs by ~1.2 pp (the expected monthly-bucketing bias on flow-heavy books); and the single-month case is suppressed by design — the bucketing approximation is unreliable below three months of history, so the app shows "—" instead of an IRR until your ledger has at least three full months.

Risk metrics

All of these inherit the Performance curve's analytical-reconstruction property, so they describe your capital's behaviour, not the exact tick-by-tick experience you had.

Monte Carlo projection

The Projection page runs 5 000 simulated market paths, each one a different sequence of monthly returns calibrated to your portfolio's actual volatility (and drift). It uses a Cornish-Fisher-adjusted geometric Brownian motion: the same family as standard log-normal modelling but with your portfolio's real skewness and kurtosis worked in so the simulated tail behaviour matches recent history.

Inputs:

The 5 000 paths give you a distribution of outcomes, summarised as median / 5th percentile / 95th percentile / "chance of doubling" / "probability of loss". These are model outputs, not predictions. Real markets have regime shifts, crashes, and once-in-a-generation events that no GBM-family model captures. Treat the projection as a planning tool, not a promise.

Known limitations

Questions or corrections? Email support@kuantura.com. We read every message personally and want to know if a number looks wrong.