flatex-pdf-cli

command module
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 13, 2026 License: MIT Imports: 19 Imported by: 0

README

flatex-pdf-cli

CI Coverage Status CodeQL Release Go Version

Get your transaction data out of flatex/flatexDEGIRO (a German online broker, also operating in Austria) PDF statements and into something you can actually use: structured JSON for your own tooling or AI agents, CSV for spreadsheets, or ready-to-import files for Portfolio Performance. Point it at a single PDF or a whole directory — trades, dividends, interest, fund distributions, orders, crypto, savings plans.

Don't have the PDFs yet? flatex-fetch logs into the flatex.at portal and downloads them for you; this tool then turns them into structured data.

Disclaimer: This is an independent, unofficial open-source project. It is not affiliated with, endorsed by, sponsored by, or in any way associated with flatexDEGIRO AG, flatex, DEGIRO, or any of their subsidiaries. "flatex" and "flatexDEGIRO" are trademarks of their respective owners and are used here only to describe the document format this tool parses. Use at your own risk; always verify extracted data against the original documents.

Features

  • Seven document types — trades, dividends, interest, accumulating funds, orders, crypto settlements, savings plans
  • Three output formats — JSON, CSV, and Portfolio Performance import files (English or German)
  • Every charge, itemised — Provision, Eigene/Fremde Spesen and the full Gebühren breakdown (Courtage, Tradinggebühr, Regulierung, …), plus a ready-to-use total
  • Unambiguous dates — trade date, order date and value date are separate fields, not one guess
  • Batch processing — single PDFs or whole directory trees; one bad file never aborts the batch
  • Depot metadata & audit trail — optionally include depot number/holder and per-transaction source filename
  • AI-agent ready — ships a Claude Code skill so coding agents can drive the CLI

Quick Start

brew install welworx/tap/flatex-pdf-cli
# or: go install github.com/welworx/flatex-pdf-cli@latest

flatex-pdf-cli ~/Downloads/statement.pdf
[
  {
    "document_type": "DIVIDEND",
    "isin": "IE00B3RBWM25",
    "date": "2025-10-01",
    "quantity": 74.45,
    "distribution_per_share": 0.422745,
    "gross_amount": 31.47,
    "net_amount": 22.43,
    "net_currency": "EUR"
  }
]

Pre-built binaries and other install options: skill/INSTALL.md.

Supported Documents

The tool automatically detects and parses the following flatex document types:

Type Status Description
TRADE ✅ Full Buy/sell confirmations (Wertpapierabrechnung Kauf/Verkauf) with pricing, costs, and gain/loss
DIVIDEND ✅ Full Dividend payment statements (Ausschüttung) with distribution details and withholding tax
INTEREST ✅ Full Interest payment notices (Zinsen) on cash accounts
ACCUMULATING ✅ Full Reinvestment/accumulation notices (Ertragsmitteilung, thesaurierende Fonds)
ORDER 🟡 Partial Order confirmations (Sammelauftragsbestätigung); one record per pending order — see limitations
CRYPTO ✅ Full Crypto buy/sell settlements (Sammelabrechnung Kryptowerte)
SAVINGSPLAN ✅ Full Annual savings-plan settlement (Sammelabrechnung aus); one transaction per executed order row

German-language PDFs only — non-German statements are rejected with an error (see Known Limitations). Developed and tested against Austrian flatex statements; German (Germany) statements use the same platform and should follow the same layout, but haven't been verified against real samples yet — please open an issue if you hit a mismatch.

Usage

Process a single PDF file (JSON to stdout) or a directory of PDFs:

flatex-pdf-cli path/to/statement.pdf
flatex-pdf-cli path/to/documents/
Flags
  • -o FILE — Output file (stdout if not provided)
  • -format FORMAT — Output format: json (default), csv, or pp (Portfolio Performance)
  • -lang LANG — Language for pp output: en (default) or de
  • -include-source — Add source filename to each transaction
  • -include-metadata — Wrap output with depot metadata
  • -quiet — Hide skipped/problematic files; emit only valid JSON
  • -verbose — Print progress to stderr: files parsed, and any charge derived rather than read from the document
  • -version — Show version and exit

