Run it from source
There is no release yet: the first version, v0.1, is underway (see the roadmap). Its source can already read your exports and write the returns, so you can try it on your own computer. Treat what it writes as a draft to check, not a return to file.
What it reads today
Section titled “What it reads today”- Trading 212: the CSV export of your account history.
- Interactive Brokers (IBKR): an Activity Flex Query in XML (see below for its sections).
- Trade Republic: the transaction export (CSV), with all transactions. Its dividends are not read yet: a file with one stops both returns and says why.
Export your whole history, from the day you opened the account: each sale is matched against your earliest purchases of the same security first.
Setting up the IBKR Flex Query
Section titled “Setting up the IBKR Flex Query”In the Client Portal, open Performance & Reports → Flex Queries and add an Activity Flex Query, delivered as XML, with these sections:
| Section | What to tick |
|---|---|
| Account Information | Account ID and IB Entity |
| Trades | Executions, all fields (not Orders or Symbol Summary) |
| Corporate Actions | All fields |
| Cash Transactions | Dividends, Payment in Lieu of Dividends, Withholding Tax |
| Financial Instrument Information | All fields |
| Transfers | All fields |
Keep the general settings at their defaults (date yyyyMMdd). Select every account, closed
and migrated ones included, and run the query once per calendar year since you opened the
account: IBKR returns at most 365 days at a time.
What you need
Section titled “What you need”- Node.js 24 or newer.
- pnpm 10: run
corepack enableonce, and Node provides it. - Git, to fetch the source.
git clone https://github.com/jaxtothemax/broker-to-edavki.gitcd broker-to-edavkipnpm install --frozen-lockfilepnpm run buildIn your browser
Section titled “In your browser”pnpm --dir apps/web buildpnpm --dir apps/web previewOpen the address it prints (usually http://localhost:4173). The build carries the app’s
security policy, under which the files you add are read in a background worker whose network
and storage functions are removed and which may load only the app’s own files. Nothing is uploaded, and closing the tab forgets them.
pnpm --dir apps/web dev runs the same app for development, without that policy.
On the command line
Section titled “On the command line”node apps/cli/dist/bin.js my-exports/*.csv my-exports/*.xml \ --year 2026 --tax-number 12345678 --out returns/ --payers payers.jsonIt prints what it read, the estimated tax and every finding, and writes Doh_KDVP_2026.xml and
Doh_Div_2026.xml into returns/ when nothing blocks them; a return with nothing on it is not
written. The exit code is 0 when nothing blocks, 1 when something does, and 2 for a mistake in
the command. Add --json for a report other tools can read.
The JSON report says what became of each return, under returns: written; withheld, when
the return is needed but not written (a finding blocks it, a file was refused, or the write
failed); or nothingToFile. While any file is refused, both returns are withheld, because a
file that was not read may hold the year’s sales or payments; refused says which. The
estimates are given in every case, but for a withheld return the figure may change once what
stops it is fixed. The plain text says the same on each return’s line.
The JSON report also lists the shares you still hold, under holdings, in two views:
accounts: each account’s own position per security, which you can compare with what the broker shows, and the day it is as of: the last day that account’s files cover. An account is named by its broker and a number (ibkr-1), never by its account number.securities: the lots still open across all your accounts, matched first in, first out. These are the lots your next sale will be taxed against. Each lot shows its purchase date, its cost in euro at the Banka Slovenije rate of that day, andnextBucket: the lower tax rate it moves to next and the date it appliesfrom, ornullonce a lot is exempt. That date is the day after the anniversary, because FURS has not said whether the anniversary itself counts. A security’sasOfis the earliest last day among the accounts that hold it, since after that day one of them may have traded it in a file you did not add.
Market prices are never fetched, so holdings show what you paid, not what the shares are worth. If earlier exports are missing, holdings come out too low. An account’s day can be past the end of the exchange rates the app ships with only as far as its own trades reach, so a cash row dated years ahead does not make every lot look old. Three flags say where a figure may be wrong:
transferred: the account’s files move shares in or out, which are not read yet.refusedRows: a row of the account’s files was refused, so its position may be missing it.incomplete: your files sell more of the security than they buy.
If the holdings cannot be worked out, holdings is null and the returns are written as
usual.
Brokers do not export a dividend payer’s address, which Doh-Div needs, so give it in a small JSON file, one entry per security (by ISIN):
{ "US1912161007": { "name": "The Coca-Cola Company", "address": "One Coca-Cola Plaza, Atlanta, GA 30313, United States", "country": "US" }}A Slovenian payer also takes "taxNumber", and a foreign one may take its
"identificationNumber".
Before you import anything
Section titled “Before you import anything”Compare every figure with your broker’s own statements, and read every finding. TaxReporter prepares a return for you to check; it does not file it, and it is not tax advice. If a number looks wrong, please open an issue, without attaching your files.