Back to Portfolio On Fire

Multi-currency portfolio tracking, done properly

Converting foreign holdings with today's exchange rate is the single most common way a portfolio tracker quietly reports the wrong profit. Here is what correct handling requires, including the London pence trap that inflates a holding by a factor of one hundred.

The short answer

  • A purchase must be converted at the rate on its trade date, not today's rate. Using today's conflates currency movement with investment performance.
  • Cross-rates are derived through a single pivot currency, so USD/GBP is always consistent with EUR/USD and EUR/GBP.
  • London quotes many shares in pence (GBp), not pounds. Treating one as the other overstates a holding 100x.
  • Portfolio On Fire covers 23 currencies plus the euro, fetches dated rates on import, and uses the nearest rate at or before a date for weekends and holidays.

The mistake almost everyone makes

Say you bought a US holding three years ago for $10,000. Your portfolio reports in euros. What was that purchase worth?

The tempting answer is to take $10,000 and convert it at today's rate. It is one lookup, it always works, and it is wrong — because it reports what that dollar amount is worth now, not what you actually paid then.

The consequence is that your profit and loss silently mixes two different things: how the investment performed, and how the currency moved. A holding that gained 20% in dollars while the dollar fell 15% against the euro is a genuinely different outcome from one that gained 20% with the currency flat — and if the cost basis is converted at today's rate, both display identically.

Why it is hard to notice

The number is never absurd. It is plausibly wrong by a few percent, which is exactly the range where you assume it is right. Unlike a crash or a blank screen, a mis-converted cost basis produces a portfolio that looks completely normal and is quietly inaccurate for years.

What correct handling requires

A purchase must be converted at the rate that applied on the day it happened. That means a tracker needs historical rates, not just a live one — which is more work and is why many skip it.

When you import a broker export into Portfolio On Fire, transactions are matched against dated FX rates from their own trade dates. The rates for each currency are fetched once as a series, and each transaction looks up its own date within it.

Weekends, holidays and the "on or before" rule

Markets close. A transaction dated on a Saturday, or on a public holiday in one market but not another, has no rate of its own.

The rule is to take the nearest available rate at or before that date — the last rate that genuinely existed when the trade happened. Never a later one: reaching forward to Monday's rate would use information that did not exist on the day, which is the same category of error as converting at today's rate, just smaller.

Cross-rates and why the pivot matters

With 24 currencies there are hundreds of possible pairs. Fetching each one independently would be wasteful and, worse, inconsistent — rates sourced at slightly different moments produce a portfolio where USD → GBP does not equal USD → EUR → GBP. Totals then disagree with the sum of their parts, by a little, unpredictably.

Portfolio On Fire stores every rate against a single pivot — the euro — as units per euro, and derives everything else:

  • 1 MAIN = (target per EUR) ÷ (main per EUR) TARGET

One fetch per currency instead of one per pair, and arithmetic consistency by construction. The pivot is an implementation detail, not a limitation: your portfolio can report in any supported currency, and euro holds no special status beyond being the hub the maths routes through.

The 23 non-euro currencies covered are USD, GBP, CHF, JPY, CAD, AUD, NZD, SEK, NOK, DKK, PLN, MXN, CNY, HKD, KRW, INR, SGD, BRL, ARS, CLP, ZAR, ILS and MWK.

Every exchange rate is stored against a single pivot currency Six currencies each connect only to a central euro node, rather than to each other. Any pair is derived by dividing one euro rate by another, which keeps sub-totals consistent with totals. USD USD is stored as units per euro GBP GBP is stored as units per euro CHF CHF is stored as units per euro JPY JPY is stored as units per euro SEK SEK is stored as units per euro AUD AUD is stored as units per euro EUR The euro is the pivot: every rate is stored as units per euro 1 MAIN = (target per EUR) ÷ (main per EUR) TARGET
One rate per currency instead of one per pair. Cross-rates are derived, so sub-totals cannot drift out of step with the total.

The London pence trap

This one deserves its own section because it is the most spectacular failure mode in multi-currency tracking, and it is entirely avoidable.

Many shares on the London Stock Exchange are quoted in pence, not pounds. The currency code is GBp (lowercase p) rather than GBP. A share trading at "250" is £2.50, not £250.

Take that 250 as pounds and the holding is overstated by a factor of one hundred. In a mixed portfolio the result is a single UK position appearing to dwarf everything else — and, more insidiously, a yield calculation that divides a correct dividend by a price inflated 100x, producing a yield of 0.04% where 4% was right.

Why it is a persistent problem

Data providers are not consistent about it. The same instrument can come back in pence from one endpoint and pounds from another, and a provider can change behaviour without notice — which means historical data already stored may be on a different scale from data fetched today. Portfolio On Fire detects and corrects the scale, including retroactively repairing price history that was stored on the wrong one.

If you hold UK shares in any tracker, this is worth ten seconds of checking: compare a holding's displayed value against your broker. A factor-of-100 discrepancy is immediately obvious once you look, and invisible until you do.

Formatting follows your device, not the app

A number is not just a value, it is a convention. 1.674 means one thousand six hundred and seventy-four in the Netherlands and one point six seven four in the United States. Get this wrong in a display and you have made a correct number unreadable; get it wrong in a parser and you have corrupted data (exactly what happens with Dutch broker exports).

Numbers, dates and currency formatting follow your device locale rather than a hard-coded convention, across the nine languages the app ships in.

What to check in any multi-currency tracker

  1. Is cost basis converted at the trade date? Add an old foreign purchase and see whether the reported cost matches what you actually paid.
  2. Do UK holdings look sane? The pence trap, in ten seconds.
  3. Do sub-totals sum to the total? If not, the tracker is fetching pairs independently rather than deriving from a pivot.
  4. Are dividends converted at the payment date? Same principle as cost basis, and more often missed.
  5. Does it separate currency effect from performance? The most useful thing a multi-currency tracker can tell you.

All of this runs on the device. FX rates are fetched from public sources — a request for an exchange rate reveals nothing about who is asking or what they hold — and the conversion happens locally, alongside the dividend calculations and the FIRE projection.

22+ currencies, converted properly

Dated rates on import, consistent cross-rates, and the pence trap handled.

Download Portfolio On Fire