NakedPnL

The public registry of verified investment performance. Every return sourced from SEC filings, exchange APIs, or platform data.

Registry

  • Registry
  • Market Context
  • How It Works
  • Community

Verification

  • Get Verified
  • Connect Exchange

Legal

  • Terms of Service
  • Privacy Policy
  • Refund & Cancellation
  • Support
  • GDPR Rights
  • Cookie Policy
  • Disclaimers
  • Methodology
  • Compliance
Follow

NakedPnL is a publisher of verified performance data. Nothing on this site constitutes investment advice, a recommendation, or a solicitation to buy, sell, or hold any security, commodity, or digital asset. Past performance does not indicate future results. Trading carries a high risk of total capital loss.

© 2026 NakedPnLAll performance data is verified by the NakedPnL teamcontact@nakedpnl.com
NakedPnL
RegistryPricingHow It WorksCommunitySupport
NakedPnL/Guides/How Time-Weighted Return (TWR) Works — A Step-by-Step Guide
Methodology guide

How Time-Weighted Return (TWR) Works — A Step-by-Step Guide

Time-weighted return isolates manager skill from cash-flow timing by chain-linking sub-period returns. A precise, worked walkthrough with code.

By NakedPnL Research·May 7, 2026·12 min read
TL;DR
  • TWR is the geometric chain-link of sub-period returns, where each sub-period ends at an external cash flow.
  • It removes the distorting effect of deposit and withdrawal timing, isolating the trader's skill on the assets they actually controlled.
  • GIPS, the global standard for fund performance reporting, requires TWR for comparability across managers.
  • The math is simple: split the period at every external flow, compute each sub-period return, multiply (1 + r_i) together, subtract 1.
  • NakedPnL computes TWR daily from raw exchange NAV snapshots and publishes the result in an append-only, hash-chained registry.
On this page
  1. Why TWR exists in the first place
  2. The formula
  3. What counts as an external cash flow
  4. Why daily snapshots, not monthly
  5. A worked example
  6. Reference implementation
  7. Handling missing or stale NAVs
  8. Why TWR is the metric regulators chose
  9. How to verify a TWR figure independently
  10. Frequently asked questions

Time-weighted return (TWR) is the standard methodology for measuring the performance of an investment manager when the size of the portfolio changes over time due to deposits and withdrawals. It answers a specific question: how would one dollar invested at the start have grown if the manager were never given more capital and never lost capital to withdrawals?

That question matters because raw account growth conflates two completely different things — what the trader did with the money they had, and how lucky they got with the timing of new capital. TWR strips out the second factor. The result is a number that is comparable across traders, across funds, and across measurement windows.

Why TWR exists in the first place

Consider two traders. Both start with $10,000. Both end the year with a portfolio worth $14,000. Trader A made every dollar from trading. Trader B started the year flat, then a friend wired in $4,000 on December 30th — the trading account itself produced zero return. Their final balance is identical. Their skill is not.

A naive percentage change ((14000 − 10000) / 10000 = 40%) treats them as equals. TWR does not. By splitting the year at the December 30th deposit and computing the return of each sub-period independently, TWR correctly assigns Trader A a 40% return and Trader B a 0% return. This is the entire point of the metric.

The formula

Let the measurement period contain n external cash flows, dividing it into n+1 sub-periods. For each sub-period i, let V_start be the portfolio value immediately after the previous flow (or at the very start), and let V_end be the portfolio value immediately before the next flow (or at the very end). The sub-period return is:

r_i = (V_end_i - V_start_i) / V_start_i
Sub-period return for the i-th interval.

The total time-weighted return over the full period is the geometric chain-link of those sub-period returns:

TWR = (1 + r_1) * (1 + r_2) * ... * (1 + r_n+1) - 1
Geometric chain-link across all sub-periods.

The geometric form (multiplying growth factors) is essential. Adding sub-period returns produces an arithmetic average, which systematically overstates performance whenever returns are volatile. The geometric chain mirrors the actual compounding behaviour of capital.

What counts as an external cash flow

An external cash flow is any movement of money into or out of the portfolio that is not the result of the trader's investment decisions. These must terminate sub-periods. Internal transactions — buying a token, closing a position, paying exchange fees — never trigger a new sub-period; they are simply reflected in the next NAV snapshot.

  • Deposit of fiat or stablecoin to the exchange account
  • Withdrawal of any asset off the exchange
  • Internal transfer to a different sub-account
  • Airdrops or external token grants (treated as deposits)
  • Exchange-paid promotional rebates credited to the spot wallet
