Currencies

Why every transaction stores two amounts, what keeping both buys you, and where the exchange rates come from.

Every transaction has two amounts

A transaction records two amounts, not one. The first is what the thing cost, in the currency it was priced in: the figure on the receipt. The second is what actually left the wallet, in that wallet's own currency.

When those two currencies match, which is most of the time, the amounts are simply identical and you never think about them. When they differ, they are two genuinely different numbers, and the app keeps both rather than picking one.

Why both are kept

The pair is the record of the rate that was actually applied. It is stored on the transaction rather than worked out on the way to the screen, so nothing restates last March's coffee at today's rate.

A rate service is consulted while you are typing, but only to offer you a number. Enter or edit a transaction in a currency other than the wallet's and the rate for that date is fetched and shown greyed out in the wallet-amount field, as a suggestion rather than an entry. Type your own figure and yours is what is saved. Leave the field empty and the suggested one is used instead.

That matters because the figure your bank booked is rarely the figure a rate table would produce: it has the bank's own spread inside it. When a statement says what it charged the account, an import keeps that number rather than reconverting the price, because no rate looked up afterwards would reproduce it.

The wallet amount is also the one that moves your balance, so it has to be exact rather than recomputed. Keep only the price and the balance becomes an estimate; keep only what left the wallet and you have lost what the thing cost.

Where rates come from

A rate is looked up where a conversion is genuinely needed, when a month of mixed-currency spending is totalled into one figure, for instance. Rates are stored per base currency, target currency and date, so each is tied to the day it belongs to rather than to now.

They come from an external rate service, fetched on demand rather than on a schedule: the first time a pair and date is wanted it is fetched and kept, and every later use reads the stored one. Nothing refreshes them in the background, so a rate stamped with today's date is whatever the service first returned that day.

If a rate cannot be had at all, no rate is guessed at: the amount is carried across as it stands, as though the two currencies had been the same. Where that happens on an import you are told, because the draft's comment picks up a note saying the wallet amount needs review. Where it happens inside a total assembled later there is no note, and the figure just reads a little low or a little high with nothing on the page to say why.

On imported rows

Import a statement into a wallet whose currency is not the statement's and both amounts get filled in for you. The first takes whatever the statement shows. The second is always in the wallet's own currency. That is never relabelled to match the file, however the file is denominated.

Which number fills the wallet side depends on what the statement offers. If it states what it booked to the account, that figure is used as it stands, spread and all. Otherwise the amount is converted at the rate for that row's own date, and failing that it is carried across unchanged, with a note appended to the draft's comment saying the wallet amount needs review. Fix it before you publish.