A CSV of trades almost never says what currency it is in. It says -1250.00 and leaves it at that.
That is fine while everything you trade settles in the same currency — and it stops being fine the
moment a DAX strategy sits next to an SPX one in the same portfolio, because then the total is a sum of
euros and dollars, and a sum of euros and dollars is not a number.
VEEMAN handles this in two halves: it works out what currency each strategy is in, and it converts everything into one currency you choose to read in.
Every session is expressed in a single base currency — the unit of the initial capital, of every P/L figure, of the KPI strip, the charts, the tables and the exports. You set it from the currency picker that sits next to the capital: in the Workspace header, and in the status bar of the other analysis modules. Settings holds the default for new analyses, not a switch over the one you have open.
Changing it is a restatement, not a recalculation. Every amount is multiplied by one rate — the initial capital and your manual costs included — and nothing else moves:
What a currency switch cannot change
Sharpe, Sortino, Calmar, CAGR, win rate, profit factor, max drawdown in %, the shape of the equity curve, the ranking of your strategies. These are ratios: scaling every dollar figure by the same number leaves them exactly where they were. If one of them moved, that would be a bug.
New sessions start in your default currency (Settings → Formats). A saved portfolio remembers the currency it was saved in, so reopening it gives you back the same units — on any device, whatever that device's preference says.
Each strategy keeps its own currency — the one its file is written in. The stored series is never rewritten: conversion happens when the portfolio is read, so re-importing, exporting or updating the data always gives you back what your broker actually wrote.
VEEMAN works out that currency from the strongest signal the file offers:
| Signal | Certainty |
|---|---|
A currency symbol inside the amounts (€1.234,50) | Read from the file |
A Currency / Valuta / CCY column with one value | Read from the file |
| The base currency of an Interactive Brokers statement | Read from the file |
A Symbol column matched against the instrument registry | Inferred |
The strategy or file name matched against the registry (FDAX → EUR) | Inferred |
| Nothing at all | You are asked |
The registry knows the major indices, futures and exchange suffixes: SPX, ES, NQ and RTY settle in
dollars; FDAX, FESX, IBEX and CAC in euros; N225 in yen; FTSE in sterling; SMI in francs; .MI, .DE
and .PA in euros, .L in sterling, .T in yen. It also knows the traps — NKD is the Nikkei at the
CME and settles in dollars, while NIY is the same index at the same exchange in yen; a CME FX
future like 6E is the euro quoted in dollars, not an instrument in euros; and a forex pair settles
in its quote currency, so EURUSD makes dollars and USDJPY makes yen.
Short roots don't decide on their own
Roots like ES, SI, CL or LE are also ordinary words. A file called ambito_es_test.csv is not
the E-mini, and guessing that it is would silently reinterpret its P/L. Those matches only ever
preselect the answer to the question — they never answer it for you.
If a file says nothing and its name gives nothing away, the import still goes through: the strategies
enter with your reading currency as a stated assumption, and one question appears at the end of the
import — one for the whole import, not one per file. Answer it and the strategies are corrected in a
single step; postpone it and the assumption stays visible until you confirm it. In the strategy list it
is stated once, above the rows ("5 strategies with an assumed currency"): click it and pick the
currency to confirm it for all of them in one step (one Timeline entry, one undo). Each affected row
carries a small amber dot; hover the row to see the dashed badge with its ?, which confirms or corrects
that single strategy.
You can change a strategy's currency at any time from that badge, and — with several rows selected — for all of them at once. Once you have set a strategy's currency yourself, its badge stays on the row, even when that currency matches your reading currency.
Nothing stops you from mixing markets: an SPX strategy in dollars and a DAX one in euros aggregate correctly, because each leg is converted before it is summed. The currency badge appears on every row while a portfolio is mixed, so you can always see who is in what.
Conversion applies to everything that comes from the file — the daily P/L, and for dynamically sized legs also the premium, the per-contract P/L and the margin, so that contract sizing compares like with like against your capital. The same goes for the account balance some exports carry (Option Omega's Funds at Close), which the risk-based optimizer uses as its day-by-day capital ceiling: it is a figure in the account's own currency, so it is converted before it is compared with anything. Numbers you type — capital, commissions, slippage, the dollar stop, the manual margin — are already in the reading currency and stay untouched until you switch currency, at which point they are converted with everything else.
Rates are the European Central Bank reference rates: one published fixing per day, official, free and reproducible. A live quote feed would give a slightly different number every minute, and two readings of the same page a minute apart would show two different P/Ls with nothing having changed.
A session pins its rates the first time it needs one, so the figures don't move under your hands while you work. The chip tells you which fixing you're on ("ECB rates from 2026-09-19") and offers Refresh rates when you want to move to today's. New sessions always start on current rates.
Today's rate over the whole history
The conversion applies one rate — today's — to the entire history. It answers "what is this track record worth in euros today", and it deliberately adds no currency volatility to your metrics. Reconstructing what a euro-denominated account would actually have shown, day by day, is a different question — one about currency risk. It is answered separately, by the currency effect below, rather than mixed into every ratio.
Reading at a constant rate keeps your metrics clean, but currency risk is real money: on a long track record it is not a rounding difference. Rather than making you choose between reading clean and knowing, the two are separated — and they add up exactly:
P/L at historical rates = P/L at a constant rate + currency effect
The Metrics page carries a Currency effect box whenever at least one strategy is in another currency (in a single-currency portfolio it doesn't exist, and nothing is even requested). It shows the total over the framed period, what share of your net result that is, a cumulative curve — which says when the currency weighed — and a per-strategy breakdown. It follows the period like every other figure on that page.
Day by day the arithmetic is simply:
effect(t) = the strategy's daily contribution × ( rate(t) / today's rate − 1 )
where the contribution is the P/L as it enters the portfolio today, with weight, group scale, sizing and compounding already applied.
The assumption, stated
The effect assumes each day is converted at that day's rate — an account that brings its results home as it goes. If you instead hold the balance in a foreign currency, you did not take this effect on individual trades: your exposure sits on the balance, which is a different and usually larger thing. VEEMAN cannot know which of the two your account is, so it states the assumption instead of guessing it. Sizing is deliberately not re-simulated at historical rates: the box measures the translation effect on realised P/L, not the second-order effect of different rates leading to different contract counts.
Strategies whose rate history can't be fetched are left out of the total and named, so the figure never quietly covers less than it claims to.
The effect is what the currency did. The box also states what you are exposed to now: how much of your result is denominated in each foreign currency, and what a move is worth — on the result you have accumulated, and (clearly labelled as conditional) on the whole balance if your capital sits in that currency too. The second number is the one that matters for anyone who leaves the account abroad: a dollar 10% lower costs 10% of the balance, which has nothing to do with any single day's P/L.
The same metrics — net P/L, annual volatility, max drawdown, Sharpe, Calmar — computed on both readings, side by side. Two curves made of the same P/L converted two ways, anchored to the same capital, so the difference between the columns is the currency's contribution. On a decade of Nikkei read in euros it is the difference between a −6.2% and a −8.3% maximum drawdown.
What matters is not how much a currency swings but how far it has drifted from where it is today. Sterling swung 27% over a decade and came back: reading an old result at today's rate is nearly correct. The yen fell 69% and did not come back: a 2016 result read today is understated by about half.
So the box escalates on its own. Past roughly 10% — on the foreign part or on your net result — it stops being a quiet panel and becomes a warning that names the number.
For a portfolio where the drift is material, the constant-rate reading is convenient but is not what the account saw. You can switch that portfolio to historical rates from the currency-effect box: every day is then converted at the rate it had.
It is a property of the portfolio — saved with it — and deliberately not a global setting: an
application-wide switch would make every number in VEEMAN ambiguous depending on how it happened to be
set. While it is on, the currency chip says · historical and the metrics page says it plainly, because
currency risk is then inside every figure: Sharpe, drawdown and volatility included, and those
figures are no longer literally comparable with a portfolio read at a constant rate.
One convention at a time
If the rate history can't be fetched for even one strategy, the whole portfolio falls back to the constant rate and says so. A total that mixes one leg at historical rates with another at today's rate answers no question at all.
A saved portfolio reopens in the currency it was saved in. A variant behaves differently on purpose: it is a frozen result that lives next to the live session in the comparison view, so when you read the session in another currency its figures are restated into that unit — the money scaled by one rate, the percentages, ratios and curve shapes untouched. Switching currency to show your work to someone else does not break the comparisons you had set up.
Two things that restatement is not. It is not a recomputation: the numbers stay the ones you froze, only expressed differently — a variant that mixes currencies was composed at the rates of its own snapshot and stays that way. And it is not silent when it fails: if the rate can't be reached, the variant keeps its own currency, says so on its chip and in the comparison column, and its numbers should not be read next to the live ones until the rate is back.
If a strategy is in another currency and no rate can be obtained — no network since startup and nothing cached — that leg is left out of the calculation and said so, in the chip and on the row. It is not summed at a rate of 1. A made-up rate is a scale error, and a scale error doesn't look like an error: the numbers stay perfectly plausible while being wrong by a fifth, or by a factor of 150.
A CSV export, on the other hand, carries the amounts as the session shows them: the equity and monthly exports state the currency in their header, so a file of bare numbers can't be mistaken for another unit. See Exporting.