Pivolt
AI

Why an LLM Should Never Compute Your TWR

Aug 20268 min read
Why an LLM Should Never Compute Your TWR

The demo that always works

You upload a portfolio. You type: “How did this client do last quarter?” Three seconds later a sentence comes back — fluent, confident, correctly punctuated, with a percentage in the middle of it.

Everyone in the room leans forward. It is the single most persuasive thirty seconds in a WealthTech demo, and it should be the moment your risk officer starts asking harder questions than your innovation lead.

Because that percentage was not calculated. It was written.

A return is not a fact. It’s a policy.

The instinct behind the demo is that a return is a fact sitting inside the data, waiting to be retrieved — like a birth date or an ISIN. It isn’t. Time-weighted return is the output of a chain of methodological decisions, most of which are invisible to the client and several of which are legitimately contested:

  • Sub-period construction. Do you revalue at every external cash flow, daily, or monthly? Standards have tightened steadily in this direction — from revaluation at large external flows to full daily valuation — but plenty of production books still run on approximations.
  • Flow timing convention. Is a contribution treated as arriving at the start or the end of the day it settles on? Both conventions are defensible. They produce different numbers.
  • Approximation method. Modified Dietz remains widely used where daily valuations aren’t available for every line. It is an accepted method. It is also, by construction, not the same number as a true daily-linked TWR.
  • Fees, accruals, and taxes. Gross or net? Net of which fees? Accrued income recognised when earned or when received?
  • FX translation. At which rate is a flow in a second currency converted, and does currency effect sit inside the return or beside it in attribution?

None of these are edge cases. They are the daily reality of a consolidated multi-custodian book. And they mean something uncomfortable for anyone building a chat interface over a portfolio: two competent firms, given identical data, will produce different time-weighted returns — and both will be right, provided each can state which convention it applied.

Take a single account over a single month. One ledger, no ambiguity in the underlying data. Now apply the conventions above and watch the answer move:

One account · one month · nobody disputes the data

Day 0Opening market value1,000,000
Day 14Valuation, close1,018,000
Day 15Valuation, before flow1,020,000
Day 15Client contribution+300,000
Day 30Closing market value1,380,000
Method
Flow timing

6.64%

Daily-linked TWR · flow at end of day

FIG. 1 — The same ledger, priced by five conventions. Four defensible answers sit inside a 37-basis-point band; a fifth, still returned by systems that divide the gain by the opening value, sits 141 basis points above the lowest.

On one month. On one account. On data nobody disputes.

The number is not in the data. The number is in the policy. Which is precisely why the layer that produces it has to be the most boring, most versioned, most testable part of your stack — and precisely why a probabilistic text generator is the wrong tenant for that job.

Three structural reasons the language layer can’t own the number

1. It isn’t reproducible, and reproducibility is the product. Ask the same question twice and a sampling-based model can give you two different answers. In most software this is a quirk. In performance reporting it is fatal, because the entire discipline exists to let a client, an auditor, and a regulator arrive at the same figure independently. A return you cannot reproduce on demand — six months later, on the data as it stood then — is not a return. It’s an anecdote.

2. It fails plausibly, not loudly. A calculation engine that hits a missing price throws an error. It stops. Someone gets paged. A language model in the same situation produces a number that looks exactly like a correct one: right order of magnitude, sensible decimals, embedded in a well-formed sentence. Finance can absorb systems that break. It cannot absorb systems that are quietly, confidently wrong — because the failure isn’t caught by a screen, it’s repeated out loud by an advisor in a client meeting.

3. There is no lineage behind a token. The moment a client asks the follow-up question — “why is that lower than last quarter?” — you need a computation graph: sub-period returns, the flows that split them, the positions that drove them, the FX leg, the fee accrual. You need to drill from 6.64% down to a transaction. A generated number has no parents. You can ask the model to explain it, and it will produce an explanation, which is a different and considerably more dangerous thing than a decomposition.

“But it writes Python now”

This is the strongest counter-argument, and it deserves better than a dismissal. Tool use and code execution do fix the arithmetic. A model that calls a calculator is not doing mental math.

But look at what actually moved. The model is no longer choosing the digits — it is choosing the method. And the method is exactly the regulated decision. Ad-hoc generated code is not a versioned, tested, signed-off methodology; it’s a fresh implementation of your firm’s performance policy, written from scratch, by a system with no memory of what it wrote yesterday. If the model reaches for Modified Dietz on an account where your policy mandates daily linking, you now have a compliance event with flawless arithmetic. That is a worse position, not a better one, because the error is harder to detect.

