TR Analyzer

// May 2026 – May 2026

Visit project
TR Analyzer - Trade Republic Transaction Export Analyzer PWA

What it does

TR Analyzer is a local-first portfolio and trade analysis app for Trade Republic exports. You import a CSV, and it turns the raw transaction data into a dashboard for current holdings, realized and unrealized P&L, asset allocation, cash flow, and a German capital gains tax overview.

The goal was to get a clearer view of my own investing activity without uploading personal financial data to another service or maintaining yet another spreadsheet.

Features

  • Portfolio dashboard — current holdings, invested amount, current value, fees, tax, and allocation
  • Trade journal — FIFO-matched buy/sell pairs with realized P&L, hold duration, win rate, and detailed trade breakdowns
  • Cash flow — deposits, withdrawals, interest, dividends, fees, and tax withheld over time
  • Tax overview — German KeSt/Soli calculation, income breakdown, and Freistellungsauftrag tracking
  • Local-first import — CSV parsing happens in the browser; persistence is optional through IndexedDB

Tech

Built as a privacy-focused PWA:

  • Nuxt 4 — SPA frontend and app shell
  • Nuxt UI + Tailwind CSS — interface components and styling
  • Pinia — client-side state management
  • PapaParse — browser-side CSV parsing
  • Dexie — optional IndexedDB persistence
  • Unovis — charts for P&L, allocation, trades, and cash flow
  • Vite PWA — installable app with offline support after the first load

Keeping it local-first was the main architectural decision. The CSV never needs to leave the browser, and the only server route is an optional live-price proxy so the app can fetch current prices without running into CORS issues.

Live price API

The app can optionally fetch approximate live prices for open positions. When enabled, the frontend sends the ISINs of current holdings to a small Nuxt server route, which looks up matching Yahoo Finance symbols and returns the latest price data.

That route exists mostly as a practical proxy layer: it avoids browser CORS issues, keeps the client code simpler, and lets the app prefer EUR listings where possible, including German exchanges such as Frankfurt (FRA), Xetra/Germany (GER), Stuttgart, Munich, and others.

If the best available quote is not already in EUR, the API converts it through Frankfurter before returning a normalized EUR price to the app. Prices are cached for a short time, so refreshing the dashboard does not immediately hammer the upstream APIs.