{
“cells”: [
{

“cell_type”: “markdown”, “id”: “kju0kmcn62”, “metadata”: {}, “source”: [

“# Portfolio Ensembles via Stackingn”, “n”, “This notebook shows how to blend multiple portfolio specifications into an”, “single ensemble allocation. Three models – sample mean-variance,n”, “shrinkage mean-variance, and CVaR – are aligned by risk percentile andn”, “combined via both simple averaging and exposure stacking.”

]

}, {

“cell_type”: “code”, “execution_count”: 1, “id”: “ywsxde2ipn”, “metadata”: {

“execution”: {

“iopub.execute_input”: “2026-03-30T19:38:39.164450Z”, “iopub.status.busy”: “2026-03-30T19:38:39.164193Z”, “iopub.status.idle”: “2026-03-30T19:38:39.811041Z”, “shell.execute_reply”: “2026-03-30T19:38:39.810733Z”

}

}, “outputs”: [], “source”: [

“import numpy as npn”, “import pandas as pdn”, “import matplotlib.pyplot as pltn”, “from pyvallocation import (n”, “ assemble_portfolio_ensemble,n”, “ make_portfolio_spec,n”, “)”

]

}, {

“cell_type”: “markdown”, “id”: “4toyw6xqjhw”, “metadata”: {}, “source”: [

“## Load return datan”, “n”, “We use the last 750 daily returns from the bundled ETF prices.”

]

}, {

“cell_type”: “code”, “execution_count”: 2, “id”: “ifw9uik4bb”, “metadata”: {

“execution”: {

“iopub.execute_input”: “2026-03-30T19:38:39.812363Z”, “iopub.status.busy”: “2026-03-30T19:38:39.812269Z”, “iopub.status.idle”: “2026-03-30T19:38:39.819984Z”, “shell.execute_reply”: “2026-03-30T19:38:39.819779Z”

}

}, “outputs”: [

{

“name”: “stdout”, “output_type”: “stream”, “text”: [

“Assets : [‘DBC’, ‘GLD’, ‘SPY’, ‘TLT’]n”, “Periods: 750n”

]

}

], “source”: [

“from pathlib import Pathn”, “n”, “_candidates = [n”, “ Path("examples/ETF_prices.csv"),n”, “ Path("../examples/ETF_prices.csv"),n”, “ Path("../../examples/ETF_prices.csv"),n”, “ Path("../../../examples/ETF_prices.csv"),n”, “]n”, “_csv = next((p for p in _candidates if p.exists()), None)n”, “if _csv is None:n”, “ raise FileNotFoundError("ETF_prices.csv not found")n”, “prices = pd.read_csv(_csv, index_col="Date", parse_dates=True)n”, “prices = prices.dropna(how="all").ffill()n”, “returns = prices.pct_change().dropna(how="any").iloc[-750:]n”, “n”, “print(f"Assets : {list(returns.columns)}")n”, “print(f"Periods: {len(returns)}")”

]

}, {

“cell_type”: “markdown”, “id”: “s2sbr6plsxq”, “metadata”: {}, “source”: [

“## Define three portfolio specificationsn”, “n”, “Each spec uses a different model but is aligned at the median risk percentilen”, “so that the selected portfolios are comparable:n”, “n”, “1. Sample MV – sample mean and covariance.n”, “2. Shrinkage MV – Jorion mean + Ledoit-Wolf covariance.n”, “3. CVaR – scenario-based CVaR at alpha=5%.”

]

}, {

“cell_type”: “code”, “execution_count”: 3, “id”: “cn6np2kj767”, “metadata”: {

“execution”: {

“iopub.execute_input”: “2026-03-30T19:38:39.820978Z”, “iopub.status.busy”: “2026-03-30T19:38:39.820918Z”, “iopub.status.idle”: “2026-03-30T19:38:39.822692Z”, “shell.execute_reply”: “2026-03-30T19:38:39.822485Z”

}

}, “outputs”: [], “source”: [

“selector_kwargs = {"percentile": 0.5, "risk_label": "Volatility"}n”, “n”, “specs = [n”, “ make_portfolio_spec(n”, “ "Sample MV",n”, “ returns=returns,n”, “ mean_estimator="sample",n”, “ cov_estimator="sample",n”, “ optimiser="mean_variance",n”, “ selector="risk_percentile",n”, “ selector_kwargs=selector_kwargs,n”, “ ),n”, “ make_portfolio_spec(n”, “ "Shrinkage MV",n”, “ returns=returns,n”, “ mean_estimator="jorion",n”, “ cov_estimator="ledoit_wolf",n”, “ optimiser="mean_variance",n”, “ selector="risk_percentile",n”, “ selector_kwargs=selector_kwargs,n”, “ ),n”, “]”

]

}, {

“cell_type”: “code”, “execution_count”: 4, “id”: “yare2i03vgs”, “metadata”: {

“execution”: {

“iopub.execute_input”: “2026-03-30T19:38:39.823566Z”, “iopub.status.busy”: “2026-03-30T19:38:39.823511Z”, “iopub.status.idle”: “2026-03-30T19:38:39.825050Z”, “shell.execute_reply”: “2026-03-30T19:38:39.824875Z”

}

}, “outputs”: [

{

“name”: “stdout”, “output_type”: “stream”, “text”: [

“Defined 3 specs: [‘Sample MV’, ‘Shrinkage MV’, ‘CVaR’]n”

]

}

], “source”: [

“specs.append(n”, “ make_portfolio_spec(n”, “ "CVaR",n”, “ returns=returns,n”, “ use_scenarios=True,n”, “ optimiser="cvar",n”, “ optimiser_kwargs={"alpha": 0.05},n”, “ selector="risk_percentile",n”, “ selector_kwargs=selector_kwargs,n”, “ ),n”, “)n”, “n”, “print(f"Defined {len(specs)} specs: {[s.name for s in specs]}")”

]

}, {

“cell_type”: “markdown”, “id”: “m29g7pg83lm”, “metadata”: {}, “source”: [

“## Assemble the ensemblen”, “n”, “assemble_portfolio_ensemble runs each spec, selects portfolios at then”, “target risk percentile, and combines them via averaging and stacking.”

]

}, {

“cell_type”: “code”, “execution_count”: 5, “id”: “kv4eofw16rs”, “metadata”: {

“execution”: {

“iopub.execute_input”: “2026-03-30T19:38:39.825956Z”, “iopub.status.busy”: “2026-03-30T19:38:39.825883Z”, “iopub.status.idle”: “2026-03-30T19:38:40.115916Z”, “shell.execute_reply”: “2026-03-30T19:38:40.115624Z”

}

}, “outputs”: [

{

“name”: “stderr”, “output_type”: “stream”, “text”: [

“No constraints set; using default long-only, fully-invested.n”

]

}, {

“name”: “stderr”, “output_type”: “stream”, “text”: [

“No constraints set; using default long-only, fully-invested.n”

]

}, {

“name”: “stderr”, “output_type”: “stream”, “text”: [

“Estimating mu and cov from scenarios (no explicit values provided).n”

]

}, {

“name”: “stderr”, “output_type”: “stream”, “text”: [

“No constraints set; using default long-only, fully-invested.n”

]

}

], “source”: [

“result = assemble_portfolio_ensemble(n”, “ specs,n”, “ ensemble=("average", "stack"),n”, “ combine="selected",n”, “)”

]

}, {

“cell_type”: “markdown”, “id”: “rfwgv2smubg”, “metadata”: {}, “source”: [

“## Print stacked vs averaged weights”

]

}, {

“cell_type”: “code”, “execution_count”: 6, “id”: “weymdt4a7n”, “metadata”: {

“execution”: {

“iopub.execute_input”: “2026-03-30T19:38:40.117140Z”, “iopub.status.busy”: “2026-03-30T19:38:40.117075Z”, “iopub.status.idle”: “2026-03-30T19:38:40.120306Z”, “shell.execute_reply”: “2026-03-30T19:38:40.120112Z”

}

}, “outputs”: [

{

“name”: “stdout”, “output_type”: “stream”, “text”: [

“=== Selected portfolios (aligned by risk percentile) ===n”, “ Sample MV Shrinkage MV CVaRn”, “DBC 0.1026 0.1027 0.0000n”, “GLD 0.4400 0.4399 0.5327n”, “SPY 0.2782 0.2781 0.2526n”, “TLT 0.1793 0.1792 0.2147n”, “n”, “=== Ensemble portfolios ===n”, “n”, “[average]n”, “DBC 0.0684n”, “GLD 0.4709n”, “SPY 0.2696n”, “TLT 0.1911n”, “Name: Average Exposure, dtype: float64n”, “n”, “[stack]n”, “DBC 0.0745n”, “GLD 0.4654n”, “SPY 0.2711n”, “TLT 0.1890n”, “Name: Exposure Stacking (L=3), dtype: float64n”

]

}

], “source”: [

“print("=== Selected portfolios (aligned by risk percentile) ===")n”, “print(result.selections.round(4))n”, “n”, “print("\n=== Ensemble portfolios ===")n”, “for name, w in result.ensembles.items():n”, “ print(f"\n[{name}]")n”, “ print(w.round(4))”

]

}, {

“cell_type”: “markdown”, “id”: “ww0i1b1qnpj”, “metadata”: {}, “source”: [

“## Compare ensemble weights visuallyn”, “n”, “A grouped bar chart highlights how stacking dampens idiosyncratic tiltsn”, “compared to simple averaging.”

]

}, {

“cell_type”: “code”, “execution_count”: 7, “id”: “gokz8z3hecr”, “metadata”: {

“execution”: {

“iopub.execute_input”: “2026-03-30T19:38:40.121278Z”, “iopub.status.busy”: “2026-03-30T19:38:40.121217Z”, “iopub.status.idle”: “2026-03-30T19:38:40.173709Z”, “shell.execute_reply”: “2026-03-30T19:38:40.173500Z”

}

}, “outputs”: [

{
“data”: {

“image/png”: “iVBORw0KGgoAAAANSUhEUgAAAxYAAAHqCAYAAACZcdjsAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAQt5JREFUeJzt3Qd4VFX+//FvqCFAQk+ARboCShOEBQuICIhdVxFREBXXwoqLqLAqRVTsooKLZUFFEOyuoigiIE0R0BUL7KIgrEhTCU0CJPN/Pue3M/+ZMCHBk2SSzPv1PGMyd+7MnFuC53NPuQmBQCBgAAAAAOChlM+bAQAAAEAIFgAAAAC8ESwAAAAAeCNYAAAAAPBGsAAAAADgjWABAAAAwBvBAgAAAIA3ggUAAAAAbwQLAAAAAN4IFgDi0nPPPWcJCQm2fPnyXNft2rWre5Q0U6dOtWbNmlnZsmWtSpUqR/TeK664who0aBCxTPtz9OjR+VxKIH/o/Bw8eHCsiwGUaAQLAIeteOf0+OSTT2JdxGJLlfLwfZmcnGytW7e2hx9+2DIyMvLtezZt2uQq+l988cUhr61evdqVo3HjxvbMM8/Y008/bSXRrbfe6vZxnz59Yl2UuLNt2zYbMmSIC68VKlSwWrVqWYcOHey2226z3bt3h9abPn26jR8/PqZlBZA/yuTT5wAooe666y5r2LDhIcubNGkSk/KUFOXLl7dnn33W/b5jxw577bXXbNiwYfbZZ5/ZjBkz8i1YjBkzxrUstGnTJuK1+fPnW1ZWlj322GP5dix/++03K1Om6PxvJRAI2EsvveS2/+2337Zdu3ZZ5cqVY12suPDLL79Y+/btbefOnXbllVe6cPHzzz/bl19+aX//+9/tuuuus0qVKoWCxVdffWU33XRTrIsNwFPR+T8AgCLpjDPOcBUE5C9VwC+77LLQ8+uvv946duxoM2fOtEceecTq1Knzuz/74MGDLjQcztatW93PI+0CdTiJiYlWlCg8/fe//7WPPvrIevbsaa+//roNGDCgUMsQPBblypWzePKPf/zDNmzYYIsXL7bOnTtHvKawEW/7A4gXdIUC4GX9+vWuq8lDDz3kutOoa42uxp9wwgnu6nu4zZs328CBA+0Pf/iDW6d27dp27rnnus8I995779nJJ59sFStWdFeYzzzzTPv6668j1lE3Hl3xVOXlrLPOcr/XrVvXJk6c6F5ftWqVdevWzX1G/fr13VXRaPbu3Wt//vOfrXr16q5LUv/+/e3XX3/NdbvVZWnUqFHuar+2pV69eq7bze/tylSqVKnQOI7g/lDl/6qrrrLU1FRXaVd3qeeffz7H/a/uJMH9/+STT7pjINrnwW5X6uKmK/gqu9SsWfOQsRF677HHHus+RwHnhhtucK0quYk2xuLzzz934VT7VsfotNNOO6Qb3YEDB1zLStOmTd126licdNJJNmfOnIh11H3rp59+yvM+nTZtmrVo0cJOPfVU6969u3setGXLFhfu9L3ZrVmzxm3LhAkTQsu0/bqiruOs/aLjfv/990cEuJyOxTfffGP79++3kSNHWrt27SwlJcWdlzrH582bd8j368r+5Zdf7vaZgp/C0L/+9a/Q8QunffKnP/3JqlWr5vadLgL885//POx+0b7U+jovslOlX5+j1rOgJ554wp0PSUlJVrVqVfcdOf09BX333XdWunRp++Mf/3jIa9quYAjVOT9r1iz74YcfQudocOzOkeyzYOtby5Yt3WfrvO7Vq1euY6juvvtu97enbQTgjxYLAIeVnp5u27dvj1im//mr8hdOFQ11NVElXa8/8MADdsEFF9j333/vBgfLhRde6ALCX/7yF1d5UMVZlUeFg2BlQgOKVZHSFWZV3FTxV9cJVTRVSQ0fMJyZmekqraeccor7PlUcNThTFZDbb7/d+vXr58owadIkFxg6dep0SLcura/KmyrEqlDqu1TJ0dVubUc0qsScc845tmjRIrvmmmusefPmLsg8+uij9u9//9vefPPN37WvVRkT7Vt1K1Kla+3ata6MKvcrr7ziApUqueq7Hm7KlCm2b98+Vx5VZs8//3x3PFQx0zJVyERXj1XpfeGFF+yNN95w26sKf6tWrdzr2g+qbKsiru4qwX2ikKirz8FjmRc61vpeVSQVuvTep556ym3XggULXAtN8DvHjRtnV199teuDr8qtKoQrV660008/3a3z448/uv2scyN75ToaBTx1L7v55pvd8759+7qKtMJtWlqaC2tdunSxl19+ORSygtRqpErxRRdd5J7rHNS6KoPO76OOOsqWLFliI0aMcEEn+/iA7MdClXhtk7q+qRyDBg1yx0ZX9XWeL1u2LNRVTefW2Wef7ZZp/6sL0VtvvRW1pUX798QTT3SBevjw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AADeCBYAAADAEejatavddNNN+f65o0ePtjZt2lhxRbAAAABAiXHFFVe4rj3XXnvtIa/dcMMN7jWtkxfz58936zNdbt4QLAAAAFCi1KtXz2bMmGG//fZbaNm+ffts+vTpdtRRR8W0bCUZwQIAAAAlyvHHH+/Cxeuvvx5apt8VKtq2bRtalpWVZePGjbOGDRu6aVdbt25tr776qntt/fr1duqpp7rfq1atekhLh9576623WrVq1dzN5UaPHh1Rhg0bNti5555rlSpVsuTkZLv44otty5YtEevcd999lpqaapUrV7arrrrKhZ/ijGABAACAEufKK6+0KVOmhJ5PnjzZBg4cGLGOQsULL7xgkyZNsq+//tr++te/2mWXXWYLFixwweS1115z661Zs8Z++ukne+yxx0Lvff75561ixYr26aef2gMPPGB33XWXzZkzJxQ6FCp++eUX91la/v3331ufPn1C73/55ZddGLn33ntt+fLl7uZ0Tz75pBVn3CAPAAAAJY4CwogRI+yHH35wzxcvXuy6R2nchGRkZLhK/YcffmidOnVyyxo1amSLFi2yp556yrp06eJaI0Q3jqtSpUrE57dq1cpGjRrlfm/atKlNmDDB5s6da6effrr7uWrVKlu3bp0LKKIAc+yxx9pnn31mJ5xwgo0fP961Uughd999tytLcW61IFgAAACgxKlZs6adeeaZ9txzz1kgEHC/16hRI/T62rVrbe/evS4IhNu/f39Ed6mcKFiEq127trt7tXz77bcuUARDhbRo0cKFE72mYKGf2QeYK+DMmzfPiiuCBYB80WD4LIsn6+87M9ZFAADkoTvU4MGD3e8TJ06MeG337t3u56xZs6xu3boRr5UvXz7Xzy5btmzE84SEBNcFKp4xxgIAAAAlUq9evVwLxIEDB6xnz54Rr6kFQQFCg6ybNGkS8Qi2NJQrV879zMzMPKLvbd68uW3cuNE9gr755hs3ba2+N7iOxmeE++STT6w4o8UCAAAAJVLp0qVdl6Pg7+E0E9OwYcPcgG21NJx00kmWnp7uxmJoFqcBAwZY/fr1XUvEO++8Y71793YzR2mWp9x0797dWrZsaf369XNjKQ4ePGjXX3+9G7fRvn17t86QIUPcLFN6fuKJJ9q0adPcAHKN8yiuaLEAAABAiaWQoEc0Y8eOtTvvvNPNDqUWBLVwqGuUpp8V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woLFwYMH7YILLrD69eu7ZWq9ELVgZGRkWFpaWsR77rjjjoiB2MOGDbMZM2aEgsU999xjl1xyiY0ZMya0XuvWrQ/5brV8TJ061RYsWGDHHnusFTcECwAAACCswn/aaae5MNGzZ0/r0aOH/elPf7KqVavm+J6ZM2fa448/bt99953t3r3bBZPk5OTQ61988YVrxTichx9+2Pbs2WPLly933amKI8ZYAAAAAP9TunRpmzNnjr333nvWokULe+KJJ+yYY46xdevWRV1/6dKl1q9fP+vdu7e988479vnnn7suT+ruFKSWjtycfPLJlpmZaS+//LIVVwQLAAAAIIwGZp944omu65KCQrly5eyNN95wP1X5D7dkyRLXZer222+39u3bW9OmTe2HH36IWKdVq1a5DsTWeAqFmXvvvdceeughK47oCgUAAAD8z6effupCgLpA1apVyz3ftm2bNW/e3Pbt22fvv/++rVmzxs0WlZKS4oKEBnXPmDHDzfqkgdoKIeFGjRrlulc1btzYjbVQVykN3taYinCdO3d2y8844wwrU6aM3XTTTVac0GIBAAAA/I/GRnz88ceua5OmkNXAbI1/UGVf4yTULUotEzVr1rTFixfbOeecY3/9619t8ODB1qZNG9eCoelmw3Xt2tVeeeUV++c//+nW6datmy1btizq95900kkunOh71Q2rOEkIBAIBiyOaIkzpMj09PWJQDQA/DYbPsniyPvFSiyv5eOdaAPFBV/c1LqFhw4bu3g0onsfqSOrOtFgAAAAA8EawAAAAAOCNYAEAAADAG8ECAAAAgDeCBQAAAABvBAsAAAAUmKysrFgXAYV0jLhBHgAAAPKd7lJdqlQp27Rpk7vng57rjtYoOnTXif3797sbAOpY6RgV+2AxceJEe/DBB23z5s3WunVrdzMQ3dY8N7rDYd++fe3cc8+1N998s1DKCgAAgNypoqr7Ivz0008uXKDoSkpKsqOOOsods2IdLGbOnGlDhw61SZMmWceOHW38+PHWs2dPd6t03UY9J+vXr7dhw4bZySefXKjlBQAAQN7oCrgqrAcPHrTMzMxYFwdRlC5d2sqUKZMvrUkxDxaPPPKIuz36wIED3XMFDN3GfPLkyTZ8+PCo79GJ2a9fPxszZowtXLjQduzYUcilBgAAQF6owlq2bFn3QMkW08Hb6tO1YsUK6969+/8v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KCLB4pFHHrFBgwbZwIEDrUWLFjZp0iRLSkqyyZMnR13/scces169etktt9xizZs3t7Fjx9rxxx9vEyZMKPSyAwAAAPg/ZSyG9u/fbytWrLARI0aElpUqVcq6d+9uS5cujfoeLVcLRzi1cLz55ptR18/IyHCPoPT0dPdz586dVhxkZey1eLIzIWBxpZich3nBuVrCca4WW5yrxRfnagm3s3icq8E6cyAQKNrBYvv27ZaZmWmpqakRy/V89erVUd+zefPmqOtreTTjxo2zMWPGHLK8Xr16XmVHwUixOHNf3G1xiRF3R45ztdiKuyPHuVpsxd2Ru694bfGuXbssJSWl6AaLwqDWkPAWjqysLPvll1+sevXqlpCQENOy4dBErMC3ceNGS05OjnVxgBxxrqK44FxFccG5WnSppUKhok6dOrmuG9NgUaNGDStdurRt2bIlYrmep6WlRX2Plh/J+uXLl3ePcFWqVPEuOwqO/kHhHxUUB5yrKC44V1FccK4WTbm1VBSJwdvlypWzdu3a2dy5cyNaFPS8U6dOUd+j5eHry5w5c3JcHwAAAEDBi3lXKHVTGjBggLVv3946dOhg48ePtz179rhZoqR///5Wt25dN1ZChgwZYl26dLGHH37YzjzzTJsxY4YtX77cnn766RhvCQAAABC/Yh4s+vTpY9u2bbORI0e6Adht2rSx2bNnhwZob9iwwc0UFdS5c2ebPn263XHHHfa3v/3NmjZt6maEOu6442K4FcgP6rKm+5lk77oGFDWcqyguOFdRXHCulgwJgbzMHQUAAAAARfkGeQAAAACKP4IFAAAAAG8ECwAAAADeCBYAAAAAvBEsAAAoATRVO1DUNWrUyH7++edYFwMldbpZACgONIHeihUrbP369ZaQkGANGza0tm3but+BoqBVq1b2/PPP20knnRTrogA50r+hmZmZsS4GCggtFoiZnTt3ujutZ6d/cPQaUFTMmzfPGjdubB07drSLL77YLrroIjvhhBPcfXQ+/vjjWBcPcC688ELr1q2b3XLLLbZ///5YFwdAHOI+FoiJN954w2677Tb74osvLCkp6ZDm/OOPP94eeughO/vss2NWRkDWrl1rrVu3dqFiyJAh1qxZM9d68c0339jjjz9uy5cvty+//NI17wOx9sknn9iVV17pbiw7depU16oGFCU6N9WylpKSctj1zjnnnEIrE/IPwQIx0aNHD3fl9+qrr476+uTJk23mzJn2/vvvF3rZgHCDBw+2b7/91ubOnXvIa/rns3v37taiRQt74oknYlI+ILuMjAy74447bMKECXb66adbmTKRvZ5ff/31mJUNULDIjbqY0l2qeKIrFGLiq6++sq5du+b4+imnnGKrVq0q1DIB0cyfP99uuummHP/np9fUVQooSsFi69at7vzUVeHsDyDWNm/e7LpC5/QgVBRfDN5GTPz666928ODBHF8/cOCAWweItQ0bNljLli1zfP24446zH374oVDLBORkzpw5ritU7dq13WQDzZs3j3WRgAi5TXihULFlyxarU6dOoZUJ+YcWC8REgwYNXN/0nOi1+vXrF2qZgGh27959yDigcHpt7969hVomIJo///nPdtZZZ9mgQYNs6dKlhAoUSbn1wFePhnr16hVaeZC/aLFATFxwwQV2++23u/6/qamphzSRqn/wZZddFrPyAeE0UFvnZTTbt28v9PIA0SxevNgFCk1+ARRVAwYMsAoVKsS6GCggDN5GTOzatcs6derkupkoQBxzzDFu+erVq23atGnuaoVmN6lcuXKsi4o4p4GGarqP9k9lcDkDDVEUaIrZlStX2ttvv+1+P+2006xXr16xLhZwRP71r3+5cMy/qcUTwQIxk56ebiNGjHCzPwXHU1SpUsUuueQSu+eee6xq1aqxLiKQ5/ETdN1DrL366qvWp08fdzW4bNmy7n5A999/vw0bNizWRQPyjGBRvBEsEHM6BdWdRD9r1qzJnYxRrOzYscPeffddu/TSS2NdFMS5du3auRs3Tpw40UqXLm3jxo2zBx980H755ZdYFw0I0X1/Dkc9F/r27UuwKKYIFigydCpq2s7ffvvNOnfuTIsFigWurqGoqFSpkrvpaJMmTdxzdYeqWLGi/fjjj1arVq1YFw9w6F5asjF4GzG7yqu7GKs/8B//+Ed7+OGHrXfv3rZkyRL3uv4n+MEHH1irVq1iXVQAKBY0O1lycnLoebly5SwxMdHNbEawQFGxbt26WBcBBYhggZhQn1/NXqLZITTQUAMMdZVCy3Q149Zbb3WzRuk1AEDePPvss67lIkj3C3ruueesRo0aoWU33nhjjEoHmD3//POuDnC4abxRfNEVCjFRt25dmz59unXp0sU102sWqI8++ih0N+5ly5bZOeeck+MUn0BRQVcoFKX7A+U2Rk2vf//994VWJiA7jf/56aefaEUroWixQEzorppHH310KGSouT78hjhHHXWUbdu2LYYlBP7P448/ftjXFYyBomD9+vWxLgKQK65nl2wEC8REVlaWu2oRpN/Dr7QxMxSKikcffTTXdRSEgVhTV9Kff/7Z3X076IUXXrBRo0bZnj177LzzzrMnnnjCypcvH9NyAvw/vuQiWKBI9AXO3g9YN9ADigIGGqK4GDNmjJ166qmhYLFq1Sq76qqr7IorrrDmzZu7qWfr1Kljo0ePjnVREefUYyG3cME0ycUTYyxQZPsCC5U6xNq+ffvsww8/DFXWdFPHjIyM0OtlypSxu+66y3XnA2Kpdu3absKL9u3bu+eaAGPBggW2aNEi9/yVV15xrRfffPNNjEuKeKYJWsaPH28pKSmHXU+Tu6D4ocUCMUFfYBQXakmbNWtWKFhMmDDBjj32WHd34+DNnNLS0mzo0KExLini3a+//mqpqamh5woVZ5xxRui5bp63cePGGJUO+P8uueQSBm+XUKViXQDE9ziLyZMnuwrbcccdZy1btrRzzz3X9QmmIQ1FxbRp0+yaa66JWKYZzXQzRz3UvURXgoFYU6gItvLq5njB+wQFqYtp2bJlY1hCgPEVJR3BAjGh4HD22Wfb1Vdf7WbVUajQVWC1ZKg/8Pnnnx/rIgLO2rVr3fkZpC5PasoP6tChA11LUCToJqPDhw+3hQsXui57uk/AySefHHr9yy+/tMaNG8e0jAAXDks2ukIhZt1L9D+/uXPnusGG4XQ/C81eopaL/v37x6yMQPAu8eFjKrJPg6yWt/DXgVgZO3asXXDBBe7+QJoYQzci0923g9RC3KNHj5iWEdC/mSi5CBaIiZdeesn+9re/HRIqpFu3bu6qm7qgECwQa3/4wx/sq6++smOOOSbq67oKrHWAWNOseh9//LGlp6e7YBE+pbeoy174XbkBIL/RFQoxocpYr169cnxdAw51R2OgKHQvGTlypJsdKrvffvvNTfF55plnxqRsQDSabSd7qJBq1apFtGAAQH5julnEhP7n9sMPP7jpEaPZtGmTNWzYkC4mKBJ3iW/Tpo07ZwcPHhy6Y/yaNWvcDFG6B8vnn38eMRsPAADxiGCBmNDVtM2bN1vNmjVzrMzpRk6ZmZmFXjYgO820c91119mcOXNCAw81s8npp59uTz75pDVq1CjWRQQAIOYIFogJzaqj7k7ly5eP+rpaKmbPnk2wQJGiO8Fqlihp0qSJ61oCAAD+D8ECMTFw4MA8rTdlypQCLwsAAAD8ESwAAAAAeGNWKAAAAADeCBYAAAAAvBEsAAAAAHgjWAAAAADwRrAAAAAA4I1gAQAAAMAbwQIAAACAN4IFAAAAAPP1/wB/plk7I93aEwAAAABJRU5ErkJggg==”, “text/plain”: [

“<Figure size 800x500 with 1 Axes>”

]

}, “metadata”: {}, “output_type”: “display_data”

}

], “source”: [

“ensemble_df = pd.DataFrame(n”, “ {name: w for name, w in result.ensembles.items()}n”, “)n”, “n”, “fig, ax = plt.subplots(figsize=(8, 5))n”, “ensemble_df.plot.bar(ax=ax, width=0.7)n”, “ax.set_ylabel("Weight")n”, “ax.set_title("Ensemble Portfolios: Average vs Stack")n”, “ax.legend(title="Method")n”, “fig.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.12.9”

}

}, “nbformat”: 4, “nbformat_minor”: 5

}