The correct pattern is narrower than “let it write code.” It is a fixed, typed interface to a certified engine: the model may select from a catalogue of named, parameterised metrics that your firm has defined, configured, and tested. It requests twr(account, period, method, net_of_fees). It does not implement it.

The wrong question is worse than the wrong arithmetic

There’s a failure mode more common than bad math, and language interfaces make it dramatically more likely.

A client asks: “How did my portfolio do?”

Time-weighted return answers how the manager did — it strips out the effect of the client’s own contribution and withdrawal timing, which is the point of it. Money-weighted return answers how the client’s money did — it includes exactly that timing. For a client who added 300,000 the week before a rally, these two numbers can diverge by hundreds of basis points, and both are correct answers to different questions.

A well-designed report resolves this by construction: the metric shown is the metric the firm decided to show, labelled, in context. A free-text interface hands the resolution to whichever reading of the question the model finds most likely. That is not a rounding error. It is a system silently deciding which question the client asked.

Deterministic core, probabilistic surface

The architecture that resolves this is not exotic. It’s a boundary, enforced.

Data layer. Positions, transactions, prices, FX, corporate actions. Versioned and reconciled, with a point-in-time view so any past answer can be replayed against the data as it stood.

Computation layer. TWR, IRR, attribution, contribution, risk. Parametric, deterministic, unit-tested, identical output for identical input, every time. This is where the policy lives.

Metric contract. A catalogue of named metrics with fixed definitions and declared parameters — the vocabulary the rest of the system is allowed to speak. Nothing above this line invents a metric; it selects one.

Language layer. Interprets the question, selects the metric, and narrates the result: adjusts register for a first-generation founder versus a third-generation beneficiary, foregrounds what changed, connects the figure to the objective it serves, drafts the meeting note.

Where the boundary sits

the shortcut: a number that never touched the engine — 6.64%

the question descends

Language layer

interprets the question · selects the metric · narrates the result

probabilistic — not reproducible, and that is acceptable here

which number to show — never what the number is

Metric contract

twr(account, period, method, net_of_fees) — a catalogue, not a prompt

Computation layer

TWR · IRR · attribution · risk — parametric, unit-tested

deterministic — the firm’s policy lives here

Data layer

positions · flows · prices · FX — versioned, point-in-time

the number ascends, with its lineage

Everything below the line replays six months later, against the data as it stood. The boundary is the design: each layer is then judged by the standard it can actually meet.

FIG. 2 — One rule holds the stack together. Everything below the line is reproducible and auditable; everything above it is fluent and adaptive.
The model may decide which number to show, and how to explain it. It never decides what the number is.

The value of the boundary is that each layer gets to be judged by the standard it can actually meet.

What a defensible answer looks like

Whether the stack is built in-house or bought in, the boundary shows up as six observable properties. None of them is exotic, and all of them are cheaper to design for than to retrofit.

  • Repeatability. The same question, asked in five separate sessions, returns the identical figure to the basis point.
  • Decomposition. The sub-period breakdown is available on request, and it ties back to the headline number exactly.
  • Sensitivity. Change one transaction and the return moves by the amount it should — and the system can show which sub-period absorbed it.
  • Configurability. The return methodology lives in a setting the firm owns and can point to, not in a prompt.
  • Replayability. An answer given six months ago can be reproduced against the data as it stood that day.
  • Honest gaps. When a price is missing, the system names the gap instead of filling it. Here, a refusal is a feature.

The list is short on purpose. It is not a scorecard for anyone else’s product — it’s the shape a number has to have before an advisor can defend it in a meeting.

The scarce thing was never the number

Wealth management has had numbers for thirty years. What it has never had at scale is the capacity to explain them — to translate a decomposed, correctly-computed, policy-compliant figure into something a client understands, in their language, tied to what they were trying to achieve, on the day they asked.

That is a genuine scarcity, and language models are extraordinarily good at closing it. Pointing them at the calculator instead is not ambition. It’s a category error that trades the one thing the industry already does reliably for the one thing it doesn’t.

Pivolt is built on that boundary. Returns, attribution and scenarios are produced by a deterministic, parametric engine with full flow transparency and drill-down to the transaction — the same input always yields the same output, and every figure traces back to its source. The intelligence sits where it belongs: choosing what matters, framing it for the person reading, and turning a defensible number into a conversation worth having.

Put these ideas to work

See how Pivolt turns insight into automated, AI-native wealth management.

Talk to sales