Skip to content

diogogithub/firefolio

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Firefolio

A calm, browser-first portfolio control room for your XTB portfolio (and IBKR later). It turns raw broker statements into a plain-English monthly review: what you own, how much you put in, how much your investments actually gained, whether you are following your core/satellite plan, and what to buy with your next contribution.

Everything runs in your browser. Your portfolio data never leaves your machine — only public market symbols and currency pairs are sent to a small bundled PHP API that fetches and caches quotes, FX and historical bars.

Licence

Firefolio is free software under the GNU Affero General Public License, version 3. See LICENSE. If you run a modified version over a network, the AGPL requires that users be offered the corresponding source code.


What it does

  • Dashboard — value, money contributed, investment gain, core share, FIRE gauge, top actions, and your full recommendation list.
  • Review — a beginner-friendly monthly review with a copyable plain-English summary.
  • Holdings — every open position with value, cost, unrealized P/L, role and class.
  • Allocation — actual-vs-target by ticker / class / role, currency & region exposure, concentration, tiny positions, and a new-money rebalancing planner (167 / 250 / 500 / 1000 / custom).
  • Analytics — daily timeline, time-weighted and money-weighted return, Modified Dietz, realized vs unrealized, drawdown, monthly returns, rolling returns and a return-decomposition waterfall. Estimates are clearly labelled.
  • Benchmarks — growth-of-100 against VWCE, FWIA, V80A, SPY, QQQ, plus learning-oriented counterfactuals ("what if tactical buys had gone into VWCE?").
  • Doctor — separates real issues from harmless noise, plus a cash reconciliation breakdown by account.
  • Settings & data — import, prices/FX, the ticker table editor, transactions, copyable reports, FIRE export, settings, backup/reset.

Requirements

  • Any host that can serve static files and run PHP 7.4+ (the finance API is a single PHP file). A plain Apache/Nginx + PHP-FPM box, or php -S for local use, is enough.
  • A modern browser (Chrome, Edge, Firefox, Safari). Imports use the browser's built-in zip/decompression APIs.
  • No build step, no database, no Docker, no broker login.

Run it

Locally (quickest):

cd firefolio
php -S localhost:8000
# open http://localhost:8000

On a web host: copy the whole firefolio/ folder into a PHP-capable web root. Make sure data/finance-cache/ is writable by the web server (that is the only writable directory; it stores cached public quotes).

If you open index.html directly with file://, the app loads but price/FX/history updates fail because there is no PHP. Serve it over HTTP.


Using Firefolio

1. Import your XTB statements

Go to Settings & data → Import and drop your XTB export. Firefolio accepts the XTB ZIP (containing the per-account .xlsx files) or the individual .xlsx files. It reads both the Cash Operations sheet (deposits, withdrawals, buys, sells, dividends, fees, taxes, transfers) and the Closed Positions sheet (for broker-exact realized P/L). Multiple accounts and currencies are handled and kept separate.

Re-importing is safe — rows are de-duplicated, so you can drop a fresh export each month.

2. Update prices and FX

Go to Settings & data → Prices & FX → Update prices. This sends only your tickers (as public symbols) to api/finance.php, which fetches quotes, applies XTB→Yahoo symbol mapping and GBp/pence scale fixes, and caches results for 6 hours. Then Update FX rates for any non-base currencies.

3. Review the ticker table

Go to Settings & data → Ticker table. This is where classification lives. For each ticker you can edit name, asset class, theme, region, quote currency, price symbol, scale, role and target weight, all inline.

  • Roles: core, satellite, speculative, cash-like, legacy.
  • Core ETFs are detected explicitly (VWCE.DE, FWIA.DE, AVWS.DE, V80A.DE) — never guessed from a fund name.
  • Target weights accept either form: 0.48 or 48 both mean 48%. A live indicator shows whether your targets sum to 100%.
  • Apply recommended classifications fills classes/roles/themes for known tickers; Apply recommended targets previews a starter target set before you commit.
  • Search, sort and bulk-edit are supported. Edits are held until you press Save ticker table (an unsaved-changes banner reminds you). You can import/export the table as JSON or CSV.

4. Build analytics

Go to Analytics → Build analytics. Firefolio fetches daily history for your holdings and FX pairs and reconstructs a daily portfolio timeline. This unlocks the charts and return figures across Dashboard, Review, Analytics and Benchmarks. Rebuild whenever you import new data or change classifications.

5. Allocation & rebalancing

Allocation shows where you have drifted from your target structure and includes the new-money planner: pick a contribution amount and Firefolio suggests what to buy, why, how much gap each buy closes, and what to avoid topping up — preferring new money over selling.

6. Benchmarks