When given a directory, the tool processes every .pdf it finds. A file it cannot parse is reported on stderr and skipped — the rest still produce output, so one bad document never aborts the batch. Use -quiet to suppress the skip messages and get pure JSON on stdout.

A run that skipped anything exits non-zero and prints how many of the files parsed, even under -quiet. Output is still written: the documents that parsed are worth having. This matters on a schedule, where the exit status is usually the only thing anything looks at, and a partial batch reported as success is a data gap nobody notices.

Examples
# Save output to file
flatex-pdf-cli -o output.json path/to/documents/

# Include depot metadata in output
flatex-pdf-cli -include-metadata path/to/trade-confirmation.pdf

# Include source filename with transactions (for audit trail)
flatex-pdf-cli -include-source -o transactions.json path/to/documents/

# Combine flags
flatex-pdf-cli -include-source -include-metadata -o output.json path/to/documents/
Upgrading
flatex-pdf-cli upgrade -check   # report whether a newer release is available
flatex-pdf-cli upgrade          # check, then prompt to download and install it
flatex-pdf-cli upgrade -y       # skip the confirmation prompt

Downloads the release asset for your platform from GitHub, verifies it against the published SHA256SUMS.txt, and atomically replaces the running binary.

Use Cases

Prepare a Portfolio Performance import

-format pp parses your PDFs into two CSVs shaped for PP's CSV import — trades and account transactions — so the import is a few clicks instead of manual column mapping. Use -lang de if your PP runs in German; PP's column auto-recognition is locale-sensitive, and -lang de emits the German headers, Typ values, and number format it expects.

flatex-pdf-cli -format pp -lang de -o portfolio ~/Downloads/flatex
# writes portfolio-portfolio.csv and portfolio-accounts.csv

Read more: docs/portfolio-performance.md — import walkthrough, -lang de details, caveats.

Export CSV for spreadsheets

-format csv writes one row per transaction, every parsed field as a column. Good for spreadsheets or your own scripts.

flatex-pdf-cli -format csv -o transactions.csv ~/Downloads/flatex
Organize your downloads

Sort flatex PDFs from your Downloads folder into a structured archive — one folder per depot, files renamed by date and document type — using the CLI's JSON output and jq.

Read more: docs/organize-downloads.md — ready-to-paste shell recipes.

Use from AI agents

This repo ships a ready-made Claude Code skill so AI coding agents can call the CLI and consume its JSON (flatex-pdf-cli -quiet -include-metadata <path>).

Read more: skill/SKILL.md — the full agent contract and install steps (skill/INSTALL.md).

JSON Reference

Each transaction is a flat JSON object; -include-metadata wraps the list with depot metadata:

{
  "metadata": {
    "depot_number": "1234567890",
    "depot_holder": "Max Mustermann",
    "account_number": "9876543210"
  },
  "transactions": [
    {
      "document_type": "TRADE",
      "isin": "DE0005140008",
      "wkn": "514000",
      "date": "2024-06-15",
      "order_date": "2024-06-13",
      "value_date": "2024-06-17",
      "type": "BUY",
      "quantity": 10.0,
      "price": 25.50,
      "price_currency": "EUR",
      "gross_value": 255.00,
      "costs": {
        "provision": 5.50,
        "own_expenses": 0,
        "foreign_expenses": 3.00,
        "total": 8.50,
        "fees": {
          "courtage": 0,
          "trading_fee": 0.50,
          "settlement": 2.50,
          "closing_notes": 0,
          "ls_allocation": 0,
          "financial_transaction_tax": 0,
          "other": 0
        }
      },
      "final_amount": -263.50,
      "final_currency": "EUR",
      "custody_type": "Wertpapierrechnung",
      "depositary": "Clearstream Lux.",
      "deposit_country": "GB",
      "execution_venue": "XETRA"
    }
  ]
}

