ml-finance-python

python scripts for finance machine learning

git clone https://9o.is/git/ml-finance-python.git

001_equal_weight_S&P_500.ipynb

(9658B)


      1 {
      2  "cells": [
      3   {
      4    "cell_type": "markdown",
      5    "metadata": {},
      6    "source": [
      7     "# Equal-Weight S&P 500 Index Fund\n",
      8     "\n",
      9     "## Introduction & Library Imports\n",
     10     "\n",
     11     "The S&P 500 is the world's most popular stock market index. The largest fund that is benchmarked to this index is the SPDR® S&P 500® ETF Trust. It has more than US$250 billion of assets under management.\n",
     12     "\n",
     13     "The goal of this section of the course is to create a Python script that will accept the value of your portfolio and tell you how many shares of each S&P 500 constituent you should purchase to get an equal-weight version of the index fund.\n",
     14     "\n",
     15     "## Library Imports\n",
     16     "\n",
     17     "The first thing we need to do is import the open-source software libraries that we'll be using in this tutorial."
     18    ]
     19   },
     20   {
     21    "cell_type": "code",
     22    "execution_count": null,
     23    "metadata": {},
     24    "outputs": [],
     25    "source": []
     26   },
     27   {
     28    "cell_type": "markdown",
     29    "metadata": {},
     30    "source": [
     31     "## Importing Our List of Stocks\n",
     32     "\n",
     33     "The next thing we need to do is import the constituents of the S&P 500.\n",
     34     "\n",
     35     "These constituents change over time, so in an ideal world you would connect directly to the index provider (Standard & Poor's) and pull their real-time constituents on a regular basis.\n",
     36     "\n",
     37     "Paying for access to the index provider's API is outside of the scope of this course. \n",
     38     "\n",
     39     "There's a static version of the S&P 500 constituents available here. [Click this link to download them now](https://drive.google.com/file/d/1ZJSpbY69DVckVZlO9cC6KkgfSufybcHN/view?usp=sharing). Move this file into the `starter-files` folder so it can be accessed by other files in that directory.\n",
     40     "\n",
     41     "Now it's time to import these stocks to our Jupyter Notebook file."
     42    ]
     43   },
     44   {
     45    "cell_type": "code",
     46    "execution_count": null,
     47    "metadata": {},
     48    "outputs": [],
     49    "source": []
     50   },
     51   {
     52    "cell_type": "markdown",
     53    "metadata": {},
     54    "source": [
     55     "## Acquiring an API Token\n",
     56     "\n",
     57     "Now it's time to import our IEX Cloud API token. This is the data provider that we will be using throughout this course.\n",
     58     "\n",
     59     "API tokens (and other sensitive information) should be stored in a `secrets.py` file that doesn't get pushed to your local Git repository. We'll be using a sandbox API token in this course, which means that the data we'll use is randomly-generated and (more importantly) has no cost associated with it.\n",
     60     "\n",
     61     "[Click here](http://nickmccullum.com/algorithmic-trading-python/secrets.py) to download your `secrets.py` file. Move the file into the same directory as this Jupyter Notebook before proceeding."
     62    ]
     63   },
     64   {
     65    "cell_type": "code",
     66    "execution_count": null,
     67    "metadata": {},
     68    "outputs": [],
     69    "source": []
     70   },
     71   {
     72    "cell_type": "markdown",
     73    "metadata": {},
     74    "source": [
     75     "## Making Our First API Call\n",
     76     "\n",
     77     "Now it's time to structure our API calls to IEX cloud. \n",
     78     "\n",
     79     "We need the following information from the API:\n",
     80     "\n",
     81     "* Market capitalization for each stock\n",
     82     "* Price of each stock\n",
     83     "\n"
     84    ]
     85   },
     86   {
     87    "cell_type": "code",
     88    "execution_count": null,
     89    "metadata": {},
     90    "outputs": [],
     91    "source": []
     92   },
     93   {
     94    "cell_type": "markdown",
     95    "metadata": {},
     96    "source": [
     97     "## Parsing Our API Call\n",
     98     "\n",
     99     "The API call that we executed in the last code block contains all of the information required to build our equal-weight S&P 500 strategy. \n",
    100     "\n",
    101     "With that said, the data isn't in a proper format yet. We need to parse it first."
    102    ]
    103   },
    104   {
    105    "cell_type": "code",
    106    "execution_count": null,
    107    "metadata": {},
    108    "outputs": [],
    109    "source": []
    110   },
    111   {
    112    "cell_type": "markdown",
    113    "metadata": {},
    114    "source": [
    115     "## Adding Our Stocks Data to a Pandas DataFrame\n",
    116     "\n",
    117     "The next thing we need to do is add our stock's price and market capitalization to a pandas DataFrame. Think of a DataFrame like the Python version of a spreadsheet. It stores tabular data."
    118    ]
    119   },
    120   {
    121    "cell_type": "code",
    122    "execution_count": null,
    123    "metadata": {},
    124    "outputs": [],
    125    "source": []
    126   },
    127   {
    128    "cell_type": "code",
    129    "execution_count": null,
    130    "metadata": {},
    131    "outputs": [],
    132    "source": []
    133   },
    134   {
    135    "cell_type": "markdown",
    136    "metadata": {},
    137    "source": [
    138     "## Looping Through The Tickers in Our List of Stocks\n",
    139     "\n",
    140     "Using the same logic that we outlined above, we can pull data for all S&P 500 stocks and store their data in the DataFrame using a `for` loop."
    141    ]
    142   },
    143   {
    144    "cell_type": "code",
    145    "execution_count": null,
    146    "metadata": {},
    147    "outputs": [],
    148    "source": []
    149   },
    150   {
    151    "cell_type": "code",
    152    "execution_count": null,
    153    "metadata": {},
    154    "outputs": [],
    155    "source": []
    156   },
    157   {
    158    "cell_type": "markdown",
    159    "metadata": {},
    160    "source": [
    161     "## Using Batch API Calls to Improve Performance\n",
    162     "\n",
    163     "Batch API calls are one of the easiest ways to improve the performance of your code.\n",
    164     "\n",
    165     "This is because HTTP requests are typically one of the slowest components of a script.\n",
    166     "\n",
    167     "Also, API providers will often give you discounted rates for using batch API calls since they are easier for the API provider to respond to.\n",
    168     "\n",
    169     "IEX Cloud limits their batch API calls to 100 tickers per request. Still, this reduces the number of API calls we'll make in this section from 500 to 5 - huge improvement! In this section, we'll split our list of stocks into groups of 100 and then make a batch API call for each group."
    170    ]
    171   },
    172   {
    173    "cell_type": "code",
    174    "execution_count": null,
    175    "metadata": {},
    176    "outputs": [],
    177    "source": []
    178   },
    179   {
    180    "cell_type": "code",
    181    "execution_count": null,
    182    "metadata": {},
    183    "outputs": [],
    184    "source": []
    185   },
    186   {
    187    "cell_type": "markdown",
    188    "metadata": {},
    189    "source": [
    190     "## Calculating the Number of Shares to Buy\n",
    191     "\n",
    192     "As you can see in the DataFrame above, we stil haven't calculated the number of shares of each stock to buy.\n",
    193     "\n",
    194     "We'll do that next."
    195    ]
    196   },
    197   {
    198    "cell_type": "code",
    199    "execution_count": null,
    200    "metadata": {},
    201    "outputs": [],
    202    "source": []
    203   },
    204   {
    205    "cell_type": "code",
    206    "execution_count": null,
    207    "metadata": {},
    208    "outputs": [],
    209    "source": []
    210   },
    211   {
    212    "cell_type": "markdown",
    213    "metadata": {},
    214    "source": [
    215     "## Formatting Our Excel Output\n",
    216     "\n",
    217     "We will be using the XlsxWriter library for Python to create nicely-formatted Excel files.\n",
    218     "\n",
    219     "XlsxWriter is an excellent package and offers tons of customization. However, the tradeoff for this is that the library can seem very complicated to new users. Accordingly, this section will be fairly long because I want to do a good job of explaining how XlsxWriter works.\n",
    220     "\n",
    221     "### Initializing our XlsxWriter Object"
    222    ]
    223   },
    224   {
    225    "cell_type": "code",
    226    "execution_count": null,
    227    "metadata": {},
    228    "outputs": [],
    229    "source": []
    230   },
    231   {
    232    "cell_type": "markdown",
    233    "metadata": {},
    234    "source": [
    235     "### Creating the Formats We'll Need For Our `.xlsx` File\n",
    236     "\n",
    237     "Formats include colors, fonts, and also symbols like `%` and `$`. We'll need four main formats for our Excel document:\n",
    238     "* String format for tickers\n",
    239     "* \\\\$XX.XX format for stock prices\n",
    240     "* \\\\$XX,XXX format for market capitalization\n",
    241     "* Integer format for the number of shares to purchase"
    242    ]
    243   },
    244   {
    245    "cell_type": "code",
    246    "execution_count": null,
    247    "metadata": {},
    248    "outputs": [],
    249    "source": []
    250   },
    251   {
    252    "cell_type": "markdown",
    253    "metadata": {},
    254    "source": [
    255     "### Applying the Formats to the Columns of Our `.xlsx` File\n",
    256     "\n",
    257     "We can use the `set_column` method applied to the `writer.sheets['Recommended Trades']` object to apply formats to specific columns of our spreadsheets.\n",
    258     "\n",
    259     "Here's an example:\n",
    260     "\n",
    261     "```python\n",
    262     "writer.sheets['Recommended Trades'].set_column('B:B', #This tells the method to apply the format to column B\n",
    263     "                     18, #This tells the method to apply a column width of 18 pixels\n",
    264     "                     string_template #This applies the format 'string_template' to the column\n",
    265     "                    )\n",
    266     "```"
    267    ]
    268   },
    269   {
    270    "cell_type": "code",
    271    "execution_count": null,
    272    "metadata": {},
    273    "outputs": [],
    274    "source": []
    275   },
    276   {
    277    "cell_type": "markdown",
    278    "metadata": {},
    279    "source": [
    280     "This code works, but it violates the software principle of \"Don't Repeat Yourself\". \n",
    281     "\n",
    282     "Let's simplify this by putting it in 2 loops:"
    283    ]
    284   },
    285   {
    286    "cell_type": "code",
    287    "execution_count": null,
    288    "metadata": {},
    289    "outputs": [],
    290    "source": []
    291   },
    292   {
    293    "cell_type": "markdown",
    294    "metadata": {},
    295    "source": [
    296     "## Saving Our Excel Output\n",
    297     "\n",
    298     "Saving our Excel file is very easy:"
    299    ]
    300   },
    301   {
    302    "cell_type": "code",
    303    "execution_count": null,
    304    "metadata": {},
    305    "outputs": [],
    306    "source": []
    307   }
    308  ],
    309  "metadata": {
    310   "kernelspec": {
    311    "display_name": "Python 3",
    312    "language": "python",
    313    "name": "python3"
    314   },
    315   "language_info": {
    316    "codemirror_mode": {
    317     "name": "ipython",
    318     "version": 3
    319    },
    320    "file_extension": ".py",
    321    "mimetype": "text/x-python",
    322    "name": "python",
    323    "nbconvert_exporter": "python",
    324    "pygments_lexer": "ipython3",
    325    "version": "3.8.2"
    326   }
    327  },
    328  "nbformat": 4,
    329  "nbformat_minor": 4
    330 }