Where the line gets blurry
Funding fees, staking yield, and exchange-internal interest are not external — they are returns on capital the trader is already deploying. NakedPnL's adapters treat them as part of the NAV change, not as cash flows.

Why daily snapshots, not monthly

GIPS requires sub-period termination at every external flow above a materiality threshold. The more granular the snapshots, the smaller the residual error from approximation between flow events. Monthly snapshots can mis-attribute up to several percentage points of return when a large flow lands mid-month and the portfolio is volatile.

Daily snapshots are the practical sweet spot for crypto and 24/7 markets: they bound the worst-case error to a single trading day's drift between flow time and snapshot time, and they align with how exchange APIs publish account valuations. NakedPnL's daily cron at 23:55 UTC pulls a NAV reading from each connected venue and feeds it directly into the TWR engine.

A worked example

Suppose a trader starts on 2026-01-01 with $10,000 in their Binance spot account. The portfolio drifts up and down, and on 2026-01-15 they deposit another $5,000. The values look like this:

DateNAV before flowExternal flowNAV after flow
2026-01-01$10,000—$10,000
2026-01-14$11,500—$11,500
2026-01-15$11,200+$5,000$16,200
2026-01-31$17,820—$17,820
Two sub-periods: Jan 1 → Jan 15 (pre-deposit), and Jan 15 → Jan 31 (post-deposit).

Sub-period 1 runs from $10,000 to $11,200, the value immediately before the deposit. Sub-period 2 runs from $16,200, the value immediately after the deposit, to $17,820 at month-end.

r_1 = (11200 - 10000) / 10000  = 0.12000
r_2 = (17820 - 16200) / 16200  = 0.10000

TWR = (1 + 0.12) * (1 + 0.10) - 1
    = 1.12 * 1.10 - 1
    = 1.232 - 1
    = 0.232  =>  23.2%
Geometric chain-link of two sub-periods.

Compare that to the naive percentage change. The trader contributed $15,000 of capital total and ended with $17,820, suggesting a return of (17820 − 15000) / 15000 = 18.8%. The naive number is wrong: it under-states performance because it averages the two sub-periods on a dollar-weighted basis, ignoring that the trader earned 12% on the first $10,000 over two weeks before the new capital arrived.

Reference implementation

Below is a minimal Python implementation of the GIPS-required TWR computation. NakedPnL's production engine in lib/calculation/twr-engine.ts follows the same algorithm but uses Decimal.js to avoid IEEE 754 floating-point error across thousands of compounded daily steps.

from decimal import Decimal, getcontext
from dataclasses import dataclass
from typing import List

getcontext().prec = 28

@dataclass
class Snapshot:
    date: str
    nav: Decimal     # NAV before any flow on that date
    flow: Decimal    # +deposit, -withdrawal, 0 if none

def twr(snapshots: List[Snapshot]) -> Decimal:
    """Geometric chain-linked TWR per GIPS methodology.

    Each snapshot's `nav` is taken before the flow that day,
    so a sub-period ends on the day-before's nav and resumes
    from (nav + flow) on the flow day.
    """
    if len(snapshots) < 2:
        return Decimal(0)

    growth = Decimal(1)
    start = snapshots[0].nav + snapshots[0].flow  # post-flow base

    for prev, curr in zip(snapshots, snapshots[1:]):
        end = curr.nav  # value immediately before today's flow
        if start <= 0:
            raise ValueError(f"non-positive sub-period base on {curr.date}")
        sub_return = (end - start) / start
        growth *= (Decimal(1) + sub_return)
        # next sub-period starts post-flow
        start = curr.nav + curr.flow

    return growth - Decimal(1)

# Example matching the worked table above
snaps = [
    Snapshot('2026-01-01', Decimal('10000'), Decimal('0')),
    Snapshot('2026-01-15', Decimal('11200'), Decimal('5000')),
    Snapshot('2026-01-31', Decimal('17820'), Decimal('0')),
]
print(twr(snaps))  # -> 0.232  (23.2%)
Python TWR engine using arbitrary-precision decimals. Mirrors the production logic in lib/calculation/twr-engine.ts.

Handling missing or stale NAVs

Real exchange data is messy. APIs go down. Maintenance windows skip a snapshot. A market freeze (Binance outage during the May 2021 cascade liquidations is the canonical example) leaves the account un-snapshottable for hours. The honest response is to record the gap explicitly rather than fabricate a value.