Two things worth knowing before you use the numbers:

  • date is the trade date (Handelstag, or Schlusstag/Buchtag on crypto and savings plans) — not the date printed at the top of the letter. order_date (Auftragsdatum) and value_date (Valuta) are emitted alongside it, and on a real statement all three are usually different days. Dividends and interest use Valuta as their date, since that is when the money moves.
  • costs.total is the transaction's total chargeProvision plus Eigene Spesen plus Fremde Spesen. The entries under costs.fees itemise foreign_expenses and are already counted in the total; adding them on top double-counts. costs is absent when a document has no charge block at all, which is how a real 0,00 EUR fee stays distinguishable from an unparsed one.

Full field reference (common, trade, dividend, interest, accumulating, order, and crypto fields): docs/output-format.md.

Known Limitations

  • Savings-plan charges are derived, not read. A Sammelabrechnung aus prints only the amount settled per row, never a fee line: a 200,00 EUR execution at 134,2400 EUR buys 1,478695 shares, which is 198,50 EUR of stock, and the missing 1,50 EUR is a charge the document does not itemise. The parser recovers it as that gap and reports it as costs.unitemised, kept separate from provision / own_expenses / foreign_expenses because those carry a label the statement actually printed and this one does not. Run with -verbose to see the arithmetic per row. A gap that is negative, or larger than 5% of the amount settled, is treated as a layout change and fails the parse rather than being booked as an implausibly large fee.
  • German-language PDFs only. Document-type detection and field extraction are keyed to German labels (Wertpapierabrechnung, Valuta, Devisenkurs, …); non-German statements are detected and rejected with an error rather than silently mis-parsed. Numbers are parsed format-agnostically (both 1.234,56 and 1,234.56 are accepted), so the restriction is purely about field labels — English support needs a real English sample to map the labels. Developed and tested against Austrian flatex statements only; German (Germany) statements haven't been verified against real samples — please open an issue if you hit a mismatch.
  • ORDER security_name includes the execution venue. gxpdf does not always put a space between the Bezeichnung and Ausf.platz/-art columns (e.g. "GLOBAL X COPPER MINERS ETXETRA"), so the venue is left attached to the name rather than split unreliably. Order confirmations therefore do not populate a separate execution_venue.
  • Metadata extraction (depot_holder, depot_number) can be empty or noisy on documents whose layout places the value far from its label.
  • Account number (Konto Nr.) is matched at a fixed length (11 digits) to work around a page-break run-on in text extraction; non-standard lengths won't match. (The depot number is matched at any length.)
  • SAVINGSPLAN WKN is not present in Sammelabrechnung documents; the wkn field will be empty for these transactions.
  • deposit_country covers a fixed country list. Lagerland is translated from its German name to an ISO 3166-1 alpha-2 code against a built-in table. gxpdf runs that column straight into the next one ("GroßbritannienBemessungsgrundlage: 0,00 EUR"), so matching a known name is also what separates the two — a country outside the table yields no code rather than a half-captured string. Please open an issue if a real statement names one the table misses.

Additional document types (e.g. tax reports) will be added as samples become available.

Contributing & Development

Contributions are welcome — bug reports, code, and above all real sample documents. The parsers only get better with real-world PDFs, but broker statements are full of PII. This project's test fixtures are real flatex PDFs with the PII redacted and replaced in place with synthetic values — visually and structurally identical to production documents, safe for a public repo:

The full method — and why naively generated synthetic PDFs give you passing tests and a broken parser — is covered in Your AI's Test Fixtures Are Lying to You. Make real-world synthetic PDF files, PII safe!

Project layout, test/lint setup, and the PR checklist: CONTRIBUTING.md. For issues, feature requests, or questions, open an issue on GitHub.

License

Licensed under the MIT License. You're free to use, modify, and redistribute it, including for commercial purposes, provided the copyright notice is retained. The software is provided "as is", without warranty of any kind and with no liability on the author's part — see the LICENSE file for the full disclaimer.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL