Skip to main content

How currency conversion works

How currency conversion works in Gold Silver Ledger. Every value is stored in USD; the conversion to your chosen display currency happens at render time, using the live FX rate at that moment. Implications and edge cases.

When you change your display currency, the numbers on every page change — but the underlying data stays exactly where it was.

This article walks through how that's possible: the storage-vs-display split that sits underneath every monetary value in the app, the FX feed that drives the conversion, and where the split has small consequences worth knowing about.

The model in one sentence

Every monetary value in Gold Silver Ledger is stored in USD. The conversion to your chosen display currency happens at the moment a page renders the value, using the live FX rate at that moment.

That sentence is the whole model. The rest of this article unpacks what each part of it means.

Why this design

A portfolio tracker has two reasonable choices for handling currency: store everything in the user's chosen currency, or store everything in one reference currency and convert at display time. Gold Silver Ledger uses the second approach, and the reasons are practical.

  • The market is quoted in USD: Wholesale precious metals spot prices tend to live in USD. Storing data in USD means no internal translation step between the market feed and your records — fewer rounding errors, less drift over time.

  • Your data shouldn't move when your preferences do: A user who switches from USD to EUR to GBP and back shouldn't see their cost basis subtly shift each time because of round-trip conversion errors. Storing in one currency and translating on display keeps the stored figure pristine.

  • The conversion is reversible: If you ever change display currency, no historical data has been lost — every number is still anchored to the original USD figure and can be re-translated on demand.

  • Tax records have a stable basis: Your underlying USD cost basis doesn't drift with FX. That matters for record-keeping consistency over multi-year holding periods.

What "at render time" means

The conversion isn't a periodic batch job that rewrites your stored values. It's a calculation that happens at the precise moment a page loads or refreshes:

  1. The app reads the USD value from storage.

  2. The app reads the latest FX rate for your display currency.

  3. The two are multiplied.

  4. The result is formatted and shown on screen.

By the time you see the number, the USD value is still in storage — unchanged — and the converted figure exists only in the rendered HTML. Close the page, reopen it ten minutes later, and the USD figure is the same; the displayed figure might be slightly different if FX has moved.

This applies to every monetary surface in the app — Dashboard cards, Holdings values, transaction prices, Analytics charts, Annual Report headlines — without exception.

The FX rate that's applied

The FX feed runs on its own schedule, separate from the spot price feed. It pulls live exchange rates from major interbank sources and updates regularly, so the rate the app uses at render time is the most recent quote on file.

A few details:

  • USD is the base of every rate: A USD-to-EUR rate, a USD-to-GBP rate, a USD-to-JPY rate, and so on for the full list. See The 15 supported display currencies.

  • Rates refresh on a fast cadence: Not as fast as spot prices, but fast enough that the displayed value reflects the current FX market in real terms. See [How often FX rates update].

  • No interpolation between updates: Just as with spot, you see the most recent rate on file. Values don't tick sub-rate.

  • Pegged currencies still convert each time: HKD is pegged to USD and DKK is pegged to EUR, but both still go through the conversion pipeline using the live rate, not a hardcoded peg ratio.

The FX feed is what makes the storage-vs-display split work invisibly. You don't think about it; the app handles it.

A worked example

Suppose you've recorded a buy of one 1 oz American Gold Buffalo at $4,790 USD all-in. That $4,790 is the value stored against the transaction.

  • You have USD set as display: The Holdings page shows $4,790. No conversion needed.

  • You switch display to EUR, and the live USD-to-EUR rate is 0.90: The Holdings page reads the stored $4,790, multiplies by 0.90, and renders €4,311. The stored value is still $4,790.

  • You switch display to GBP, and the live USD-to-GBP rate is 0.78: Same flow — stored $4,790 × 0.78 = £3,736.20. Stored value still $4,790.

  • You switch display to JPY, and the rate is 155: $4,790 × 155 = ¥742,450, rendered without decimals per the Japanese yen convention.

  • You switch back to USD a week later: The Holdings page shows $4,790 again — the same number it always was, because that's what's stored.

The displayed numbers reflect a moving FX market; the stored number is constant. The two layers do their jobs without interfering with each other.

What this means for your data

The model has a few small consequences in everyday use that are worth knowing about.

  • Stored numbers never move with FX: Your transaction records, cost basis figures, premium amounts, and historical buy/sell prices are all locked in USD and stay where they are.

  • Displayed numbers can drift slightly even without trading: If your display currency is EUR and the EUR weakens against USD overnight, your portfolio value (in EUR) will tick up the next time you open the app — even if no spot prices changed and you didn't record any transactions. That's the FX move, not a market move.

  • Switching display currency is purely visual: No data is lost, no figures are recalculated, no historical records change. The next render uses a different multiplier and that's it.

  • A user on EUR and a user on GBP looking at the same item see different numbers: Both are correct, both are derived from the same underlying USD figure, and either could re-derive the other given the FX rate.

CSV exports — the deliberate exception

The storage-vs-display split applies to everything rendered on screen and in PDF exports. CSV exports take a different approach.

The USD-only CSV convention exists so that bulk-import round-trips work without translation, and so that two users on different display currencies can share or compare CSV files directly. It's a deliberate exception, not an oversight.

Where to go next

Did this answer your question?