NakedPnL's engine refuses to interpolate between known NAVs. If a daily snapshot is missing, the gap is recorded in the calculation hash chain and the affected sub-period is flagged. The verification page at /verify/chain/[handle] surfaces these gaps to anyone re-checking the math, so a track record with hidden gaps cannot be quietly smoothed over.

Why TWR is the metric regulators chose

The Global Investment Performance Standards (GIPS), published by the CFA Institute, are the reporting framework most institutional asset managers worldwide adopt. GIPS Standards 2020 require firms to present TWR for all composites, and explicitly disallow money-weighted return as a primary metric except in tightly defined private-market contexts.

“Time-weighted returns must be used to remove the effects of external cash flows, which are generally client-driven. By removing the effects of external cash flows, time-weighted returns reflect the firm's investment management decisions.”
— GIPS Standards for Firms 2020, Section 2.A

The reasoning is straightforward: when comparing managers, the comparison must control for things the manager did not choose. Cash-flow timing is one of those things. NakedPnL publishes TWR for the same reason GIPS requires it — comparability is impossible without it.

How to verify a TWR figure independently

Every NavSnapshot row in the NakedPnL registry is hashed (SHA-256 over the canonicalized raw exchange response) and chain-linked to the previous day. The published TWR is reproducible by any third party with the chain export and a working hash function. The /docs/verification page contains complete reference snippets in Python and JavaScript.

Independently re-verifiable
Pull a trader's chain bundle from /verify/chain/[handle], rehash each row with the algorithm in /docs/verification, recompute the TWR with the snippet above, and compare. The numbers must match to 8 decimal places.

Frequently asked questions

What is the difference between TWR and IRR?
TWR measures the return earned on the assets a manager controlled, removing the impact of when external capital arrived. IRR (internal rate of return) is the discount rate that makes the net present value of all cash flows equal zero — it deliberately incorporates flow timing. IRR is the right metric for evaluating a single investor's wallet outcome (since their personal timing matters to them); TWR is the right metric for evaluating a manager's skill, which is why regulators require it for fund reporting.
Why is daily NAV better than monthly NAV for TWR?
Sub-period return error is bounded by the time gap between an external cash flow and the nearest snapshot. A monthly cadence can leave up to 30 days of unexplained drift if a flow happens mid-month, and that drift gets attributed incorrectly to either the pre- or post-flow sub-period. Daily snapshots cap the error at less than 24 hours of drift, which for typical volatility is roughly an order of magnitude tighter.
What happens if a NAV snapshot is missing for a day?
NakedPnL records the gap explicitly in the hash chain rather than interpolating. The affected sub-period is widened to span the gap, but the gap itself is publicly visible to anyone who fetches the chain bundle. This is why the registry rejects practices like back-filling missing days with the average of neighbouring values — it would corrupt the verification chain.
Does TWR change if the trader makes many small trades versus a few large ones?
No. TWR depends only on NAV at the boundaries of each sub-period (defined by external flows), not on intra-period activity. A thousand winning scalps and a single decisive swing trade producing the same end-of-day NAV will produce the same TWR. This is correct: TWR measures the outcome of the trader's decisions, not the path or the trade count.
Is TWR the same as the geometric mean of daily returns?
Only when there are zero external cash flows. With no flows, every day is its own sub-period and TWR collapses to (1 + r_1)(1 + r_2)…(1 + r_n) − 1, which is identical to the geometric chain of daily returns. Add any deposit or withdrawal and the two diverge, because TWR forces the sub-period to end exactly at the flow.
Can a trader game TWR by choosing when to deposit?
No, and that is the entire point. TWR is mathematically insensitive to deposit timing — a deposit terminates one sub-period and begins another, and the new capital is not credited with the prior sub-period's return. This is why TWR is the metric a regulator-style registry like NakedPnL publishes: it cannot be inflated by lucky or strategic flow timing.

References

  • GIPS Standards for Firms (2020)
  • CFA Institute — Calculation Methodology Guidance
  • Bacon, C. (2021). Practical Portfolio Performance Measurement and Attribution, 3rd ed.
  • Investopedia — Time-Weighted Rate of Return
NakedPnL is a publisher of verified investment performance data. We are not an investment adviser, broker, dealer, or asset manager, and nothing on this page constitutes investment advice or a recommendation. See the compliance page for our full regulatory posture.