diff --git a/M1/Portfolio Management/TP-Project.ipynb b/M1/Portfolio Management/TP-Project.ipynb
new file mode 100644
index 0000000..843e152
--- /dev/null
+++ b/M1/Portfolio Management/TP-Project.ipynb
@@ -0,0 +1,518 @@
+{
+ "cells": [
+ {
+ "metadata": {},
+ "cell_type": "markdown",
+ "source": [
+ "# Project - Portfolio Management\n",
+ "\n",
+ "## Group: Danjou Arthur & Forest Thais\n",
+ "\n",
+ "### Time period studied from 2017-01-01 to 2018-01-01\n",
+ "\n",
+ "### Risk-free rate: 2%"
+ ],
+ "id": "81049114d821d00e"
+ },
+ {
+ "cell_type": "code",
+ "id": "initial_id",
+ "metadata": {
+ "collapsed": true,
+ "ExecuteTime": {
+ "end_time": "2024-11-25T13:43:46.298758Z",
+ "start_time": "2024-11-25T13:43:46.293696Z"
+ }
+ },
+ "source": [
+ "import yfinance as yf\n",
+ "import pandas as pd\n",
+ "import numpy as np"
+ ],
+ "outputs": [],
+ "execution_count": 51
+ },
+ {
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-11-25T13:43:47.318911Z",
+ "start_time": "2024-11-25T13:43:47.198820Z"
+ }
+ },
+ "cell_type": "code",
+ "source": [
+ "# Data Extraction\n",
+ "Tickers = [\"^RUT\", \"^IXIC\", \"^GSPC\", \"XWD.TO\"]\n",
+ "start_input = \"2017-01-01\"\n",
+ "end_input = \"2018-01-01\"\n",
+ "S = pd.DataFrame()\n",
+ "for t in Tickers:\n",
+ " S[t] = yf.Tickers(t).history(start=start_input, end=end_input)[\"Close\"]\n",
+ "\n",
+ "S = S.interpolate(method=\"pad\")\n",
+ "\n",
+ "# Show the first five and last five values extracted\n",
+ "display(S.head())\n",
+ "display(S.tail())\n",
+ "print(S.shape)"
+ ],
+ "id": "9f9fc36832c97e0",
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[*********************100%***********************] 1 of 1 completed\n",
+ "[*********************100%***********************] 1 of 1 completed\n",
+ "[*********************100%***********************] 1 of 1 completed\n",
+ "[*********************100%***********************] 1 of 1 completed\n",
+ "/var/folders/tp/_ld5_pzs6nx6mv1pbjhq1l740000gn/T/ipykernel_92506/348989065.py:9: FutureWarning: DataFrame.interpolate with method=pad is deprecated and will raise in a future version. Use obj.ffill() or obj.bfill() instead.\n",
+ " S = S.interpolate(method=\"pad\")\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ " ^RUT ^IXIC ^GSPC XWD.TO\n",
+ "Date \n",
+ "2017-01-03 00:00:00+00:00 1365.489990 5429.080078 2257.830078 38.499630\n",
+ "2017-01-04 00:00:00+00:00 1387.949951 5477.000000 2270.750000 38.553375\n",
+ "2017-01-05 00:00:00+00:00 1371.939941 5487.939941 2269.000000 38.481716\n",
+ "2017-01-06 00:00:00+00:00 1367.280029 5521.060059 2276.979980 38.517544\n",
+ "2017-01-09 00:00:00+00:00 1357.489990 5531.819824 2268.899902 38.383186"
+ ],
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " ^RUT | \n",
+ " ^IXIC | \n",
+ " ^GSPC | \n",
+ " XWD.TO | \n",
+ "
\n",
+ " \n",
+ " | Date | \n",
+ " | \n",
+ " | \n",
+ " | \n",
+ " | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 2017-01-03 00:00:00+00:00 | \n",
+ " 1365.489990 | \n",
+ " 5429.080078 | \n",
+ " 2257.830078 | \n",
+ " 38.499630 | \n",
+ "
\n",
+ " \n",
+ " | 2017-01-04 00:00:00+00:00 | \n",
+ " 1387.949951 | \n",
+ " 5477.000000 | \n",
+ " 2270.750000 | \n",
+ " 38.553375 | \n",
+ "
\n",
+ " \n",
+ " | 2017-01-05 00:00:00+00:00 | \n",
+ " 1371.939941 | \n",
+ " 5487.939941 | \n",
+ " 2269.000000 | \n",
+ " 38.481716 | \n",
+ "
\n",
+ " \n",
+ " | 2017-01-06 00:00:00+00:00 | \n",
+ " 1367.280029 | \n",
+ " 5521.060059 | \n",
+ " 2276.979980 | \n",
+ " 38.517544 | \n",
+ "
\n",
+ " \n",
+ " | 2017-01-09 00:00:00+00:00 | \n",
+ " 1357.489990 | \n",
+ " 5531.819824 | \n",
+ " 2268.899902 | \n",
+ " 38.383186 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/plain": [
+ " ^RUT ^IXIC ^GSPC XWD.TO\n",
+ "Date \n",
+ "2017-12-22 00:00:00+00:00 1542.930054 6959.959961 2683.340088 44.323349\n",
+ "2017-12-26 00:00:00+00:00 1544.229980 6936.250000 2680.500000 44.323349\n",
+ "2017-12-27 00:00:00+00:00 1543.939941 6939.339844 2682.620117 44.052303\n",
+ "2017-12-28 00:00:00+00:00 1548.930054 6950.160156 2687.540039 43.857414\n",
+ "2017-12-29 00:00:00+00:00 1535.510010 6903.390137 2673.610107 43.784576"
+ ],
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " ^RUT | \n",
+ " ^IXIC | \n",
+ " ^GSPC | \n",
+ " XWD.TO | \n",
+ "
\n",
+ " \n",
+ " | Date | \n",
+ " | \n",
+ " | \n",
+ " | \n",
+ " | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 2017-12-22 00:00:00+00:00 | \n",
+ " 1542.930054 | \n",
+ " 6959.959961 | \n",
+ " 2683.340088 | \n",
+ " 44.323349 | \n",
+ "
\n",
+ " \n",
+ " | 2017-12-26 00:00:00+00:00 | \n",
+ " 1544.229980 | \n",
+ " 6936.250000 | \n",
+ " 2680.500000 | \n",
+ " 44.323349 | \n",
+ "
\n",
+ " \n",
+ " | 2017-12-27 00:00:00+00:00 | \n",
+ " 1543.939941 | \n",
+ " 6939.339844 | \n",
+ " 2682.620117 | \n",
+ " 44.052303 | \n",
+ "
\n",
+ " \n",
+ " | 2017-12-28 00:00:00+00:00 | \n",
+ " 1548.930054 | \n",
+ " 6950.160156 | \n",
+ " 2687.540039 | \n",
+ " 43.857414 | \n",
+ "
\n",
+ " \n",
+ " | 2017-12-29 00:00:00+00:00 | \n",
+ " 1535.510010 | \n",
+ " 6903.390137 | \n",
+ " 2673.610107 | \n",
+ " 43.784576 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "(251, 4)\n"
+ ]
+ }
+ ],
+ "execution_count": 52
+ },
+ {
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-11-25T13:43:50.080380Z",
+ "start_time": "2024-11-25T13:43:50.073119Z"
+ }
+ },
+ "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": "53483cf3a925a4db",
+ "outputs": [],
+ "execution_count": 53
+ },
+ {
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-11-25T13:43:50.965092Z",
+ "start_time": "2024-11-25T13:43:50.961969Z"
+ }
+ },
+ "cell_type": "code",
+ "source": [
+ "mean = mean_d * 252\n",
+ "covar = covar_d * 252\n",
+ "std = np.sqrt(np.diag(covar))"
+ ],
+ "id": "c327ed5967b1f442",
+ "outputs": [],
+ "execution_count": 54
+ },
+ {
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-11-25T13:43:51.701725Z",
+ "start_time": "2024-11-25T13:43:51.695020Z"
+ }
+ },
+ "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": "6bc6a850bf06cc9d",
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Mean:\n",
+ "\n",
+ "^RUT 0.125501\n",
+ "^IXIC 0.246863\n",
+ "^GSPC 0.172641\n",
+ "XWD.TO 0.133175\n",
+ "dtype: float64\n",
+ "\n",
+ "Covariance:\n",
+ "\n",
+ " ^RUT ^IXIC ^GSPC XWD.TO\n",
+ "^RUT 0.014417 0.008400 0.006485 0.004797\n",
+ "^IXIC 0.008400 0.009182 0.005583 0.004337\n",
+ "^GSPC 0.006485 0.005583 0.004426 0.003309\n",
+ "XWD.TO 0.004797 0.004337 0.003309 0.006996\n",
+ "\n",
+ "Standard Deviation:\n",
+ "\n",
+ "[0.12007222 0.09582499 0.06653127 0.08364295]\n",
+ "\n",
+ "Correlation:\n",
+ "\n",
+ " ^RUT ^IXIC ^GSPC XWD.TO\n",
+ "^RUT 1.000000 0.730047 0.811734 0.477668\n",
+ "^IXIC 0.730047 1.000000 0.875687 0.541087\n",
+ "^GSPC 0.811734 0.875687 1.000000 0.594658\n",
+ "XWD.TO 0.477668 0.541087 0.594658 1.000000\n"
+ ]
+ }
+ ],
+ "execution_count": 55
+ },
+ {
+ "metadata": {},
+ "cell_type": "markdown",
+ "source": "# Question 1",
+ "id": "fc4bec874f710f7c"
+ },
+ {
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-11-25T13:43:53.113423Z",
+ "start_time": "2024-11-25T13:43:53.109514Z"
+ }
+ },
+ "cell_type": "code",
+ "source": [
+ "r = 0.02\n",
+ "d = len(Tickers)\n",
+ "vec1 = np.linspace(1, 1, d)\n",
+ "sigma = covar\n",
+ "inv_sigma = np.linalg.inv(sigma)\n",
+ "\n",
+ "a = vec1.T.dot(inv_sigma).dot(vec1)\n",
+ "b = mean.T.dot(inv_sigma).dot(vec1)"
+ ],
+ "id": "780c9cca6e0ed2d3",
+ "outputs": [],
+ "execution_count": 56
+ },
+ {
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-11-25T13:43:54.545400Z",
+ "start_time": "2024-11-25T13:43:54.541579Z"
+ }
+ },
+ "cell_type": "code",
+ "source": [
+ "# 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(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(\n",
+ " f\"We can verify that the allocation is possible as the sum of the allocations for the different indices is {sum(pi_T)}, that is very close to 1\")"
+ ],
+ "id": "81c956f147c68070",
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Expected return m_T: 0.2364033641931515\n",
+ "Standard deviation sd_T: 0.07276528490265963\n",
+ "Allocation pi_T: [-0.60853811 0.45748917 1.17944152 -0.02839259]\n",
+ "We can verify that the allocation is possible as the sum of the allocations for the different indices is 0.9999999999999993, that is very close to 1\n"
+ ]
+ }
+ ],
+ "execution_count": 57
+ },
+ {
+ "metadata": {},
+ "cell_type": "markdown",
+ "source": "# Question 2",
+ "id": "2e121c2dfb946f3c"
+ },
+ {
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-11-25T13:43:59.797115Z",
+ "start_time": "2024-11-25T13:43:59.792462Z"
+ }
+ },
+ "cell_type": "code",
+ "source": [
+ "for i in range(len(std)):\n",
+ " print(f\"The annualized volatilities of the index {Tickers[i]} is {std[i]}\")\n",
+ " print(f\"The annualized expected returns of the index {Tickers[i]} is {mean[Tickers[i]]}\")\n",
+ " print(\"\")\n",
+ "\n",
+ "print(f\"The annualized volatility of the Tangent Portfolio is {sd_T * np.sqrt(252)}\")\n",
+ "print(f\"The annualized expected return of the Tangent Portfolio is {m_T * 252}\")"
+ ],
+ "id": "c169808384ca1112",
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "The annualized volatilities of the index ^RUT is 0.12007221535411407\n",
+ "The annualized expected returns of the index ^RUT is 0.12550141384538263\n",
+ "\n",
+ "The annualized volatilities of the index ^IXIC is 0.09582499431305072\n",
+ "The annualized expected returns of the index ^IXIC is 0.24686267015709437\n",
+ "\n",
+ "The annualized volatilities of the index ^GSPC is 0.06653126757186174\n",
+ "The annualized expected returns of the index ^GSPC is 0.17264098207081371\n",
+ "\n",
+ "The annualized volatilities of the index XWD.TO is 0.08364295296865466\n",
+ "The annualized expected returns of the index XWD.TO is 0.1331750489518068\n",
+ "\n",
+ "The annualized volatility of the Tangent Portfolio is 1.155113087587201\n",
+ "The annualized expected return of the Tangent Portfolio is 59.57364777667418\n"
+ ]
+ }
+ ],
+ "execution_count": 58
+ },
+ {
+ "metadata": {},
+ "cell_type": "markdown",
+ "source": "# Question 3",
+ "id": "af8d29ecdbf2ae1"
+ },
+ {
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-11-25T13:44:01.393591Z",
+ "start_time": "2024-11-25T13:44:01.388830Z"
+ }
+ },
+ "cell_type": "code",
+ "source": [
+ "print(\"sharpe ratio of the Tangent portfolio :\", (m_T - r) / sd_T)\n",
+ "\n",
+ "for i in range(4):\n",
+ " print(f\"the sharpe ratio of the index {Tickers[i]} is {(mean[Tickers[i]] - r) / std[i]}\")"
+ ],
+ "id": "2e0215ab7904906a",
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "sharpe ratio of the Tangent portfolio : 2.9739918490340687\n",
+ "the sharpe ratio of the index ^RUT is 0.8786496820620858\n",
+ "the sharpe ratio of the index ^IXIC is 2.3674686524473625\n",
+ "the sharpe ratio of the index ^GSPC is 2.294274371158541\n",
+ "the sharpe ratio of the index XWD.TO is 1.353073330567601\n"
+ ]
+ }
+ ],
+ "execution_count": 59
+ }
+ ],
+ "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
+}