{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "970067da",
   "metadata": {},
   "source": [
    "# Cours 5 — Approfondissement des dictionnaires pour la modélisation financière (MBA)\n",
    "\n",
    "Ce cours prolonge le **Cours 4** (introduction aux dictionnaires). Il est conçu pour des étudiants en **MBA Modélisation Financière**.\n",
    "\n",
    "On va passer des cas marketing à des cas **finance** :\n",
    "- une **action** (Apple, Total, LVMH...) décrite par un dictionnaire (ticker, prix, quantité, secteur, ...) ;\n",
    "- un **portefeuille** = une **liste de dictionnaires** (un dictionnaire par position) ;\n",
    "- des **calculs financiers** simples : valeur de portefeuille, poids des positions, rendement, P&L.\n",
    "\n",
    "### Prérequis (Cours 1 à 4)\n",
    "- Variables, types (`int`, `float`, `str`, `bool`).\n",
    "- Listes et accès par index (`actions[0]`).\n",
    "- Boucles `for`, conditions `if / elif / else`.\n",
    "- Bases des **dictionnaires** : création, lecture (`d['cle']`), modification.\n",
    "\n",
    "### Objectifs du Cours 5\n",
    "- Maîtriser les **méthodes** des dictionnaires : `.keys()`, `.values()`, `.items()`.\n",
    "- Itérer **proprement** sur un dictionnaire avec `for cle, valeur in d.items()`.\n",
    "- Modéliser un **actif financier** avec un dictionnaire (avec champs imbriqués).\n",
    "- Modéliser un **portefeuille** avec une liste de dictionnaires.\n",
    "- Calculer la **valeur de portefeuille**, les **poids**, et un **P&L** simple par position.\n",
    "- Faire un mini reporting de portefeuille en boucle + condition.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fbf1ef0b",
   "metadata": {},
   "source": [
    "## 0. Rappel express du Cours 4\n",
    "\n",
    "Au cours précédent, on a vu que :\n",
    "- une **liste** stocke des valeurs **dans un ordre** (`prices[0]`, `prices[1]`, ...) ;\n",
    "- un **dictionnaire** stocke des valeurs avec une **clé explicite** (`action['prix']`, `action['ticker']`).\n",
    "\n",
    "En modélisation financière, le dictionnaire est très naturel : un actif a un **ticker**, un **prix**, un **secteur**, une **devise**, etc. Avoir des **noms de champs métier** rend le code beaucoup plus lisible qu'une simple liste de nombres.\n",
    "\n",
    "Dans la cellule suivante, on refait un mini exemple pour vérifier que tout fonctionne."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "107240b8",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Sanity check: a single stock represented as a dictionary\n",
    "action_apple = {\n",
    "    \"ticker\": \"AAPL\",\n",
    "    \"secteur\": \"Technology\",\n",
    "    \"devise\": \"USD\",\n",
    "    \"prix\": 187.50,\n",
    "    \"quantite\": 100,\n",
    "}\n",
    "\n",
    "print(f\"Ticker : {action_apple['ticker']}\")\n",
    "print(f\"Prix unitaire : {action_apple['prix']} {action_apple['devise']}\")\n",
    "print(f\"Quantité détenue : {action_apple['quantite']}\")\n",
    "print(f\"Valeur de marché : {action_apple['prix'] * action_apple['quantite']} {action_apple['devise']}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "924341b8",
   "metadata": {},
   "source": [
    "## 1. Les méthodes essentielles : `.keys()`, `.values()`, `.items()`\n",
    "\n",
    "Trois méthodes très utilisées sur un dictionnaire :\n",
    "\n",
    "- `d.keys()` : la liste (vue) des **clés**\n",
    "- `d.values()` : la liste (vue) des **valeurs**\n",
    "- `d.items()` : la liste (vue) des **couples** `(clé, valeur)`\n",
    "\n",
    "Ces méthodes sont la **base** pour itérer sur un dictionnaire (section suivante)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2e3b8d62",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Inspect keys, values and items of a financial dictionary\n",
    "action = {\n",
    "    \"ticker\": \"MC.PA\",       # LVMH on Euronext Paris\n",
    "    \"secteur\": \"Luxury\",\n",
    "    \"prix\": 712.40,\n",
    "    \"quantite\": 25,\n",
    "    \"devise\": \"EUR\",\n",
    "}\n",
    "\n",
    "print(f\"Clés    : {list(action.keys())}\")\n",
    "print(f\"Valeurs : {list(action.values())}\")\n",
    "print(f\"Items   : {list(action.items())}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3ae1b641",
   "metadata": {},
   "source": [
    "### Exercice 1 — Explorer un actif\n",
    "\n",
    "Crée un dictionnaire `obligation` représentant une obligation d'État avec les clés suivantes :\n",
    "- `emetteur` (par ex. `\"France\"`)\n",
    "- `coupon` (taux nominal annuel, par ex. `0.032` pour 3,2%)\n",
    "- `maturite` (en années, par ex. `10`)\n",
    "- `nominal` (par ex. `1000`)\n",
    "- `devise` (par ex. `\"EUR\"`)\n",
    "\n",
    "Puis affiche :\n",
    "1. la liste des **clés** ;\n",
    "2. la liste des **valeurs** ;\n",
    "3. la liste des **items** (`(clé, valeur)`)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0b0494a6",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO — Exercise 1\n",
    "pass\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d940e97f",
   "metadata": {},
   "source": [
    "## 2. Itérer sur un dictionnaire avec `for cle, valeur in d.items()`\n",
    "\n",
    "Pour parcourir un dictionnaire, on utilise très souvent `.items()` :\n",
    "\n",
    "```python\n",
    "for cle, valeur in d.items():\n",
    "    print(cle, valeur)\n",
    "```\n",
    "\n",
    "C'est le schéma à connaître par cœur : on l'utilise dès qu'on veut produire un **petit reporting** ligne par ligne à partir d'un dictionnaire (par exemple résumer les caractéristiques d'un actif).\n",
    "\n",
    "On peut aussi itérer seulement sur les clés (`for cle in d:` ou `for cle in d.keys()`) ou seulement sur les valeurs (`for v in d.values()`), mais `.items()` est le cas le plus utile."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "3cec0fe4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--- Fiche actif ---\n",
      "ticker : TTE.PA\n",
      "secteur : Energy\n",
      "prix : 61.3\n",
      "quantite : 80\n",
      "devise : EUR\n"
     ]
    }
   ],
   "source": [
    "# Iterate over a dictionary to print a small fact sheet\n",
    "action = {\n",
    "    \"ticker\": \"TTE.PA\",       # TotalEnergies\n",
    "    \"secteur\": \"Energy\",\n",
    "    \"prix\": 61.30,\n",
    "    \"quantite\": 80,\n",
    "    \"devise\": \"EUR\",\n",
    "}\n",
    "\n",
    "print(\"--- Fiche actif ---\")\n",
    "for cle, valeur in action.items():\n",
    "    print(f\"{cle} : {valeur}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9deb2a43",
   "metadata": {},
   "source": [
    "### Exercice 2 — Fiche d'identité d'un actif\n",
    "\n",
    "À partir du dictionnaire `obligation` que tu as créé à l'**exercice 1** :\n",
    "\n",
    "1. Parcours-le avec `for cle, valeur in obligation.items():`.\n",
    "2. Pour chaque clé, affiche une ligne du type `\"emetteur : France\"`.\n",
    "3. **Bonus** : calcule et affiche, en dehors de la boucle, le **coupon annuel en euros** = `nominal * coupon`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fd93f6a1",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO — Exercise 2\n",
    "pass\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "21745b34",
   "metadata": {},
   "source": [
    "## 3. Dictionnaires imbriqués (nested dicts)\n",
    "\n",
    "En finance, un actif a souvent **plusieurs niveaux d'information**. Par exemple :\n",
    "- un bloc `\"identite\"` : ticker, secteur, devise ;\n",
    "- un bloc `\"position\"` : prix d'achat, quantité, prix actuel.\n",
    "\n",
    "On peut imbriquer un dictionnaire **à l'intérieur** d'un autre :\n",
    "\n",
    "```python\n",
    "action = {\n",
    "    \"identite\": {\"ticker\": \"AAPL\", \"secteur\": \"Tech\"},\n",
    "    \"position\": {\"prix_achat\": 150.0, \"quantite\": 100, \"prix_actuel\": 187.5},\n",
    "}\n",
    "```\n",
    "\n",
    "Pour accéder à une valeur imbriquée, on enchaîne les crochets :\n",
    "\n",
    "```python\n",
    "action[\"position\"][\"prix_actuel\"]   # 187.5\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "5ada589a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Position sur AAPL\n",
      "  Quantité    : 100\n",
      "  Prix achat  : 150.0 USD\n",
      "  Prix actuel : 187.5 USD\n",
      "  P&L latent  :  3750.0 USD\n",
      "  Rendement   : 0.25\n"
     ]
    }
   ],
   "source": [
    "# Nested dictionary representing a stock with identity + current position\n",
    "action = {\n",
    "    \"identite\": {\n",
    "        \"ticker\": \"AAPL\",\n",
    "        \"secteur\": \"Technology\",\n",
    "        \"devise\": \"USD\",\n",
    "    },\n",
    "    \"position\": {\n",
    "        \"prix_achat\": 150.00,\n",
    "        \"prix_actuel\": 187.50,\n",
    "        \"quantite\": 100,\n",
    "    },\n",
    "}\n",
    "\n",
    "ticker = action[\"identite\"][\"ticker\"]\n",
    "prix_achat = action[\"position\"][\"prix_achat\"]\n",
    "prix_actuel = action[\"position\"][\"prix_actuel\"]\n",
    "quantite = action[\"position\"][\"quantite\"]\n",
    "\n",
    "# Simple P&L on this position\n",
    "pnl = (prix_actuel - prix_achat) * quantite\n",
    "rendement = (prix_actuel - prix_achat) / prix_achat\n",
    "\n",
    "print(f\"Position sur {ticker}\")\n",
    "print(f\"  Quantité    : {quantite}\")\n",
    "print(f\"  Prix achat  : {prix_achat} {action['identite']['devise']}\")\n",
    "print(f\"  Prix actuel : {prix_actuel} {action['identite']['devise']}\")\n",
    "print(f\"  P&L latent  : {pnl } {action['identite']['devise']}\")\n",
    "print(f\"  Rendement   : {rendement}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "26af98e6",
   "metadata": {},
   "source": [
    "### Exercice 3 — Position sur une action\n",
    "\n",
    "Crée un dictionnaire imbriqué `position_lvmh` avec :\n",
    "- un sous-dictionnaire `identite` : `ticker = \"MC.PA\"`, `secteur = \"Luxury\"`, `devise = \"EUR\"` ;\n",
    "- un sous-dictionnaire `position` : `prix_achat = 680.0`, `prix_actuel = 712.4`, `quantite = 25`.\n",
    "\n",
    "Puis calcule et affiche :\n",
    "1. la **valeur de marché actuelle** (`prix_actuel * quantite`) ;\n",
    "2. le **coût d'achat** (`prix_achat * quantite`) ;\n",
    "3. le **P&L latent** (différence entre les deux) ;\n",
    "4. le **rendement** en pourcentage (`(prix_actuel - prix_achat) / prix_achat`)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4be2b3e8",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO — Exercise 3\n",
    "pass\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d64e8f70",
   "metadata": {},
   "source": [
    "## 4. Modéliser un portefeuille : liste de dictionnaires\n",
    "\n",
    "Un **portefeuille** d'actifs se modélise très naturellement comme une **liste de dictionnaires**, où chaque dictionnaire est une **position** (une ligne du portefeuille).\n",
    "\n",
    "On reste sur des dictionnaires **plats** (pas imbriqués) pour faciliter les boucles de calcul."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7ecbe465",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Portfolio = list of positions (each position is a dict)\n",
    "portefeuille = [\n",
    "    {\"ticker\": \"AAPL\",  \"secteur\": \"Tech\",   \"prix\": 187.50, \"quantite\": 100, \"devise\": \"USD\"},\n",
    "    {\"ticker\": \"MC.PA\", \"secteur\": \"Luxury\", \"prix\": 712.40, \"quantite\":  25, \"devise\": \"EUR\"},\n",
    "    {\"ticker\": \"TTE.PA\",\"secteur\": \"Energy\", \"prix\":  61.30, \"quantite\":  80, \"devise\": \"EUR\"},\n",
    "    {\"ticker\": \"BNP.PA\",\"secteur\": \"Banks\",  \"prix\":  68.10, \"quantite\":  50, \"devise\": \"EUR\"},\n",
    "]\n",
    "\n",
    "for position in portefeuille:\n",
    "    valeur = position[\"prix\"] * position[\"quantite\"]\n",
    "    print(f\"{position['ticker']:<7s} | {position['secteur']:<7s} | valeur = {valeur:>10.2f} {position['devise']}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5b239ae9",
   "metadata": {},
   "source": [
    "### Valeur totale et poids des positions\n",
    "\n",
    "Pour analyser un portefeuille, deux calculs sont indispensables :\n",
    "\n",
    "1. la **valeur totale** = somme des `prix * quantite` de toutes les positions ;\n",
    "2. le **poids** de chaque position = `valeur_position / valeur_totale`.\n",
    "\n",
    "Attention : ici on simplifie en supposant **une seule devise** (sinon il faudrait convertir tous les actifs dans une devise de référence). On fera cette hypothèse pour l'exercice."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dfc4775c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Compute total portfolio value and per-position weights\n",
    "# (assumes a single currency for simplicity)\n",
    "portefeuille_eur = [\n",
    "    {\"ticker\": \"MC.PA\", \"secteur\": \"Luxury\", \"prix\": 712.40, \"quantite\": 25},\n",
    "    {\"ticker\": \"TTE.PA\",\"secteur\": \"Energy\", \"prix\":  61.30, \"quantite\": 80},\n",
    "    {\"ticker\": \"BNP.PA\",\"secteur\": \"Banks\",  \"prix\":  68.10, \"quantite\": 50},\n",
    "    {\"ticker\": \"SAN.PA\",\"secteur\": \"Pharma\", \"prix\":  92.20, \"quantite\": 40},\n",
    "]\n",
    "\n",
    "# 1) Total value\n",
    "valeur_totale = 0.0\n",
    "for position in portefeuille_eur:\n",
    "    valeur_totale += position[\"prix\"] * position[\"quantite\"]\n",
    "\n",
    "print(f\"Valeur totale du portefeuille : {valeur_totale:,.2f} EUR\")\n",
    "print(\"-\")\n",
    "\n",
    "# 2) Weight per position\n",
    "for position in portefeuille_eur:\n",
    "    valeur_position = position[\"prix\"] * position[\"quantite\"]\n",
    "    poids = valeur_position / valeur_totale\n",
    "    print(f\"{position['ticker']:<7s} | valeur = {valeur_position:>10.2f} EUR | poids = {poids:.2%}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6e02dd6a",
   "metadata": {},
   "source": [
    "### Exercice 4 — Construire ton portefeuille\n",
    "\n",
    "Crée une liste `mon_portefeuille` contenant **4 positions** (dictionnaires) en **euros** (pour simplifier). Chaque dictionnaire doit avoir les clés `ticker`, `secteur`, `prix`, `quantite`.\n",
    "\n",
    "Puis :\n",
    "\n",
    "1. Calcule la **valeur totale** du portefeuille.\n",
    "2. Pour chaque position, calcule et affiche :\n",
    "   - le `ticker` ;\n",
    "   - le `secteur` ;\n",
    "   - la **valeur de marché** (`prix * quantite`) ;\n",
    "   - le **poids** en pourcentage du portefeuille.\n",
    "3. Vérifie (à l'oral ou avec une `print`) que la somme des poids est bien proche de **100%**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "db5d4955",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO — Exercise 4\n",
    "pass\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d70aa292",
   "metadata": {},
   "source": [
    "## 5. P&L par position et classification (boucle + condition)\n",
    "\n",
    "On va combiner :\n",
    "- une **liste de dictionnaires** (positions du portefeuille) ;\n",
    "- une **boucle `for`** pour parcourir les positions ;\n",
    "- une **condition `if / elif / else`** pour classifier chaque position.\n",
    "\n",
    "Cette fois, chaque position contient à la fois un **prix d'achat** et un **prix actuel**, ce qui permet de calculer un **rendement** et un **P&L latent**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5a842d9d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Per-position P&L and naive recommendation rule\n",
    "portefeuille = [\n",
    "    {\"ticker\": \"MC.PA\", \"prix_achat\": 680.0, \"prix_actuel\": 712.4, \"quantite\": 25},\n",
    "    {\"ticker\": \"TTE.PA\",\"prix_achat\":  58.0, \"prix_actuel\":  61.3, \"quantite\": 80},\n",
    "    {\"ticker\": \"BNP.PA\",\"prix_achat\":  75.0, \"prix_actuel\":  68.1, \"quantite\": 50},\n",
    "    {\"ticker\": \"SAN.PA\",\"prix_achat\":  95.0, \"prix_actuel\":  92.2, \"quantite\": 40},\n",
    "]\n",
    "\n",
    "for position in portefeuille:\n",
    "    rendement = (position[\"prix_actuel\"] - position[\"prix_achat\"]) / position[\"prix_achat\"]\n",
    "    pnl = (position[\"prix_actuel\"] - position[\"prix_achat\"]) * position[\"quantite\"]\n",
    "\n",
    "    if rendement >= 0.10:\n",
    "        statut = \"Forte plus-value — envisager prise de profits\"\n",
    "    elif rendement >= 0.00:\n",
    "        statut = \"Position positive — conserver\"\n",
    "    elif rendement >= -0.10:\n",
    "        statut = \"Légère moins-value — surveiller\"\n",
    "    else:\n",
    "        statut = \"Forte moins-value — analyser et envisager arbitrage\"\n",
    "\n",
    "    print(\n",
    "        f\"{position['ticker']:<7s} | rdt = {rendement:>7.2%} | \"\n",
    "        f\"P&L = {pnl:>9.2f} EUR | {statut}\"\n",
    "    )\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "993ae0d6",
   "metadata": {},
   "source": [
    "### Exercice 5 — Mini analyse de portefeuille\n",
    "\n",
    "Crée une liste `analyse_portefeuille` de **4 positions** avec les clés `ticker`, `prix_achat`, `prix_actuel`, `quantite`.\n",
    "\n",
    "Pour chaque position, calcule :\n",
    "1. le **rendement** : `(prix_actuel - prix_achat) / prix_achat` ;\n",
    "2. le **P&L latent** : `(prix_actuel - prix_achat) * quantite` ;\n",
    "3. un **statut** selon la règle suivante :\n",
    "   - `rendement >= 0.10` → `\"Top performer\"` ;\n",
    "   - `0.00 <= rendement < 0.10` → `\"En croissance\"` ;\n",
    "   - `-0.05 <= rendement < 0.00` → `\"Sous surveillance\"` ;\n",
    "   - `rendement < -0.05` → `\"À arbitrer\"`.\n",
    "\n",
    "Affiche une ligne par position avec : ticker, rendement (en %), P&L et statut.\n",
    "\n",
    "**Bonus** : à la fin de la boucle, affiche le **P&L total** du portefeuille (somme des P&L de toutes les positions)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3a11ae7e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO — Exercise 5\n",
    "pass\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6abf88fc",
   "metadata": {},
   "source": [
    "## 6. Corrections proposées\n",
    "\n",
    "Compare tes solutions avec ces propositions. Plusieurs bonnes réponses sont possibles."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bd3536e2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Correction — Exercise 1\n",
    "obligation = {\n",
    "    \"emetteur\": \"France\",\n",
    "    \"coupon\": 0.032,\n",
    "    \"maturite\": 10,\n",
    "    \"nominal\": 1000,\n",
    "    \"devise\": \"EUR\",\n",
    "}\n",
    "\n",
    "print(f\"Clés    : {list(obligation.keys())}\")\n",
    "print(f\"Valeurs : {list(obligation.values())}\")\n",
    "print(f\"Items   : {list(obligation.items())}\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "60316943",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Correction — Exercise 2\n",
    "obligation = {\n",
    "    \"emetteur\": \"France\",\n",
    "    \"coupon\": 0.032,\n",
    "    \"maturite\": 10,\n",
    "    \"nominal\": 1000,\n",
    "    \"devise\": \"EUR\",\n",
    "}\n",
    "\n",
    "print(\"--- Fiche obligation ---\")\n",
    "for cle, valeur in obligation.items():\n",
    "    print(f\"{cle:>10s} : {valeur}\")\n",
    "\n",
    "coupon_annuel = obligation[\"nominal\"] * obligation[\"coupon\"]\n",
    "print(f\"\\nCoupon annuel : {coupon_annuel:.2f} {obligation['devise']}\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3fc2c19d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Correction — Exercise 3\n",
    "position_lvmh = {\n",
    "    \"identite\": {\n",
    "        \"ticker\": \"MC.PA\",\n",
    "        \"secteur\": \"Luxury\",\n",
    "        \"devise\": \"EUR\",\n",
    "    },\n",
    "    \"position\": {\n",
    "        \"prix_achat\": 680.0,\n",
    "        \"prix_actuel\": 712.4,\n",
    "        \"quantite\": 25,\n",
    "    },\n",
    "}\n",
    "\n",
    "prix_achat = position_lvmh[\"position\"][\"prix_achat\"]\n",
    "prix_actuel = position_lvmh[\"position\"][\"prix_actuel\"]\n",
    "quantite = position_lvmh[\"position\"][\"quantite\"]\n",
    "devise = position_lvmh[\"identite\"][\"devise\"]\n",
    "\n",
    "valeur_marche = prix_actuel * quantite\n",
    "cout_achat = prix_achat * quantite\n",
    "pnl = valeur_marche - cout_achat\n",
    "rendement = (prix_actuel - prix_achat) / prix_achat\n",
    "\n",
    "print(f\"Valeur de marché : {valeur_marche:.2f} {devise}\")\n",
    "print(f\"Coût d'achat     : {cout_achat:.2f} {devise}\")\n",
    "print(f\"P&L latent       : {pnl:.2f} {devise}\")\n",
    "print(f\"Rendement        : {rendement:.2%}\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7b90a908",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Correction — Exercise 4\n",
    "mon_portefeuille = [\n",
    "    {\"ticker\": \"MC.PA\", \"secteur\": \"Luxury\", \"prix\": 712.40, \"quantite\": 25},\n",
    "    {\"ticker\": \"TTE.PA\",\"secteur\": \"Energy\", \"prix\":  61.30, \"quantite\": 80},\n",
    "    {\"ticker\": \"BNP.PA\",\"secteur\": \"Banks\",  \"prix\":  68.10, \"quantite\": 50},\n",
    "    {\"ticker\": \"SAN.PA\",\"secteur\": \"Pharma\", \"prix\":  92.20, \"quantite\": 40},\n",
    "]\n",
    "\n",
    "# Total portfolio value\n",
    "valeur_totale = 0.0\n",
    "for position in mon_portefeuille:\n",
    "    valeur_totale += position[\"prix\"] * position[\"quantite\"]\n",
    "\n",
    "print(f\"Valeur totale : {valeur_totale:,.2f} EUR\")\n",
    "print(\"-\")\n",
    "\n",
    "# Per-position breakdown\n",
    "somme_poids = 0.0\n",
    "for position in mon_portefeuille:\n",
    "    valeur_position = position[\"prix\"] * position[\"quantite\"]\n",
    "    poids = valeur_position / valeur_totale\n",
    "    somme_poids += poids\n",
    "    print(\n",
    "        f\"{position['ticker']:<7s} | {position['secteur']:<7s} | \"\n",
    "        f\"valeur = {valeur_position:>10.2f} EUR | poids = {poids:.2%}\"\n",
    "    )\n",
    "\n",
    "print(\"-\")\n",
    "print(f\"Somme des poids (sanity check) : {somme_poids:.2%}\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "54e84040",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Correction — Exercise 5\n",
    "analyse_portefeuille = [\n",
    "    {\"ticker\": \"MC.PA\", \"prix_achat\": 680.0, \"prix_actuel\": 712.4, \"quantite\": 25},\n",
    "    {\"ticker\": \"TTE.PA\",\"prix_achat\":  58.0, \"prix_actuel\":  61.3, \"quantite\": 80},\n",
    "    {\"ticker\": \"BNP.PA\",\"prix_achat\":  75.0, \"prix_actuel\":  68.1, \"quantite\": 50},\n",
    "    {\"ticker\": \"SAN.PA\",\"prix_achat\":  95.0, \"prix_actuel\":  92.2, \"quantite\": 40},\n",
    "]\n",
    "\n",
    "pnl_total = 0.0\n",
    "\n",
    "for position in analyse_portefeuille:\n",
    "    rendement = (position[\"prix_actuel\"] - position[\"prix_achat\"]) / position[\"prix_achat\"]\n",
    "    pnl = (position[\"prix_actuel\"] - position[\"prix_achat\"]) * position[\"quantite\"]\n",
    "    pnl_total += pnl\n",
    "\n",
    "    if rendement >= 0.10:\n",
    "        statut = \"Top performer\"\n",
    "    elif rendement >= 0.00:\n",
    "        statut = \"En croissance\"\n",
    "    elif rendement >= -0.05:\n",
    "        statut = \"Sous surveillance\"\n",
    "    else:\n",
    "        statut = \"À arbitrer\"\n",
    "\n",
    "    print(\n",
    "        f\"{position['ticker']:<7s} | rdt = {rendement:>7.2%} | \"\n",
    "        f\"P&L = {pnl:>9.2f} EUR | {statut}\"\n",
    "    )\n",
    "\n",
    "print(\"-\")\n",
    "print(f\"P&L total du portefeuille : {pnl_total:,.2f} EUR\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c966d2e2",
   "metadata": {},
   "source": [
    "## 7. Mini défi de fin de séance — Allocation sectorielle\n",
    "\n",
    "Tu disposes du portefeuille suivant :\n",
    "\n",
    "```python\n",
    "portefeuille = [\n",
    "    {\"ticker\": \"MC.PA\",  \"secteur\": \"Luxury\", \"prix\": 712.40, \"quantite\": 25},\n",
    "    {\"ticker\": \"KER.PA\", \"secteur\": \"Luxury\", \"prix\": 385.10, \"quantite\": 20},\n",
    "    {\"ticker\": \"TTE.PA\", \"secteur\": \"Energy\", \"prix\":  61.30, \"quantite\": 80},\n",
    "    {\"ticker\": \"BNP.PA\", \"secteur\": \"Banks\",  \"prix\":  68.10, \"quantite\": 50},\n",
    "    {\"ticker\": \"GLE.PA\", \"secteur\": \"Banks\",  \"prix\":  24.50, \"quantite\": 100},\n",
    "    {\"ticker\": \"SAN.PA\", \"secteur\": \"Pharma\", \"prix\":  92.20, \"quantite\": 40},\n",
    "]\n",
    "```\n",
    "\n",
    "Ton objectif est de construire un **dictionnaire d'allocation sectorielle** :\n",
    "\n",
    "- chaque **clé** est un secteur (`\"Luxury\"`, `\"Energy\"`, `\"Banks\"`, `\"Pharma\"`) ;\n",
    "- chaque **valeur** est la **valeur totale investie** dans ce secteur (somme des `prix * quantite`).\n",
    "\n",
    "Puis affiche, pour chaque secteur, son **poids en %** dans le portefeuille total.\n",
    "\n",
    "**Indice** : utilise la méthode `.get(cle, 0)` pour gérer le cas où le secteur n'est pas encore dans le dictionnaire d'allocation, par exemple :\n",
    "\n",
    "```python\n",
    "allocation[secteur] = allocation.get(secteur, 0) + valeur_position\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "89a5e493",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO — Mini challenge: sector allocation\n",
    "pass\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "15088b8d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Correction — Mini challenge: sector allocation\n",
    "portefeuille = [\n",
    "    {\"ticker\": \"MC.PA\",  \"secteur\": \"Luxury\", \"prix\": 712.40, \"quantite\": 25},\n",
    "    {\"ticker\": \"KER.PA\", \"secteur\": \"Luxury\", \"prix\": 385.10, \"quantite\": 20},\n",
    "    {\"ticker\": \"TTE.PA\", \"secteur\": \"Energy\", \"prix\":  61.30, \"quantite\": 80},\n",
    "    {\"ticker\": \"BNP.PA\", \"secteur\": \"Banks\",  \"prix\":  68.10, \"quantite\": 50},\n",
    "    {\"ticker\": \"GLE.PA\", \"secteur\": \"Banks\",  \"prix\":  24.50, \"quantite\": 100},\n",
    "    {\"ticker\": \"SAN.PA\", \"secteur\": \"Pharma\", \"prix\":  92.20, \"quantite\": 40},\n",
    "]\n",
    "\n",
    "# 1) Aggregate market value by sector\n",
    "allocation = {}\n",
    "valeur_totale = 0.0\n",
    "\n",
    "for position in portefeuille:\n",
    "    valeur_position = position[\"prix\"] * position[\"quantite\"]\n",
    "    secteur = position[\"secteur\"]\n",
    "    allocation[secteur] = allocation.get(secteur, 0) + valeur_position\n",
    "    valeur_totale += valeur_position\n",
    "\n",
    "print(f\"Valeur totale du portefeuille : {valeur_totale:,.2f} EUR\")\n",
    "print(\"-\")\n",
    "print(\"Allocation sectorielle :\")\n",
    "\n",
    "# 2) Display weights per sector\n",
    "for secteur, valeur in allocation.items():\n",
    "    poids = valeur / valeur_totale\n",
    "    print(f\"  {secteur:<8s} : {valeur:>10.2f} EUR  ({poids:.2%})\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "71e03416",
   "metadata": {},
   "source": [
    "## 8. Récapitulatif\n",
    "\n",
    "À la fin de ce **Cours 5**, tu dois être à l'aise avec :\n",
    "\n",
    "- les méthodes `.keys()`, `.values()`, `.items()` d'un dictionnaire ;\n",
    "- l'**itération** sur un dictionnaire avec `for cle, valeur in d.items()` ;\n",
    "- les **dictionnaires imbriqués** (un dict à l'intérieur d'un autre dict) ;\n",
    "- la modélisation d'un **portefeuille** comme une **liste de dictionnaires** ;\n",
    "- les calculs financiers de base : valeur de marché, poids, P&L latent, rendement ;\n",
    "- la combinaison **boucle + condition** pour classifier des positions.\n",
    "\n",
    "**À venir au Cours 6** :\n",
    "- les **fonctions** Python pour réutiliser ces calculs sur n'importe quel portefeuille ;\n",
    "- une introduction à `pandas` pour passer d'une liste de dictionnaires à un vrai **DataFrame** de portefeuille."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
