Files
ArtStudies/M1/Portfolio Management/TP-Project.ipynb
Arthur DANJOU 8cf328e18a Refactor code in numerical methods notebooks
- Updated import order in Point_Fixe.ipynb for consistency.
- Changed lambda functions to regular function definitions for clarity in Point_Fixe.ipynb.
- Added numpy import in TP1_EDO_EulerExp.ipynb, TP2_Lokta_Volterra.ipynb, and TP3_Convergence.ipynb for better readability.
- Modified for loops in TP1_EDO_EulerExp.ipynb and TP2_Lokta_Volterra.ipynb to include strict=False for compatibility with future Python versions.
2025-09-01 16:14:53 +02:00

524 lines
16 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "81049114d821d00e",
"metadata": {},
"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%"
]
},
{
"cell_type": "code",
"execution_count": 51,
"id": "initial_id",
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-25T13:43:46.298758Z",
"start_time": "2024-11-25T13:43:46.293696Z"
},
"collapsed": true
},
"outputs": [],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"import yfinance as yf"
]
},
{
"cell_type": "code",
"execution_count": 52,
"id": "9f9fc36832c97e0",
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-25T13:43:47.318911Z",
"start_time": "2024-11-25T13:43:47.198820Z"
}
},
"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/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>^RUT</th>\n",
" <th>^IXIC</th>\n",
" <th>^GSPC</th>\n",
" <th>XWD.TO</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Date</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2017-01-03 00:00:00+00:00</th>\n",
" <td>1365.489990</td>\n",
" <td>5429.080078</td>\n",
" <td>2257.830078</td>\n",
" <td>38.499630</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-01-04 00:00:00+00:00</th>\n",
" <td>1387.949951</td>\n",
" <td>5477.000000</td>\n",
" <td>2270.750000</td>\n",
" <td>38.553375</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-01-05 00:00:00+00:00</th>\n",
" <td>1371.939941</td>\n",
" <td>5487.939941</td>\n",
" <td>2269.000000</td>\n",
" <td>38.481716</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-01-06 00:00:00+00:00</th>\n",
" <td>1367.280029</td>\n",
" <td>5521.060059</td>\n",
" <td>2276.979980</td>\n",
" <td>38.517544</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-01-09 00:00:00+00:00</th>\n",
" <td>1357.489990</td>\n",
" <td>5531.819824</td>\n",
" <td>2268.899902</td>\n",
" <td>38.383186</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"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"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"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>^RUT</th>\n",
" <th>^IXIC</th>\n",
" <th>^GSPC</th>\n",
" <th>XWD.TO</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Date</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2017-12-22 00:00:00+00:00</th>\n",
" <td>1542.930054</td>\n",
" <td>6959.959961</td>\n",
" <td>2683.340088</td>\n",
" <td>44.323349</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-12-26 00:00:00+00:00</th>\n",
" <td>1544.229980</td>\n",
" <td>6936.250000</td>\n",
" <td>2680.500000</td>\n",
" <td>44.323349</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-12-27 00:00:00+00:00</th>\n",
" <td>1543.939941</td>\n",
" <td>6939.339844</td>\n",
" <td>2682.620117</td>\n",
" <td>44.052303</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-12-28 00:00:00+00:00</th>\n",
" <td>1548.930054</td>\n",
" <td>6950.160156</td>\n",
" <td>2687.540039</td>\n",
" <td>43.857414</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-12-29 00:00:00+00:00</th>\n",
" <td>1535.510010</td>\n",
" <td>6903.390137</td>\n",
" <td>2673.610107</td>\n",
" <td>43.784576</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"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"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"(251, 4)\n"
]
}
],
"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)"
]
},
{
"cell_type": "code",
"execution_count": 53,
"id": "53483cf3a925a4db",
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-25T13:43:50.080380Z",
"start_time": "2024-11-25T13:43:50.073119Z"
}
},
"outputs": [],
"source": [
"R = S / S.shift() - 1\n",
"R = R[1:]\n",
"mean_d = R.mean()\n",
"covar_d = R.cov()\n",
"corr = R.corr()"
]
},
{
"cell_type": "code",
"execution_count": 54,
"id": "c327ed5967b1f442",
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-25T13:43:50.965092Z",
"start_time": "2024-11-25T13:43:50.961969Z"
}
},
"outputs": [],
"source": [
"mean = mean_d * 252\n",
"covar = covar_d * 252\n",
"std = np.sqrt(np.diag(covar))"
]
},
{
"cell_type": "code",
"execution_count": 55,
"id": "6bc6a850bf06cc9d",
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-25T13:43:51.701725Z",
"start_time": "2024-11-25T13:43:51.695020Z"
}
},
"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"
]
}
],
"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)"
]
},
{
"cell_type": "markdown",
"id": "fc4bec874f710f7c",
"metadata": {},
"source": "# Question 1"
},
{
"cell_type": "code",
"execution_count": 56,
"id": "780c9cca6e0ed2d3",
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-25T13:43:53.113423Z",
"start_time": "2024-11-25T13:43:53.109514Z"
}
},
"outputs": [],
"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)"
]
},
{
"cell_type": "code",
"execution_count": 57,
"id": "81c956f147c68070",
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-25T13:43:54.545400Z",
"start_time": "2024-11-25T13:43:54.541579Z"
}
},
"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"
]
}
],
"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\"\n",
")"
]
},
{
"cell_type": "markdown",
"id": "2e121c2dfb946f3c",
"metadata": {},
"source": "# Question 2"
},
{
"cell_type": "code",
"execution_count": 58,
"id": "c169808384ca1112",
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-25T13:43:59.797115Z",
"start_time": "2024-11-25T13:43:59.792462Z"
}
},
"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"
]
}
],
"source": [
"for i in range(len(std)):\n",
" print(f\"The annualized volatilities of the index {Tickers[i]} is {std[i]}\")\n",
" print(\n",
" f\"The annualized expected returns of the index {Tickers[i]} is {mean[Tickers[i]]}\"\n",
" )\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}\")"
]
},
{
"cell_type": "markdown",
"id": "af8d29ecdbf2ae1",
"metadata": {},
"source": "# Question 3"
},
{
"cell_type": "code",
"execution_count": 59,
"id": "2e0215ab7904906a",
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-25T13:44:01.393591Z",
"start_time": "2024-11-25T13:44:01.388830Z"
}
},
"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"
]
}
],
"source": [
"print(\"sharpe ratio of the Tangent portfolio :\", (m_T - r) / sd_T)\n",
"\n",
"for i in range(4):\n",
" print(\n",
" f\"the sharpe ratio of the index {Tickers[i]} is {(mean[Tickers[i]] - r) / std[i]}\"\n",
" )"
]
}
],
"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
}