Tool · European taxation

Multi-currency cost basis

Securities bought in dollars, taxes computed in your own currency: the cost basis must convert each operation at the exchange rate of its own date. Enter your operations below — everything runs in your browser, and nothing is sent anywhere.

The calculator

Pick your country: it presets the lot-matching method your tax authority generally applies. Converting each operation at the exchange rate of its own date holds across Europe.

This calculator requires JavaScript. The page text below explains the rule it implements.

The rule, the rate convention and the CSV format

Across Europe, the taxable gain on foreign-currency securities is computed in the national currency, each operation converted at the exchange rate of its own date — never at the sale-day rate. What varies by country is the lot-matching method. Under the weighted average, a purchase adds the converted cost of the lot (quantity × dollar price, plus any fees, divided by that day's rate) to the running cost, then re-establishes the average over the new total quantity.

A sale converts the proceeds at the sale-day exchange rate (quantity × dollar price, minus fees, divided by that rate). Under the average method, the gain is those proceeds minus quantity × average cost — which does not change: only the quantity falls. Under FIFO, the sale consumes the oldest lots first: the gain is the sum, lot by lot, of proceeds minus the original cost of the quantities consumed. The calculator sorts operations chronologically before computing, and a sale that exceeds the quantity held at its date is flagged as a blocking error.

Rate convention. Rates are entered ECB-style — 1 unit of your reference currency = X $ (for instance 1 € = X $, 1 £ = X $) — so the conversion is always currency = dollars ÷ rate. The calculator's rate field is labelled after the chosen currency, making inversion impossible. Use the ECB euro reference exchange rates for the date of each operation.

CSV format. Export and import use a semicolon separator and the fixed header date;type;qty;price_usd;fees_usd;rate_eur_usd. type is buy or sell; date is ISO YYYY-MM-DD. One security per file — export and import per ticker. Your operations are also saved automatically in this browser (localStorage); the “Clear all” button removes them. The rate column keeps its historical name rate_eur_usd whatever your reference currency: it holds each operation's “1 unit = X $” rate.

Not tax advice

This tool applies the selected method — weighted average or FIFO — with each operation converted at the exchange rate of its own date. It is neither tax nor investment advice: verify the method and rates that apply to your situation (ECB reference rates: link).

Methods by country

European tax systems agree on converting each operation at the exchange rate of its own date, but they diverge on how lots are matched when you sell: weighted average in some countries, first-in-first-out (FIFO) in others, and a few that do not tax realised gains this way at all. Pick your country in the calculator above to preset the method — you can still switch it by hand.

CountryMethodNote
FrancePMPWeighted-average acquisition cost.
ItalyPMPWeighted-average cost (self-assessment regime).
AustriaPMPMoving-average cost.
SwedenPMPAverage method (genomsnittsmetoden).
DenmarkPMPAverage method.
United KingdomPMP“Section 104” pool (average). Same-day and 30-day rules NOT implemented.
SpainFIFOFIFO mandatory (fungible securities).
PortugalFIFOFIFO mandatory.
GermanyFIFOFIFO (per securities account).
IrelandFIFOFIFO. Four-week rule NOT implemented.
FinlandFIFOFIFO. Deemed-acquisition-cost option NOT implemented.
PolandFIFOFIFO.
NorwayFIFOFIFO. “Skjerming” shielding allowance NOT implemented.
CzechiaFIFOFIFO. Holding-period exemption NOT implemented.
NetherlandsFlat wealth tax (box 3): the realised gain is generally not the tax base. Informational calculation.
BelgiumPrivate management historically exempt; a new capital-gains tax regime is being introduced — verify the current state.
SwitzerlandPrivate capital gains generally exempt. Informational calculation.
LuxembourgUsual exemption beyond 6 months (non-substantial holdings) — verify your case.

Per-country methods last checked: June 2026. A country not listed → choose the method manually.

Worked example — four operations on one security (no fees), reference currency EUR:

#OperationRate 1 € = $
1Buy 10 @ $1001.10
2Buy 10 @ $1201.20
3Sell 5 @ $1301.25
4Buy 5 @ $1101.00

The method changes the outcome: in the example above, the very same sale of 5 shares yields +42.73 in weighted-average terms — and +65.45 under FIFO. Same portfolio, same sale, two different taxable gains. Hence the importance of your country's method.

Indicative, not advice

The per-country methods above are indicative (last checked: June 2026); tax rules evolve and carry exceptions (wash-sale-style rules, allowances, elections) this tool does not implement. It is neither tax nor investment advice: verify the rule that applies to your situation.

Import from your broker

Typing every operation by hand is tedious. A small script can read your filled trades straight from your broker and write the CSV this calculator imports — with the ECB exchange rate of each trade date already filled in. It runs on your own machine, never in this page: brokers cannot be called from a third-party web page, and an API key has no business inside a browser tab.

Download pt-trades-export.py — Python 3, standard library only (no pip install), supports Alpaca and tastytrade.

  1. Save the file, then open a terminal in the folder where you saved it.
  2. Put your API keys in environment variables (the script never accepts them on the command line, where they would leak into your shell history). Run the command once without --symbol to list the tickers it finds, then again with the one you want:

Alpaca (drop --paper for a live account):

export APCA_API_KEY_ID=your_key
export APCA_API_SECRET_KEY=your_secret
python3 pt-trades-export.py alpaca --paper            # lists symbols
python3 pt-trades-export.py alpaca --paper --symbol SPY

tastytrade (add --cert for the sandbox, --otp CODE if you use two-factor):

export TT_LOGIN=you@example.com
export TT_PASSWORD=your_password
python3 pt-trades-export.py tastytrade                # lists symbols
python3 pt-trades-export.py tastytrade --symbol AAPL

The script writes SYMBOL-operations.csv (override with --out); then click Import CSV in the calculator above. Restrict the window with --from/--to, or skip the rate lookup with --no-rates. For a non-euro reference currency, add --currency GBP (or CHF, SEK, DKK, NOK, PLN, CZK) — the rate is cross-rated from ECB reference rates.

Rate convention. For a trade on a day the ECB did not publish a rate (a weekend or a public holiday), the script uses the last rate published before that date — the conventional carry-forward. If the ECB request fails, the rate column is left empty and you fill it in by hand; the script never stops on that account. Alpaca fills carry no commission, so the fees column is 0 for Alpaca; tastytrade fills include commission and regulatory fees.

Your keys stay with you

The script runs on your machine and sends your keys only to the broker you chose (over HTTPS), plus an anonymous request to the ECB for the rates. Nothing but the CSV is written to disk — no keys, no tokens, no logs. Never paste an API key into a web page. Use read-only or trading-disabled keys if your broker offers them, and revoke the keys afterwards if you wish.

Liability limitation

This tool is provided "as is", with no warranty of accuracy, completeness or fitness for your situation. We are not accountants, tax advisers or lawyers. Despite the care taken, errors remain possible — in the tool and in the per-country information — and we accept no liability for the consequences of using its results. Have your figures validated by a professional before filing anything.