diff --git a/PortFolio Optimaization Using Genetic ALgorithm/.ipynb_checkpoints/Portfolio_Optimization_Using_Genetic_Algorithm-checkpoint.ipynb b/PortFolio Optimaization Using Genetic ALgorithm/.ipynb_checkpoints/Portfolio_Optimization_Using_Genetic_Algorithm-checkpoint.ipynb new file mode 100644 index 0000000..8f9f64c --- /dev/null +++ b/PortFolio Optimaization Using Genetic ALgorithm/.ipynb_checkpoints/Portfolio_Optimization_Using_Genetic_Algorithm-checkpoint.ipynb @@ -0,0 +1,793 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "FgneRLb5xWON" + }, + "source": [ + "# **Portfolio Optimization Using Genetic Algorithm**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HTGK4uLYMf5A" + }, + "source": [ + "Load the data" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 324 + }, + "id": "CCgHhKp6FHbT", + "outputId": "f358ffad-1db0-4203-ee75-37ce1f5c1234" + }, + "outputs": [ + { + "ename": "FileNotFoundError", + "evalue": "[Errno 2] No such file or directory: '/content/portfolio_data.csv'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mFileNotFoundError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[12], line 4\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mpandas\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mpd\u001b[39;00m\n\u001b[0;32m 3\u001b[0m \u001b[38;5;66;03m# Load data\u001b[39;00m\n\u001b[1;32m----> 4\u001b[0m df \u001b[38;5;241m=\u001b[39m \u001b[43mpd\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mread_csv\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43m/content/portfolio_data.csv\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mindex_col\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparse_dates\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m\n\u001b[0;32m 5\u001b[0m df\u001b[38;5;241m.\u001b[39mhead()\n", + "File \u001b[1;32mD:\\Anaconda\\Lib\\site-packages\\pandas\\io\\parsers\\readers.py:1026\u001b[0m, in \u001b[0;36mread_csv\u001b[1;34m(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, date_format, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, encoding_errors, dialect, on_bad_lines, delim_whitespace, low_memory, memory_map, float_precision, storage_options, dtype_backend)\u001b[0m\n\u001b[0;32m 1013\u001b[0m kwds_defaults \u001b[38;5;241m=\u001b[39m _refine_defaults_read(\n\u001b[0;32m 1014\u001b[0m dialect,\n\u001b[0;32m 1015\u001b[0m delimiter,\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 1022\u001b[0m dtype_backend\u001b[38;5;241m=\u001b[39mdtype_backend,\n\u001b[0;32m 1023\u001b[0m )\n\u001b[0;32m 1024\u001b[0m kwds\u001b[38;5;241m.\u001b[39mupdate(kwds_defaults)\n\u001b[1;32m-> 1026\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_read\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfilepath_or_buffer\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mkwds\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mD:\\Anaconda\\Lib\\site-packages\\pandas\\io\\parsers\\readers.py:620\u001b[0m, in \u001b[0;36m_read\u001b[1;34m(filepath_or_buffer, kwds)\u001b[0m\n\u001b[0;32m 617\u001b[0m _validate_names(kwds\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnames\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m))\n\u001b[0;32m 619\u001b[0m \u001b[38;5;66;03m# Create the parser.\u001b[39;00m\n\u001b[1;32m--> 620\u001b[0m parser \u001b[38;5;241m=\u001b[39m \u001b[43mTextFileReader\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfilepath_or_buffer\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwds\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 622\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m chunksize \u001b[38;5;129;01mor\u001b[39;00m iterator:\n\u001b[0;32m 623\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m parser\n", + "File \u001b[1;32mD:\\Anaconda\\Lib\\site-packages\\pandas\\io\\parsers\\readers.py:1620\u001b[0m, in \u001b[0;36mTextFileReader.__init__\u001b[1;34m(self, f, engine, **kwds)\u001b[0m\n\u001b[0;32m 1617\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39moptions[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhas_index_names\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m kwds[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhas_index_names\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n\u001b[0;32m 1619\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhandles: IOHandles \u001b[38;5;241m|\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m-> 1620\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_engine \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_make_engine\u001b[49m\u001b[43m(\u001b[49m\u001b[43mf\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mengine\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mD:\\Anaconda\\Lib\\site-packages\\pandas\\io\\parsers\\readers.py:1880\u001b[0m, in \u001b[0;36mTextFileReader._make_engine\u001b[1;34m(self, f, engine)\u001b[0m\n\u001b[0;32m 1878\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mb\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m mode:\n\u001b[0;32m 1879\u001b[0m mode \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mb\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m-> 1880\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhandles \u001b[38;5;241m=\u001b[39m \u001b[43mget_handle\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 1881\u001b[0m \u001b[43m \u001b[49m\u001b[43mf\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1882\u001b[0m \u001b[43m \u001b[49m\u001b[43mmode\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1883\u001b[0m \u001b[43m \u001b[49m\u001b[43mencoding\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43moptions\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mencoding\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1884\u001b[0m \u001b[43m \u001b[49m\u001b[43mcompression\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43moptions\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mcompression\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1885\u001b[0m \u001b[43m \u001b[49m\u001b[43mmemory_map\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43moptions\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mmemory_map\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1886\u001b[0m \u001b[43m \u001b[49m\u001b[43mis_text\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mis_text\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1887\u001b[0m \u001b[43m \u001b[49m\u001b[43merrors\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43moptions\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mencoding_errors\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mstrict\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1888\u001b[0m \u001b[43m \u001b[49m\u001b[43mstorage_options\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43moptions\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mstorage_options\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1889\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1890\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhandles \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 1891\u001b[0m f \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhandles\u001b[38;5;241m.\u001b[39mhandle\n", + "File \u001b[1;32mD:\\Anaconda\\Lib\\site-packages\\pandas\\io\\common.py:873\u001b[0m, in \u001b[0;36mget_handle\u001b[1;34m(path_or_buf, mode, encoding, compression, memory_map, is_text, errors, storage_options)\u001b[0m\n\u001b[0;32m 868\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(handle, \u001b[38;5;28mstr\u001b[39m):\n\u001b[0;32m 869\u001b[0m \u001b[38;5;66;03m# Check whether the filename is to be opened in binary mode.\u001b[39;00m\n\u001b[0;32m 870\u001b[0m \u001b[38;5;66;03m# Binary mode does not support 'encoding' and 'newline'.\u001b[39;00m\n\u001b[0;32m 871\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m ioargs\u001b[38;5;241m.\u001b[39mencoding \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mb\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m ioargs\u001b[38;5;241m.\u001b[39mmode:\n\u001b[0;32m 872\u001b[0m \u001b[38;5;66;03m# Encoding\u001b[39;00m\n\u001b[1;32m--> 873\u001b[0m handle \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mopen\u001b[39;49m\u001b[43m(\u001b[49m\n\u001b[0;32m 874\u001b[0m \u001b[43m \u001b[49m\u001b[43mhandle\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 875\u001b[0m \u001b[43m \u001b[49m\u001b[43mioargs\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmode\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 876\u001b[0m \u001b[43m \u001b[49m\u001b[43mencoding\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mioargs\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mencoding\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 877\u001b[0m \u001b[43m \u001b[49m\u001b[43merrors\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43merrors\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 878\u001b[0m \u001b[43m \u001b[49m\u001b[43mnewline\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 879\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 880\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 881\u001b[0m \u001b[38;5;66;03m# Binary mode\u001b[39;00m\n\u001b[0;32m 882\u001b[0m handle \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mopen\u001b[39m(handle, ioargs\u001b[38;5;241m.\u001b[39mmode)\n", + "\u001b[1;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: '/content/portfolio_data.csv'" + ] + } + ], + "source": [ + "import pandas as pd\n", + "\n", + "# Load data\n", + "df = pd.read_csv('/content/portfolio_data.csv', index_col=0, parse_dates=True)\n", + "df.head()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "SzuX4BaAMi1X" + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "otw_6mVnwCrn" + }, + "source": [ + "# **Calculate Return**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 237 + }, + "id": "Pm3NBpSVFbEj", + "outputId": "73fa7e6b-70d1-4b18-bbe0-393da1eaedff" + }, + "outputs": [ + { + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "summary": "{\n \"name\": \"returns\",\n \"rows\": 1042,\n \"fields\": [\n {\n \"column\": \"timestamp\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 1042,\n \"samples\": [\n \"14-01-2022\",\n \"03-04-2023\",\n \"02-11-2021\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Asset_1\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 224.6327785434078,\n \"min\": -0.9999210466892944,\n \"max\": 7222.0687432832765,\n \"num_unique_values\": 1042,\n \"samples\": [\n -0.6761679148750576,\n 0.49714190646952816,\n -0.4763627141394565\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Asset_2\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 59.53731595106503,\n \"min\": -0.9988055106324675,\n \"max\": 1736.7807387827322,\n \"num_unique_values\": 1042,\n \"samples\": [\n 0.2878634293587754,\n -0.8129127864207362,\n -0.8511612594885148\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Asset_3\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 17.748320739953726,\n \"min\": -0.9993120588883697,\n \"max\": 380.4407359233574,\n \"num_unique_values\": 1042,\n \"samples\": [\n -0.5503353506007611,\n -0.06812604800404243,\n -0.4344354157245046\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Portfolio_Value\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.78378699798799,\n \"min\": -0.8891291434918596,\n \"max\": 6.697990119731567,\n \"num_unique_values\": 1042,\n \"samples\": [\n -0.21442045447586378,\n -0.2965740287022468,\n -0.6318635767325322\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Market_Index\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.06793369258923397,\n \"min\": -0.2066701830021066,\n \"max\": 0.20590153875399797,\n \"num_unique_values\": 1042,\n \"samples\": [\n -0.0447209020183893,\n -0.12488407279002756,\n -0.045631757458398425\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}", + "type": "dataframe", + "variable_name": "returns" + }, + "text/html": [ + "\n", + "
\n", + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Asset_1Asset_2Asset_3Portfolio_ValueMarket_Index
timestamp
02-01-2020-0.1969161.1049520.4919830.509525-0.008552
03-01-2020-0.123737-0.112190-0.451162-0.241793-0.001205
06-01-20200.4814370.169089-0.865690-0.060214-0.056688
07-01-2020-0.846615-0.97815610.721087-0.4861020.072232
08-01-20207.93105742.0307170.1753482.029164-0.019868
\n", + "
\n", + "
\n", + "\n", + "
\n", + " \n", + "\n", + " \n", + "\n", + " \n", + "
\n", + "\n", + "\n", + "
\n", + " \n", + "\n", + "\n", + "\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n" + ], + "text/plain": [ + " Asset_1 Asset_2 Asset_3 Portfolio_Value Market_Index\n", + "timestamp \n", + "02-01-2020 -0.196916 1.104952 0.491983 0.509525 -0.008552\n", + "03-01-2020 -0.123737 -0.112190 -0.451162 -0.241793 -0.001205\n", + "06-01-2020 0.481437 0.169089 -0.865690 -0.060214 -0.056688\n", + "07-01-2020 -0.846615 -0.978156 10.721087 -0.486102 0.072232\n", + "08-01-2020 7.931057 42.030717 0.175348 2.029164 -0.019868" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "returns = df.pct_change().dropna()\n", + "returns.head()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7MLPZBswwuTL" + }, + "source": [ + "# Define Fitness Function" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "ADnAYwDKFdu7" + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "def fitness_function(weights, returns):\n", + " portfolio_return = np.sum(returns.mean() * weights) * 252\n", + " portfolio_stddev = np.sqrt(np.dot(weights.T, np.dot(returns.cov() * 252, weights)))\n", + " sharpe_ratio = portfolio_return / portfolio_stddev\n", + " return sharpe_ratio\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tN7T8oixw0ZL" + }, + "source": [ + "# Initial Population" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "newRizz2FhTL" + }, + "outputs": [], + "source": [ + "def initialize_population(pop_size, num_assets):\n", + " population = []\n", + " for _ in range(pop_size):\n", + " weights = np.random.random(num_assets)\n", + " weights /= np.sum(weights)\n", + " population.append(weights)\n", + " return np.array(population)\n", + "\n", + "pop_size = 100\n", + "num_assets = len(df.columns)\n", + "population = initialize_population(pop_size, num_assets)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xfwajDq9w4AH" + }, + "source": [ + "# Selection" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "JVhMT8DbFjMo" + }, + "outputs": [], + "source": [ + "def selection(population, fitness_scores, num_parents):\n", + " parents = np.empty((num_parents, population.shape[1]))\n", + " for i in range(num_parents):\n", + " max_fitness_idx = np.where(fitness_scores == np.max(fitness_scores))\n", + " max_fitness_idx = max_fitness_idx[0][0]\n", + " parents[i, :] = population[max_fitness_idx, :]\n", + " fitness_scores[max_fitness_idx] = -999999\n", + " return parents\n", + "\n", + "num_parents = 20\n", + "fitness_scores = np.array([fitness_function(weights, returns) for weights in population])\n", + "parents = selection(population, fitness_scores, num_parents)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jqEhbITsw9t1" + }, + "source": [ + "# Crossover" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "1kGod21wFldT" + }, + "outputs": [], + "source": [ + "def crossover(parents, offspring_size):\n", + " offspring = np.empty(offspring_size)\n", + " crossover_point = np.uint8(offspring_size[1]/2)\n", + "\n", + " for k in range(offspring_size[0]):\n", + " parent1_idx = k % parents.shape[0]\n", + " parent2_idx = (k + 1) % parents.shape[0]\n", + " offspring[k, 0:crossover_point] = parents[parent1_idx, 0:crossover_point]\n", + " offspring[k, crossover_point:] = parents[parent2_idx, crossover_point:]\n", + " return offspring\n", + "\n", + "offspring_size = (pop_size - parents.shape[0], num_assets)\n", + "offspring = crossover(parents, offspring_size)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AjnCQOIrxBbe" + }, + "source": [ + "# Mutation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "fCZuohWDFnyT" + }, + "outputs": [], + "source": [ + "def mutation(offspring, mutation_rate=0.01):\n", + " for idx in range(offspring.shape[0]):\n", + " for gene_idx in range(offspring.shape[1]):\n", + " if np.random.rand() < mutation_rate:\n", + " random_value = np.random.random()\n", + " offspring[idx, gene_idx] = offspring[idx, gene_idx] + random_value\n", + " offspring[idx, gene_idx] /= np.sum(offspring[idx, :])\n", + " return offspring\n", + "\n", + "mutated_offspring = mutation(offspring)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xEDvzIMbxGTc" + }, + "source": [ + "# Termination" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "WzsJq1NSFpf3" + }, + "outputs": [], + "source": [ + "def mutation(offspring, mutation_rate=0.01):\n", + " for idx in range(offspring.shape[0]):\n", + " for gene_idx in range(offspring.shape[1]):\n", + " if np.random.rand() < mutation_rate:\n", + " random_value = np.random.random()\n", + " offspring[idx, gene_idx] = offspring[idx, gene_idx] + random_value\n", + " offspring[idx, gene_idx] /= np.sum(offspring[idx, :])\n", + " return offspring\n", + "\n", + "mutated_offspring = mutation(offspring)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s-2eE9IWxIxw" + }, + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "rkW-7vLYFrRq", + "outputId": "45fbe294-405e-491d-9b41-312512d0b006" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Generation 0: Best Fitness = 1.417253614680323\n", + "Generation 1: Best Fitness = 1.8779466185434148\n", + "Generation 2: Best Fitness = 2.0430037580572336\n", + "Generation 3: Best Fitness = 2.0920158355234864\n", + "Generation 4: Best Fitness = 2.4902477236462275\n", + "Generation 5: Best Fitness = 2.4902477236462275\n", + "Generation 6: Best Fitness = 2.4902477236462275\n", + "Generation 7: Best Fitness = 2.521225040481554\n", + "Generation 8: Best Fitness = 2.521225040481554\n", + "Generation 9: Best Fitness = 2.5409096684344568\n", + "Generation 10: Best Fitness = 2.5409096684344568\n", + "Generation 11: Best Fitness = 2.5414701981903742\n", + "Generation 12: Best Fitness = 2.5414701981903742\n", + "Generation 13: Best Fitness = 2.575155889229864\n", + "Generation 14: Best Fitness = 2.575155889229864\n", + "Generation 15: Best Fitness = 2.575155889229864\n", + "Generation 16: Best Fitness = 2.5758970013396527\n", + "Generation 17: Best Fitness = 2.5758970013396527\n", + "Generation 18: Best Fitness = 2.5759063088633067\n", + "Generation 19: Best Fitness = 2.5760569272179454\n", + "Generation 20: Best Fitness = 2.5760569272179454\n", + "Generation 21: Best Fitness = 2.580023239229417\n", + "Generation 22: Best Fitness = 2.580023239229417\n", + "Generation 23: Best Fitness = 2.5861124541129388\n", + "Generation 24: Best Fitness = 2.5861124541129388\n", + "Generation 25: Best Fitness = 2.586185095785435\n", + "Generation 26: Best Fitness = 2.586185095785435\n", + "Generation 27: Best Fitness = 2.586185095785435\n", + "Generation 28: Best Fitness = 2.586185095785435\n", + "Generation 29: Best Fitness = 2.586185095785435\n", + "Generation 30: Best Fitness = 2.586185095785435\n", + "Generation 31: Best Fitness = 2.586185095785435\n", + "Generation 32: Best Fitness = 2.586185095785435\n", + "Generation 33: Best Fitness = 2.586185095785435\n", + "Generation 34: Best Fitness = 2.586185095785435\n", + "Generation 35: Best Fitness = 2.586185095785435\n", + "Generation 36: Best Fitness = 2.586185095785435\n", + "Generation 37: Best Fitness = 2.586185095785435\n", + "Generation 38: Best Fitness = 2.588992264842197\n", + "Generation 39: Best Fitness = 2.596323300370395\n", + "Generation 40: Best Fitness = 2.596323300370395\n", + "Generation 41: Best Fitness = 2.596323300370395\n", + "Generation 42: Best Fitness = 2.596323300370395\n", + "Generation 43: Best Fitness = 2.596323300370395\n", + "Generation 44: Best Fitness = 2.596323300370395\n", + "Generation 45: Best Fitness = 2.596323300370395\n", + "Generation 46: Best Fitness = 2.596323300370395\n", + "Generation 47: Best Fitness = 2.596331571848502\n", + "Generation 48: Best Fitness = 2.596331571848502\n", + "Generation 49: Best Fitness = 2.596331571848502\n", + "Generation 50: Best Fitness = 2.596331571848502\n", + "Generation 51: Best Fitness = 2.596331571848502\n", + "Generation 52: Best Fitness = 2.596331571848502\n", + "Generation 53: Best Fitness = 2.596331571848502\n", + "Generation 54: Best Fitness = 2.596331571848502\n", + "Generation 55: Best Fitness = 2.596331571848502\n", + "Generation 56: Best Fitness = 2.596331571848502\n", + "Generation 57: Best Fitness = 2.596331571848502\n", + "Generation 58: Best Fitness = 2.596331571848502\n", + "Generation 59: Best Fitness = 2.596331571848502\n", + "Generation 60: Best Fitness = 2.596331571848502\n", + "Generation 61: Best Fitness = 2.596331571848502\n", + "Generation 62: Best Fitness = 2.596331571848502\n", + "Generation 63: Best Fitness = 2.596331571848502\n", + "Generation 64: Best Fitness = 2.596331571848502\n", + "Generation 65: Best Fitness = 2.596331571848502\n", + "Generation 66: Best Fitness = 2.596331571848502\n", + "Generation 67: Best Fitness = 2.5963368694291065\n", + "Generation 68: Best Fitness = 2.5963368694291065\n", + "Generation 69: Best Fitness = 2.5963368694291065\n", + "Generation 70: Best Fitness = 2.5963368694291065\n", + "Generation 71: Best Fitness = 2.5963368694291065\n", + "Generation 72: Best Fitness = 2.5963368694291065\n", + "Generation 73: Best Fitness = 2.5963368694291065\n", + "Generation 74: Best Fitness = 2.5963368694291065\n", + "Generation 75: Best Fitness = 2.5963368694291065\n", + "Generation 76: Best Fitness = 2.5963368694291065\n", + "Generation 77: Best Fitness = 2.5963368694291065\n", + "Generation 78: Best Fitness = 2.5963368694291065\n", + "Generation 79: Best Fitness = 2.5963498076018925\n", + "Generation 80: Best Fitness = 2.5963498076018925\n", + "Generation 81: Best Fitness = 2.5963498076018925\n", + "Generation 82: Best Fitness = 2.5963498076018925\n", + "Generation 83: Best Fitness = 2.5963498076018925\n", + "Generation 84: Best Fitness = 2.5963498076018925\n", + "Generation 85: Best Fitness = 2.5963498076018925\n", + "Generation 86: Best Fitness = 2.5963498076018925\n", + "Generation 87: Best Fitness = 2.5963498076018925\n", + "Generation 88: Best Fitness = 2.5963498076018925\n", + "Generation 89: Best Fitness = 2.5963498076018925\n", + "Generation 90: Best Fitness = 2.5963498076018925\n", + "Generation 91: Best Fitness = 2.5963498076018925\n", + "Generation 92: Best Fitness = 2.5963498076018925\n", + "Generation 93: Best Fitness = 2.5963498076018925\n", + "Generation 94: Best Fitness = 2.5963498076018925\n", + "Generation 95: Best Fitness = 2.5963498076018925\n", + "Generation 96: Best Fitness = 2.5963498076018925\n", + "Generation 97: Best Fitness = 2.5963498076018925\n", + "Generation 98: Best Fitness = 2.5963498076018925\n", + "Generation 99: Best Fitness = 2.5963502910456278\n" + ] + } + ], + "source": [ + "def genetic_algorithm(returns, num_generations, pop_size, num_parents, mutation_rate):\n", + " num_assets = returns.shape[1]\n", + " population = initialize_population(pop_size, num_assets)\n", + " for generation in range(num_generations):\n", + " fitness_scores = np.array([fitness_function(weights, returns) for weights in population])\n", + " parents = selection(population, fitness_scores, num_parents)\n", + " offspring_size = (pop_size - parents.shape[0], num_assets)\n", + " offspring = crossover(parents, offspring_size)\n", + " offspring = mutation(offspring, mutation_rate)\n", + " population[0:parents.shape[0], :] = parents\n", + " population[parents.shape[0]:, :] = offspring\n", + " best_fitness = np.max(fitness_scores)\n", + " print(f\"Generation {generation}: Best Fitness = {best_fitness}\")\n", + " return population, fitness_scores\n", + "\n", + "num_generations = 100\n", + "population, fitness_scores = genetic_algorithm(returns, num_generations, pop_size, num_parents, mutation_rate=0.01)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YFQ1uXj5xNuu" + }, + "source": [ + "# Evaluate Best portfolio" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "6vLI0G12Fxfc", + "outputId": "061304f9-ef21-447f-87c7-f1782a0e732f" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Best Portfolio Weights: [0.04189262 0.13620183 0.72651027 0.56140873 0.49904594]\n", + "Expected Annual Return: 737.635018426684\n", + "Annual Volatility: 284.1045836421465\n", + "Sharpe Ratio: 2.5963502910456278\n" + ] + } + ], + "source": [ + "best_idx = np.argmax(fitness_scores)\n", + "best_portfolio = population[best_idx, :]\n", + "best_portfolio_return = np.sum(returns.mean() * best_portfolio) * 252\n", + "best_portfolio_stddev = np.sqrt(np.dot(best_portfolio.T, np.dot(returns.cov() * 252, best_portfolio)))\n", + "best_portfolio_sharpe = best_portfolio_return / best_portfolio_stddev\n", + "\n", + "print(f\"Best Portfolio Weights: {best_portfolio}\")\n", + "print(f\"Expected Annual Return: {best_portfolio_return}\")\n", + "print(f\"Annual Volatility: {best_portfolio_stddev}\")\n", + "print(f\"Sharpe Ratio: {best_portfolio_sharpe}\")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tybZDt2YxUIU" + }, + "source": [] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + }, + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/PortFolio Optimaization Using Genetic ALgorithm/.ipynb_checkpoints/backlog-checkpoint b/PortFolio Optimaization Using Genetic ALgorithm/.ipynb_checkpoints/backlog-checkpoint new file mode 100644 index 0000000..0a3989d --- /dev/null +++ b/PortFolio Optimaization Using Genetic ALgorithm/.ipynb_checkpoints/backlog-checkpoint @@ -0,0 +1,666 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "FgneRLb5xWON" + }, + "source": [ + "# **Portfolio Optimization Using Genetic Algorithm**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HTGK4uLYMf5A" + }, + "source": [ + "Load the data" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 324 + }, + "id": "CCgHhKp6FHbT", + "outputId": "f358ffad-1db0-4203-ee75-37ce1f5c1234" + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Asset_1Asset_2Asset_3Portfolio_ValueMarket_Index
timestamp
01-01-2020544.883183423.654799645.894113525.0518341034.932512
02-01-2020437.587211891.773001963.662760792.5791241026.081261
03-01-2020383.441519791.725038528.894920600.9391991024.844657
06-01-2020568.044561925.59663871.036058564.754139966.747919
07-01-202087.12930020.218397832.619845290.2260711036.577579
\n", + "
" + ], + "text/plain": [ + " Asset_1 Asset_2 Asset_3 Portfolio_Value Market_Index\n", + "timestamp \n", + "01-01-2020 544.883183 423.654799 645.894113 525.051834 1034.932512\n", + "02-01-2020 437.587211 891.773001 963.662760 792.579124 1026.081261\n", + "03-01-2020 383.441519 791.725038 528.894920 600.939199 1024.844657\n", + "06-01-2020 568.044561 925.596638 71.036058 564.754139 966.747919\n", + "07-01-2020 87.129300 20.218397 832.619845 290.226071 1036.577579" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "\n", + "# Load data\n", + "df = pd.read_csv('portfolio_data.csv', index_col=0, parse_dates=True)\n", + "df.head()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "SzuX4BaAMi1X" + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "otw_6mVnwCrn" + }, + "source": [ + "# **Calculate Return**" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 237 + }, + "id": "Pm3NBpSVFbEj", + "outputId": "73fa7e6b-70d1-4b18-bbe0-393da1eaedff" + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Asset_1Asset_2Asset_3Portfolio_ValueMarket_Index
timestamp
02-01-2020-0.1969161.1049520.4919830.509525-0.008552
03-01-2020-0.123737-0.112190-0.451162-0.241793-0.001205
06-01-20200.4814370.169089-0.865690-0.060214-0.056688
07-01-2020-0.846615-0.97815610.721087-0.4861020.072232
08-01-20207.93105742.0307170.1753482.029164-0.019868
\n", + "
" + ], + "text/plain": [ + " Asset_1 Asset_2 Asset_3 Portfolio_Value Market_Index\n", + "timestamp \n", + "02-01-2020 -0.196916 1.104952 0.491983 0.509525 -0.008552\n", + "03-01-2020 -0.123737 -0.112190 -0.451162 -0.241793 -0.001205\n", + "06-01-2020 0.481437 0.169089 -0.865690 -0.060214 -0.056688\n", + "07-01-2020 -0.846615 -0.978156 10.721087 -0.486102 0.072232\n", + "08-01-2020 7.931057 42.030717 0.175348 2.029164 -0.019868" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "returns = df.pct_change().dropna()\n", + "returns.head()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7MLPZBswwuTL" + }, + "source": [ + "# Define Fitness Function" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "id": "ADnAYwDKFdu7" + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "def fitness_function(weights, returns):\n", + " portfolio_return = np.sum(returns.mean() * weights) * 252\n", + " portfolio_stddev = np.sqrt(np.dot(weights.T, np.dot(returns.cov() * 252, weights)))\n", + " sharpe_ratio = portfolio_return / portfolio_stddev\n", + " return sharpe_ratio\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tN7T8oixw0ZL" + }, + "source": [ + "# Initial Population" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "id": "newRizz2FhTL" + }, + "outputs": [], + "source": [ + "def initialize_population(pop_size, num_assets):\n", + " population = []\n", + " for _ in range(pop_size):\n", + " weights = np.random.random(num_assets)\n", + " weights /= np.sum(weights)\n", + " population.append(weights)\n", + " return np.array(population)\n", + "\n", + "pop_size = 100\n", + "num_assets = len(df.columns)\n", + "population = initialize_population(pop_size, num_assets)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xfwajDq9w4AH" + }, + "source": [ + "# Selection" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "id": "JVhMT8DbFjMo" + }, + "outputs": [], + "source": [ + "def selection(population, fitness_scores, num_parents):\n", + " parents = np.empty((num_parents, population.shape[1]))\n", + " for i in range(num_parents):\n", + " max_fitness_idx = np.where(fitness_scores == np.max(fitness_scores))\n", + " max_fitness_idx = max_fitness_idx[0][0]\n", + " parents[i, :] = population[max_fitness_idx, :]\n", + " fitness_scores[max_fitness_idx] = -999999\n", + " return parents\n", + "\n", + "num_parents = 20\n", + "fitness_scores = np.array([fitness_function(weights, returns) for weights in population])\n", + "parents = selection(population, fitness_scores, num_parents)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jqEhbITsw9t1" + }, + "source": [ + "# Crossover" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "id": "1kGod21wFldT" + }, + "outputs": [], + "source": [ + "def crossover(parents, offspring_size):\n", + " offspring = np.empty(offspring_size)\n", + " crossover_point = np.uint8(offspring_size[1]/2)\n", + "\n", + " for k in range(offspring_size[0]):\n", + " parent1_idx = k % parents.shape[0]\n", + " parent2_idx = (k + 1) % parents.shape[0]\n", + " offspring[k, 0:crossover_point] = parents[parent1_idx, 0:crossover_point]\n", + " offspring[k, crossover_point:] = parents[parent2_idx, crossover_point:]\n", + " return offspring\n", + "\n", + "offspring_size = (pop_size - parents.shape[0], num_assets)\n", + "offspring = crossover(parents, offspring_size)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AjnCQOIrxBbe" + }, + "source": [ + "# Mutation" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "id": "fCZuohWDFnyT" + }, + "outputs": [], + "source": [ + "def mutation(offspring, mutation_rate=0.01):\n", + " for idx in range(offspring.shape[0]):\n", + " for gene_idx in range(offspring.shape[1]):\n", + " if np.random.rand() < mutation_rate:\n", + " random_value = np.random.random()\n", + " offspring[idx, gene_idx] = offspring[idx, gene_idx] + random_value\n", + " offspring[idx, gene_idx] /= np.sum(offspring[idx, :])\n", + " return offspring\n", + "\n", + "mutated_offspring = mutation(offspring)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xEDvzIMbxGTc" + }, + "source": [ + "# Termination" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "id": "WzsJq1NSFpf3" + }, + "outputs": [], + "source": [ + "def mutation(offspring, mutation_rate=0.01):\n", + " for idx in range(offspring.shape[0]):\n", + " for gene_idx in range(offspring.shape[1]):\n", + " if np.random.rand() < mutation_rate:\n", + " random_value = np.random.random()\n", + " offspring[idx, gene_idx] = offspring[idx, gene_idx] + random_value\n", + " offspring[idx, gene_idx] /= np.sum(offspring[idx, :])\n", + " return offspring\n", + "\n", + "mutated_offspring = mutation(offspring)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s-2eE9IWxIxw" + }, + "source": [] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "rkW-7vLYFrRq", + "outputId": "45fbe294-405e-491d-9b41-312512d0b006" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Generation 0: Best Fitness = 1.4762715381515883\n", + "Generation 1: Best Fitness = 2.02523213483615\n", + "Generation 2: Best Fitness = 2.447525052066359\n", + "Generation 3: Best Fitness = 2.5968127611299243\n", + "Generation 4: Best Fitness = 2.601141911178252\n", + "Generation 5: Best Fitness = 2.601323996364056\n", + "Generation 6: Best Fitness = 2.651556189371385\n", + "Generation 7: Best Fitness = 2.651556189371385\n", + "Generation 8: Best Fitness = 2.651871247334236\n", + "Generation 9: Best Fitness = 2.651871247334236\n", + "Generation 10: Best Fitness = 2.6585766530068415\n", + "Generation 11: Best Fitness = 2.6706997052344295\n", + "Generation 12: Best Fitness = 2.697812640265176\n", + "Generation 13: Best Fitness = 2.697812640265176\n", + "Generation 14: Best Fitness = 2.697812640265176\n", + "Generation 15: Best Fitness = 2.6988428788994336\n", + "Generation 16: Best Fitness = 2.6989832050307423\n", + "Generation 17: Best Fitness = 2.6989832050307423\n", + "Generation 18: Best Fitness = 2.6998114819174277\n", + "Generation 19: Best Fitness = 2.7029987211167135\n", + "Generation 20: Best Fitness = 2.7029987211167135\n", + "Generation 21: Best Fitness = 2.7029987211167135\n", + "Generation 22: Best Fitness = 2.7029987211167135\n", + "Generation 23: Best Fitness = 2.7038430414694936\n", + "Generation 24: Best Fitness = 2.703919023191884\n", + "Generation 25: Best Fitness = 2.703919023191884\n", + "Generation 26: Best Fitness = 2.703919023191884\n", + "Generation 27: Best Fitness = 2.703947768620708\n", + "Generation 28: Best Fitness = 2.703947768620708\n", + "Generation 29: Best Fitness = 2.703947768620708\n", + "Generation 30: Best Fitness = 2.7210426858453953\n", + "Generation 31: Best Fitness = 2.7210426858453953\n", + "Generation 32: Best Fitness = 2.7210426858453953\n", + "Generation 33: Best Fitness = 2.7210426858453953\n", + "Generation 34: Best Fitness = 2.7210426858453953\n", + "Generation 35: Best Fitness = 2.721341020773319\n", + "Generation 36: Best Fitness = 2.721341020773319\n", + "Generation 37: Best Fitness = 2.721341020773319\n", + "Generation 38: Best Fitness = 2.721341020773319\n", + "Generation 39: Best Fitness = 2.721341020773319\n", + "Generation 40: Best Fitness = 2.726566517461905\n", + "Generation 41: Best Fitness = 2.726566517461905\n", + "Generation 42: Best Fitness = 2.726566517461905\n", + "Generation 43: Best Fitness = 2.726566517461905\n", + "Generation 44: Best Fitness = 2.726566517461905\n", + "Generation 45: Best Fitness = 2.726566517461905\n", + "Generation 46: Best Fitness = 2.7286023649211115\n", + "Generation 47: Best Fitness = 2.7286023649211115\n", + "Generation 48: Best Fitness = 2.731539215384595\n", + "Generation 49: Best Fitness = 2.731539215384595\n", + "Generation 50: Best Fitness = 2.731539215384595\n", + "Generation 51: Best Fitness = 2.731539215384595\n", + "Generation 52: Best Fitness = 2.731668375416001\n", + "Generation 53: Best Fitness = 2.731668375416001\n", + "Generation 54: Best Fitness = 2.731668375416001\n", + "Generation 55: Best Fitness = 2.731668375416001\n", + "Generation 56: Best Fitness = 2.731668375416001\n", + "Generation 57: Best Fitness = 2.731668375416001\n", + "Generation 58: Best Fitness = 2.731668375416001\n", + "Generation 59: Best Fitness = 2.731668375416001\n", + "Generation 60: Best Fitness = 2.731668375416001\n", + "Generation 61: Best Fitness = 2.731668375416001\n", + "Generation 62: Best Fitness = 2.731668375416001\n", + "Generation 63: Best Fitness = 2.731668375416001\n", + "Generation 64: Best Fitness = 2.731668375416001\n", + "Generation 65: Best Fitness = 2.731668375416001\n", + "Generation 66: Best Fitness = 2.731668375416001\n", + "Generation 67: Best Fitness = 2.731668375416001\n", + "Generation 68: Best Fitness = 2.731668375416001\n", + "Generation 69: Best Fitness = 2.731668375416001\n", + "Generation 70: Best Fitness = 2.731668375416001\n", + "Generation 71: Best Fitness = 2.731668375416001\n", + "Generation 72: Best Fitness = 2.731668375416001\n", + "Generation 73: Best Fitness = 2.731668375416001\n", + "Generation 74: Best Fitness = 2.731668375416001\n", + "Generation 75: Best Fitness = 2.731668375416001\n", + "Generation 76: Best Fitness = 2.731668375416001\n", + "Generation 77: Best Fitness = 2.731668375416001\n", + "Generation 78: Best Fitness = 2.731668375416001\n", + "Generation 79: Best Fitness = 2.731668375416001\n", + "Generation 80: Best Fitness = 2.731668375416001\n", + "Generation 81: Best Fitness = 2.731668375416001\n", + "Generation 82: Best Fitness = 2.731668375416001\n", + "Generation 83: Best Fitness = 2.731668375416001\n", + "Generation 84: Best Fitness = 2.731668375416001\n", + "Generation 85: Best Fitness = 2.731668375416001\n", + "Generation 86: Best Fitness = 2.7318855517681677\n", + "Generation 87: Best Fitness = 2.7599264504842895\n", + "Generation 88: Best Fitness = 2.7610897975155377\n", + "Generation 89: Best Fitness = 2.7610897975155377\n", + "Generation 90: Best Fitness = 2.7610897975155377\n", + "Generation 91: Best Fitness = 2.7610897975155377\n", + "Generation 92: Best Fitness = 2.7610897975155377\n", + "Generation 93: Best Fitness = 2.761122952025336\n", + "Generation 94: Best Fitness = 2.761122952025336\n", + "Generation 95: Best Fitness = 2.7611314301006784\n", + "Generation 96: Best Fitness = 2.7611314301006784\n", + "Generation 97: Best Fitness = 2.7611314301006784\n", + "Generation 98: Best Fitness = 2.7629489584544022\n", + "Generation 99: Best Fitness = 2.7629489584544022\n" + ] + } + ], + "source": [ + "def genetic_algorithm(returns, num_generations, pop_size, num_parents, mutation_rate):\n", + " num_assets = returns.shape[1]\n", + " population = initialize_population(pop_size, num_assets)\n", + " for generation in range(num_generations):\n", + " fitness_scores = np.array([fitness_function(weights, returns) for weights in population])\n", + " parents = selection(population, fitness_scores, num_parents)\n", + " offspring_size = (pop_size - parents.shape[0], num_assets)\n", + " offspring = crossover(parents, offspring_size)\n", + " offspring = mutation(offspring, mutation_rate)\n", + " population[0:parents.shape[0], :] = parents\n", + " population[parents.shape[0]:, :] = offspring\n", + " best_fitness = np.max(fitness_scores)\n", + " print(f\"Generation {generation}: Best Fitness = {best_fitness}\")\n", + " return population, fitness_scores\n", + "\n", + "num_generations = 100\n", + "population, fitness_scores = genetic_algorithm(returns, num_generations, pop_size, num_parents, mutation_rate=0.01)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YFQ1uXj5xNuu" + }, + "source": [ + "# Evaluate Best portfolio" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "6vLI0G12Fxfc", + "outputId": "061304f9-ef21-447f-87c7-f1782a0e732f" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Best Portfolio Weights: [0.01644336 0.08476277 0.52198998 0.62815317 0.5433535 ]\n", + "Expected Annual Return: 492.3823055102672\n", + "Annual Volatility: 178.2089763198907\n", + "Sharpe Ratio: 2.7629489584544022\n" + ] + } + ], + "source": [ + "best_idx = np.argmax(fitness_scores)\n", + "best_portfolio = population[best_idx, :]\n", + "best_portfolio_return = np.sum(returns.mean() * best_portfolio) * 252\n", + "best_portfolio_stddev = np.sqrt(np.dot(best_portfolio.T, np.dot(returns.cov() * 252, best_portfolio)))\n", + "best_portfolio_sharpe = best_portfolio_return / best_portfolio_stddev\n", + "\n", + "print(f\"Best Portfolio Weights: {best_portfolio}\")\n", + "print(f\"Expected Annual Return: {best_portfolio_return}\")\n", + "print(f\"Annual Volatility: {best_portfolio_stddev}\")\n", + "print(f\"Sharpe Ratio: {best_portfolio_sharpe}\")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tybZDt2YxUIU" + }, + "source": [] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.12.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/PortFolio Optimaization Using Genetic ALgorithm/.ipynb_checkpoints/readme-checkpoint.md b/PortFolio Optimaization Using Genetic ALgorithm/.ipynb_checkpoints/readme-checkpoint.md new file mode 100644 index 0000000..2d6817b --- /dev/null +++ b/PortFolio Optimaization Using Genetic ALgorithm/.ipynb_checkpoints/readme-checkpoint.md @@ -0,0 +1,36 @@ +# Portfolio Optimization Using Genetic Algorithms + +## Overview +This project implements portfolio optimization using genetic algorithms to find the optimal asset allocation that maximizes returns and minimizes risk. + +## Objectives +- **Data Collection:** Gather historical price data for a set of assets. +- **Data Preprocessing:** Clean and prepare the data for analysis. +- **Feature Engineering:** Calculate returns, volatility, and correlations. +- **Genetic Algorithm Implementation:** Develop and apply a genetic algorithm to optimize the portfolio. +- **Evaluation:** Assess the performance of the optimized portfolio. + +## Methodology +1. **Data Collection:** + - Collect historical price data for various assets from sources like Yahoo Finance, Quandl, or Bloomberg. + +2. **Data Preprocessing:** + - Handle missing values and outliers. + - Calculate daily, monthly, or annual returns. + +3. **Feature Engineering:** + - Compute metrics such as average return, standard deviation, and correlation matrix. + +4. **Genetic Algorithm Implementation:** + - Define the chromosome representation, fitness function, and genetic operators (selection, crossover, mutation). + - Optimize the portfolio by maximizing the Sharpe ratio or minimizing risk. + +5. **Evaluation:** + - Evaluate the optimized portfolio's performance against a benchmark. + - Use metrics such as Sharpe ratio, Sortino ratio, and Maximum Drawdown. + +## Tools and Technologies +- **Programming Languages:** Python +- **Libraries:** pandas, numpy, scipy, matplotlib, seaborn, DEAP (for genetic algorithms) + + diff --git a/PortFolio Optimaization Using Genetic ALgorithm/Portfolio_Optimization_Using_Genetic_Algorithm.ipynb b/PortFolio Optimaization Using Genetic ALgorithm/Portfolio_Optimization_Using_Genetic_Algorithm.ipynb deleted file mode 100644 index 292f4a3..0000000 --- a/PortFolio Optimaization Using Genetic ALgorithm/Portfolio_Optimization_Using_Genetic_Algorithm.ipynb +++ /dev/null @@ -1,1090 +0,0 @@ -{ - "nbformat": 4, - "nbformat_minor": 0, - "metadata": { - "colab": { - "provenance": [] - }, - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - }, - "language_info": { - "name": "python" - } - }, - "cells": [ - { - "cell_type": "markdown", - "source": [ - "# **Portfolio Optimization Using Genetic Algorithm**" - ], - "metadata": { - "id": "FgneRLb5xWON" - } - }, - { - "cell_type": "code", - "source": [ - "Load the data" - ], - "metadata": { - "id": "HTGK4uLYMf5A" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 324 - }, - "id": "CCgHhKp6FHbT", - "outputId": "f358ffad-1db0-4203-ee75-37ce1f5c1234" - }, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - " Asset_1 Asset_2 Asset_3 Portfolio_Value Market_Index\n", - "timestamp \n", - "01-01-2020 544.883183 423.654799 645.894113 525.051834 1034.932512\n", - "02-01-2020 437.587211 891.773001 963.662760 792.579124 1026.081261\n", - "03-01-2020 383.441519 791.725038 528.894920 600.939199 1024.844657\n", - "06-01-2020 568.044561 925.596638 71.036058 564.754139 966.747919\n", - "07-01-2020 87.129300 20.218397 832.619845 290.226071 1036.577579" - ], - "text/html": [ - "\n", - "
\n", - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Asset_1Asset_2Asset_3Portfolio_ValueMarket_Index
timestamp
01-01-2020544.883183423.654799645.894113525.0518341034.932512
02-01-2020437.587211891.773001963.662760792.5791241026.081261
03-01-2020383.441519791.725038528.894920600.9391991024.844657
06-01-2020568.044561925.59663871.036058564.754139966.747919
07-01-202087.12930020.218397832.619845290.2260711036.577579
\n", - "
\n", - "
\n", - "\n", - "
\n", - " \n", - "\n", - " \n", - "\n", - " \n", - "
\n", - "\n", - "\n", - "
\n", - " \n", - "\n", - "\n", - "\n", - " \n", - "
\n", - "\n", - "
\n", - "
\n" - ], - "application/vnd.google.colaboratory.intrinsic+json": { - "type": "dataframe", - "variable_name": "df", - "summary": "{\n \"name\": \"df\",\n \"rows\": 1043,\n \"fields\": [\n {\n \"column\": \"timestamp\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 1043,\n \"samples\": [\n \"20-12-2023\",\n \"27-01-2021\",\n \"19-01-2022\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Asset_1\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 297.35676415681485,\n \"min\": 0.073699433,\n \"max\": 998.3548771,\n \"num_unique_values\": 1043,\n \"samples\": [\n 968.94482,\n 817.3391115,\n 650.9140039\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Asset_2\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 291.42740758056345,\n \"min\": 0.367343751,\n \"max\": 999.9640185,\n \"num_unique_values\": 1043,\n \"samples\": [\n 161.7411946,\n 473.1429785,\n 827.3132278\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Asset_3\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 286.894731308728,\n \"min\": 0.545964897,\n \"max\": 999.8085781,\n \"num_unique_values\": 1043,\n \"samples\": [\n 272.3958027,\n 882.2836719,\n 684.4985465\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Portfolio_Value\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 176.64503631072182,\n \"min\": 70.49999954,\n \"max\": 953.5230386,\n \"num_unique_values\": 1043,\n \"samples\": [\n 412.0217229,\n 692.1879739,\n 735.8043658\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Market_Index\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 49.23344411753262,\n \"min\": 849.6750642,\n \"max\": 1190.083011,\n \"num_unique_values\": 1043,\n \"samples\": [\n 988.9304751,\n 1040.616679,\n 981.022294\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}" - } - }, - "metadata": {}, - "execution_count": 1 - } - ], - "source": [ - "import pandas as pd\n", - "\n", - "# Load data\n", - "df = pd.read_csv('/content/portfolio_data.csv', index_col=0, parse_dates=True)\n", - "df.head()\n" - ] - }, - { - "cell_type": "code", - "source": [], - "metadata": { - "id": "SzuX4BaAMi1X" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "# **Calculate Return**" - ], - "metadata": { - "id": "otw_6mVnwCrn" - } - }, - { - "cell_type": "code", - "source": [ - "returns = df.pct_change().dropna()\n", - "returns.head()\n" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 237 - }, - "id": "Pm3NBpSVFbEj", - "outputId": "73fa7e6b-70d1-4b18-bbe0-393da1eaedff" - }, - "execution_count": null, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - " Asset_1 Asset_2 Asset_3 Portfolio_Value Market_Index\n", - "timestamp \n", - "02-01-2020 -0.196916 1.104952 0.491983 0.509525 -0.008552\n", - "03-01-2020 -0.123737 -0.112190 -0.451162 -0.241793 -0.001205\n", - "06-01-2020 0.481437 0.169089 -0.865690 -0.060214 -0.056688\n", - "07-01-2020 -0.846615 -0.978156 10.721087 -0.486102 0.072232\n", - "08-01-2020 7.931057 42.030717 0.175348 2.029164 -0.019868" - ], - "text/html": [ - "\n", - "
\n", - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Asset_1Asset_2Asset_3Portfolio_ValueMarket_Index
timestamp
02-01-2020-0.1969161.1049520.4919830.509525-0.008552
03-01-2020-0.123737-0.112190-0.451162-0.241793-0.001205
06-01-20200.4814370.169089-0.865690-0.060214-0.056688
07-01-2020-0.846615-0.97815610.721087-0.4861020.072232
08-01-20207.93105742.0307170.1753482.029164-0.019868
\n", - "
\n", - "
\n", - "\n", - "
\n", - " \n", - "\n", - " \n", - "\n", - " \n", - "
\n", - "\n", - "\n", - "
\n", - " \n", - "\n", - "\n", - "\n", - " \n", - "
\n", - "\n", - "
\n", - "
\n" - ], - "application/vnd.google.colaboratory.intrinsic+json": { - "type": "dataframe", - "variable_name": "returns", - "summary": "{\n \"name\": \"returns\",\n \"rows\": 1042,\n \"fields\": [\n {\n \"column\": \"timestamp\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 1042,\n \"samples\": [\n \"14-01-2022\",\n \"03-04-2023\",\n \"02-11-2021\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Asset_1\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 224.6327785434078,\n \"min\": -0.9999210466892944,\n \"max\": 7222.0687432832765,\n \"num_unique_values\": 1042,\n \"samples\": [\n -0.6761679148750576,\n 0.49714190646952816,\n -0.4763627141394565\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Asset_2\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 59.53731595106503,\n \"min\": -0.9988055106324675,\n \"max\": 1736.7807387827322,\n \"num_unique_values\": 1042,\n \"samples\": [\n 0.2878634293587754,\n -0.8129127864207362,\n -0.8511612594885148\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Asset_3\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 17.748320739953726,\n \"min\": -0.9993120588883697,\n \"max\": 380.4407359233574,\n \"num_unique_values\": 1042,\n \"samples\": [\n -0.5503353506007611,\n -0.06812604800404243,\n -0.4344354157245046\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Portfolio_Value\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.78378699798799,\n \"min\": -0.8891291434918596,\n \"max\": 6.697990119731567,\n \"num_unique_values\": 1042,\n \"samples\": [\n -0.21442045447586378,\n -0.2965740287022468,\n -0.6318635767325322\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Market_Index\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.06793369258923397,\n \"min\": -0.2066701830021066,\n \"max\": 0.20590153875399797,\n \"num_unique_values\": 1042,\n \"samples\": [\n -0.0447209020183893,\n -0.12488407279002756,\n -0.045631757458398425\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}" - } - }, - "metadata": {}, - "execution_count": 2 - } - ] - }, - { - "cell_type": "markdown", - "source": [ - "# Define Fitness Function" - ], - "metadata": { - "id": "7MLPZBswwuTL" - } - }, - { - "cell_type": "code", - "source": [ - "import numpy as np\n", - "\n", - "def fitness_function(weights, returns):\n", - " portfolio_return = np.sum(returns.mean() * weights) * 252\n", - " portfolio_stddev = np.sqrt(np.dot(weights.T, np.dot(returns.cov() * 252, weights)))\n", - " sharpe_ratio = portfolio_return / portfolio_stddev\n", - " return sharpe_ratio\n" - ], - "metadata": { - "id": "ADnAYwDKFdu7" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "# Initial Population" - ], - "metadata": { - "id": "tN7T8oixw0ZL" - } - }, - { - "cell_type": "code", - "source": [ - "def initialize_population(pop_size, num_assets):\n", - " population = []\n", - " for _ in range(pop_size):\n", - " weights = np.random.random(num_assets)\n", - " weights /= np.sum(weights)\n", - " population.append(weights)\n", - " return np.array(population)\n", - "\n", - "pop_size = 100\n", - "num_assets = len(df.columns)\n", - "population = initialize_population(pop_size, num_assets)\n" - ], - "metadata": { - "id": "newRizz2FhTL" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "# Selection" - ], - "metadata": { - "id": "xfwajDq9w4AH" - } - }, - { - "cell_type": "code", - "source": [ - "def selection(population, fitness_scores, num_parents):\n", - " parents = np.empty((num_parents, population.shape[1]))\n", - " for i in range(num_parents):\n", - " max_fitness_idx = np.where(fitness_scores == np.max(fitness_scores))\n", - " max_fitness_idx = max_fitness_idx[0][0]\n", - " parents[i, :] = population[max_fitness_idx, :]\n", - " fitness_scores[max_fitness_idx] = -999999\n", - " return parents\n", - "\n", - "num_parents = 20\n", - "fitness_scores = np.array([fitness_function(weights, returns) for weights in population])\n", - "parents = selection(population, fitness_scores, num_parents)\n" - ], - "metadata": { - "id": "JVhMT8DbFjMo" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "# Crossover" - ], - "metadata": { - "id": "jqEhbITsw9t1" - } - }, - { - "cell_type": "code", - "source": [ - "def crossover(parents, offspring_size):\n", - " offspring = np.empty(offspring_size)\n", - " crossover_point = np.uint8(offspring_size[1]/2)\n", - "\n", - " for k in range(offspring_size[0]):\n", - " parent1_idx = k % parents.shape[0]\n", - " parent2_idx = (k + 1) % parents.shape[0]\n", - " offspring[k, 0:crossover_point] = parents[parent1_idx, 0:crossover_point]\n", - " offspring[k, crossover_point:] = parents[parent2_idx, crossover_point:]\n", - " return offspring\n", - "\n", - "offspring_size = (pop_size - parents.shape[0], num_assets)\n", - "offspring = crossover(parents, offspring_size)\n" - ], - "metadata": { - "id": "1kGod21wFldT" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "# Mutation" - ], - "metadata": { - "id": "AjnCQOIrxBbe" - } - }, - { - "cell_type": "code", - "source": [ - "def mutation(offspring, mutation_rate=0.01):\n", - " for idx in range(offspring.shape[0]):\n", - " for gene_idx in range(offspring.shape[1]):\n", - " if np.random.rand() < mutation_rate:\n", - " random_value = np.random.random()\n", - " offspring[idx, gene_idx] = offspring[idx, gene_idx] + random_value\n", - " offspring[idx, gene_idx] /= np.sum(offspring[idx, :])\n", - " return offspring\n", - "\n", - "mutated_offspring = mutation(offspring)\n" - ], - "metadata": { - "id": "fCZuohWDFnyT" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "# Termination" - ], - "metadata": { - "id": "xEDvzIMbxGTc" - } - }, - { - "cell_type": "code", - "source": [ - "def mutation(offspring, mutation_rate=0.01):\n", - " for idx in range(offspring.shape[0]):\n", - " for gene_idx in range(offspring.shape[1]):\n", - " if np.random.rand() < mutation_rate:\n", - " random_value = np.random.random()\n", - " offspring[idx, gene_idx] = offspring[idx, gene_idx] + random_value\n", - " offspring[idx, gene_idx] /= np.sum(offspring[idx, :])\n", - " return offspring\n", - "\n", - "mutated_offspring = mutation(offspring)\n" - ], - "metadata": { - "id": "WzsJq1NSFpf3" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [], - "metadata": { - "id": "s-2eE9IWxIxw" - } - }, - { - "cell_type": "code", - "source": [ - "def genetic_algorithm(returns, num_generations, pop_size, num_parents, mutation_rate):\n", - " num_assets = returns.shape[1]\n", - " population = initialize_population(pop_size, num_assets)\n", - " for generation in range(num_generations):\n", - " fitness_scores = np.array([fitness_function(weights, returns) for weights in population])\n", - " parents = selection(population, fitness_scores, num_parents)\n", - " offspring_size = (pop_size - parents.shape[0], num_assets)\n", - " offspring = crossover(parents, offspring_size)\n", - " offspring = mutation(offspring, mutation_rate)\n", - " population[0:parents.shape[0], :] = parents\n", - " population[parents.shape[0]:, :] = offspring\n", - " best_fitness = np.max(fitness_scores)\n", - " print(f\"Generation {generation}: Best Fitness = {best_fitness}\")\n", - " return population, fitness_scores\n", - "\n", - "num_generations = 100\n", - "population, fitness_scores = genetic_algorithm(returns, num_generations, pop_size, num_parents, mutation_rate=0.01)\n" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "rkW-7vLYFrRq", - "outputId": "45fbe294-405e-491d-9b41-312512d0b006" - }, - "execution_count": null, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Generation 0: Best Fitness = 1.417253614680323\n", - "Generation 1: Best Fitness = 1.8779466185434148\n", - "Generation 2: Best Fitness = 2.0430037580572336\n", - "Generation 3: Best Fitness = 2.0920158355234864\n", - "Generation 4: Best Fitness = 2.4902477236462275\n", - "Generation 5: Best Fitness = 2.4902477236462275\n", - "Generation 6: Best Fitness = 2.4902477236462275\n", - "Generation 7: Best Fitness = 2.521225040481554\n", - "Generation 8: Best Fitness = 2.521225040481554\n", - "Generation 9: Best Fitness = 2.5409096684344568\n", - "Generation 10: Best Fitness = 2.5409096684344568\n", - "Generation 11: Best Fitness = 2.5414701981903742\n", - "Generation 12: Best Fitness = 2.5414701981903742\n", - "Generation 13: Best Fitness = 2.575155889229864\n", - "Generation 14: Best Fitness = 2.575155889229864\n", - "Generation 15: Best Fitness = 2.575155889229864\n", - "Generation 16: Best Fitness = 2.5758970013396527\n", - "Generation 17: Best Fitness = 2.5758970013396527\n", - "Generation 18: Best Fitness = 2.5759063088633067\n", - "Generation 19: Best Fitness = 2.5760569272179454\n", - "Generation 20: Best Fitness = 2.5760569272179454\n", - "Generation 21: Best Fitness = 2.580023239229417\n", - "Generation 22: Best Fitness = 2.580023239229417\n", - "Generation 23: Best Fitness = 2.5861124541129388\n", - "Generation 24: Best Fitness = 2.5861124541129388\n", - "Generation 25: Best Fitness = 2.586185095785435\n", - "Generation 26: Best Fitness = 2.586185095785435\n", - "Generation 27: Best Fitness = 2.586185095785435\n", - "Generation 28: Best Fitness = 2.586185095785435\n", - "Generation 29: Best Fitness = 2.586185095785435\n", - "Generation 30: Best Fitness = 2.586185095785435\n", - "Generation 31: Best Fitness = 2.586185095785435\n", - "Generation 32: Best Fitness = 2.586185095785435\n", - "Generation 33: Best Fitness = 2.586185095785435\n", - "Generation 34: Best Fitness = 2.586185095785435\n", - "Generation 35: Best Fitness = 2.586185095785435\n", - "Generation 36: Best Fitness = 2.586185095785435\n", - "Generation 37: Best Fitness = 2.586185095785435\n", - "Generation 38: Best Fitness = 2.588992264842197\n", - "Generation 39: Best Fitness = 2.596323300370395\n", - "Generation 40: Best Fitness = 2.596323300370395\n", - "Generation 41: Best Fitness = 2.596323300370395\n", - "Generation 42: Best Fitness = 2.596323300370395\n", - "Generation 43: Best Fitness = 2.596323300370395\n", - "Generation 44: Best Fitness = 2.596323300370395\n", - "Generation 45: Best Fitness = 2.596323300370395\n", - "Generation 46: Best Fitness = 2.596323300370395\n", - "Generation 47: Best Fitness = 2.596331571848502\n", - "Generation 48: Best Fitness = 2.596331571848502\n", - "Generation 49: Best Fitness = 2.596331571848502\n", - "Generation 50: Best Fitness = 2.596331571848502\n", - "Generation 51: Best Fitness = 2.596331571848502\n", - "Generation 52: Best Fitness = 2.596331571848502\n", - "Generation 53: Best Fitness = 2.596331571848502\n", - "Generation 54: Best Fitness = 2.596331571848502\n", - "Generation 55: Best Fitness = 2.596331571848502\n", - "Generation 56: Best Fitness = 2.596331571848502\n", - "Generation 57: Best Fitness = 2.596331571848502\n", - "Generation 58: Best Fitness = 2.596331571848502\n", - "Generation 59: Best Fitness = 2.596331571848502\n", - "Generation 60: Best Fitness = 2.596331571848502\n", - "Generation 61: Best Fitness = 2.596331571848502\n", - "Generation 62: Best Fitness = 2.596331571848502\n", - "Generation 63: Best Fitness = 2.596331571848502\n", - "Generation 64: Best Fitness = 2.596331571848502\n", - "Generation 65: Best Fitness = 2.596331571848502\n", - "Generation 66: Best Fitness = 2.596331571848502\n", - "Generation 67: Best Fitness = 2.5963368694291065\n", - "Generation 68: Best Fitness = 2.5963368694291065\n", - "Generation 69: Best Fitness = 2.5963368694291065\n", - "Generation 70: Best Fitness = 2.5963368694291065\n", - "Generation 71: Best Fitness = 2.5963368694291065\n", - "Generation 72: Best Fitness = 2.5963368694291065\n", - "Generation 73: Best Fitness = 2.5963368694291065\n", - "Generation 74: Best Fitness = 2.5963368694291065\n", - "Generation 75: Best Fitness = 2.5963368694291065\n", - "Generation 76: Best Fitness = 2.5963368694291065\n", - "Generation 77: Best Fitness = 2.5963368694291065\n", - "Generation 78: Best Fitness = 2.5963368694291065\n", - "Generation 79: Best Fitness = 2.5963498076018925\n", - "Generation 80: Best Fitness = 2.5963498076018925\n", - "Generation 81: Best Fitness = 2.5963498076018925\n", - "Generation 82: Best Fitness = 2.5963498076018925\n", - "Generation 83: Best Fitness = 2.5963498076018925\n", - "Generation 84: Best Fitness = 2.5963498076018925\n", - "Generation 85: Best Fitness = 2.5963498076018925\n", - "Generation 86: Best Fitness = 2.5963498076018925\n", - "Generation 87: Best Fitness = 2.5963498076018925\n", - "Generation 88: Best Fitness = 2.5963498076018925\n", - "Generation 89: Best Fitness = 2.5963498076018925\n", - "Generation 90: Best Fitness = 2.5963498076018925\n", - "Generation 91: Best Fitness = 2.5963498076018925\n", - "Generation 92: Best Fitness = 2.5963498076018925\n", - "Generation 93: Best Fitness = 2.5963498076018925\n", - "Generation 94: Best Fitness = 2.5963498076018925\n", - "Generation 95: Best Fitness = 2.5963498076018925\n", - "Generation 96: Best Fitness = 2.5963498076018925\n", - "Generation 97: Best Fitness = 2.5963498076018925\n", - "Generation 98: Best Fitness = 2.5963498076018925\n", - "Generation 99: Best Fitness = 2.5963502910456278\n" - ] - } - ] - }, - { - "cell_type": "markdown", - "source": [ - "# Evaluate Best portfolio" - ], - "metadata": { - "id": "YFQ1uXj5xNuu" - } - }, - { - "cell_type": "code", - "source": [ - "best_idx = np.argmax(fitness_scores)\n", - "best_portfolio = population[best_idx, :]\n", - "best_portfolio_return = np.sum(returns.mean() * best_portfolio) * 252\n", - "best_portfolio_stddev = np.sqrt(np.dot(best_portfolio.T, np.dot(returns.cov() * 252, best_portfolio)))\n", - "best_portfolio_sharpe = best_portfolio_return / best_portfolio_stddev\n", - "\n", - "print(f\"Best Portfolio Weights: {best_portfolio}\")\n", - "print(f\"Expected Annual Return: {best_portfolio_return}\")\n", - "print(f\"Annual Volatility: {best_portfolio_stddev}\")\n", - "print(f\"Sharpe Ratio: {best_portfolio_sharpe}\")\n" - ], - "metadata": { - "id": "6vLI0G12Fxfc", - "outputId": "061304f9-ef21-447f-87c7-f1782a0e732f", - "colab": { - "base_uri": "https://localhost:8080/" - } - }, - "execution_count": null, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Best Portfolio Weights: [0.04189262 0.13620183 0.72651027 0.56140873 0.49904594]\n", - "Expected Annual Return: 737.635018426684\n", - "Annual Volatility: 284.1045836421465\n", - "Sharpe Ratio: 2.5963502910456278\n" - ] - } - ] - }, - { - "cell_type": "markdown", - "source": [], - "metadata": { - "id": "tybZDt2YxUIU" - } - } - ] -} \ No newline at end of file diff --git a/backlog/Portfolio_Optimization_Using_Genetic_Algorithm.ipynb b/backlog/Portfolio_Optimization_Using_Genetic_Algorithm.ipynb new file mode 100644 index 0000000..0a3989d --- /dev/null +++ b/backlog/Portfolio_Optimization_Using_Genetic_Algorithm.ipynb @@ -0,0 +1,666 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "FgneRLb5xWON" + }, + "source": [ + "# **Portfolio Optimization Using Genetic Algorithm**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HTGK4uLYMf5A" + }, + "source": [ + "Load the data" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 324 + }, + "id": "CCgHhKp6FHbT", + "outputId": "f358ffad-1db0-4203-ee75-37ce1f5c1234" + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Asset_1Asset_2Asset_3Portfolio_ValueMarket_Index
timestamp
01-01-2020544.883183423.654799645.894113525.0518341034.932512
02-01-2020437.587211891.773001963.662760792.5791241026.081261
03-01-2020383.441519791.725038528.894920600.9391991024.844657
06-01-2020568.044561925.59663871.036058564.754139966.747919
07-01-202087.12930020.218397832.619845290.2260711036.577579
\n", + "
" + ], + "text/plain": [ + " Asset_1 Asset_2 Asset_3 Portfolio_Value Market_Index\n", + "timestamp \n", + "01-01-2020 544.883183 423.654799 645.894113 525.051834 1034.932512\n", + "02-01-2020 437.587211 891.773001 963.662760 792.579124 1026.081261\n", + "03-01-2020 383.441519 791.725038 528.894920 600.939199 1024.844657\n", + "06-01-2020 568.044561 925.596638 71.036058 564.754139 966.747919\n", + "07-01-2020 87.129300 20.218397 832.619845 290.226071 1036.577579" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "\n", + "# Load data\n", + "df = pd.read_csv('portfolio_data.csv', index_col=0, parse_dates=True)\n", + "df.head()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "SzuX4BaAMi1X" + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "otw_6mVnwCrn" + }, + "source": [ + "# **Calculate Return**" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 237 + }, + "id": "Pm3NBpSVFbEj", + "outputId": "73fa7e6b-70d1-4b18-bbe0-393da1eaedff" + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Asset_1Asset_2Asset_3Portfolio_ValueMarket_Index
timestamp
02-01-2020-0.1969161.1049520.4919830.509525-0.008552
03-01-2020-0.123737-0.112190-0.451162-0.241793-0.001205
06-01-20200.4814370.169089-0.865690-0.060214-0.056688
07-01-2020-0.846615-0.97815610.721087-0.4861020.072232
08-01-20207.93105742.0307170.1753482.029164-0.019868
\n", + "
" + ], + "text/plain": [ + " Asset_1 Asset_2 Asset_3 Portfolio_Value Market_Index\n", + "timestamp \n", + "02-01-2020 -0.196916 1.104952 0.491983 0.509525 -0.008552\n", + "03-01-2020 -0.123737 -0.112190 -0.451162 -0.241793 -0.001205\n", + "06-01-2020 0.481437 0.169089 -0.865690 -0.060214 -0.056688\n", + "07-01-2020 -0.846615 -0.978156 10.721087 -0.486102 0.072232\n", + "08-01-2020 7.931057 42.030717 0.175348 2.029164 -0.019868" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "returns = df.pct_change().dropna()\n", + "returns.head()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7MLPZBswwuTL" + }, + "source": [ + "# Define Fitness Function" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "id": "ADnAYwDKFdu7" + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "def fitness_function(weights, returns):\n", + " portfolio_return = np.sum(returns.mean() * weights) * 252\n", + " portfolio_stddev = np.sqrt(np.dot(weights.T, np.dot(returns.cov() * 252, weights)))\n", + " sharpe_ratio = portfolio_return / portfolio_stddev\n", + " return sharpe_ratio\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tN7T8oixw0ZL" + }, + "source": [ + "# Initial Population" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "id": "newRizz2FhTL" + }, + "outputs": [], + "source": [ + "def initialize_population(pop_size, num_assets):\n", + " population = []\n", + " for _ in range(pop_size):\n", + " weights = np.random.random(num_assets)\n", + " weights /= np.sum(weights)\n", + " population.append(weights)\n", + " return np.array(population)\n", + "\n", + "pop_size = 100\n", + "num_assets = len(df.columns)\n", + "population = initialize_population(pop_size, num_assets)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xfwajDq9w4AH" + }, + "source": [ + "# Selection" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "id": "JVhMT8DbFjMo" + }, + "outputs": [], + "source": [ + "def selection(population, fitness_scores, num_parents):\n", + " parents = np.empty((num_parents, population.shape[1]))\n", + " for i in range(num_parents):\n", + " max_fitness_idx = np.where(fitness_scores == np.max(fitness_scores))\n", + " max_fitness_idx = max_fitness_idx[0][0]\n", + " parents[i, :] = population[max_fitness_idx, :]\n", + " fitness_scores[max_fitness_idx] = -999999\n", + " return parents\n", + "\n", + "num_parents = 20\n", + "fitness_scores = np.array([fitness_function(weights, returns) for weights in population])\n", + "parents = selection(population, fitness_scores, num_parents)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jqEhbITsw9t1" + }, + "source": [ + "# Crossover" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "id": "1kGod21wFldT" + }, + "outputs": [], + "source": [ + "def crossover(parents, offspring_size):\n", + " offspring = np.empty(offspring_size)\n", + " crossover_point = np.uint8(offspring_size[1]/2)\n", + "\n", + " for k in range(offspring_size[0]):\n", + " parent1_idx = k % parents.shape[0]\n", + " parent2_idx = (k + 1) % parents.shape[0]\n", + " offspring[k, 0:crossover_point] = parents[parent1_idx, 0:crossover_point]\n", + " offspring[k, crossover_point:] = parents[parent2_idx, crossover_point:]\n", + " return offspring\n", + "\n", + "offspring_size = (pop_size - parents.shape[0], num_assets)\n", + "offspring = crossover(parents, offspring_size)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AjnCQOIrxBbe" + }, + "source": [ + "# Mutation" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "id": "fCZuohWDFnyT" + }, + "outputs": [], + "source": [ + "def mutation(offspring, mutation_rate=0.01):\n", + " for idx in range(offspring.shape[0]):\n", + " for gene_idx in range(offspring.shape[1]):\n", + " if np.random.rand() < mutation_rate:\n", + " random_value = np.random.random()\n", + " offspring[idx, gene_idx] = offspring[idx, gene_idx] + random_value\n", + " offspring[idx, gene_idx] /= np.sum(offspring[idx, :])\n", + " return offspring\n", + "\n", + "mutated_offspring = mutation(offspring)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xEDvzIMbxGTc" + }, + "source": [ + "# Termination" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "id": "WzsJq1NSFpf3" + }, + "outputs": [], + "source": [ + "def mutation(offspring, mutation_rate=0.01):\n", + " for idx in range(offspring.shape[0]):\n", + " for gene_idx in range(offspring.shape[1]):\n", + " if np.random.rand() < mutation_rate:\n", + " random_value = np.random.random()\n", + " offspring[idx, gene_idx] = offspring[idx, gene_idx] + random_value\n", + " offspring[idx, gene_idx] /= np.sum(offspring[idx, :])\n", + " return offspring\n", + "\n", + "mutated_offspring = mutation(offspring)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s-2eE9IWxIxw" + }, + "source": [] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "rkW-7vLYFrRq", + "outputId": "45fbe294-405e-491d-9b41-312512d0b006" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Generation 0: Best Fitness = 1.4762715381515883\n", + "Generation 1: Best Fitness = 2.02523213483615\n", + "Generation 2: Best Fitness = 2.447525052066359\n", + "Generation 3: Best Fitness = 2.5968127611299243\n", + "Generation 4: Best Fitness = 2.601141911178252\n", + "Generation 5: Best Fitness = 2.601323996364056\n", + "Generation 6: Best Fitness = 2.651556189371385\n", + "Generation 7: Best Fitness = 2.651556189371385\n", + "Generation 8: Best Fitness = 2.651871247334236\n", + "Generation 9: Best Fitness = 2.651871247334236\n", + "Generation 10: Best Fitness = 2.6585766530068415\n", + "Generation 11: Best Fitness = 2.6706997052344295\n", + "Generation 12: Best Fitness = 2.697812640265176\n", + "Generation 13: Best Fitness = 2.697812640265176\n", + "Generation 14: Best Fitness = 2.697812640265176\n", + "Generation 15: Best Fitness = 2.6988428788994336\n", + "Generation 16: Best Fitness = 2.6989832050307423\n", + "Generation 17: Best Fitness = 2.6989832050307423\n", + "Generation 18: Best Fitness = 2.6998114819174277\n", + "Generation 19: Best Fitness = 2.7029987211167135\n", + "Generation 20: Best Fitness = 2.7029987211167135\n", + "Generation 21: Best Fitness = 2.7029987211167135\n", + "Generation 22: Best Fitness = 2.7029987211167135\n", + "Generation 23: Best Fitness = 2.7038430414694936\n", + "Generation 24: Best Fitness = 2.703919023191884\n", + "Generation 25: Best Fitness = 2.703919023191884\n", + "Generation 26: Best Fitness = 2.703919023191884\n", + "Generation 27: Best Fitness = 2.703947768620708\n", + "Generation 28: Best Fitness = 2.703947768620708\n", + "Generation 29: Best Fitness = 2.703947768620708\n", + "Generation 30: Best Fitness = 2.7210426858453953\n", + "Generation 31: Best Fitness = 2.7210426858453953\n", + "Generation 32: Best Fitness = 2.7210426858453953\n", + "Generation 33: Best Fitness = 2.7210426858453953\n", + "Generation 34: Best Fitness = 2.7210426858453953\n", + "Generation 35: Best Fitness = 2.721341020773319\n", + "Generation 36: Best Fitness = 2.721341020773319\n", + "Generation 37: Best Fitness = 2.721341020773319\n", + "Generation 38: Best Fitness = 2.721341020773319\n", + "Generation 39: Best Fitness = 2.721341020773319\n", + "Generation 40: Best Fitness = 2.726566517461905\n", + "Generation 41: Best Fitness = 2.726566517461905\n", + "Generation 42: Best Fitness = 2.726566517461905\n", + "Generation 43: Best Fitness = 2.726566517461905\n", + "Generation 44: Best Fitness = 2.726566517461905\n", + "Generation 45: Best Fitness = 2.726566517461905\n", + "Generation 46: Best Fitness = 2.7286023649211115\n", + "Generation 47: Best Fitness = 2.7286023649211115\n", + "Generation 48: Best Fitness = 2.731539215384595\n", + "Generation 49: Best Fitness = 2.731539215384595\n", + "Generation 50: Best Fitness = 2.731539215384595\n", + "Generation 51: Best Fitness = 2.731539215384595\n", + "Generation 52: Best Fitness = 2.731668375416001\n", + "Generation 53: Best Fitness = 2.731668375416001\n", + "Generation 54: Best Fitness = 2.731668375416001\n", + "Generation 55: Best Fitness = 2.731668375416001\n", + "Generation 56: Best Fitness = 2.731668375416001\n", + "Generation 57: Best Fitness = 2.731668375416001\n", + "Generation 58: Best Fitness = 2.731668375416001\n", + "Generation 59: Best Fitness = 2.731668375416001\n", + "Generation 60: Best Fitness = 2.731668375416001\n", + "Generation 61: Best Fitness = 2.731668375416001\n", + "Generation 62: Best Fitness = 2.731668375416001\n", + "Generation 63: Best Fitness = 2.731668375416001\n", + "Generation 64: Best Fitness = 2.731668375416001\n", + "Generation 65: Best Fitness = 2.731668375416001\n", + "Generation 66: Best Fitness = 2.731668375416001\n", + "Generation 67: Best Fitness = 2.731668375416001\n", + "Generation 68: Best Fitness = 2.731668375416001\n", + "Generation 69: Best Fitness = 2.731668375416001\n", + "Generation 70: Best Fitness = 2.731668375416001\n", + "Generation 71: Best Fitness = 2.731668375416001\n", + "Generation 72: Best Fitness = 2.731668375416001\n", + "Generation 73: Best Fitness = 2.731668375416001\n", + "Generation 74: Best Fitness = 2.731668375416001\n", + "Generation 75: Best Fitness = 2.731668375416001\n", + "Generation 76: Best Fitness = 2.731668375416001\n", + "Generation 77: Best Fitness = 2.731668375416001\n", + "Generation 78: Best Fitness = 2.731668375416001\n", + "Generation 79: Best Fitness = 2.731668375416001\n", + "Generation 80: Best Fitness = 2.731668375416001\n", + "Generation 81: Best Fitness = 2.731668375416001\n", + "Generation 82: Best Fitness = 2.731668375416001\n", + "Generation 83: Best Fitness = 2.731668375416001\n", + "Generation 84: Best Fitness = 2.731668375416001\n", + "Generation 85: Best Fitness = 2.731668375416001\n", + "Generation 86: Best Fitness = 2.7318855517681677\n", + "Generation 87: Best Fitness = 2.7599264504842895\n", + "Generation 88: Best Fitness = 2.7610897975155377\n", + "Generation 89: Best Fitness = 2.7610897975155377\n", + "Generation 90: Best Fitness = 2.7610897975155377\n", + "Generation 91: Best Fitness = 2.7610897975155377\n", + "Generation 92: Best Fitness = 2.7610897975155377\n", + "Generation 93: Best Fitness = 2.761122952025336\n", + "Generation 94: Best Fitness = 2.761122952025336\n", + "Generation 95: Best Fitness = 2.7611314301006784\n", + "Generation 96: Best Fitness = 2.7611314301006784\n", + "Generation 97: Best Fitness = 2.7611314301006784\n", + "Generation 98: Best Fitness = 2.7629489584544022\n", + "Generation 99: Best Fitness = 2.7629489584544022\n" + ] + } + ], + "source": [ + "def genetic_algorithm(returns, num_generations, pop_size, num_parents, mutation_rate):\n", + " num_assets = returns.shape[1]\n", + " population = initialize_population(pop_size, num_assets)\n", + " for generation in range(num_generations):\n", + " fitness_scores = np.array([fitness_function(weights, returns) for weights in population])\n", + " parents = selection(population, fitness_scores, num_parents)\n", + " offspring_size = (pop_size - parents.shape[0], num_assets)\n", + " offspring = crossover(parents, offspring_size)\n", + " offspring = mutation(offspring, mutation_rate)\n", + " population[0:parents.shape[0], :] = parents\n", + " population[parents.shape[0]:, :] = offspring\n", + " best_fitness = np.max(fitness_scores)\n", + " print(f\"Generation {generation}: Best Fitness = {best_fitness}\")\n", + " return population, fitness_scores\n", + "\n", + "num_generations = 100\n", + "population, fitness_scores = genetic_algorithm(returns, num_generations, pop_size, num_parents, mutation_rate=0.01)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YFQ1uXj5xNuu" + }, + "source": [ + "# Evaluate Best portfolio" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "6vLI0G12Fxfc", + "outputId": "061304f9-ef21-447f-87c7-f1782a0e732f" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Best Portfolio Weights: [0.01644336 0.08476277 0.52198998 0.62815317 0.5433535 ]\n", + "Expected Annual Return: 492.3823055102672\n", + "Annual Volatility: 178.2089763198907\n", + "Sharpe Ratio: 2.7629489584544022\n" + ] + } + ], + "source": [ + "best_idx = np.argmax(fitness_scores)\n", + "best_portfolio = population[best_idx, :]\n", + "best_portfolio_return = np.sum(returns.mean() * best_portfolio) * 252\n", + "best_portfolio_stddev = np.sqrt(np.dot(best_portfolio.T, np.dot(returns.cov() * 252, best_portfolio)))\n", + "best_portfolio_sharpe = best_portfolio_return / best_portfolio_stddev\n", + "\n", + "print(f\"Best Portfolio Weights: {best_portfolio}\")\n", + "print(f\"Expected Annual Return: {best_portfolio_return}\")\n", + "print(f\"Annual Volatility: {best_portfolio_stddev}\")\n", + "print(f\"Sharpe Ratio: {best_portfolio_sharpe}\")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tybZDt2YxUIU" + }, + "source": [] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.12.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}