{ "cells": [ { "cell_type": "markdown", "id": "3657705c", "metadata": {}, "source": [ "# Mean-Variance Data Preparation" ] }, { "cell_type": "markdown", "id": "9e135fd4", "metadata": {}, "source": [ "## Import time series data" ] }, { "cell_type": "code", "execution_count": 1, "id": "ef31b229", "metadata": { "execution": { "iopub.execute_input": "2025-01-31T10:05:44.552541Z", "iopub.status.busy": "2025-01-31T10:05:44.552311Z", "iopub.status.idle": "2025-01-31T10:05:45.314273Z", "shell.execute_reply": "2025-01-31T10:05:45.313528Z" }, "nbsphinx": "hidden" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Requirement already satisfied: numpy in /opt/hostedtoolcache/Python/3.11.11/x64/lib/python3.11/site-packages (2.2.2)\r\n", "Requirement already satisfied: scipy in /opt/hostedtoolcache/Python/3.11.11/x64/lib/python3.11/site-packages (1.15.1)\r\n", "Requirement already satisfied: gurobipy in /opt/hostedtoolcache/Python/3.11.11/x64/lib/python3.11/site-packages (11.0.3)\r\n", "Requirement already satisfied: pandas in /opt/hostedtoolcache/Python/3.11.11/x64/lib/python3.11/site-packages (2.2.3)\r\n", "Requirement already satisfied: matplotlib in /opt/hostedtoolcache/Python/3.11.11/x64/lib/python3.11/site-packages (3.10.0)\r\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Requirement already satisfied: python-dateutil>=2.8.2 in /opt/hostedtoolcache/Python/3.11.11/x64/lib/python3.11/site-packages (from pandas) (2.9.0.post0)\r\n", "Requirement already satisfied: pytz>=2020.1 in /opt/hostedtoolcache/Python/3.11.11/x64/lib/python3.11/site-packages (from pandas) (2025.1)\r\n", "Requirement already satisfied: tzdata>=2022.7 in /opt/hostedtoolcache/Python/3.11.11/x64/lib/python3.11/site-packages (from pandas) (2025.1)\r\n", "Requirement already satisfied: contourpy>=1.0.1 in /opt/hostedtoolcache/Python/3.11.11/x64/lib/python3.11/site-packages (from matplotlib) (1.3.1)\r\n", "Requirement already satisfied: cycler>=0.10 in /opt/hostedtoolcache/Python/3.11.11/x64/lib/python3.11/site-packages (from matplotlib) (0.12.1)\r\n", "Requirement already satisfied: fonttools>=4.22.0 in /opt/hostedtoolcache/Python/3.11.11/x64/lib/python3.11/site-packages (from matplotlib) (4.55.8)\r\n", "Requirement already satisfied: kiwisolver>=1.3.1 in /opt/hostedtoolcache/Python/3.11.11/x64/lib/python3.11/site-packages (from matplotlib) (1.4.8)\r\n", "Requirement already satisfied: packaging>=20.0 in /opt/hostedtoolcache/Python/3.11.11/x64/lib/python3.11/site-packages (from matplotlib) (24.2)\r\n", "Requirement already satisfied: pillow>=8 in /opt/hostedtoolcache/Python/3.11.11/x64/lib/python3.11/site-packages (from matplotlib) (11.1.0)\r\n", "Requirement already satisfied: pyparsing>=2.3.1 in /opt/hostedtoolcache/Python/3.11.11/x64/lib/python3.11/site-packages (from matplotlib) (3.2.1)\r\n", "Requirement already satisfied: six>=1.5 in /opt/hostedtoolcache/Python/3.11.11/x64/lib/python3.11/site-packages (from python-dateutil>=2.8.2->pandas) (1.17.0)\r\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Note: you may need to restart the kernel to use updated packages.\n" ] } ], "source": [ "# Install dependencies\n", "%pip install numpy scipy gurobipy pandas matplotlib" ] }, { "cell_type": "code", "execution_count": 2, "id": "ca6c9e2f", "metadata": { "execution": { "iopub.execute_input": "2025-01-31T10:05:45.316410Z", "iopub.status.busy": "2025-01-31T10:05:45.316207Z", "iopub.status.idle": "2025-01-31T10:05:45.728385Z", "shell.execute_reply": "2025-01-31T10:05:45.727812Z" } }, "outputs": [], "source": [ "import pandas as pd\n", "import numpy as np\n", "import scipy.linalg as la" ] }, { "cell_type": "markdown", "id": "93d4a2eb", "metadata": {}, "source": [ "The primary data used for mean-variance portfolio analysis are _estimates_ of the return and risk of the involved assets. Assuming that the excess returns of the assets are normally distributed, we need to estimate the parameters of the underlying distribution. The methods used for this vary greatly and depend on the nature of the available data. Commonly used return/risk models are:\n", "\n", "1. Estimates from time series\n", "2. Single-factor models such as CAPM\n", "3. Commercial multiple-factor models like from Axioma, Barra or others\n", "\n", "Our primary goal here is to generate sensible, realistic data for demonstrating the modeling and solving features of Gurobi. In order to keep things simple, we will discuss a simplistic variation of option 1 from above and reuse this data through most of our examples." ] }, { "cell_type": "markdown", "id": "fcd9cffd", "metadata": {}, "source": [ "The starting point for our estimators are the weekly closing values for a set of 462 stocks from the S&P500 index, collected over a time span of ten years:" ] }, { "cell_type": "code", "execution_count": 3, "id": "9c651267", "metadata": { "execution": { "iopub.execute_input": "2025-01-31T10:05:45.731104Z", "iopub.status.busy": "2025-01-31T10:05:45.730813Z", "iopub.status.idle": "2025-01-31T10:05:45.750368Z", "shell.execute_reply": "2025-01-31T10:05:45.749669Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " | APTV | \n", "DVN | \n", "HSY | \n", "CAG | \n", "HST | \n", "LUV | \n", "MMC | \n", "BA | \n", "VRSK | \n", "TSLA | \n", "... | \n", "GL | \n", "CPB | \n", "STLD | \n", "BG | \n", "TDG | \n", "AEE | \n", "AAPL | \n", "AIZ | \n", "UNP | \n", "K | \n", "
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2013-01-07 | \n", "29.253906 | \n", "37.565445 | \n", "57.688988 | \n", "16.892731 | \n", "11.112709 | \n", "9.571073 | \n", "28.727692 | \n", "63.796139 | \n", "51.355377 | \n", "2.289333 | \n", "... | \n", "31.923758 | \n", "26.039112 | \n", "11.071469 | \n", "55.641228 | \n", "76.824593 | \n", "21.690004 | \n", "16.001547 | \n", "28.292595 | \n", "50.840179 | \n", "36.513779 | \n", "
2013-01-14 | \n", "28.817282 | \n", "38.202770 | \n", "57.806736 | \n", "16.965885 | \n", "11.456966 | \n", "10.055566 | \n", "28.361572 | \n", "62.120152 | \n", "52.218086 | \n", "2.194000 | \n", "... | \n", "32.215347 | \n", "25.665024 | \n", "11.382249 | \n", "55.746841 | \n", "74.700508 | \n", "21.788601 | \n", "15.325012 | \n", "28.348913 | \n", "51.520897 | \n", "36.726971 | \n", "
2013-01-21 | \n", "29.330509 | \n", "38.431908 | \n", "59.792229 | \n", "17.483582 | \n", "11.395001 | \n", "10.128694 | \n", "28.304636 | \n", "62.296135 | \n", "52.189018 | \n", "2.260000 | \n", "... | \n", "32.464428 | \n", "26.156462 | \n", "11.584254 | \n", "57.157295 | \n", "74.183243 | \n", "22.091415 | \n", "14.841517 | \n", "29.201626 | \n", "51.987900 | \n", "36.843266 | \n", "
2013-01-28 | \n", "29.606276 | \n", "38.875881 | \n", "60.592682 | \n", "17.911243 | \n", "11.567130 | \n", "10.384659 | \n", "28.564873 | \n", "62.011208 | \n", "52.848152 | \n", "2.346000 | \n", "... | \n", "33.065845 | \n", "26.589228 | \n", "11.654181 | \n", "58.703533 | \n", "75.316818 | \n", "22.429447 | \n", "13.435313 | \n", "30.528965 | \n", "52.585495 | \n", "37.579758 | \n", "
2013-02-04 | \n", "29.613934 | \n", "40.787815 | \n", "61.047863 | \n", "18.316059 | \n", "11.298610 | \n", "10.220111 | \n", "28.654951 | \n", "61.717922 | \n", "53.129269 | \n", "2.500667 | \n", "... | \n", "33.642952 | \n", "26.523214 | \n", "11.747411 | \n", "59.254131 | \n", "74.529922 | \n", "22.830845 | \n", "13.509834 | \n", "30.697912 | \n", "51.912697 | \n", "37.534512 | \n", "
5 rows × 462 columns
\n", "\n", " | APTV | \n", "DVN | \n", "HSY | \n", "CAG | \n", "HST | \n", "LUV | \n", "MMC | \n", "BA | \n", "VRSK | \n", "TSLA | \n", "... | \n", "GL | \n", "CPB | \n", "STLD | \n", "BG | \n", "TDG | \n", "AEE | \n", "AAPL | \n", "AIZ | \n", "UNP | \n", "K | \n", "
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2013-01-14 | \n", "-1.492534 | \n", "1.696573 | \n", "0.204109 | \n", "0.433053 | \n", "3.097871 | \n", "5.062058 | \n", "-1.274448 | \n", "-2.627098 | \n", "1.679881 | \n", "-4.164230 | \n", "... | \n", "0.913394 | \n", "-1.436640 | \n", "2.807031 | \n", "0.189812 | \n", "-2.764850 | \n", "0.454571 | \n", "-4.227933 | \n", "0.199057 | \n", "1.338936 | \n", "0.583867 | \n", "
2013-01-21 | \n", "1.780971 | \n", "0.599793 | \n", "3.434708 | \n", "3.051396 | \n", "-0.540850 | \n", "0.727237 | \n", "-0.200751 | \n", "0.283295 | \n", "-0.055667 | \n", "3.008203 | \n", "... | \n", "0.773174 | \n", "1.914816 | \n", "1.774741 | \n", "2.530105 | \n", "-0.692452 | \n", "1.389784 | \n", "-3.154939 | \n", "3.007920 | \n", "0.906434 | \n", "0.316647 | \n", "
2013-01-28 | \n", "0.940203 | \n", "1.155221 | \n", "1.338724 | \n", "2.446077 | \n", "1.510563 | \n", "2.527130 | \n", "0.919414 | \n", "-0.457376 | \n", "1.262974 | \n", "3.805308 | \n", "... | \n", "1.852543 | \n", "1.654528 | \n", "0.603640 | \n", "2.705233 | \n", "1.528075 | \n", "1.530150 | \n", "-9.474801 | \n", "4.545429 | \n", "1.149489 | \n", "1.998987 | \n", "
2013-02-04 | \n", "0.025866 | \n", "4.918046 | \n", "0.751215 | \n", "2.260120 | \n", "-2.321409 | \n", "-1.584529 | \n", "0.315347 | \n", "-0.472955 | \n", "0.531932 | \n", "6.592802 | \n", "... | \n", "1.745325 | \n", "-0.248271 | \n", "0.799964 | \n", "0.937930 | \n", "-1.044781 | \n", "1.789601 | \n", "0.554666 | \n", "0.553400 | \n", "-1.279437 | \n", "-0.120400 | \n", "
2013-02-11 | \n", "-0.905307 | \n", "1.983842 | \n", "2.866628 | \n", "2.136201 | \n", "0.670313 | \n", "0.804988 | \n", "3.286669 | \n", "3.014293 | \n", "-0.948740 | \n", "1.652877 | \n", "... | \n", "-0.631966 | \n", "1.963475 | \n", "0.529126 | \n", "-8.197570 | \n", "2.953356 | \n", "0.586077 | \n", "3.398002 | \n", "0.602701 | \n", "0.632769 | \n", "0.688484 | \n", "
5 rows × 462 columns
\n", "