Project_Carmignac/data_exploration/competitors_analysis.ipynb

865 lines
499 KiB
Plaintext
Raw Normal View History

2026-02-22 15:02:41 +01:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
2026-03-10 23:01:34 +01:00
"# Competitors Analysis"
2026-02-22 15:02:41 +01:00
]
},
{
"cell_type": "code",
2026-03-10 23:01:34 +01:00
"execution_count": 1,
2026-02-22 15:02:41 +01:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Requirement already satisfied: openpyxl in /opt/python/lib/python3.13/site-packages (3.1.5)\n",
"Requirement already satisfied: et-xmlfile in /opt/python/lib/python3.13/site-packages (from openpyxl) (2.0.0)\n"
2026-02-22 15:02:41 +01:00
]
}
],
"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"
2026-02-22 15:02:41 +01:00
]
},
{
"cell_type": "code",
"execution_count": 2,
"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": 3,
"metadata": {},
2026-03-10 23:01:34 +01:00
"outputs": [],
2026-02-22 15:02:41 +01:00
"source": [
2026-03-10 23:01:34 +01:00
"with fs.open('s3://projet-bdc-data/carmignac/Data Modélisation/competitors/weekly_perf_full.csv', 'rb') as f:\n",
" weekly_perf = pd.read_csv(f, sep=\";\")"
2026-02-22 15:02:41 +01:00
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
2026-03-10 23:01:34 +01:00
"outputs": [],
"source": [
"weekly_perf[\"Date\"] = pd.to_datetime(weekly_perf['Date'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Time span of each competitor fund"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
2026-02-22 15:02:41 +01:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2026-03-10 23:01:34 +01:00
" First_Appearance Last_Appearance\n",
"shareClass_name \n",
"AB EM Multi-Asset A EUR H 2012-12-01 2025-09-27\n",
"AB European Growth A EUR 2024-03-23 2025-09-27\n",
"AB European Income A2 EUR 2012-12-01 2025-09-27\n",
"AB Event Driven S1 EUR H 2020-03-21 2025-09-27\n",
"AB Global Dynamic Bond I2 GBP 2014-06-21 2025-09-27\n",
"... ... ...\n",
"iShares MSCI EM ex China ETF USD Acc 2021-05-29 2025-09-27\n",
"iShares € Aggt Bd ESG SRI ETF EUR Dist 2012-12-01 2025-09-27\n",
"iShares € Corp Bd 0-3yr ESG SRI ETF€Dist 2016-02-06 2025-09-27\n",
"iShares € Govt Bond 1-3yr ETF EUR Dist 2012-12-01 2025-09-27\n",
"ÖkoWorld ÖkoVision Classic C 2015-01-07 2015-12-30\n",
"\n",
"[1012 rows x 2 columns]\n"
2026-02-22 15:02:41 +01:00
]
}
],
"source": [
2026-03-10 23:01:34 +01:00
"span_df = weekly_perf.groupby('shareClass_name')['Date'].agg(['min', 'max'])\n",
"\n",
"span_df.columns = ['First_Appearance', 'Last_Appearance']\n",
2026-02-22 15:02:41 +01:00
"\n",
2026-03-10 23:01:34 +01:00
"print(span_df)"
2026-02-22 15:02:41 +01:00
]
},
{
2026-03-10 23:01:34 +01:00
"cell_type": "code",
"execution_count": 6,
2026-02-22 15:02:41 +01:00
"metadata": {},
2026-03-10 23:01:34 +01:00
"outputs": [],
2026-02-22 15:02:41 +01:00
"source": [
2026-03-10 23:01:34 +01:00
"carmignac_funds = weekly_perf[weekly_perf['shareClass_name'].str.contains(\"Carmignac\", case=False, na=False)]\n",
"carmignac_span = carmignac_funds.groupby('shareClass_name')['Date'].agg(['min', 'max'])"
2026-02-22 15:02:41 +01:00
]
},
{
"cell_type": "code",
2026-03-10 23:01:34 +01:00
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"carmignac_weekly_perf_head = carmignac_funds.head(150)\n",
"carmignac_weekly_perf_head.to_csv(\"weekly_perf_head.csv\")"
]
},
{
"cell_type": "code",
"execution_count": null,
2026-02-22 15:02:41 +01:00
"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",
2026-03-10 23:01:34 +01:00
" <th>min</th>\n",
" <th>max</th>\n",
" </tr>\n",
" <tr>\n",
" <th>shareClass_name</th>\n",
" <th></th>\n",
" <th></th>\n",
2026-02-22 15:02:41 +01:00
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
2026-03-10 23:01:34 +01:00
" <th>AXA Sel Carmignac Convictions Instl I €</th>\n",
" <td>2015-01-07</td>\n",
" <td>2015-12-30</td>\n",
" </tr>\n",
" <tr>\n",
" <th>AXA Sel Carmignac Convictions Rtl R EUR</th>\n",
" <td>2015-01-07</td>\n",
" <td>2015-12-30</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Best Carmignac FI</th>\n",
" <td>2015-01-07</td>\n",
" <td>2015-12-30</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Carmignac Absolute Ret Eur A EUR Acc</th>\n",
" <td>2012-12-01</td>\n",
" <td>2025-09-27</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Carmignac Absolute Ret Eur A EUR Ydis</th>\n",
" <td>2015-01-07</td>\n",
" <td>2015-12-30</td>\n",
2026-02-22 15:02:41 +01:00
" </tr>\n",
" <tr>\n",
2026-03-10 23:01:34 +01:00
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
2026-02-22 15:02:41 +01:00
" </tr>\n",
" <tr>\n",
2026-03-10 23:01:34 +01:00
" <th>Multimgrs Equilibre-Carmignac Patrim I</th>\n",
" <td>2015-01-07</td>\n",
" <td>2015-12-30</td>\n",
2026-02-22 15:02:41 +01:00
" </tr>\n",
" <tr>\n",
2026-03-10 23:01:34 +01:00
" <th>Multimgrs Equilibre-Carmignac Patrim P</th>\n",
" <td>2015-01-07</td>\n",
" <td>2015-12-30</td>\n",
2026-02-22 15:02:41 +01:00
" </tr>\n",
" <tr>\n",
2026-03-10 23:01:34 +01:00
" <th>Multimgrs Equilibre-Carmignac Patrim S</th>\n",
" <td>2015-01-07</td>\n",
" <td>2015-12-30</td>\n",
2026-02-22 15:02:41 +01:00
" </tr>\n",
" <tr>\n",
2026-03-10 23:01:34 +01:00
" <th>Nomura Carmignac Fund A</th>\n",
" <td>2015-01-07</td>\n",
" <td>2015-12-30</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Nomura Carmignac Fund B</th>\n",
" <td>2015-01-07</td>\n",
" <td>2015-12-30</td>\n",
2026-02-22 15:02:41 +01:00
" </tr>\n",
" </tbody>\n",
"</table>\n",
2026-03-10 23:01:34 +01:00
"<p>224 rows × 2 columns</p>\n",
2026-02-22 15:02:41 +01:00
"</div>"
],
"text/plain": [
2026-03-10 23:01:34 +01:00
" min max\n",
"shareClass_name \n",
"AXA Sel Carmignac Convictions Instl I € 2015-01-07 2015-12-30\n",
"AXA Sel Carmignac Convictions Rtl R EUR 2015-01-07 2015-12-30\n",
"Best Carmignac FI 2015-01-07 2015-12-30\n",
"Carmignac Absolute Ret Eur A EUR Acc 2012-12-01 2025-09-27\n",
"Carmignac Absolute Ret Eur A EUR Ydis 2015-01-07 2015-12-30\n",
"... ... ...\n",
"Multimgrs Equilibre-Carmignac Patrim I 2015-01-07 2015-12-30\n",
"Multimgrs Equilibre-Carmignac Patrim P 2015-01-07 2015-12-30\n",
"Multimgrs Equilibre-Carmignac Patrim S 2015-01-07 2015-12-30\n",
"Nomura Carmignac Fund A 2015-01-07 2015-12-30\n",
"Nomura Carmignac Fund B 2015-01-07 2015-12-30\n",
"\n",
"[224 rows x 2 columns]"
2026-02-22 15:02:41 +01:00
]
},
2026-03-10 23:01:34 +01:00
"execution_count": 13,
2026-02-22 15:02:41 +01:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2026-03-10 23:01:34 +01:00
"carmignac_span_filtered = carmignac_span[carmignac_span[\"max\"] >= 2025-12]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Other"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" Date perfPeriod shareClass_name \\\n",
"4 2012-12-29 1YrRet Carmignac Pf Asia Discovery A EUR Acc \n",
"11 2012-12-29 1YrRet Carmignac Pf Asia Discovery F EUR Acc \n",
"16 2013-01-05 1YrRet Carmignac Pf Asia Discovery F EUR Acc \n",
"26 2013-01-05 1YrRet Carmignac Pf Asia Discovery A EUR Acc \n",
"32 2013-01-12 1YrRet Carmignac Pf Asia Discovery F EUR Acc \n",
"... ... ... ... \n",
"2370113 2015-12-30 WeeklyRet Carmignac Pf Global Bond A EUR Acc \n",
"2370124 2015-12-30 WeeklyRet Carmignac Pf Asia Discovery F EUR Acc \n",
"2370142 2015-12-30 WeeklyRet Carmignac Pf Investissement A EUR Acc \n",
"2370150 2015-12-30 WeeklyRet Carmignac Patrimoine A EUR Acc \n",
"2370157 2015-12-30 WeeklyRet Carmignac Pf Sécurité FW EUR Acc \n",
"\n",
" return percentile max_date \n",
"4 15.370509 2.0 2025-09-27 \n",
"11 15.364424 2.0 2025-09-27 \n",
"16 15.487607 2.0 2025-09-27 \n",
"26 15.487613 2.0 2025-09-27 \n",
"32 10.613214 6.0 2025-09-27 \n",
"... ... ... ... \n",
"2370113 0.014101 51.0 2025-09-27 \n",
"2370124 -0.179625 90.0 2025-09-27 \n",
"2370142 0.387834 68.0 2025-09-27 \n",
"2370150 0.105970 72.0 2025-09-27 \n",
"2370157 0.019303 51.0 2025-09-27 \n",
"\n",
"[140423 rows x 6 columns]\n"
]
}
],
"source": [
"df = weekly_perf\n",
"\n",
"# 1. Ensure Date is datetime format [cite: 1, 2]\n",
"df['Date'] = pd.to_datetime(df['Date'])\n",
"\n",
"# 2. Create the 'max' (Last Appearance) column for each fund [cite: 1, 2]\n",
"df['max_date'] = df.groupby('shareClass_name')['Date'].transform('max')\n",
2026-02-22 15:02:41 +01:00
"\n",
2026-03-10 23:01:34 +01:00
"# 3. Define your target date\n",
"target_value = pd.to_datetime('2025-01-01')\n",
2026-02-22 15:02:41 +01:00
"\n",
2026-03-10 23:01:34 +01:00
"# 4. Filter for Carmignac funds that appeared AFTER the target value\n",
"# This keeps all historical rows for funds whose LAST appearance > target\n",
"filtered_carmignac = df[\n",
" (df['shareClass_name'].str.contains(\"Carmignac\", case=False)) & \n",
" (df['max_date'] > target_value)\n",
"]\n",
"\n",
"print(filtered_carmignac)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Rest"
2026-02-22 15:02:41 +01:00
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"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": "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
"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}/'\")"
]
},
2026-02-22 15:02:41 +01:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Sum of AUM by Product - Fund"
]
},
{
"cell_type": "code",
"execution_count": 6,
2026-02-22 15:02:41 +01:00
"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"
}
],
2026-02-22 15:02:41 +01:00
"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": "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
"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()"
]
2026-02-22 15:02:41 +01:00
}
],
"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
}