Broker imports
How CSV imports work, which brokers auto-detect, and what to do when yours isn't on the list yet.
Broker imports
Importing your portfolio happens via CSV. No Plaid, no bank passwords, no screen-scraping — you export from your broker, drop the file onto Millefold, the parser auto-detects the format and lands every row as a ledger event.
Auto-detected brokers
| Broker | Region | Coverage | |---|---|---| | Trading 212 | EU | Stocks + cash + dividends | | Revolut | EU | Stocks + crypto | | Trade Republic | EU (DE) | Shares + ETFs | | DEGIRO | EU | EN / NL / DE / FR / IT / ES locales | | IBKR | Global | Activity Statement (multi-section) | | Robinhood | US | Shares + options | | Coinbase | Global | Crypto | | Binance | Global | Crypto |
If your broker is on this list, you don't need to pick a format — the parser detects the file from its header row or preamble.
What to do if yours isn't there
Two options:
1. Generic CSV with column mapping. The drop zone on /dashboard/assets and /dashboard/liabilities accepts a flat CSV with at least name,category,current_value,currency for assets, or name,category,principal,currency,apr for liabilities. We surface a column-mapper UI that lets you pick which column maps to which field.
2. Email `hello@millefold.com` with a sample CSV. If 3+ users have the same broker, we add native auto-detection. So far this has shipped: T212, Revolut, TR, DEGIRO, IBKR, Robinhood, Coinbase, Binance — and the next ones queued are Saxo, Nordnet, Lightyear.
What gets imported
For each transaction row, we land:
- Type — deposit / withdrawal / buy / sell / dividend / dividend_tax / interest / fee / fx_conv
- Amount — signed in the original currency
- Ticker — for trade-related rows
- Shares + unit price — for buy/sell rows
- Source —
csv_import_<broker>so re-imports dedupe
You see all of it at /dashboard/events, grouped by type with running totals.
Position reconstruction
Positions are rebuilt from the event ledger: for each ticker, we walk the buys and sells chronologically, track shares + cost basis, and save the result as holdings on /dashboard/assets. This means re-importing the same CSV later just refreshes the ledger; positions follow automatically.
Multi-currency
Every row keeps its native currency. The dashboard sums everything in your default_currency (set on /dashboard/settings) using daily ECB reference rates from Frankfurter. Historical events use the FX rate at the time of import, not at the time of the event — see FAQ for the trade-off.
Privacy
CSV files are parsed on the server and not stored. The holdings built from them (names, values, cost basis) are encrypted at rest. The transaction rows themselves (type, amount, ticker, shares, unit price, date) are stored unencrypted, limited to your account by row-level security. See encryption at rest for what that does and doesn't protect against.