Files
fn_registry/dev/issues/0088d-trading-portfolio-tracker-app.md

66 lines
2.9 KiB
Markdown

---
id: "0088d"
title: "Trading: app `portfolio_tracker` (ledger INSERT-only)"
status: pendiente
type: feature
domain:
- trading
scope: app-scoped
priority: alta
depends: []
blocks: []
related: []
created: 2026-05-17
updated: 2026-05-17
tags: []
---
# 0088d — Trading: app `portfolio_tracker` (ledger INSERT-only)
**Status:** pendiente
**Created:** 2026-05-14
**Type:** feature
**Parent:** 0088
**Depends:** 0088a
**Blocks:** 0088c, 0088h
## Problema
Necesitamos un ledger inmutable multi-account, multi-currency, multi-asset desde el dia 1 + UI minima para inspeccionarlo. Es la fuente de verdad del estado de cuentas; cualquier broker (paper o real) escribe contra este ledger.
## Piezas
1. App Go en `projects/trading/apps/portfolio_tracker/` (service + sqlite_api + Mantine UI).
2. Schema (en `migrations/*.sql`, aditivo):
- `accounts` (id, label, currency_base, broker_kind, created_at).
- `instruments` (id, symbol, kind, currency_quote).
- `transactions` (id, account_id, instrument_id, ts, side, qty, price, fee, fee_currency, client_order_id, broker_fill_id, raw_json, source). **INSERT-only**, indice por `(account_id, ts)` y unique sobre `client_order_id`.
- `equity_snapshots` (id, account_id, ts, equity_quote_currency, unrealized_pnl, realized_pnl_delta).
- `valuation_marks` (id, instrument_id, ts, price, source). Marca de precio para valoracion.
3. Funciones puras del registry (no inline en la app):
- `reduce_positions_from_transactions_py_finance(txs) -> list[Position]`.
- `compute_realized_pnl_py_finance(txs) -> float`.
- `compute_unrealized_pnl_py_finance(positions, marks) -> float`.
- `compute_equity_py_finance(balance, positions, marks) -> float`.
4. API HTTP via sqlite_api/CRUD generator sobre las 5 tablas. Endpoint custom `/api/equity_curve?account_id=X`.
5. UI Mantine con @fn_library:
- Lista de cuentas con balance + equity actual.
- Detalle de cuenta: tabla de transactions, grafico equity curve, posiciones abiertas.
- Form de transaction manual (para depositos/retiradas/ajustes que no vienen de broker).
6. `e2e_checks` en `app.md`:
- `build_frontend`, `build_backend`, `smoke` (arranca puerto efimero + GET `/api/health`).
- `ledger_immutable`: intenta UPDATE/DELETE sobre `transactions` y espera fallo (constraint trigger).
- `reconciliation`: tras insertar N transactions sinteticas, `reduce_positions` retorna lo esperado.
7. Tag `service` en `app.md`. Tag de grupo `journal`/`trading`.
## Aceptacion
- Ledger no permite UPDATE/DELETE de transactions (trigger SQLite).
- Reconciliacion determinista: dadas las mismas transactions, mismo resultado de posiciones/balance/equity.
- `fn doctor artefacts` y `fn doctor cpp-apps` (n/a aqui) sin errores.
- App lanzable como service con `deploy_server` (no obligatorio para cerrar el issue, pero `app.md` debe declarar deploy target).
## No-objetivos
- Integracion broker. Eso entra en 0088c.
- Computo de impuestos/FIFO fiscal. Solo PnL operativo.