# 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é. **Où** : - Source : `tools/finlab/` (code finlab + Dockerfile + persona `workspace/CLAUDE.md`). - Image : CI `.github/workflows/build-finlab.yml` → `ghcr.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.local` → `claude` → `/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 [--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 ` / `--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`.