{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Downloading data\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import yfinance as yf\n",
    "from tqdm import tqdm\n",
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "tickers = [\"SAF.PA\", \"ATO.PA\", \"MC.PA\", \"AIR.PA\", \"RNO.PA\", \"HO.PA\", \"ENGI.PA\", \"CS.PA\", \"ENR.DE\", \"TOT\", \"CA.PA\", \"SU.PA\", \"BN.PA\", \"SIEGY\", \"AI.PA\", \"ML.PA\", \"AM.PA\", \"ORA.PA\",  \"FR0007052782.SG\"]\n",
    "period = \"2y\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[*********************100%***********************]  10 of 10 completed\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>AIR.PA</th>\n",
       "      <th>ATO.PA</th>\n",
       "      <th>CS.PA</th>\n",
       "      <th>ENGI.PA</th>\n",
       "      <th>ENR.DE</th>\n",
       "      <th>HO.PA</th>\n",
       "      <th>MC.PA</th>\n",
       "      <th>RNO.PA</th>\n",
       "      <th>SAF.PA</th>\n",
       "      <th>TOT</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",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2020-12-28</th>\n",
       "      <td>91.980003</td>\n",
       "      <td>75.300003</td>\n",
       "      <td>19.728001</td>\n",
       "      <td>12.900</td>\n",
       "      <td>29.730000</td>\n",
       "      <td>75.680000</td>\n",
       "      <td>504.000000</td>\n",
       "      <td>36.110001</td>\n",
       "      <td>119.949997</td>\n",
       "      <td>42.413864</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-12-29</th>\n",
       "      <td>93.070000</td>\n",
       "      <td>75.760002</td>\n",
       "      <td>19.736000</td>\n",
       "      <td>12.755</td>\n",
       "      <td>29.900000</td>\n",
       "      <td>76.320000</td>\n",
       "      <td>512.799988</td>\n",
       "      <td>36.255001</td>\n",
       "      <td>120.500000</td>\n",
       "      <td>42.512001</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-12-30</th>\n",
       "      <td>91.250000</td>\n",
       "      <td>75.339996</td>\n",
       "      <td>19.676001</td>\n",
       "      <td>12.695</td>\n",
       "      <td>30.000000</td>\n",
       "      <td>75.440002</td>\n",
       "      <td>513.099976</td>\n",
       "      <td>35.945000</td>\n",
       "      <td>119.000000</td>\n",
       "      <td>42.669998</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-12-31</th>\n",
       "      <td>89.779999</td>\n",
       "      <td>74.779999</td>\n",
       "      <td>19.511999</td>\n",
       "      <td>12.520</td>\n",
       "      <td>NaN</td>\n",
       "      <td>74.900002</td>\n",
       "      <td>510.899994</td>\n",
       "      <td>35.759998</td>\n",
       "      <td>115.949997</td>\n",
       "      <td>41.910000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-01-04</th>\n",
       "      <td>89.889999</td>\n",
       "      <td>76.120003</td>\n",
       "      <td>19.438000</td>\n",
       "      <td>12.805</td>\n",
       "      <td>30.129999</td>\n",
       "      <td>75.180000</td>\n",
       "      <td>512.099976</td>\n",
       "      <td>35.759998</td>\n",
       "      <td>116.150002</td>\n",
       "      <td>42.380001</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               AIR.PA     ATO.PA      CS.PA  ENGI.PA     ENR.DE      HO.PA  \\\n",
       "Date                                                                         \n",
       "2020-12-28  91.980003  75.300003  19.728001   12.900  29.730000  75.680000   \n",
       "2020-12-29  93.070000  75.760002  19.736000   12.755  29.900000  76.320000   \n",
       "2020-12-30  91.250000  75.339996  19.676001   12.695  30.000000  75.440002   \n",
       "2020-12-31  89.779999  74.779999  19.511999   12.520        NaN  74.900002   \n",
       "2021-01-04  89.889999  76.120003  19.438000   12.805  30.129999  75.180000   \n",
       "\n",
       "                 MC.PA     RNO.PA      SAF.PA        TOT  \n",
       "Date                                                      \n",
       "2020-12-28  504.000000  36.110001  119.949997  42.413864  \n",
       "2020-12-29  512.799988  36.255001  120.500000  42.512001  \n",
       "2020-12-30  513.099976  35.945000  119.000000  42.669998  \n",
       "2020-12-31  510.899994  35.759998  115.949997  41.910000  \n",
       "2021-01-04  512.099976  35.759998  116.150002  42.380001  "
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ohlc = yf.download(tickers, period=period)\n",
    "prices = ohlc[\"Adj Close\"]\n",
    "prices.tail()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[*********************100%***********************]  1 of 1 completed\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "Date\n",
       "2019-01-04    4737.120117\n",
       "2019-01-07    4719.169922\n",
       "2019-01-08    4773.270020\n",
       "2019-01-09    4813.580078\n",
       "2019-01-10    4805.660156\n",
       "Name: Adj Close, dtype: float64"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "market_prices = yf.download(\"^FCHI\", period=period)[\"Adj Close\"]\n",
    "market_prices.head()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████████████████████████████████████████████████████████████████████████████| 10/10 [00:45<00:00,  4.52s/it]\n"
     ]
    }
   ],
   "source": [
    "mcaps = {}\n",
    "for t in tqdm(tickers):\n",
    "    stock = yf.Ticker(t)\n",
    "    mcaps[t] = stock.info[\"marketCap\"]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'SAF.PA': 49588846592,\n",
       " 'ATO.PA': 8368633344,\n",
       " 'MC.PA': 258050244608,\n",
       " 'AIR.PA': 70448144384,\n",
       " 'RNO.PA': 10383272960,\n",
       " 'HO.PA': 16002814976,\n",
       " 'ENGI.PA': 30947381248,\n",
       " 'CS.PA': 46335721472,\n",
       " 'ENR.DE': 12153989120,\n",
       " 'TOT': 115413041152}"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mcaps"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Constructing the prior¶\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.5192887221015647"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pypfopt\n",
    "from pypfopt import black_litterman, risk_models\n",
    "from pypfopt import BlackLittermanModel, plotting\n",
    "\n",
    "S = risk_models.CovarianceShrinkage(prices).ledoit_wolf()\n",
    "delta = black_litterman.market_implied_risk_aversion(market_prices)\n",
    "delta"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 15144 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plotting.plot_covariance(S, plot_correlation=True);\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIR.PA     0.211797\n",
       "ATO.PA     0.119274\n",
       "CS.PA      0.144824\n",
       "ENGI.PA    0.117140\n",
       "ENR.DE     0.027215\n",
       "HO.PA      0.137631\n",
       "MC.PA      0.142924\n",
       "RNO.PA     0.198142\n",
       "SAF.PA     0.208159\n",
       "TOT        0.165501\n",
       "dtype: float64"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "market_prior = black_litterman.market_implied_prior_returns(mcaps, delta, S)\n",
    "market_prior"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 10280 characters]\n",
      "text/plain": [
       "<Figure size 720x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "market_prior.plot.barh(figsize=(10,5));\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Views"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "# You don't have to provide views on all the assets\n",
    "viewdict = {\n",
    "    \"SAF.PA\":-0.01, \n",
    "    \"ATO.PA\":0.15, \n",
    "    \"MC.PA\":-0.06, \n",
    "    \"AIR.PA\":0.06, \n",
    "    \"RNO.PA\":-0.12, \n",
    "    \"HO.PA\":0.12, \n",
    "    \"ENGI.PA\" : 0.16, \n",
    "    \"TOT\" : 0.17,\n",
    "    \"ENR.DE\":-0.027,\n",
    "    \"CS.PA\":0.22,\n",
    "}\n",
    "\n",
    "bl = BlackLittermanModel(S, pi=market_prior, absolute_views=viewdict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## View confidences\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "confidences = [\n",
    "    0.7,#SAFRAN\n",
    "    0.7,#ATOS\n",
    "    0.3,#LVMH\n",
    "    0.6,#AIRBUS\n",
    "    0.3,#RNO\n",
    "    0.6,#Thales\n",
    "    0.3,#ENGIE\n",
    "    0.3,#TOTAL\n",
    "    0.3,#SIEMENS ENERGY\n",
    "    0.3 #AXA\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "bl = BlackLittermanModel(S, pi=market_prior, absolute_views=viewdict, omega=\"idzorek\", view_confidences=confidences)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 12500 characters]\n",
      "text/plain": [
       "<Figure size 504x504 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(figsize=(7,7))\n",
    "im = ax.imshow(bl.omega)\n",
    "\n",
    "# We want to show all ticks...\n",
    "ax.set_xticks(np.arange(len(bl.tickers)))\n",
    "ax.set_yticks(np.arange(len(bl.tickers)))\n",
    "\n",
    "ax.set_xticklabels(bl.tickers)\n",
    "ax.set_yticklabels(bl.tickers)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.00565163, 0.00271865, 0.01110963, 0.00951223, 0.03600991,\n",
       "       0.00438299, 0.01260052, 0.0203283 , 0.00301438, 0.0140658 ])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.diag(bl.omega)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "def stockreturn(prices, ticker, shift=1):\n",
    "    stock_returns = (prices[ticker] / prices[ticker] .shift(shift)) - 1\n",
    "    stock_returns =  stock_returns.to_frame()\n",
    "    stock_returns.columns = [f'{ticker} {shift} days Return']\n",
    "    return stock_returns\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 88640 characters]\n",
      "text/plain": [
       "<Figure size 1296x864 with 6 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 89788 characters]\n",
      "text/plain": [
       "<Figure size 1296x864 with 6 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 91636 characters]\n",
      "text/plain": [
       "<Figure size 1296x864 with 6 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 86908 characters]\n",
      "text/plain": [
       "<Figure size 1296x864 with 6 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 93424 characters]\n",
      "text/plain": [
       "<Figure size 1296x864 with 6 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 92120 characters]\n",
      "text/plain": [
       "<Figure size 1296x864 with 6 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 88524 characters]\n",
      "text/plain": [
       "<Figure size 1296x864 with 6 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 88220 characters]\n",
      "text/plain": [
       "<Figure size 1296x864 with 6 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 61832 characters]\n",
      "text/plain": [
       "<Figure size 1296x864 with 6 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 89148 characters]\n",
      "text/plain": [
       "<Figure size 1296x864 with 6 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "for t in tickers:\n",
    "    fig, axs = plt.subplots(2, 3, figsize=(3*6, 2*6))\n",
    "    for ax, shift in zip(axs.flat, [1, 5, 20, 50, 100, 100]):\n",
    "        try:\n",
    "            x = stockreturn(prices, t, shift=shift)*100\n",
    "            sns.histplot(x, kde=True, ax = ax, bins=30) #binwidth=10)\n",
    "            ax.axvline(np.nanmean(x.values), color=\"red\")\n",
    "            ax.axvline(np.nanmean(x.values) - np.nanstd(x.values), color=\"green\")\n",
    "            ax.axvline(np.nanmean(x.values) + np.nanstd(x.values), color=\"green\")\n",
    "        except ValueError:\n",
    "            pass\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "intervals = [\n",
    "    (-0.2, 0.4),#SAFRAN\n",
    "    (-0.12, 0.2),#ATOS\n",
    "    (0, 0.25),#LVMH\n",
    "    (-0.35, 0.4),#AIRBUS\n",
    "    (-0.2, 0.5),#RNO\n",
    "    (-0.2, 0.1),#Thales\n",
    "    (-0.15, 0.25),#ENGIE\n",
    "    (-0.2, 0.2),#TOTAL\n",
    "    (0.15, 0.35),#SIEMENS ENERGY\n",
    "    (-0.2, 0.25),#AXA\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.09000000000000002, 0.0256, 0.015625, 0.140625, 0.12249999999999998, 0.022500000000000006, 0.04000000000000001, 0.04000000000000001, 0.009999999999999998, 0.050625]\n"
     ]
    }
   ],
   "source": [
    "variances = []\n",
    "for lb, ub in intervals:\n",
    "    sigma = (ub - lb)/2\n",
    "    variances.append(sigma ** 2)\n",
    "\n",
    "print(variances)\n",
    "omega = np.diag(variances)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Posterior estimates"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "# We are using the shortcut to automatically compute market-implied prior\n",
    "bl = BlackLittermanModel(S, pi=\"market\", market_caps=mcaps, risk_aversion=delta,\n",
    "                        absolute_views=viewdict, omega=omega)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIR.PA     0.149275\n",
       "ATO.PA     0.086625\n",
       "CS.PA      0.104912\n",
       "ENGI.PA    0.083524\n",
       "ENR.DE     0.003080\n",
       "HO.PA      0.096096\n",
       "MC.PA      0.084373\n",
       "RNO.PA     0.133569\n",
       "SAF.PA     0.145659\n",
       "TOT        0.125082\n",
       "dtype: float64"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Posterior estimate of returns\n",
    "ret_bl = bl.bl_returns()\n",
    "ret_bl"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "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>Prior</th>\n",
       "      <th>Posterior</th>\n",
       "      <th>Views</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>AIR.PA</th>\n",
       "      <td>0.211797</td>\n",
       "      <td>0.149275</td>\n",
       "      <td>0.060</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ATO.PA</th>\n",
       "      <td>0.119274</td>\n",
       "      <td>0.086625</td>\n",
       "      <td>0.150</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>CS.PA</th>\n",
       "      <td>0.144824</td>\n",
       "      <td>0.104912</td>\n",
       "      <td>0.220</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ENGI.PA</th>\n",
       "      <td>0.117140</td>\n",
       "      <td>0.083524</td>\n",
       "      <td>0.160</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ENR.DE</th>\n",
       "      <td>0.027215</td>\n",
       "      <td>0.003080</td>\n",
       "      <td>-0.027</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>HO.PA</th>\n",
       "      <td>0.137631</td>\n",
       "      <td>0.096096</td>\n",
       "      <td>0.120</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>MC.PA</th>\n",
       "      <td>0.142924</td>\n",
       "      <td>0.084373</td>\n",
       "      <td>-0.060</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>RNO.PA</th>\n",
       "      <td>0.198142</td>\n",
       "      <td>0.133569</td>\n",
       "      <td>-0.120</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>SAF.PA</th>\n",
       "      <td>0.208159</td>\n",
       "      <td>0.145659</td>\n",
       "      <td>-0.010</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>TOT</th>\n",
       "      <td>0.165501</td>\n",
       "      <td>0.125082</td>\n",
       "      <td>0.170</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            Prior  Posterior  Views\n",
       "AIR.PA   0.211797   0.149275  0.060\n",
       "ATO.PA   0.119274   0.086625  0.150\n",
       "CS.PA    0.144824   0.104912  0.220\n",
       "ENGI.PA  0.117140   0.083524  0.160\n",
       "ENR.DE   0.027215   0.003080 -0.027\n",
       "HO.PA    0.137631   0.096096  0.120\n",
       "MC.PA    0.142924   0.084373 -0.060\n",
       "RNO.PA   0.198142   0.133569 -0.120\n",
       "SAF.PA   0.208159   0.145659 -0.010\n",
       "TOT      0.165501   0.125082  0.170"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rets_df = pd.DataFrame([market_prior, ret_bl, pd.Series(viewdict)], \n",
    "             index=[\"Prior\", \"Posterior\", \"Views\"]).T\n",
    "rets_df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 15844 characters]\n",
      "text/plain": [
       "<Figure size 864x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "rets_df.plot.bar(figsize=(12,8));\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 15884 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "S_bl = bl.bl_cov()\n",
    "plotting.plot_covariance(S_bl);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Portfolio allocation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pypfopt import EfficientFrontier, objective_functions\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\D580656\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\pypfopt\\efficient_frontier.py:196: UserWarning: max_sharpe transforms the optimisation problem so additional objectives may not work as expected.\n",
      "  \"max_sharpe transforms the optimisation problem so additional objectives may not work as expected.\"\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "OrderedDict([('AIR.PA', 0.15455),\n",
       "             ('ATO.PA', 0.08261),\n",
       "             ('CS.PA', 0.10543),\n",
       "             ('ENGI.PA', 0.07509),\n",
       "             ('ENR.DE', 0.0),\n",
       "             ('HO.PA', 0.08634),\n",
       "             ('MC.PA', 0.07821),\n",
       "             ('RNO.PA', 0.12137),\n",
       "             ('SAF.PA', 0.14893),\n",
       "             ('TOT', 0.14747)])"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ef = EfficientFrontier(ret_bl, S_bl)\n",
    "ef.add_objective(objective_functions.L2_reg)\n",
    "ef.max_sharpe()\n",
    "weights = ef.clean_weights()\n",
    "weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 37352 characters]\n",
      "text/plain": [
       "<Figure size 720x720 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "pd.Series(weights).plot.pie(figsize=(10,10));\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Leftover: $10.37\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'AIR.PA': 2,\n",
       " 'ATO.PA': 1,\n",
       " 'CS.PA': 7,\n",
       " 'ENGI.PA': 8,\n",
       " 'HO.PA': 2,\n",
       " 'RNO.PA': 4,\n",
       " 'SAF.PA': 2,\n",
       " 'TOT': 4}"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from pypfopt import DiscreteAllocation\n",
    "\n",
    "da = DiscreteAllocation(weights, prices.iloc[-1], total_portfolio_value=1200)\n",
    "alloc, leftover = da.lp_portfolio()\n",
    "print(f\"Leftover: ${leftover:.2f}\")\n",
    "alloc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "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.7.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