Benchmarks → Build comparison plots your portfolio's growth-of-100 against simple index ETFs and shows counterfactuals for behaviour review (not predictions).

7. Recommendations

The Dashboard lists a small, calm set of recommendations. Each shows severity, confidence, why it triggered, the supporting data, a suggested action, what happens if ignored, and a link to the relevant tab. Dismiss or Snooze (30 days) anything that does not apply.

8. Reports

Settings & data → Reports gives copyable plain-English narratives (monthly review, allocation, trading behaviour, FIRE summary) you can paste into a journal.

9. Backups

Settings & data → Backup & reset → Download backup exports a full JSON snapshot (transactions, prices, aliases, FX, settings) you can re-import later or move to another browser. Reset erases all local data.

10. Export to your FIRE planner

Settings & data → FIRE export writes a clean, unencrypted JSON bridge (portfolio value, holdings/cash split, net contributed, investment gain, monthly contribution assumption, allocation summary, optional daily series and benchmark summary). Firefolio deliberately does not do full retirement scenario planning — that belongs in your separate FIRE app.


Privacy & data flow

  • Portfolio data (transactions, prices, aliases, settings) is stored locally in IndexedDB. A couple of small preferences (theme, dismissed/snoozed recommendations) live in localStorage.
  • The only data sent to the server is public market symbols and currency pairs. No holdings, amounts, account numbers or personal data are transmitted.
  • The PHP API caches public responses in data/finance-cache/. No database is used.

Notes & limitations

  • Returns, realized/unrealized P/L and counterfactuals are estimates for review, not tax or accounting outputs. Realized P/L is broker-exact when XTB's Closed Positions sheet is imported, and an average-cost estimate otherwise (clearly labelled).
  • Charts, the daily timeline and benchmarks require the PHP finance API to fetch history; without network access those sections stay in their empty state, but everything else (holdings, allocation, classification, cash reconciliation) works offline from your import.
  • IBKR Activity Flex CSV import is scaffolded for the future; XTB is the supported path today.

Project layout

firefolio/
  index.html            # small static shell (nav + empty panels, rendered by JS)
  assets/app.js         # single build-free module: pure engine + browser UI
  assets/styles.css     # calm light theme (default) + optional dark theme
  api/finance.php       # public quotes / FX / history, with 6h file cache
  data/default-aliases.json   # reference classification library (also embedded in app)
  data/finance-cache/   # cached public market data (must be writable)

v3.0.1 import fix

If the XTB importer gets stuck at Reading <file>.zip…, use this build. It includes a built-in pure JavaScript ZIP/DEFLATE inflater so imports no longer depend on browser-specific DecompressionStream('deflate-raw') behaviour.

v3.0.3 import save fix

  • Fixed an IndexedDB save stall that could stop around 600/710 row(s) during large XTB ZIP imports.
  • Broker rows are now saved with idempotent put() operations in smaller 50-row chunks.
  • Re-importing the same export is still safe because rows are keyed by content hash.
  • Import progress now reports saved rows instead of trying to classify new vs duplicate rows during the heavy save step.

v3.1 final polish

This release fixes the remaining portfolio-reading issues found during review:

  • Benchmarks now include V60A.DE.
  • Learning counterfactuals prefer FWIA.DE and V60A.DE instead of only VWCE.DE.
  • Likely XTB subaccount cleanup / immediate reinvestment is de-emphasised in churn-style insights.
  • ERNA/cash-like instruments are tracked in allocation but excluded from automatic new-money buy suggestions.
  • Fixed quote scaling for London instruments such as WISE.UK: the PHP API already normalises pence/GBp, so the browser no longer multiplies by the API scale again.
  • Analytics metrics have plainer explanations for time-weighted return, money-weighted return, Modified Dietz, rolling returns and drawdown.
  • Actual-vs-target bars are clearer and no longer label-collide around target markers.

After installing, run Prices → Update holding prices once to correct any old WISE/GBp cached browser price row.

v3.3 note

The Behaviour lessons section now has a clearer contribution-planner button and a more informative tiny-position simplification check. Tiny positions are compared against FWIA using still-open FIFO lots, so the result is meant as a practical behaviour lesson rather than a precise backtest.

Tests and synthetic demo

Run the dependency-free engine tests with:

npm test

demo/firefolio-demo.json contains synthetic transactions only and can be imported through Firefolio's backup/import workflow. Generated market-data cache files are deliberately excluded from source control.

Live version

The canonical deployment is diogo.site/apps/firefolio/. Firefolio requires PHP for quotes, FX and historical prices, so GitHub Pages can host only the static shell, not the complete application.

About

Browser-first portfolio analytics for XTB statements, allocation, benchmarks, data quality and FIRE export.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors