Funk-lab/admin/ia/finlab.md
ALI YESILKAYA 9d55cc803d
feat(finlab): import déterministe d'un relevé de compte Revolut → positions (#72)
Procédure de mise à jour du portefeuille « à chaque trade » à partir des relevés
Revolut, sans IA (exact).

- finlab/revolut.py : reconstruit les positions depuis le « trading account
  statement » (toutes transactions) par COÛT MOYEN (achats − ventes, PRU pondéré),
  mappe les tickers Revolut→Yahoo (ASME→ASML.AS, TOTB→TTE.PA, BNP→BNP.PA, AXA→CS.PA,
  FTE→ORA.PA, AIR1→AI.PA) et vérifie les cours. Idempotent, ne touche qu'un compte,
  préserve les autres comptes/cash/commentaires (round-trip ruamel.yaml)
- CLI : python -m finlab.cli import-revolut <csv> [--write] [--account]
- Dashboard : le bouton « Importer un relevé » accepte les CSV → endpoints
  /api/revolut/preview (aperçu) + /api/revolut/apply (écrit), avec garde anti-évasion
  de chemin ; le front affiche les positions + bouton « Appliquer »
- portfolio.yaml : compte Revolut reconstruit depuis l'historique complet → ajoute
  AMAT (achetée le 29/06, manquait) ; valeurs alignées au centime
- requirements : + ruamel.yaml ; persona console + admin/ia/finlab.md documentés

Validé sur l'historique réel : 11 positions reconstruites = portfolio.yaml existant
(cours vérifiés, 0 warning) + AMAT. Flux dashboard upload→preview→apply testé
(TestClient), JS OK.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 16:31:01 +02:00

5.9 KiB
Raw Blame History

FinLab — dashboard finance + console Claude Code + toolkit d'analyse

Quoi : boîte à outils d'analyse de marché maison (finlab, données Yahoo Finance gratuites) déployée in-cluster sous deux faces (une seule image) : un dashboard web (graphiques, portefeuille, watchlists, actions) et une console Claude Code finance. Remplace l'approche OpenAlice abandonnée (cf. admin/ia/openalice.md) par plus simple et plus puissant : ton vrai Claude Code (sur ton abonnement, pas l'API au compteur) + une UI graphique gratuite.

  • Dashboard (finance.lab.local/) — graphiques chandeliers (MM50/200 + volume), portefeuille (P&L/poids/secteurs), watchlists thématiques scannées, alertes du jour, plan de trade R:R. FastAPI dashboard/server.py, aucun LLM/clé (analyse technique pure).
  • Console (finance.lab.local/console/) — terminal web (ttyd) → claude agentique, persona + outils finlab en MCP, login abonnement persisté.

:

  • Source : tools/finlab/ (code finlab + Dockerfile + persona workspace/CLAUDE.md).
  • Image : CI .github/workflows/build-finlab.ymlghcr.io/alkatrazz24/funk-finlab.
  • Déploiement : ns ai, finance.lab.local, manifests k8s/apps/finlab/, app ArgoCD k8s/apps-of-apps/apps/finlab.yaml.
  • MCP local : .mcp.json (racine repo lab) → outils finlab dans les sessions Claude Code du lab.

Cadre : analyse/aide à la décision uniquement, aucun ordre réel (seul le paper trading Alpaca fictif est exécutable). Persona dans tools/finlab/workspace/CLAUDE.md (profil swing trader concentré tech/semis, philosophie R:R/concentration/discipline).

Architecture

Composant Détail
initContainer seed Peuple le workspace (cp -rn), robuste au piège NFS (fsGroup non honoré → recrée le dossier s'il est root/non-inscriptible). Tourne avant les conteneurs
container dashboard uvicorn dashboard.server:app :8800 — UI + API JSON finlab
container console ttyd -b /console :7681 → claude dans le workspace
container watcher python -m finlab.watcher — alertes de prix par email, boucle 5 min
Cerveau (console) Abonnement Claude Code (login OAuth persisté dans ~/.claude sur le PVC) — pas de clé API
Code vs data Code (finlab + dashboard) dans l'image /opt/app (maj avec l'image) ; configs éditables via FINLAB_HOME=/home/finlab/workspace (PVC)
PVC finlab-data 5Gi NFS → /home/finlab : login + workspace (configs + .cache)
Auth basicAuth Traefik (finlab-auth) sur les deux routes — un shell web ne s'expose pas nu
Routes /console → 7681 · reste → 8800

Découplage code/data : finlab lit ses configs depuis FINLAB_HOME si défini (sinon repli sur le dossier du package → dév local inchangé). Le workspace est seedé au 1er boot puis vit sur le PVC (edits + login persistent ; une nouvelle image n'ajoute que les fichiers manquants).

Outils finlab

digest (vue d'ensemble compacte, à privilégier), portfolio_summary, opportunities/scan, technical_analysis/tech (RSI/MACD/MM50-200/Bollinger/ATR), fundamentals (PER/PEG/ROE/dette/ cible), trade_plan/plan (entrée/stop ATR/objectifs/taille/R:R), alerts_today, price, plus paper trading (paper_account/paper_positions/paper_order, clés Alpaca optionnelles).

Configs (workspace, éditables) : portfolio.yaml (multi-comptes : accounts avec name/type/cash/positions — ex. Revolut + BNP Paribas PEA ; agrégats globaux + par compte), watchlists.yaml (thèmes chaîne IA/datacenter), alerts.yaml (règles).

Onboarding (premier boot)

Checklist détaillée : k8s/apps/finlab/README.md.

  1. Secrets manuels dans ai : ghcr-pull (pull GHCR) + finlab-auth (htpasswd basicAuth).
  2. Ouvrir finance.lab.localclaude/login (abonnement, persisté sur le PVC).

Import de portefeuille — relevé Revolut (déterministe)

finlab/revolut.py reconstruit les positions depuis un relevé de compte Revolut (account statement CSV, export sur toute la période) par coût moyen (achats ventes, PRU pondéré), mappe les tickers Revolut→Yahoo (ASME→ASML.AS, TOTB→TTE.PA, BNP→BNP.PA, AXA→CS.PA, FTE→ORA.PA, AIR1→AI.PA) et vérifie les cours. Idempotent, ne touche qu'un compte (défaut « Revolut »), préserve les autres comptes/cash/commentaires (round-trip ruamel).

  • Dashboard : bouton « Importer un relevé » accepte les CSV → endpoints /api/revolut/preview (aperçu) + /api/revolut/apply (écrit portfolio.yaml). Sans IA.
  • CLI : python -m finlab.cli import-revolut <csv> [--write] [--account Revolut].

C'est la procédure de mise à jour « à chaque trade » : ré-exporter le relevé complet → importer. Le P&L statement et les exports mono-mois ne suffisent pas (positions incomplètes).

Alertes de prix par email

Sidecar watcher (finlab/watcher.py) : boucle toutes les 5 min, lit price_alerts.yaml (workspace), et envoie un email quand un seuil (above/below) est franchi. Envoi via le relais postfix du lab (storage-01:25, SMTP_HOST) qui réécrit l'expéditeur en Gmail — aucun secret (les pods k8s sont dans mynetworks, cf. admin/infra/email.md). Anti-spam : un seuil ne notifie qu'une fois (état .watcher-state.json), ré-armé en ré-éditant la règle. La Console IA édite price_alerts.yaml sur demande (« mets un mail quand NVDA atteint 200$ »). Test : python -m finlab.watcher --test <email> / --once.

Accès programmatique

  • MCP dans le repo lab : .mcp.json racine pointe tools/finlab/.venv → outils finlab dans les sessions Claude Code du lab (approbation MCP au 1er lancement).
  • Headless : kubectl -n ai exec deploy/finlab -- python -m finlab.cli digest.

Liens

  • Source historique : ex-projet Projets/Finance (rapatrié ici).
  • Approche précédente abandonnée : admin/ia/openalice.md.