{ "cells": [ { "cell_type": "markdown", "id": "421nv0mvomd", "metadata": {}, "source": [ "# Sector Allocation with Group Constraints\n", "\n", "This notebook shows how to enforce **sector-level allocation limits** using\n", "`Constraints.group_constraints`. We define a five-asset universe split into\n", "an Equity bucket (assets 0-1) and a Fixed-Income bucket (assets 2-4), then\n", "trace the variance-efficient frontier subject to those bounds." ] }, { "cell_type": "code", "execution_count": 1, "id": "f05euk6l3yu", "metadata": { "execution": { "iopub.execute_input": "2026-03-30T19:38:34.788540Z", "iopub.status.busy": "2026-03-30T19:38:34.788353Z", "iopub.status.idle": "2026-03-30T19:38:35.271715Z", "shell.execute_reply": "2026-03-30T19:38:35.271468Z" } }, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", "from pyvallocation import PortfolioWrapper, Constraints" ] }, { "cell_type": "markdown", "id": "x64unysue7", "metadata": {}, "source": [ "## Define expected returns and covariance\n", "\n", "Five assets with decreasing expected returns and heterogeneous volatilities." ] }, { "cell_type": "code", "execution_count": 2, "id": "dez873qfmv", "metadata": { "execution": { "iopub.execute_input": "2026-03-30T19:38:35.273077Z", "iopub.status.busy": "2026-03-30T19:38:35.272980Z", "iopub.status.idle": "2026-03-30T19:38:35.275217Z", "shell.execute_reply": "2026-03-30T19:38:35.275026Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Expected returns: [0.1 0.08 0.06 0.04 0.03]\n", "\n", "Covariance matrix:\n", " [[0.05 0.01 0.01 0.01 0.01 ]\n", " [0.01 0.04 0.01 0.01 0.01 ]\n", " [0.01 0.01 0.03 0.01 0.01 ]\n", " [0.01 0.01 0.01 0.025 0.01 ]\n", " [0.01 0.01 0.01 0.01 0.02 ]]\n" ] } ], "source": [ "assets = [\"US_Equity\", \"EU_Equity\", \"IG_Credit\", \"Govt_Bonds\", \"TIPS\"]\n", "\n", "mu = np.array([0.10, 0.08, 0.06, 0.04, 0.03])\n", "\n", "cov = np.eye(5) * 0.03 + 0.01\n", "np.fill_diagonal(cov, [0.05, 0.04, 0.03, 0.025, 0.02])\n", "\n", "print(\"Expected returns:\", mu)\n", "print(\"\\nCovariance matrix:\\n\", cov.round(4))" ] }, { "cell_type": "markdown", "id": "7wnyyp5t1fo", "metadata": {}, "source": [ "## Set up group constraints\n", "\n", "- **Equity** (assets 0-1): between 30% and 60%\n", "- **Fixed Income** (assets 2-4): between 30% and 70%\n", "- Each individual asset must stay between 5% and 40%." ] }, { "cell_type": "code", "execution_count": 3, "id": "x729esbxn5a", "metadata": { "execution": { "iopub.execute_input": "2026-03-30T19:38:35.276265Z", "iopub.status.busy": "2026-03-30T19:38:35.276207Z", "iopub.status.idle": "2026-03-30T19:38:35.277799Z", "shell.execute_reply": "2026-03-30T19:38:35.277593Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Constraints(long_only=True, total_weight=1.0, bounds=(0.05, 0.4), relative_bounds=None, group_constraints={'Equity': ([0, 1], 0.3, 0.6), 'Fixed Income': ([2, 3, 4], 0.3, 0.7)}, additional_G_h=None, additional_A_b=None)\n" ] } ], "source": [ "constraints = Constraints(\n", " group_constraints={\n", " \"Equity\": ([0, 1], 0.30, 0.60),\n", " \"Fixed Income\": ([2, 3, 4], 0.30, 0.70),\n", " },\n", " bounds=(0.05, 0.40),\n", ")\n", "\n", "print(constraints)" ] }, { "cell_type": "markdown", "id": "1f3efq4nqsb", "metadata": {}, "source": [ "## Compute the variance-efficient frontier" ] }, { "cell_type": "code", "execution_count": 4, "id": "x3kqhy5cb6", "metadata": { "execution": { "iopub.execute_input": "2026-03-30T19:38:35.278733Z", "iopub.status.busy": "2026-03-30T19:38:35.278679Z", "iopub.status.idle": "2026-03-30T19:38:35.340810Z", "shell.execute_reply": "2026-03-30T19:38:35.340517Z" } }, "outputs": [], "source": [ "wrapper = PortfolioWrapper.from_moments(mu, cov, constraints=constraints)\n", "frontier = wrapper.variance_frontier(num_portfolios=8)" ] }, { "cell_type": "markdown", "id": "2eqzq8vcz3k", "metadata": {}, "source": [ "## Inspect frontier weights: equity vs fixed-income split" ] }, { "cell_type": "code", "execution_count": 5, "id": "cp5r68pobu5", "metadata": { "execution": { "iopub.execute_input": "2026-03-30T19:38:35.342014Z", "iopub.status.busy": "2026-03-30T19:38:35.341949Z", "iopub.status.idle": "2026-03-30T19:38:35.344155Z", "shell.execute_reply": "2026-03-30T19:38:35.343882Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "=== Sector-Constrained Frontier ===\n", "\n", "P0: Equity=30.0% FI=70.0% Return=5.46% Vol=11.75%\n", "P1: Equity=32.9% FI=67.1% Return=5.78% Vol=11.85%\n", "P2: Equity=38.0% FI=62.0% Return=6.11% Vol=12.02%\n", "P3: Equity=43.0% FI=57.0% Return=6.44% Vol=12.25%\n", "P4: Equity=48.1% FI=51.9% Return=6.77% Vol=12.54%\n", "P5: Equity=53.2% FI=46.8% Return=7.09% Vol=12.88%\n", "P6: Equity=58.9% FI=41.1% Return=7.42% Vol=13.27%\n", "P7: Equity=60.0% FI=40.0% Return=7.75% Vol=13.95%\n" ] } ], "source": [ "print(\"=== Sector-Constrained Frontier ===\\n\")\n", "for i in range(frontier.weights.shape[1]):\n", " w = frontier.weights[:, i]\n", " eq = w[0] + w[1]\n", " fi = w[2] + w[3] + w[4]\n", " print(\n", " f\"P{i}: Equity={eq:.1%} FI={fi:.1%} \"\n", " f\"Return={frontier.returns[i]:.2%} \"\n", " f\"Vol={frontier.risks[i]:.2%}\"\n", " )" ] }, { "cell_type": "markdown", "id": "cn1u0a2s7t", "metadata": {}, "source": [ "## Visualise sector allocations across the frontier\n", "\n", "The stacked bar chart shows how the optimizer trades off equity and\n", "fixed-income exposure as it moves from low-risk to high-return portfolios." ] }, { "cell_type": "code", "execution_count": 6, "id": "r0yo1hozjn", "metadata": { "execution": { "iopub.execute_input": "2026-03-30T19:38:35.345158Z", "iopub.status.busy": "2026-03-30T19:38:35.345100Z", "iopub.status.idle": "2026-03-30T19:38:35.567068Z", "shell.execute_reply": "2026-03-30T19:38:35.566823Z" } }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "\n", "n_port = frontier.weights.shape[1]\n", "weight_df = pd.DataFrame(\n", " frontier.weights.T, columns=assets,\n", " index=[f\"P{i}\" for i in range(n_port)],\n", ")\n", "\n", "fig, ax = plt.subplots(figsize=(9, 5))\n", "weight_df.plot.bar(stacked=True, ax=ax, colormap=\"RdYlGn\")\n", "ax.set_ylabel(\"Weight\")\n", "ax.set_title(\"Sector Allocations Across the Frontier\")\n", "ax.legend(title=\"Asset\", bbox_to_anchor=(1.02, 1), loc=\"upper left\")\n", "ax.axhline(0.30, ls=\"--\", color=\"grey\", lw=0.8, label=\"Equity min (30%)\")\n", "ax.axhline(0.60, ls=\"--\", color=\"grey\", lw=0.8, label=\"Equity max (60%)\")\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 }