← 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:

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

avg_cost     = running weighted-average cost per share
cost_basis   = shares_held × avg_cost

Two different figures, used for different things.

Net invested is the money that has gone in minus the money that has come out, each trade at that day's FX rate. It is the "Total invested" tile and the dashed line on the value chart.

Cost basis is what the shares you still hold cost you. Kuantura keeps a running weighted-average cost per share: a buy adds its cost, a sell removes the shares at the average cost of that moment, and a position sold to zero starts afresh. This is an average-cost figure. It does not match the lot-by-lot (FIFO) cost basis most brokers and tax authorities use, and the two differ after partial sells.

Unrealized gain

unrealized = current_market_value − cost_basis
realized   = Σ over sells (proceeds − shares_sold × avg_cost_at_that_time)

Current market value uses the latest available close (or live quote where supported) converted at today's FX rate. Unrealized gain is measured against the cost of the shares still held, so it is the gain you'd lock in by selling them today.

Realized gain is tracked per sell with the same running average cost and shown on the holding page and the Transactions page. Both are average-cost figures, not tax figures.

Fees

Fees are tracked separately and do not change cost basis: transactions of type Fee (platform charges, FX costs, withholding tax) and the commission entered on an individual buy or sell. They are subtracted from total profit, so the headline figure is net of friction.

total_profit = current_value − net_invested + income_received − fees
total_return = total_profit ÷ the most capital invested at any one time

For an investor who only adds money, "the most capital invested at any one time" is simply net invested. After withdrawals net invested shrinks towards zero and stops working as a denominator, so the return is measured on the largest net amount that was ever at work instead.

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 the historical dividend data of our market-data source and multiplies by the shares you held going into each ex-date (bought before it), on today's share basis. These are gross declared amounts, before any withholding tax, and they are an estimate. Manually recorded dividends take precedence per holding to avoid double-counting.

Forward run-rate is the income of the last 12 months: your own history, not an external yield estimate. Yield on cost divides it by the cost basis of the shares you still hold.

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 in 2022, GOOGL 20:1 in 2022, TSLA 3:1 in 2022, NVDA 10:1 in 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 the split-adjusted close from our market-data source. Dividends are not folded into the price: they enter returns once, as income (step 3). When the price series for a ticker isn't available (a long-tail symbol our market-data source 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 our market-data source 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 the data source 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

TWR in Kuantura is a monthly approximation rather than the textbook sub-period definition; IRR is computed on the actual transaction dates. What that means:

The math is checked by an automated test pack that runs the app's own functions against reference values. The IRR is compared with a scipy.optimize.brentq XIRR on ten canonical portfolios (single buy, DCA, partial sell, round-trip, multi-currency, dividends, splits, fees, decumulation, single-month): nine agree within 0.005 pp annualised, and the single-month case is suppressed by design. The same pack covers average cost across splits and partial sells, the total-return denominator, period returns with deposits, volatility and Sortino, portfolio P/E, the projection's drift, and the CSV import parsers.

A money-weighted rate annualised from a few weeks of data is not meaningful, so the app shows a dash instead of an IRR until your ledger spans at least three 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 volatility and expected return. 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". With planned deposits, loss means the money invested earned less than zero (it ends below everything paid in), and doubling means it earned at least the yearly rate that doubles money over the horizon. 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.