{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# AUM Analysis\n",
    "\n",
    "This notebook sums the **Value - AUM €** by **Product - Asset Type** and by **Product - Fund** from the AUM sample data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Matplotlib is building the font cache; this may take a moment.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Collecting openpyxl\n",
      "  Downloading openpyxl-3.1.5-py2.py3-none-any.whl.metadata (2.5 kB)\n",
      "Collecting et-xmlfile (from openpyxl)\n",
      "  Downloading et_xmlfile-2.0.0-py3-none-any.whl.metadata (2.7 kB)\n",
      "Downloading openpyxl-3.1.5-py2.py3-none-any.whl (250 kB)\n",
      "Downloading et_xmlfile-2.0.0-py3-none-any.whl (18 kB)\n",
      "Installing collected packages: et-xmlfile, openpyxl\n",
      "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2/2\u001b[0m [openpyxl]1/2\u001b[0m [openpyxl]\n",
      "\u001b[1A\u001b[2KSuccessfully installed et-xmlfile-2.0.0 openpyxl-3.1.5\n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "!pip install openpyxl\n",
    "import os\n",
    "import s3fs\n",
    "import seaborn as sns\n",
    "import plotly.express as px\n",
    "import re"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fs = s3fs.S3FileSystem(\n",
    "    client_kwargs={'endpoint_url': 'https://'+'minio-simple.lab.groupe-genes.fr'},\n",
    "    key = os.environ[\"AWS_ACCESS_KEY_ID\"], \n",
    "    secret = os.environ[\"AWS_SECRET_ACCESS_KEY\"], \n",
    "    token = os.environ[\"AWS_SESSION_TOKEN\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_3944/2679329308.py:2: DtypeWarning: Columns (0,1,2,3) have mixed types. Specify dtype option on import or set low_memory=False.\n",
      "  flows = pd.read_csv(f, sep=\";\")\n"
     ]
    }
   ],
   "source": [
    "with fs.open('projet-bdc-data//carmignac/Flows ENSAE V2 -20251105.csv', 'rb') as f:\n",
    "    flows = pd.read_csv(f, sep=\";\")\n",
    "\n",
    "with fs.open('projet-bdc-data//carmignac/AUM ENSAE V2 -20251105.csv', 'rb') as f:\n",
    "    stocks = pd.read_csv(f, sep=\";\")\n",
    "\n",
    "#with fs.open('projet-bdc-data/carmignac/Monthly AUM and NAV since 2010.xlsx', 'rb') as f:#\n",
    "    #nav_raw = pd.read_excel(f, header=None, engine=\"openpyxl\")\n",
    "\n",
    "#nav = nav_raw[0].str.split(\",\", expand=True)\n",
    "#nav.columns = nav.iloc[0]\n",
    "#nav = nav[1:].reset_index(drop=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Agreement - Code</th>\n",
       "      <th>Company - Id</th>\n",
       "      <th>Company - Ultimate Parent Id</th>\n",
       "      <th>Registrar Account - ID</th>\n",
       "      <th>Registrar Account - Region</th>\n",
       "      <th>RegistrarAccount - Country</th>\n",
       "      <th>Product - Asset Type</th>\n",
       "      <th>Product - Strategy</th>\n",
       "      <th>Product - Legal Status</th>\n",
       "      <th>Product - Is Dedie ?</th>\n",
       "      <th>Product - Fund</th>\n",
       "      <th>Product - Shareclass Type</th>\n",
       "      <th>Product - Shareclass Currency</th>\n",
       "      <th>Product - Isin</th>\n",
       "      <th>Centralisation Date</th>\n",
       "      <th>Quantity - AUM</th>\n",
       "      <th>Value - AUM CCY</th>\n",
       "      <th>Value - AUM €</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>3</td>\n",
       "      <td>166.0</td>\n",
       "      <td>166.0</td>\n",
       "      <td>200000647</td>\n",
       "      <td>France</td>\n",
       "      <td>France</td>\n",
       "      <td>Diversified</td>\n",
       "      <td>Patrimoine</td>\n",
       "      <td>FCP</td>\n",
       "      <td>NO</td>\n",
       "      <td>Carmignac Patrimoine</td>\n",
       "      <td>A</td>\n",
       "      <td>EUR</td>\n",
       "      <td>FR0010135103</td>\n",
       "      <td>2015-03-31</td>\n",
       "      <td>35.368</td>\n",
       "      <td>2.464867e+04</td>\n",
       "      <td>2.464867e+04</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>3</td>\n",
       "      <td>166.0</td>\n",
       "      <td>166.0</td>\n",
       "      <td>200000647</td>\n",
       "      <td>France</td>\n",
       "      <td>France</td>\n",
       "      <td>Diversified</td>\n",
       "      <td>Patrimoine</td>\n",
       "      <td>FCP</td>\n",
       "      <td>NO</td>\n",
       "      <td>Carmignac Patrimoine</td>\n",
       "      <td>A</td>\n",
       "      <td>EUR</td>\n",
       "      <td>FR0010135103</td>\n",
       "      <td>2015-11-30</td>\n",
       "      <td>35.368</td>\n",
       "      <td>2.241306e+04</td>\n",
       "      <td>2.241306e+04</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>166.0</td>\n",
       "      <td>166.0</td>\n",
       "      <td>200000647</td>\n",
       "      <td>France</td>\n",
       "      <td>France</td>\n",
       "      <td>Diversified</td>\n",
       "      <td>Patrimoine</td>\n",
       "      <td>FCP</td>\n",
       "      <td>NO</td>\n",
       "      <td>Carmignac Patrimoine</td>\n",
       "      <td>A</td>\n",
       "      <td>EUR</td>\n",
       "      <td>FR0010135103</td>\n",
       "      <td>2015-12-31</td>\n",
       "      <td>35.368</td>\n",
       "      <td>2.205124e+04</td>\n",
       "      <td>2.205124e+04</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3</td>\n",
       "      <td>166.0</td>\n",
       "      <td>166.0</td>\n",
       "      <td>200000647</td>\n",
       "      <td>France</td>\n",
       "      <td>France</td>\n",
       "      <td>Diversified</td>\n",
       "      <td>Patrimoine</td>\n",
       "      <td>FCP</td>\n",
       "      <td>NO</td>\n",
       "      <td>Carmignac Patrimoine</td>\n",
       "      <td>A</td>\n",
       "      <td>EUR</td>\n",
       "      <td>FR0010135103</td>\n",
       "      <td>2016-03-31</td>\n",
       "      <td>35.368</td>\n",
       "      <td>2.162612e+04</td>\n",
       "      <td>2.162612e+04</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>3</td>\n",
       "      <td>166.0</td>\n",
       "      <td>166.0</td>\n",
       "      <td>200000647</td>\n",
       "      <td>France</td>\n",
       "      <td>France</td>\n",
       "      <td>Diversified</td>\n",
       "      <td>Patrimoine</td>\n",
       "      <td>FCP</td>\n",
       "      <td>NO</td>\n",
       "      <td>Carmignac Patrimoine</td>\n",
       "      <td>A</td>\n",
       "      <td>EUR</td>\n",
       "      <td>FR0010135103</td>\n",
       "      <td>2016-11-30</td>\n",
       "      <td>35.368</td>\n",
       "      <td>2.248945e+04</td>\n",
       "      <td>2.248945e+04</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4880292</th>\n",
       "      <td>Private Client</td>\n",
       "      <td>Private Client</td>\n",
       "      <td>Private Client</td>\n",
       "      <td>Private Client</td>\n",
       "      <td>Switzerland</td>\n",
       "      <td>Switzerland</td>\n",
       "      <td>Fixed Income</td>\n",
       "      <td>Sécurité</td>\n",
       "      <td>SICAV</td>\n",
       "      <td>NO</td>\n",
       "      <td>Carmignac Portfolio Sécurité</td>\n",
       "      <td>AW &amp; AW-R</td>\n",
       "      <td>EUR</td>\n",
       "      <td>LU1299306321</td>\n",
       "      <td>2020-02-29</td>\n",
       "      <td>26801.000</td>\n",
       "      <td>2.740670e+06</td>\n",
       "      <td>2.740670e+06</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4880293</th>\n",
       "      <td>Private Client</td>\n",
       "      <td>Private Client</td>\n",
       "      <td>Private Client</td>\n",
       "      <td>Private Client</td>\n",
       "      <td>Switzerland</td>\n",
       "      <td>Switzerland</td>\n",
       "      <td>Fixed Income</td>\n",
       "      <td>Sécurité</td>\n",
       "      <td>SICAV</td>\n",
       "      <td>NO</td>\n",
       "      <td>Carmignac Portfolio Sécurité</td>\n",
       "      <td>AW &amp; AW-R</td>\n",
       "      <td>EUR</td>\n",
       "      <td>LU1299306321</td>\n",
       "      <td>2020-06-30</td>\n",
       "      <td>3099.000</td>\n",
       "      <td>3.122862e+05</td>\n",
       "      <td>3.122862e+05</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4880294</th>\n",
       "      <td>Private Client</td>\n",
       "      <td>Private Client</td>\n",
       "      <td>Private Client</td>\n",
       "      <td>Private Client</td>\n",
       "      <td>Switzerland</td>\n",
       "      <td>Switzerland</td>\n",
       "      <td>Fixed Income</td>\n",
       "      <td>Sécurité</td>\n",
       "      <td>SICAV</td>\n",
       "      <td>NO</td>\n",
       "      <td>Carmignac Portfolio Sécurité</td>\n",
       "      <td>AW &amp; AW-R</td>\n",
       "      <td>EUR</td>\n",
       "      <td>LU1299306321</td>\n",
       "      <td>2020-10-31</td>\n",
       "      <td>3099.000</td>\n",
       "      <td>3.184222e+05</td>\n",
       "      <td>3.184222e+05</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4880295</th>\n",
       "      <td>Private Client</td>\n",
       "      <td>Private Client</td>\n",
       "      <td>Private Client</td>\n",
       "      <td>Private Client</td>\n",
       "      <td>Switzerland</td>\n",
       "      <td>Switzerland</td>\n",
       "      <td>Fixed Income</td>\n",
       "      <td>Sécurité</td>\n",
       "      <td>SICAV</td>\n",
       "      <td>NO</td>\n",
       "      <td>Carmignac Portfolio Sécurité</td>\n",
       "      <td>AW &amp; AW-R</td>\n",
       "      <td>EUR</td>\n",
       "      <td>LU1299306321</td>\n",
       "      <td>2021-07-31</td>\n",
       "      <td>2835.000</td>\n",
       "      <td>2.976183e+05</td>\n",
       "      <td>2.976183e+05</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4880296</th>\n",
       "      <td>Private Client</td>\n",
       "      <td>Private Client</td>\n",
       "      <td>Private Client</td>\n",
       "      <td>Private Client</td>\n",
       "      <td>Switzerland</td>\n",
       "      <td>Switzerland</td>\n",
       "      <td>Fixed Income</td>\n",
       "      <td>Sécurité</td>\n",
       "      <td>SICAV</td>\n",
       "      <td>NO</td>\n",
       "      <td>Carmignac Portfolio Sécurité</td>\n",
       "      <td>FW &amp; FW-R</td>\n",
       "      <td>EUR</td>\n",
       "      <td>LU1792391911</td>\n",
       "      <td>2020-07-31</td>\n",
       "      <td>2916.394</td>\n",
       "      <td>2.874106e+05</td>\n",
       "      <td>2.874106e+05</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>4880297 rows × 18 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "        Agreement - Code    Company - Id Company - Ultimate Parent Id  \\\n",
       "0                      3           166.0                        166.0   \n",
       "1                      3           166.0                        166.0   \n",
       "2                      3           166.0                        166.0   \n",
       "3                      3           166.0                        166.0   \n",
       "4                      3           166.0                        166.0   \n",
       "...                  ...             ...                          ...   \n",
       "4880292   Private Client  Private Client               Private Client   \n",
       "4880293   Private Client  Private Client               Private Client   \n",
       "4880294   Private Client  Private Client               Private Client   \n",
       "4880295   Private Client  Private Client               Private Client   \n",
       "4880296   Private Client  Private Client               Private Client   \n",
       "\n",
       "        Registrar Account - ID Registrar Account - Region  \\\n",
       "0                    200000647                     France   \n",
       "1                    200000647                     France   \n",
       "2                    200000647                     France   \n",
       "3                    200000647                     France   \n",
       "4                    200000647                     France   \n",
       "...                        ...                        ...   \n",
       "4880292         Private Client                Switzerland   \n",
       "4880293         Private Client                Switzerland   \n",
       "4880294         Private Client                Switzerland   \n",
       "4880295         Private Client                Switzerland   \n",
       "4880296         Private Client                Switzerland   \n",
       "\n",
       "        RegistrarAccount - Country Product - Asset Type Product - Strategy  \\\n",
       "0                           France          Diversified         Patrimoine   \n",
       "1                           France          Diversified         Patrimoine   \n",
       "2                           France          Diversified         Patrimoine   \n",
       "3                           France          Diversified         Patrimoine   \n",
       "4                           France          Diversified         Patrimoine   \n",
       "...                            ...                  ...                ...   \n",
       "4880292                Switzerland         Fixed Income           Sécurité   \n",
       "4880293                Switzerland         Fixed Income           Sécurité   \n",
       "4880294                Switzerland         Fixed Income           Sécurité   \n",
       "4880295                Switzerland         Fixed Income           Sécurité   \n",
       "4880296                Switzerland         Fixed Income           Sécurité   \n",
       "\n",
       "        Product - Legal Status Product - Is Dedie ?  \\\n",
       "0                          FCP                   NO   \n",
       "1                          FCP                   NO   \n",
       "2                          FCP                   NO   \n",
       "3                          FCP                   NO   \n",
       "4                          FCP                   NO   \n",
       "...                        ...                  ...   \n",
       "4880292                  SICAV                   NO   \n",
       "4880293                  SICAV                   NO   \n",
       "4880294                  SICAV                   NO   \n",
       "4880295                  SICAV                   NO   \n",
       "4880296                  SICAV                   NO   \n",
       "\n",
       "                       Product - Fund Product - Shareclass Type  \\\n",
       "0                Carmignac Patrimoine                         A   \n",
       "1                Carmignac Patrimoine                         A   \n",
       "2                Carmignac Patrimoine                         A   \n",
       "3                Carmignac Patrimoine                         A   \n",
       "4                Carmignac Patrimoine                         A   \n",
       "...                               ...                       ...   \n",
       "4880292  Carmignac Portfolio Sécurité                 AW & AW-R   \n",
       "4880293  Carmignac Portfolio Sécurité                 AW & AW-R   \n",
       "4880294  Carmignac Portfolio Sécurité                 AW & AW-R   \n",
       "4880295  Carmignac Portfolio Sécurité                 AW & AW-R   \n",
       "4880296  Carmignac Portfolio Sécurité                 FW & FW-R   \n",
       "\n",
       "        Product - Shareclass Currency Product - Isin Centralisation Date  \\\n",
       "0                                 EUR   FR0010135103          2015-03-31   \n",
       "1                                 EUR   FR0010135103          2015-11-30   \n",
       "2                                 EUR   FR0010135103          2015-12-31   \n",
       "3                                 EUR   FR0010135103          2016-03-31   \n",
       "4                                 EUR   FR0010135103          2016-11-30   \n",
       "...                               ...            ...                 ...   \n",
       "4880292                           EUR   LU1299306321          2020-02-29   \n",
       "4880293                           EUR   LU1299306321          2020-06-30   \n",
       "4880294                           EUR   LU1299306321          2020-10-31   \n",
       "4880295                           EUR   LU1299306321          2021-07-31   \n",
       "4880296                           EUR   LU1792391911          2020-07-31   \n",
       "\n",
       "         Quantity - AUM  Value - AUM CCY  Value - AUM €  \n",
       "0                35.368     2.464867e+04   2.464867e+04  \n",
       "1                35.368     2.241306e+04   2.241306e+04  \n",
       "2                35.368     2.205124e+04   2.205124e+04  \n",
       "3                35.368     2.162612e+04   2.162612e+04  \n",
       "4                35.368     2.248945e+04   2.248945e+04  \n",
       "...                 ...              ...            ...  \n",
       "4880292       26801.000     2.740670e+06   2.740670e+06  \n",
       "4880293        3099.000     3.122862e+05   3.122862e+05  \n",
       "4880294        3099.000     3.184222e+05   3.184222e+05  \n",
       "4880295        2835.000     2.976183e+05   2.976183e+05  \n",
       "4880296        2916.394     2.874106e+05   2.874106e+05  \n",
       "\n",
       "[4880297 rows x 18 columns]"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "stocks"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Date conversion done.\n"
     ]
    }
   ],
   "source": [
    "flows[\"Centralisation Date\"] = pd.to_datetime(flows[\"Centralisation Date\"], errors=\"coerce\")\n",
    "#flows[\"Centralisation Date\"]  = pd.to_datetime(flows[\"Centralisation Date\"], errors=\"coerce\")\n",
    "#nav[\"NavDate\"] = pd.to_datetime(nav[\"NavDate\"], format=\"%d/%m/%Y\", errors=\"coerce\")\n",
    "\n",
    "print(\"Date conversion done.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "flows_head = flows.head(100)\n",
    "flows_head.to_csv(\"flows_head.csv\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_94182/1741685825.py:2: DtypeWarning: Columns (1,2,3) have mixed types. Specify dtype option on import or set low_memory=False.\n",
      "  equity_stocks = pd.read_csv(f, sep=\",\")\n"
     ]
    }
   ],
   "source": [
    "with fs.open('s3://projet-bdc-carmignac-g3/aum_equity_95pct.csv', 'rb') as f:\n",
    "    equity_stocks = pd.read_csv(f, sep=\",\")\n",
    "\n",
    "equity_stocks[\"Centralisation Date\"] = pd.to_datetime(equity_stocks[\"Centralisation Date\"], errors=\"coerce\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "equity_stocks_head = equity_stocks.head(150)\n",
    "equity_stocks_head.to_csv(\"equity_stocks_head.csv\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Sum of AUM by Product - Asset Type"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AUM (€) by Product - Asset Type:\n",
      "Product - Asset Type\n",
      "Diversified       2.249487e+12\n",
      "Fixed Income      1.901982e+12\n",
      "Equity            9.811712e+11\n",
      "Alternative       1.208047e+11\n",
      "NaN               1.786480e+10\n",
      "Private Assets    2.205183e+09\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Product - Asset Type</th>\n",
       "      <th>Total AUM (€)</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Diversified</td>\n",
       "      <td>2.249487e+12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Fixed Income</td>\n",
       "      <td>1.901982e+12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Equity</td>\n",
       "      <td>9.811712e+11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Alternative</td>\n",
       "      <td>1.208047e+11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>NaN</td>\n",
       "      <td>1.786480e+10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>Private Assets</td>\n",
       "      <td>2.205183e+09</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  Product - Asset Type  Total AUM (€)\n",
       "0          Diversified   2.249487e+12\n",
       "1         Fixed Income   1.901982e+12\n",
       "2               Equity   9.811712e+11\n",
       "3          Alternative   1.208047e+11\n",
       "4                  NaN   1.786480e+10\n",
       "5       Private Assets   2.205183e+09"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Sum Value - AUM € per Product - Asset Type\n",
    "aum_by_asset_type = stocks.groupby('Product - Asset Type', dropna=False)['Value - AUM €'].sum().sort_values(ascending=False)\n",
    "\n",
    "print(\"AUM (€) by Product - Asset Type:\")\n",
    "print(aum_by_asset_type.to_string())\n",
    "\n",
    "# Display as DataFrame for nicer formatting\n",
    "aum_by_asset_type_df = aum_by_asset_type.reset_index()\n",
    "aum_by_asset_type_df.columns = ['Product - Asset Type', 'Total AUM (€)']\n",
    "aum_by_asset_type_df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 42744 characters]",
      "text/plain": [
       "<Figure size 1000x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(figsize=(10, 5))\n",
    "aum_by_asset_type.plot(kind='bar', ax=ax, color='steelblue', edgecolor='navy', alpha=0.8)\n",
    "ax.set_title('AUM Distribution by Product - Asset Type')\n",
    "ax.set_xlabel('Product - Asset Type')\n",
    "ax.set_ylabel('Total AUM (€)')\n",
    "ax.tick_params(axis='x', rotation=45)\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 69628 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# For each asset type: AUM per account (sum across funds/dates)\n",
    "aum_per_account = stocks.groupby(['Product - Asset Type', 'Registrar Account - ID'], dropna=False)['Value - AUM €'].sum().reset_index()\n",
    "\n",
    "# Build cumulative concentration curves per asset type\n",
    "fig, ax = plt.subplots(figsize=(10, 6))\n",
    "\n",
    "for asset_type in aum_per_account['Product - Asset Type'].unique():\n",
    "    subset = aum_per_account[aum_per_account['Product - Asset Type'] == asset_type].copy()\n",
    "    subset = subset.sort_values('Value - AUM €', ascending=False).reset_index(drop=True)\n",
    "    \n",
    "    total_aum = subset['Value - AUM €'].sum()\n",
    "    if total_aum == 0:\n",
    "        continue\n",
    "    \n",
    "    subset['cumsum_aum'] = subset['Value - AUM €'].cumsum()\n",
    "    subset['cumsum_pct'] = 100 * subset['cumsum_aum'] / total_aum\n",
    "    subset['n_accounts'] = range(1, len(subset) + 1)\n",
    "    \n",
    "    ax.plot(subset['n_accounts'], subset['cumsum_pct'], label=asset_type if pd.notna(asset_type) else '(empty)', linewidth=2)\n",
    "\n",
    "ax.axhline(y=90, color='gray', linestyle='--', alpha=0.5, label='90% threshold')\n",
    "ax.set_xlabel('Number of accounts (sorted by AUM, largest first)')\n",
    "ax.set_ylabel('Cumulative % of total AUM')\n",
    "ax.set_title('Account concentration: how many accounts hold X% of each asset type?')\n",
    "ax.legend(loc='lower right')\n",
    "ax.grid(True, alpha=0.3)\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Product - Asset Type</th>\n",
       "      <th>50% of AUM</th>\n",
       "      <th>75% of AUM</th>\n",
       "      <th>90% of AUM</th>\n",
       "      <th>95% of AUM</th>\n",
       "      <th>99% of AUM</th>\n",
       "      <th>Total accounts</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Alternative</td>\n",
       "      <td>19</td>\n",
       "      <td>80</td>\n",
       "      <td>193</td>\n",
       "      <td>309</td>\n",
       "      <td>667</td>\n",
       "      <td>2679</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Diversified</td>\n",
       "      <td>36</td>\n",
       "      <td>113</td>\n",
       "      <td>289</td>\n",
       "      <td>480</td>\n",
       "      <td>1100</td>\n",
       "      <td>8846</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Equity</td>\n",
       "      <td>35</td>\n",
       "      <td>125</td>\n",
       "      <td>331</td>\n",
       "      <td>556</td>\n",
       "      <td>1378</td>\n",
       "      <td>9123</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Fixed Income</td>\n",
       "      <td>33</td>\n",
       "      <td>114</td>\n",
       "      <td>307</td>\n",
       "      <td>514</td>\n",
       "      <td>1132</td>\n",
       "      <td>7348</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Private Assets</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>18</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  Product - Asset Type  50% of AUM  75% of AUM  90% of AUM  95% of AUM  \\\n",
       "0          Alternative          19          80         193         309   \n",
       "1          Diversified          36         113         289         480   \n",
       "2               Equity          35         125         331         556   \n",
       "3         Fixed Income          33         114         307         514   \n",
       "4       Private Assets           1           1           1           1   \n",
       "\n",
       "   99% of AUM  Total accounts  \n",
       "0         667            2679  \n",
       "1        1100            8846  \n",
       "2        1378            9123  \n",
       "3        1132            7348  \n",
       "4           3              18  "
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Summary: number of accounts holding X% of each asset type\n",
    "thresholds = [50, 75, 90, 95, 99]\n",
    "results = []\n",
    "\n",
    "for asset_type in aum_per_account['Product - Asset Type'].unique():\n",
    "    subset = aum_per_account[aum_per_account['Product - Asset Type'] == asset_type].copy()\n",
    "    subset = subset.sort_values('Value - AUM €', ascending=False).reset_index(drop=True)\n",
    "    total_aum = subset['Value - AUM €'].sum()\n",
    "    if total_aum == 0:\n",
    "        continue\n",
    "    \n",
    "    cumsum_pct = 100 * subset['Value - AUM €'].cumsum() / total_aum\n",
    "    \n",
    "    row = {'Product - Asset Type': asset_type if pd.notna(asset_type) else '(empty)'}\n",
    "    for pct in thresholds:\n",
    "        n_accounts = (cumsum_pct >= pct).idxmax() + 1 if (cumsum_pct >= pct).any() else len(subset)\n",
    "        row[f'{pct}% of AUM'] = n_accounts\n",
    "    row['Total accounts'] = len(subset)\n",
    "    results.append(row)\n",
    "\n",
    "pd.DataFrame(results)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Alternative: 309 accounts (95% AUM) → 50947 rows → aum_95pct_by_asset_type/aum_alternative_95pct.csv\n",
      "Diversified: 480 accounts (95% AUM) → 354694 rows → aum_95pct_by_asset_type/aum_diversified_95pct.csv\n",
      "Equity: 556 accounts (95% AUM) → 431011 rows → aum_95pct_by_asset_type/aum_equity_95pct.csv\n",
      "Fixed Income: 514 accounts (95% AUM) → 345213 rows → aum_95pct_by_asset_type/aum_fixed_income_95pct.csv\n",
      "Private Assets: 1 accounts (95% AUM) → 88 rows → aum_95pct_by_asset_type/aum_private_assets_95pct.csv\n",
      "nan: 4 accounts (95% AUM) → 3076 rows → aum_95pct_by_asset_type/aum_empty_95pct.csv\n",
      "\n",
      "Done. Files saved in 'aum_95pct_by_asset_type/'\n"
     ]
    }
   ],
   "source": [
    "OUTPUT_DIR = 'aum_95pct_by_asset_type'\n",
    "os.makedirs(OUTPUT_DIR, exist_ok=True)\n",
    "\n",
    "def safe_filename(asset_type):\n",
    "    \"\"\"Convert asset type to a safe filename.\"\"\"\n",
    "    if pd.isna(asset_type) or str(asset_type).strip() == '':\n",
    "        return 'empty'\n",
    "    return re.sub(r'[^\\w\\-]', '_', str(asset_type).strip().lower().replace(' ', '_'))\n",
    "\n",
    "# For each asset type: get accounts holding 95% of AUM\n",
    "for asset_type in aum_per_account['Product - Asset Type'].unique():\n",
    "    if pd.isna(asset_type):\n",
    "        subset = aum_per_account[aum_per_account['Product - Asset Type'].isna()].copy()\n",
    "    else:\n",
    "        subset = aum_per_account[aum_per_account['Product - Asset Type'] == asset_type].copy()\n",
    "    subset = subset.sort_values('Value - AUM €', ascending=False).reset_index(drop=True)\n",
    "    total_aum = subset['Value - AUM €'].sum()\n",
    "    \n",
    "    if total_aum == 0:\n",
    "        n_accounts_95 = 0\n",
    "        accounts_95 = set()\n",
    "    else:\n",
    "        cumsum_pct = 100 * subset['Value - AUM €'].cumsum() / total_aum\n",
    "        n_accounts_95 = (cumsum_pct >= 95).idxmax() + 1 if (cumsum_pct >= 95).any() else len(subset)\n",
    "        accounts_95 = set(subset.head(n_accounts_95)['Registrar Account - ID'])\n",
    "    \n",
    "    # Extract all rows from original df for these accounts AND this asset type\n",
    "    if pd.isna(asset_type):\n",
    "        type_mask = stocks['Product - Asset Type'].isna()\n",
    "    else:\n",
    "        type_mask = stocks['Product - Asset Type'] == asset_type\n",
    "    mask = type_mask & (stocks['Registrar Account - ID'].isin(accounts_95))\n",
    "    df_subset = stocks.loc[mask]\n",
    "    \n",
    "    filename = f\"aum_{safe_filename(asset_type)}_95pct.csv\"\n",
    "    filepath = os.path.join(OUTPUT_DIR, filename)\n",
    "    df_subset.to_csv(filepath, index=False)\n",
    "    \n",
    "    print(f\"{asset_type or '(empty)'}: {len(accounts_95)} accounts (95% AUM) → {len(df_subset)} rows → {filepath}\")\n",
    "\n",
    "print(f\"\\nDone. Files saved in '{OUTPUT_DIR}/'\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Sum of AUM by Product - Fund"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AUM (€) by Product - Fund:\n",
      "Product - Fund\n",
      "Carmignac Patrimoine                                         1.838372e+12\n",
      "Carmignac Sécurité                                           1.053010e+12\n",
      "Carmignac Investissement                                     5.300035e+11\n",
      "Carmignac Portfolio Sécurité                                 2.562135e+11\n",
      "Carmignac Portfolio Flexible Bond                            2.223185e+11\n",
      "Carmignac Portfolio Patrimoine                               2.035761e+11\n",
      "Carmignac Emergents                                          1.218833e+11\n",
      "Carmignac Portfolio Global Bond                              1.119945e+11\n",
      "Carmignac Portfolio Credit                                   8.413277e+10\n",
      "Carmignac Court Terme                                        8.224046e+10\n",
      "Carmignac Portfolio Emerging Patrimoine                      7.216283e+10\n",
      "Carmignac Portfolio Grande Europe                            6.404670e+10\n",
      "Carmignac Portfolio Long-Short European Equities             6.162365e+10\n",
      "Carmignac Portfolio Climate Transition                       5.125412e+10\n",
      "Carmignac Absolute Return Europe                             4.100414e+10\n",
      "Carmignac Credit 2027                                        3.937522e+10\n",
      "Carmignac Portfolio Patrimoine Europe                        3.880186e+10\n",
      "Carmignac Portfolio Investissement                           3.643094e+10\n",
      "Carmignac Investissement Latitude                            3.474053e+10\n",
      "Carmignac Portfolio Emergents                                2.942745e+10\n",
      "Carmignac Portfolio Asia Discovery                           2.934378e+10\n",
      "Carmignac Multi Expertise                                    2.633552e+10\n",
      "Carmignac Euro-Entrepreneurs                                 2.522512e+10\n",
      "Carmignac Credit 2029                                        1.738790e+10\n",
      "Carmignac Portfolio Grandchildren                            1.627555e+10\n",
      "Carmignac Credit 2025                                        1.547217e+10\n",
      "Fonditalia Carmignac Active Allocation                       1.452571e+10\n",
      "Carmignac Portfolio EM Debt                                  1.231814e+10\n",
      "UFF Grande Europe 0-100                                      1.222263e+10\n",
      "Carmignac Profil Réactif 75                                  1.178726e+10\n",
      "Carmignac Global Active                                      1.079949e+10\n",
      "Carmignac Profil Réactif 100                                 1.032957e+10\n",
      "FP Carmignac European Leaders                                8.759356e+09\n",
      "Mapfre Carmignac F.P.                                        8.205244e+09\n",
      "Carmignac Portfolio Flexible Allocation 2024                 6.464648e+09\n",
      "Carmignac China New Economy                                  5.961919e+09\n",
      "Carmignac Portfolio Investissement Latitude                  5.955304e+09\n",
      "Carmignac Credit 2031                                        5.310328e+09\n",
      "FP Carmignac Global Equity Compounders                       4.482628e+09\n",
      "Carmignac Portfolio Merger Arbitrage Plus                    4.335203e+09\n",
      "Credit Suisse Carmignac Emerging Markets Multi-Asset Fund    3.920236e+09\n",
      "Carmignac Portfolio Euro-Entrepreneurs                       3.670384e+09\n",
      "Carmignac Portfolio Merger Arbitrage                         3.643225e+09\n",
      "Carmignac Portfolio Human Xperience                          3.477910e+09\n",
      "Carmignac Alts ICAV Carmignac Credit Opportunities           3.294673e+09\n",
      "Carmignac Alts ICAV European Long Short                      3.260443e+09\n",
      "Carmignac Portfolio Capital Cube                             2.773859e+09\n",
      "Carmignac Portfolio China New Economy                        2.757754e+09\n",
      "FP Carmignac Emerging Markets                                2.224219e+09\n",
      "FP Carmignac Global Bond                                     2.208401e+09\n",
      "Carmignac S.A. SICAV - PART II UCI Private Evergreen         2.205183e+09\n",
      "Carmignac Portfolio Family Governed                          2.104642e+09\n",
      "Carmignac Portfolio Tech Solutions                           1.812327e+09\n",
      "FP Carmignac Emerging Patrimoine                             1.486110e+09\n",
      "Carmignac Portfolio Long-Short Global Equities               1.450546e+09\n",
      "FP Carmignac Patrimoine                                      1.367843e+09\n",
      "FP Carmignac Emerging Discovery                              1.315189e+09\n",
      "Carmignac Portfolio Global Market Neutral                    8.912455e+08\n",
      "Carmignac Portfolio China                                    8.898217e+08\n",
      "Carmignac Portfolio Inflation Solution                       8.063914e+08\n",
      "Carmignac Portfolio Absolute Return Europe                   7.929928e+08\n",
      "Solys - Carmignac Equity Selection                           6.677506e+08\n",
      "LUX IM - Carmignac Emerging Flexible Bond                    6.397498e+08\n",
      "Carmignac Portfolio Evolution                                5.464840e+08\n",
      "Carmignac Portfolio Alpha Themes                             5.085499e+08\n",
      "Carmignac Portfolio Active Risk Allocation                   3.816403e+08\n",
      "Carmignac Portfolio Cross Asset Opportunities                2.291751e+08\n",
      "Carmignac Portfolio Sustainable Bond                         6.016398e+07\n",
      "Carmignac Epargne Actions Monde ISR                          1.858147e+07\n",
      "CFP 1                                                        2.300000e+02\n",
      "Carmignac Innovation                                         0.000000e+00\n",
      "Carmignac Euro-Investissement                                0.000000e+00\n",
      "Carmignac Portfolio Infotech                                 0.000000e+00\n",
      "Carmignac Portfolio Market Neutral                           0.000000e+00\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Product - Fund</th>\n",
       "      <th>Total AUM (€)</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Carmignac Patrimoine</td>\n",
       "      <td>1.838372e+12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Carmignac Sécurité</td>\n",
       "      <td>1.053010e+12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Carmignac Investissement</td>\n",
       "      <td>5.300035e+11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Carmignac Portfolio Sécurité</td>\n",
       "      <td>2.562135e+11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Carmignac Portfolio Flexible Bond</td>\n",
       "      <td>2.223185e+11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>69</th>\n",
       "      <td>CFP 1</td>\n",
       "      <td>2.300000e+02</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>70</th>\n",
       "      <td>Carmignac Innovation</td>\n",
       "      <td>0.000000e+00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>71</th>\n",
       "      <td>Carmignac Euro-Investissement</td>\n",
       "      <td>0.000000e+00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>72</th>\n",
       "      <td>Carmignac Portfolio Infotech</td>\n",
       "      <td>0.000000e+00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>73</th>\n",
       "      <td>Carmignac Portfolio Market Neutral</td>\n",
       "      <td>0.000000e+00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>74 rows × 2 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                        Product - Fund  Total AUM (€)\n",
       "0                 Carmignac Patrimoine   1.838372e+12\n",
       "1                   Carmignac Sécurité   1.053010e+12\n",
       "2             Carmignac Investissement   5.300035e+11\n",
       "3         Carmignac Portfolio Sécurité   2.562135e+11\n",
       "4    Carmignac Portfolio Flexible Bond   2.223185e+11\n",
       "..                                 ...            ...\n",
       "69                               CFP 1   2.300000e+02\n",
       "70                Carmignac Innovation   0.000000e+00\n",
       "71       Carmignac Euro-Investissement   0.000000e+00\n",
       "72        Carmignac Portfolio Infotech   0.000000e+00\n",
       "73  Carmignac Portfolio Market Neutral   0.000000e+00\n",
       "\n",
       "[74 rows x 2 columns]"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Sum Value - AUM € per Product - Fund\n",
    "aum_by_fund = stocks.groupby('Product - Fund', dropna=False)['Value - AUM €'].sum().sort_values(ascending=False)\n",
    "\n",
    "print(\"AUM (€) by Product - Fund:\")\n",
    "print(aum_by_fund.to_string())\n",
    "\n",
    "# Display as DataFrame for nicer formatting\n",
    "aum_by_fund_df = aum_by_fund.reset_index()\n",
    "aum_by_fund_df.columns = ['Product - Fund', 'Total AUM (€)']\n",
    "aum_by_fund_df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 365640 characters]",
      "text/plain": [
       "<Figure size 1000x800 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(figsize=(10, 8))\n",
    "aum_by_fund.plot(kind='barh', ax=ax, color='coral', edgecolor='darkred', alpha=0.8)\n",
    "ax.set_title('AUM Distribution by Product - Fund')\n",
    "ax.set_xlabel('Total AUM (€)')\n",
    "ax.set_ylabel('Product - Fund')\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.13.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
