{
 "cells": [
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2024-11-14T16:35:10.621604Z",
     "start_time": "2024-11-14T16:35:10.207160Z"
    }
   },
   "source": [
    "import yfinance as yf\n",
    "import pandas as pd\n",
    "import numpy as np"
   ],
   "outputs": [],
   "execution_count": 4
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-14T16:35:13.813794Z",
     "start_time": "2024-11-14T16:35:12.131350Z"
    }
   },
   "cell_type": "code",
   "source": [
    "Tickers = [\"^SPX\"]\n",
    "start_input = \"2010-01-01\"\n",
    "end_input = \"2024-10-01\"\n",
    "\n",
    "S = yf.Ticker(Tickers[0]).history(start=start_input, end=end_input)\n",
    "display(S.head())"
   ],
   "id": "b9829b865bba9017",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "                                  Open         High          Low        Close  \\\n",
       "Date                                                                            \n",
       "2010-01-04 00:00:00-05:00  1116.560059  1133.869995  1116.560059  1132.989990   \n",
       "2010-01-05 00:00:00-05:00  1132.660034  1136.630005  1129.660034  1136.520020   \n",
       "2010-01-06 00:00:00-05:00  1135.709961  1139.189941  1133.949951  1137.140015   \n",
       "2010-01-07 00:00:00-05:00  1136.270020  1142.459961  1131.319946  1141.689941   \n",
       "2010-01-08 00:00:00-05:00  1140.520020  1145.390015  1136.219971  1144.979980   \n",
       "\n",
       "                               Volume  Dividends  Stock Splits  \n",
       "Date                                                            \n",
       "2010-01-04 00:00:00-05:00  3991400000        0.0           0.0  \n",
       "2010-01-05 00:00:00-05:00  2491020000        0.0           0.0  \n",
       "2010-01-06 00:00:00-05:00  4972660000        0.0           0.0  \n",
       "2010-01-07 00:00:00-05:00  5270680000        0.0           0.0  \n",
       "2010-01-08 00:00:00-05:00  4389590000        0.0           0.0  "
      ],
      "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>Open</th>\n",
       "      <th>High</th>\n",
       "      <th>Low</th>\n",
       "      <th>Close</th>\n",
       "      <th>Volume</th>\n",
       "      <th>Dividends</th>\n",
       "      <th>Stock Splits</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2010-01-04 00:00:00-05:00</th>\n",
       "      <td>1116.560059</td>\n",
       "      <td>1133.869995</td>\n",
       "      <td>1116.560059</td>\n",
       "      <td>1132.989990</td>\n",
       "      <td>3991400000</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2010-01-05 00:00:00-05:00</th>\n",
       "      <td>1132.660034</td>\n",
       "      <td>1136.630005</td>\n",
       "      <td>1129.660034</td>\n",
       "      <td>1136.520020</td>\n",
       "      <td>2491020000</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2010-01-06 00:00:00-05:00</th>\n",
       "      <td>1135.709961</td>\n",
       "      <td>1139.189941</td>\n",
       "      <td>1133.949951</td>\n",
       "      <td>1137.140015</td>\n",
       "      <td>4972660000</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2010-01-07 00:00:00-05:00</th>\n",
       "      <td>1136.270020</td>\n",
       "      <td>1142.459961</td>\n",
       "      <td>1131.319946</td>\n",
       "      <td>1141.689941</td>\n",
       "      <td>5270680000</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2010-01-08 00:00:00-05:00</th>\n",
       "      <td>1140.520020</td>\n",
       "      <td>1145.390015</td>\n",
       "      <td>1136.219971</td>\n",
       "      <td>1144.979980</td>\n",
       "      <td>4389590000</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 5
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-14T16:41:20.086199Z",
     "start_time": "2024-11-14T16:41:19.960219Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from matplotlib import pyplot as plt\n",
    "\n",
    "S[\"Close\"].plot(label=\"SPX\")\n",
    "plt.title(\"Prices SPX\")\n",
    "plt.grid()\n",
    "plt.legend()\n",
    "plt.show()"
   ],
   "id": "c9cd06bad60fb4cd",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "[encoded data, 39696 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 10
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "There is a first jump in 2020 due to the covid and a second one in 2022 due to the war in Ukraine.",
   "id": "d9ff78437c5acd79"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-14T16:50:28.028431Z",
     "start_time": "2024-11-14T16:50:27.977810Z"
    }
   },
   "cell_type": "code",
   "source": [
    "SPY = yf.Ticker(\"^GSPC\")\n",
    "print(\"shortName:\", SPY.info[\"shortName\"])\n",
    "print(\"currency:\", SPY.info[\"currency\"])\n",
    "print(\"previousClose:\", SPY.info[\"previousClose\"])\n",
    "print(\"open:\", SPY.info[\"open\"])\n",
    "print(\"dayLow:\", SPY.info[\"dayLow\"])\n",
    "print(\"dayHigh:\", SPY.info[\"dayHigh\"])\n",
    "print(\"bid:\", SPY.info[\"bid\"])\n",
    "print(\"ask:\", SPY.info[\"ask\"])\n",
    "print(\"fiftyTwoWeekLow:\", SPY.info[\"fiftyTwoWeekLow\"])\n",
    "print(\"fiftyTwoWeekHigh:\", SPY.info[\"fiftyTwoWeekHigh\"])\n",
    "\n",
    "print(SPY.info.keys())"
   ],
   "id": "b6dc4cd7bc49b198",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "shortName: S&P 500\n",
      "currency: USD\n",
      "previousClose: 5985.38\n",
      "open: 5989.68\n",
      "dayLow: 5967.09\n",
      "dayHigh: 5993.88\n",
      "bid: 5973.44\n",
      "ask: 5976.5\n",
      "fiftyTwoWeekLow: 4487.83\n",
      "fiftyTwoWeekHigh: 6017.31\n",
      "dict_keys(['maxAge', 'priceHint', 'previousClose', 'open', 'dayLow', 'dayHigh', 'regularMarketPreviousClose', 'regularMarketOpen', 'regularMarketDayLow', 'regularMarketDayHigh', 'volume', 'regularMarketVolume', 'averageVolume', 'averageVolume10days', 'averageDailyVolume10Day', 'bid', 'ask', 'fiftyTwoWeekLow', 'fiftyTwoWeekHigh', 'fiftyDayAverage', 'twoHundredDayAverage', 'currency', 'exchange', 'quoteType', 'symbol', 'underlyingSymbol', 'shortName', 'longName', 'firstTradeDateEpochUtc', 'timeZoneFullName', 'timeZoneShortName', 'uuid', 'messageBoardId', 'gmtOffSetMilliseconds', 'trailingPegRatio'])\n"
     ]
    }
   ],
   "execution_count": 13
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-14T16:58:05.667830Z",
     "start_time": "2024-11-14T16:58:05.592788Z"
    }
   },
   "cell_type": "code",
   "source": [
    "Amazon = yf.Ticker(\"AMZN\")\n",
    "print(Amazon.info.keys())"
   ],
   "id": "b76cc24f25dab3ea",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_keys(['address1', 'city', 'state', 'zip', 'country', 'phone', 'website', 'industry', 'industryKey', 'industryDisp', 'sector', 'sectorKey', 'sectorDisp', 'longBusinessSummary', 'fullTimeEmployees', 'companyOfficers', 'auditRisk', 'boardRisk', 'compensationRisk', 'shareHolderRightsRisk', 'overallRisk', 'governanceEpochDate', 'compensationAsOfEpochDate', 'irWebsite', 'maxAge', 'priceHint', 'previousClose', 'open', 'dayLow', 'dayHigh', 'regularMarketPreviousClose', 'regularMarketOpen', 'regularMarketDayLow', 'regularMarketDayHigh', 'beta', 'trailingPE', 'forwardPE', 'volume', 'regularMarketVolume', 'averageVolume', 'averageVolume10days', 'averageDailyVolume10Day', 'bid', 'ask', 'bidSize', 'askSize', 'marketCap', 'fiftyTwoWeekLow', 'fiftyTwoWeekHigh', 'priceToSalesTrailing12Months', 'fiftyDayAverage', 'twoHundredDayAverage', 'currency', 'enterpriseValue', 'profitMargins', 'floatShares', 'sharesOutstanding', 'sharesShort', 'sharesShortPriorMonth', 'sharesShortPreviousMonthDate', 'dateShortInterest', 'sharesPercentSharesOut', 'heldPercentInsiders', 'heldPercentInstitutions', 'shortRatio', 'shortPercentOfFloat', 'impliedSharesOutstanding', 'bookValue', 'priceToBook', 'lastFiscalYearEnd', 'nextFiscalYearEnd', 'mostRecentQuarter', 'earningsQuarterlyGrowth', 'netIncomeToCommon', 'trailingEps', 'forwardEps', 'lastSplitFactor', 'lastSplitDate', 'enterpriseToRevenue', 'enterpriseToEbitda', '52WeekChange', 'SandP52WeekChange', 'exchange', 'quoteType', 'symbol', 'underlyingSymbol', 'shortName', 'longName', 'firstTradeDateEpochUtc', 'timeZoneFullName', 'timeZoneShortName', 'uuid', 'messageBoardId', 'gmtOffSetMilliseconds', 'currentPrice', 'targetHighPrice', 'targetLowPrice', 'targetMeanPrice', 'targetMedianPrice', 'recommendationMean', 'recommendationKey', 'numberOfAnalystOpinions', 'totalCash', 'totalCashPerShare', 'ebitda', 'totalDebt', 'quickRatio', 'currentRatio', 'totalRevenue', 'debtToEquity', 'revenuePerShare', 'returnOnAssets', 'returnOnEquity', 'freeCashflow', 'operatingCashflow', 'earningsGrowth', 'revenueGrowth', 'grossMargins', 'ebitdaMargins', 'operatingMargins', 'financialCurrency', 'trailingPegRatio'])\n"
     ]
    }
   ],
   "execution_count": 27
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-14T18:53:05.789879Z",
     "start_time": "2024-11-14T18:53:05.360311Z"
    }
   },
   "cell_type": "code",
   "source": [
    "Apple = yf.Ticker(\"AAPL\")\n",
    "print(Apple.info.keys())\n",
    "\n",
    "Apple.dividends[\"1970-01-01\":\"2024-10-01\"].plot()"
   ],
   "id": "be13381cff28863e",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_keys(['address1', 'city', 'state', 'zip', 'country', 'phone', 'website', 'industry', 'industryKey', 'industryDisp', 'sector', 'sectorKey', 'sectorDisp', 'longBusinessSummary', 'fullTimeEmployees', 'companyOfficers', 'auditRisk', 'boardRisk', 'compensationRisk', 'shareHolderRightsRisk', 'overallRisk', 'governanceEpochDate', 'compensationAsOfEpochDate', 'irWebsite', 'maxAge', 'priceHint', 'previousClose', 'open', 'dayLow', 'dayHigh', 'regularMarketPreviousClose', 'regularMarketOpen', 'regularMarketDayLow', 'regularMarketDayHigh', 'dividendRate', 'dividendYield', 'exDividendDate', 'payoutRatio', 'fiveYearAvgDividendYield', 'beta', 'trailingPE', 'forwardPE', 'volume', 'regularMarketVolume', 'averageVolume', 'averageVolume10days', 'averageDailyVolume10Day', 'bid', 'ask', 'bidSize', 'askSize', 'marketCap', 'fiftyTwoWeekLow', 'fiftyTwoWeekHigh', 'priceToSalesTrailing12Months', 'fiftyDayAverage', 'twoHundredDayAverage', 'trailingAnnualDividendRate', 'trailingAnnualDividendYield', 'currency', 'enterpriseValue', 'profitMargins', 'floatShares', 'sharesOutstanding', 'sharesShort', 'sharesShortPriorMonth', 'sharesShortPreviousMonthDate', 'dateShortInterest', 'sharesPercentSharesOut', 'heldPercentInsiders', 'heldPercentInstitutions', 'shortRatio', 'shortPercentOfFloat', 'impliedSharesOutstanding', 'bookValue', 'priceToBook', 'lastFiscalYearEnd', 'nextFiscalYearEnd', 'mostRecentQuarter', 'earningsQuarterlyGrowth', 'netIncomeToCommon', 'trailingEps', 'forwardEps', 'lastSplitFactor', 'lastSplitDate', 'enterpriseToRevenue', 'enterpriseToEbitda', '52WeekChange', 'SandP52WeekChange', 'lastDividendValue', 'lastDividendDate', 'exchange', 'quoteType', 'symbol', 'underlyingSymbol', 'shortName', 'longName', 'firstTradeDateEpochUtc', 'timeZoneFullName', 'timeZoneShortName', 'uuid', 'messageBoardId', 'gmtOffSetMilliseconds', 'currentPrice', 'targetHighPrice', 'targetLowPrice', 'targetMeanPrice', 'targetMedianPrice', 'recommendationMean', 'recommendationKey', 'numberOfAnalystOpinions', 'totalCash', 'totalCashPerShare', 'ebitda', 'totalDebt', 'quickRatio', 'currentRatio', 'totalRevenue', 'debtToEquity', 'revenuePerShare', 'returnOnAssets', 'returnOnEquity', 'freeCashflow', 'operatingCashflow', 'earningsGrowth', 'revenueGrowth', 'grossMargins', 'ebitdaMargins', 'operatingMargins', 'financialCurrency', 'trailingPegRatio'])\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='Date'>"
      ]
     },
     "execution_count": 113,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "[encoded data, 23700 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 113
  },
  {
   "metadata": {},
   "cell_type": "raw",
   "source": "# Mean Variance Analysis",
   "id": "1502803e92dc1956"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-14T18:56:43.437695Z",
     "start_time": "2024-11-14T18:56:43.419618Z"
    }
   },
   "cell_type": "code",
   "source": [
    "Tickers = [\"ALV.DE\", \"BMW.DE\"]  # Alliance & BMW Stock\n",
    "start_input = \"2024-01-01\"\n",
    "end_input = \"2024-10-01\"\n",
    "\n",
    "S = pd.DataFrame()\n",
    "\n",
    "for t in Tickers:\n",
    "    S[t] = yf.Ticker(t).history(start=start_input, end=end_input)[\"Close\"]\n",
    "\n",
    "print(S.head())\n",
    "print(S.tail())\n",
    "print(S.shape)"
   ],
   "id": "55ab9b7066bff14c",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                               ALV.DE     BMW.DE\n",
      "Date                                            \n",
      "2024-01-02 00:00:00+01:00  232.545197  95.845306\n",
      "2024-01-03 00:00:00+01:00  230.266739  93.707672\n",
      "2024-01-04 00:00:00+01:00  233.067337  95.110786\n",
      "2024-01-05 00:00:00+01:00  231.548370  94.790619\n",
      "2024-01-08 00:00:00+01:00  232.165451  95.299126\n",
      "                               ALV.DE     BMW.DE\n",
      "Date                                            \n",
      "2024-09-24 00:00:00+02:00  295.700012  78.120003\n",
      "2024-09-25 00:00:00+02:00  294.100006  75.660004\n",
      "2024-09-26 00:00:00+02:00  295.799988  78.540001\n",
      "2024-09-27 00:00:00+02:00  296.500000  81.139999\n",
      "2024-09-30 00:00:00+02:00  295.000000  79.180000\n",
      "(192, 2)\n"
     ]
    }
   ],
   "execution_count": 143
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-14T18:56:43.720652Z",
     "start_time": "2024-11-14T18:56:43.717111Z"
    }
   },
   "cell_type": "code",
   "source": [
    "R = S / S.shift() - 1\n",
    "R = R[1:]\n",
    "mean_d = R.mean()\n",
    "covar_d = R.cov()\n",
    "corr = R.corr()"
   ],
   "id": "13364c6369726018",
   "outputs": [],
   "execution_count": 144
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-14T18:56:43.925286Z",
     "start_time": "2024-11-14T18:56:43.922807Z"
    }
   },
   "cell_type": "code",
   "source": [
    "mean = mean_d * 252\n",
    "covar = covar_d * 252\n",
    "std = np.sqrt(np.diag(covar))\n",
    "# 252 is the annual working days count"
   ],
   "id": "c44b402b6708dd31",
   "outputs": [],
   "execution_count": 145
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-14T18:56:44.134395Z",
     "start_time": "2024-11-14T18:56:44.131229Z"
    }
   },
   "cell_type": "code",
   "source": [
    "print(\"Mean:\\n\")\n",
    "print(mean)\n",
    "print(\"\\nCovariance:\\n\")\n",
    "print(covar)\n",
    "print(\"\\nStandard Deviation:\\n\")\n",
    "print(std)\n",
    "print(\"\\nCorrelation:\\n\")\n",
    "print(corr)"
   ],
   "id": "5962c9633cf174f",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Mean:\n",
      "\n",
      "ALV.DE    0.325187\n",
      "BMW.DE   -0.215868\n",
      "dtype: float64\n",
      "\n",
      "Covariance:\n",
      "\n",
      "          ALV.DE    BMW.DE\n",
      "ALV.DE  0.022292  0.012378\n",
      "BMW.DE  0.012378  0.071163\n",
      "\n",
      "Standard Deviation:\n",
      "\n",
      "[0.14930589 0.26676463]\n",
      "\n",
      "Correlation:\n",
      "\n",
      "          ALV.DE    BMW.DE\n",
      "ALV.DE  1.000000  0.310781\n",
      "BMW.DE  0.310781  1.000000\n"
     ]
    }
   ],
   "execution_count": 146
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-14T18:56:44.433173Z",
     "start_time": "2024-11-14T18:56:44.431212Z"
    }
   },
   "cell_type": "code",
   "source": "from numpy import linalg as LA",
   "id": "9260dbd9c9cc7363",
   "outputs": [],
   "execution_count": 147
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-14T18:56:44.763281Z",
     "start_time": "2024-11-14T18:56:44.758797Z"
    }
   },
   "cell_type": "code",
   "source": [
    "r = 0.05\n",
    "d = len(Tickers)\n",
    "vec1 = np.linspace(1, 1, d)\n",
    "sigma = covar\n",
    "inv_sigma = LA.inv(sigma)\n",
    "\n",
    "a = vec1.T.dot(inv_sigma).dot(vec1)\n",
    "b = mean.T.dot(inv_sigma).dot(vec1)"
   ],
   "id": "e115dfab1684d913",
   "outputs": [],
   "execution_count": 148
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-14T18:56:45.086748Z",
     "start_time": "2024-11-14T18:56:45.079059Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# Portfolio of minimal variance\n",
    "pi_a = inv_sigma.dot(vec1) / a\n",
    "sd_a = 1 / np.sqrt(a)  # Standard deviation\n",
    "m_a = b / a  # Expected return\n",
    "\n",
    "print(\"Check mean equality:\", m_a, pi_a.T.dot(mean))\n",
    "print(\"Check var equality:\", sd_a ** 2, pi_a.T.dot(sigma).dot(pi_a))\n",
    "print()\n",
    "\n",
    "# Self financing portfolio\n",
    "m_w = np.sqrt((mean - b / a * vec1).T.dot(inv_sigma).dot(mean - b / a * vec1))  # Expected return\n",
    "\n",
    "# Tangent portfolio\n",
    "pi_T = inv_sigma.dot(mean - r * vec1) / (b - r * a)\n",
    "sd_T = np.sqrt(pi_T.T.dot(sigma).dot(pi_T))  # Variance\n",
    "m_T = pi_T.T.dot(mean)  # expected return\n",
    "\n",
    "print(\"Portfolio of minimal variance:\")\n",
    "print(f\"Expected return m_a: {m_a}\")\n",
    "print(f\"Standard deviation sd_a: {sd_a}\")\n",
    "print(f\"Allocation pi_a: {pi_a}\")\n",
    "print(f\"Sharpe ration pi_a: {(m_a - r) / sd_a}\")\n",
    "print()\n",
    "print(\"Tangent portfolio:\")\n",
    "print(f\"Expected return m_T: {m_T}\")\n",
    "print(f\"Standard deviation sd_T: {sd_T}\")\n",
    "print(f\"Allocation pi_T: {pi_T}\")\n",
    "print(f\"Sharpe ration pi_T: {(m_T - r) / sd_T}\")"
   ],
   "id": "64a3ac84d552ed55",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Check mean equality: 0.24710709858148827 0.24710709858148827\n",
      "Check var equality: 0.02086155601274889 0.02086155601274888\n",
      "\n",
      "Portfolio of minimal variance:\n",
      "Expected return m_a: 0.24710709858148827\n",
      "Standard deviation sd_a: 0.14443530043846237\n",
      "Allocation pi_a: [0.85568955 0.14431045]\n",
      "Sharpe ration pi_a: 1.3646739957830951\n",
      "\n",
      "Tangent portfolio:\n",
      "Expected return m_T: 0.6981063766853705\n",
      "Standard deviation sd_T: 0.2619059493450272\n",
      "Allocation pi_T: [ 1.68924511 -0.68924511]\n",
      "Sharpe ration pi_T: 2.4745767643161636\n"
     ]
    }
   ],
   "execution_count": 149
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-14T18:56:45.753370Z",
     "start_time": "2024-11-14T18:56:45.670383Z"
    }
   },
   "cell_type": "code",
   "source": [
    "np.random.seed(123)\n",
    "colors = np.random.rand(len(std))\n",
    "range_inf = np.min(mean) - 0.5\n",
    "range_sup = np.max(mean) + 1\n",
    "y = np.linspace(range_inf, range_sup, 50)\n",
    "x_1 = np.array([np.sqrt(((y - m_a) / m_w) ** 2 + sd_a ** 2)])  # Sigma values for the frontier\n",
    "x_2 = np.array([(y - r) / (m_T - r) * sd_T])  # Sigma values for the Capital Market Line\n",
    "\n",
    "fix, ax = plt.subplots()\n",
    "\n",
    "plt.xlim(0, np.max(std) + 0.2)\n",
    "plt.plot(x_1[0], y, alpha=1)  # Frontier\n",
    "plt.plot(x_2[0], y, alpha=1)  # CML\n",
    "plt.legend([\"Frontier\", \"Capital Market Line\"], loc=2)\n",
    "plt.scatter(std, mean, c=colors, alpha=0.5)  # Plot the assets\n",
    "plt.xlabel('Annualised standard deviation')\n",
    "plt.ylabel('Annualised return')\n",
    "plt.grid()\n",
    "plt.scatter(sd_T, m_T, color='red', s=50, alpha=1)  # Tangent Portfolio\n",
    "ax.annotate('Tangent Portfolio', (sd_T, m_T))\n",
    "for i, t in enumerate(Tickers):\n",
    "    ax.annotate(t, (std[i], mean.iloc[i]))\n",
    "plt.show()"
   ],
   "id": "66268b2ce7129e8e",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "[encoded data, 52964 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 150
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": "",
   "id": "c35ff26ade565825"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
