Files
ArtStudies/M1/Portfolio Management/TP-Project.ipynb
Arthur DANJOU f94ff07cab Refactor code for improved readability and consistency across notebooks
- Standardized spacing around operators and function arguments in TP7_Kmeans.ipynb and neural_network.ipynb.
- Enhanced the formatting of model building and training code in neural_network.ipynb for better clarity.
- Updated the pyproject.toml to remove a specific TensorFlow version and added linting configuration for Ruff.
- Improved comments and organization in the code to facilitate easier understanding and maintenance.
2025-07-01 20:46:08 +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 yfinance as yf\n",
"import pandas as pd\n",
"import numpy as np"
]
},
{
"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
}