From 6136d18fff68ca2031c467397f2d31717232cca2 Mon Sep 17 00:00:00 2001 From: Ankita Mehta Date: Sat, 18 Aug 2018 17:45:50 +0530 Subject: [PATCH] Project 1: Trading with momentum. --- project_1_starter (1).ipynb | 5905 ++++++++++++++++ project_1_starter.html | 12898 ++++++++++++++++++++++++++++++++++ project_1_starter.md | 599 ++ 3 files changed, 19402 insertions(+) create mode 100644 project_1_starter (1).ipynb create mode 100644 project_1_starter.html create mode 100644 project_1_starter.md diff --git a/project_1_starter (1).ipynb b/project_1_starter (1).ipynb new file mode 100644 index 0000000..b761c03 --- /dev/null +++ b/project_1_starter (1).ipynb @@ -0,0 +1,5905 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Project 1: Trading with Momentum\n", + "## Instructions\n", + "Each problem consists of a function to implement and instructions on how to implement the function. The parts of the function that need to be implemented are marked with a `# TODO` comment. After implementing the function, run the cell to test it against the unit tests we've provided. For each problem, we provide one or more unit tests from our `project_tests` package. These unit tests won't tell you if your answer is correct, but will warn you of any major errors. Your code will be checked for the correct solution when you submit it to Udacity.\n", + "\n", + "## Packages\n", + "When you implement the functions, you'll only need to you use the packages you've used in the classroom, like [Pandas](https://pandas.pydata.org/) and [Numpy](http://www.numpy.org/). These packages will be imported for you. We recommend you don't add any import statements, otherwise the grader might not be able to run your code.\n", + "\n", + "The other packages that we're importing are `helper`, `project_helper`, and `project_tests`. These are custom packages built to help you solve the problems. The `helper` and `project_helper` module contains utility functions and graph functions. The `project_tests` contains the unit tests for all the problems.\n", + "\n", + "### Install Packages" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: colour==0.1.5 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 1))\n", + "Collecting cvxpy==1.0.3 (from -r requirements.txt (line 2))\n", + " Downloading https://files.pythonhosted.org/packages/a1/59/2613468ffbbe3a818934d06b81b9f4877fe054afbf4f99d2f43f398a0b34/cvxpy-1.0.3.tar.gz (880kB)\n", + "\u001b[K 100% |████████████████████████████████| 880kB 695kB/s ta 0:00:01\n", + "\u001b[?25hRequirement already satisfied: cycler==0.10.0 in /opt/conda/lib/python3.6/site-packages/cycler-0.10.0-py3.6.egg (from -r requirements.txt (line 3))\n", + "Collecting numpy==1.13.3 (from -r requirements.txt (line 4))\n", + " Downloading https://files.pythonhosted.org/packages/57/a7/e3e6bd9d595125e1abbe162e323fd2d06f6f6683185294b79cd2cdb190d5/numpy-1.13.3-cp36-cp36m-manylinux1_x86_64.whl (17.0MB)\n", + "\u001b[K 100% |████████████████████████████████| 17.0MB 38kB/s eta 0:00:01 4% |█▌ | 808kB 11.8MB/s eta 0:00:02 8% |██▉ | 1.5MB 17.0MB/s eta 0:00:01 13% |████▍ | 2.3MB 20.0MB/s eta 0:00:01 19% |██████▎ | 3.3MB 21.1MB/s eta 0:00:01 61% |███████████████████▋ | 10.4MB 28.7MB/s eta 0:00:01 68% |██████████████████████ | 11.7MB 28.7MB/s eta 0:00:01 75% |████████████████████████▏ | 12.9MB 22.8MB/s eta 0:00:01\n", + "\u001b[?25hCollecting pandas==0.21.1 (from -r requirements.txt (line 5))\n", + " Downloading https://files.pythonhosted.org/packages/3a/e1/6c514df670b887c77838ab856f57783c07e8760f2e3d5939203a39735e0e/pandas-0.21.1-cp36-cp36m-manylinux1_x86_64.whl (26.2MB)\n", + "\u001b[K 100% |████████████████████████████████| 26.2MB 24kB/s eta 0:00:01 3% |█ | 890kB 20.3MB/s eta 0:00:02 17% |█████▋ | 4.6MB 28.2MB/s eta 0:00:01 22% |███████ | 5.8MB 27.8MB/s eta 0:00:01 64% |████████████████████▊ | 16.9MB 26.3MB/s eta 0:00:01 73% |███████████████████████▋ | 19.4MB 25.5MB/s eta 0:00:01\n", + "\u001b[?25hCollecting plotly==2.2.3 (from -r requirements.txt (line 6))\n", + " Downloading https://files.pythonhosted.org/packages/99/a6/8214b6564bf4ace9bec8a26e7f89832792be582c042c47c912d3201328a0/plotly-2.2.3.tar.gz (1.1MB)\n", + "\u001b[K 100% |████████████████████████████████| 1.1MB 578kB/s eta 0:00:01 37% |████████████ | 409kB 20.5MB/s eta 0:00:01\n", + "\u001b[?25hRequirement already satisfied: pyparsing==2.2.0 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 7))\n", + "Requirement already satisfied: python-dateutil==2.6.1 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 8))\n", + "Requirement already satisfied: pytz==2017.3 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 9))\n", + "Requirement already satisfied: requests==2.18.4 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 10))\n", + "Collecting scipy==1.0.0 (from -r requirements.txt (line 11))\n", + " Downloading https://files.pythonhosted.org/packages/d8/5e/caa01ba7be11600b6a9d39265440d7b3be3d69206da887c42bef049521f2/scipy-1.0.0-cp36-cp36m-manylinux1_x86_64.whl (50.0MB)\n", + "\u001b[K 100% |████████████████████████████████| 50.0MB 12kB/s eta 0:00:01 18% |█████▉ | 9.1MB 24.7MB/s eta 0:00:02 20% |██████▍ | 10.0MB 20.8MB/s eta 0:00:02 22% |███████ | 11.1MB 20.6MB/s eta 0:00:02 31% |██████████ | 15.6MB 21.4MB/s eta 0:00:02 33% |██████████▋ | 16.6MB 21.7MB/s eta 0:00:02 37% |████████████ | 18.8MB 20.9MB/s eta 0:00:02 44% |██████████████▏ | 22.1MB 20.9MB/s eta 0:00:02 48% |███████████████▌ | 24.2MB 22.2MB/s eta 0:00:02 52% |████████████████▉ | 26.2MB 20.2MB/s eta 0:00:02 54% |█████████████████▌ | 27.3MB 21.1MB/s eta 0:00:02 58% |██████████████████▉ | 29.4MB 21.7MB/s eta 0:00:01 60% |███████████████████▌ | 30.5MB 21.2MB/s eta 0:00:01 62% |████████████████████ | 31.4MB 21.0MB/s eta 0:00:01 64% |████████████████████▊ | 32.4MB 20.5MB/s eta 0:00:01 69% |██████████████████████ | 34.5MB 21.2MB/s eta 0:00:01 73% |███████████████████████▌ | 36.7MB 22.5MB/s eta 0:00:01 75% |████████████████████████ | 37.6MB 20.2MB/s eta 0:00:01 77% |████████████████████████▊ | 38.7MB 20.9MB/s eta 0:00:01 81% |██████████████████████████ | 40.7MB 22.1MB/s eta 0:00:01 83% |██████████████████████████▊ | 41.8MB 20.6MB/s eta 0:00:01 85% |███████████████████████████▍ | 42.7MB 21.5MB/s eta 0:00:01 91% |█████████████████████████████▎ | 45.7MB 20.3MB/s eta 0:00:01 95% |██████████████████████████████▌ | 47.7MB 19.1MB/s eta 0:00:01 99% |███████████████████████████████▉| 49.8MB 21.7MB/s eta 0:00:01\n", + "\u001b[?25hRequirement already satisfied: scikit-learn==0.19.1 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 12))\n", + "Requirement already satisfied: six==1.11.0 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 13))\n", + "Collecting tqdm==4.19.5 (from -r requirements.txt (line 14))\n", + " Downloading https://files.pythonhosted.org/packages/71/3c/341b4fa23cb3abc335207dba057c790f3bb329f6757e1fcd5d347bcf8308/tqdm-4.19.5-py2.py3-none-any.whl (51kB)\n", + "\u001b[K 100% |████████████████████████████████| 61kB 4.0MB/s eta 0:00:01\n", + "\u001b[?25hCollecting osqp (from cvxpy==1.0.3->-r requirements.txt (line 2))\n", + " Downloading https://files.pythonhosted.org/packages/05/42/0ccab82eb6ed0edb83d184928ec864232dc00c3cf968a4b92a02caf0f7ec/osqp-0.4.0-cp36-cp36m-manylinux1_x86_64.whl (146kB)\n", + "\u001b[K 100% |████████████████████████████████| 153kB 3.8MB/s eta 0:00:01\n", + "\u001b[?25hCollecting ecos>=2 (from cvxpy==1.0.3->-r requirements.txt (line 2))\n", + " Downloading https://files.pythonhosted.org/packages/b6/b4/988b15513b13e8ea2eac65e97d84221ac515a735a93f046e2a2a3d7863fc/ecos-2.0.5.tar.gz (114kB)\n", + "\u001b[K 100% |████████████████████████████████| 122kB 4.5MB/s eta 0:00:01\n", + "\u001b[?25hCollecting scs>=1.1.3 (from cvxpy==1.0.3->-r requirements.txt (line 2))\n", + " Downloading https://files.pythonhosted.org/packages/b3/fd/6e01c4f4a69fcc6c3db130ba55572089e78e77ea8c0921a679f9da1ec04c/scs-2.0.2.tar.gz (133kB)\n", + "\u001b[K 100% |████████████████████████████████| 143kB 3.9MB/s eta 0:00:01\n", + "\u001b[?25hCollecting multiprocess (from cvxpy==1.0.3->-r requirements.txt (line 2))\n", + " Downloading https://files.pythonhosted.org/packages/7a/ee/b9bf3e171f936743758ef924622d8dd00516c5532b00a1210a09bce68325/multiprocess-0.70.6.1.tar.gz (1.4MB)\n", + "\u001b[K 100% |████████████████████████████████| 1.4MB 465kB/s eta 0:00:01\n", + "\u001b[?25hRequirement already satisfied: fastcache in /opt/conda/lib/python3.6/site-packages (from cvxpy==1.0.3->-r requirements.txt (line 2))\n", + "Requirement already satisfied: toolz in /opt/conda/lib/python3.6/site-packages (from cvxpy==1.0.3->-r requirements.txt (line 2))\n", + "Requirement already satisfied: decorator>=4.0.6 in /opt/conda/lib/python3.6/site-packages (from plotly==2.2.3->-r requirements.txt (line 6))\n", + "Requirement already satisfied: nbformat>=4.2 in /opt/conda/lib/python3.6/site-packages (from plotly==2.2.3->-r requirements.txt (line 6))\n", + "Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /opt/conda/lib/python3.6/site-packages (from requests==2.18.4->-r requirements.txt (line 10))\n", + "Requirement already satisfied: idna<2.7,>=2.5 in /opt/conda/lib/python3.6/site-packages (from requests==2.18.4->-r requirements.txt (line 10))\n", + "Requirement already satisfied: urllib3<1.23,>=1.21.1 in /opt/conda/lib/python3.6/site-packages (from requests==2.18.4->-r requirements.txt (line 10))\n", + "Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/lib/python3.6/site-packages (from requests==2.18.4->-r requirements.txt (line 10))\n", + "Requirement already satisfied: future in /opt/conda/lib/python3.6/site-packages (from osqp->cvxpy==1.0.3->-r requirements.txt (line 2))\n", + "Collecting dill>=0.2.8.1 (from multiprocess->cvxpy==1.0.3->-r requirements.txt (line 2))\n", + " Downloading https://files.pythonhosted.org/packages/6f/78/8b96476f4ae426db71c6e86a8e6a81407f015b34547e442291cd397b18f3/dill-0.2.8.2.tar.gz (150kB)\n", + "\u001b[K 100% |████████████████████████████████| 153kB 3.7MB/s eta 0:00:01\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[?25hRequirement already satisfied: jsonschema!=2.5.0,>=2.4 in /opt/conda/lib/python3.6/site-packages (from nbformat>=4.2->plotly==2.2.3->-r requirements.txt (line 6))\n", + "Requirement already satisfied: jupyter-core in /opt/conda/lib/python3.6/site-packages (from nbformat>=4.2->plotly==2.2.3->-r requirements.txt (line 6))\n", + "Requirement already satisfied: traitlets>=4.1 in /opt/conda/lib/python3.6/site-packages (from nbformat>=4.2->plotly==2.2.3->-r requirements.txt (line 6))\n", + "Requirement already satisfied: ipython-genutils in /opt/conda/lib/python3.6/site-packages (from nbformat>=4.2->plotly==2.2.3->-r requirements.txt (line 6))\n", + "Building wheels for collected packages: cvxpy, plotly, ecos, scs, multiprocess, dill\n", + " Running setup.py bdist_wheel for cvxpy ... \u001b[?25ldone\n", + "\u001b[?25h Stored in directory: /root/.cache/pip/wheels/2b/60/0b/0c2596528665e21d698d6f84a3406c52044c7b4ca6ac737cf3\n", + " Running setup.py bdist_wheel for plotly ... \u001b[?25ldone\n", + "\u001b[?25h Stored in directory: /root/.cache/pip/wheels/98/54/81/dd92d5b0858fac680cd7bdb8800eb26c001dd9f5dc8b1bc0ba\n", + " Running setup.py bdist_wheel for ecos ... \u001b[?25ldone\n", + "\u001b[?25h Stored in directory: /root/.cache/pip/wheels/50/91/1b/568de3c087b3399b03d130e71b1fd048ec072c45f72b6b6e9a\n", + " Running setup.py bdist_wheel for scs ... \u001b[?25ldone\n", + "\u001b[?25h Stored in directory: /root/.cache/pip/wheels/ff/f0/aa/530ccd478d7d9900b4e9ef5bc5a39e895ce110bed3d3ac653e\n", + " Running setup.py bdist_wheel for multiprocess ... \u001b[?25ldone\n", + "\u001b[?25h Stored in directory: /root/.cache/pip/wheels/8b/36/e5/96614ab62baf927e9bc06889ea794a8e87552b84bb6bf65e3e\n", + " Running setup.py bdist_wheel for dill ... \u001b[?25ldone\n", + "\u001b[?25h Stored in directory: /root/.cache/pip/wheels/e2/5d/17/f87cb7751896ac629b435a8696f83ee75b11029f5d6f6bda72\n", + "Successfully built cvxpy plotly ecos scs multiprocess dill\n", + "Installing collected packages: numpy, scipy, osqp, ecos, scs, dill, multiprocess, cvxpy, pandas, plotly, tqdm\n", + " Found existing installation: numpy 1.12.1\n", + " Uninstalling numpy-1.12.1:\n", + " Successfully uninstalled numpy-1.12.1\n", + " Found existing installation: scipy 0.19.1\n", + " Uninstalling scipy-0.19.1:\n", + " Successfully uninstalled scipy-0.19.1\n", + " Found existing installation: dill 0.2.7.1\n", + " Uninstalling dill-0.2.7.1:\n", + " Successfully uninstalled dill-0.2.7.1\n", + " Found existing installation: pandas 0.20.3\n", + " Uninstalling pandas-0.20.3:\n", + " Successfully uninstalled pandas-0.20.3\n", + " Found existing installation: plotly 2.0.15\n", + " Uninstalling plotly-2.0.15:\n", + " Successfully uninstalled plotly-2.0.15\n", + " Found existing installation: tqdm 4.11.2\n", + " Uninstalling tqdm-4.11.2:\n", + " Successfully uninstalled tqdm-4.11.2\n", + "Successfully installed cvxpy-1.0.3 dill-0.2.8.2 ecos-2.0.5 multiprocess-0.70.6.1 numpy-1.13.3 osqp-0.4.0 pandas-0.21.1 plotly-2.2.3 scipy-1.0.0 scs-2.0.2 tqdm-4.19.5\n", + "\u001b[33mYou are using pip version 9.0.1, however version 18.0 is available.\n", + "You should consider upgrading via the 'pip install --upgrade pip' command.\u001b[0m\n" + ] + } + ], + "source": [ + "import sys\n", + "!{sys.executable} -m pip install -r requirements.txt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load Packages" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "" + ], + "text/vnd.plotly.v1+html": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "import helper\n", + "import project_helper\n", + "import project_tests" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Market Data\n", + "### Load Data\n", + "The data we use for most of the projects is end of day data. This contains data for many stocks, but we'll be looking at stocks in the S&P 500. We also made things a little easier to run by narrowing down our range of time period instead of using all of the data." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loaded Data\n" + ] + } + ], + "source": [ + "df = pd.read_csv('../../data/project_1/eod-quotemedia.csv', parse_dates=['date'], index_col=False)\n", + "\n", + "close = df.reset_index().pivot(index='date', columns='ticker', values='adj_close')\n", + "\n", + "print('Loaded Data')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### View Data\n", + "Run the cell below to see what the data looks like for `close`." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "data": [ + { + "cells": { + "fill": { + "color": [ + "silver", + "white" + ] + }, + "font": { + "size": 13 + }, + "line": { + "color": "silver" + }, + "values": [ + [ + "2013-07-01", + "2013-07-02", + "2013-07-03", + "2013-07-05", + "2013-07-08", + "2013-07-09", + "2013-07-10", + "2013-07-11", + "2013-07-12", + "2013-07-15", + "..." + ], + [ + "29.994", + "29.650", + "29.705", + "30.435", + "30.524", + "30.689", + "31.178", + "31.460", + "31.480", + "31.728", + "..." + ], + [ + "16.176", + "15.820", + "16.128", + "16.215", + "16.311", + "16.715", + "16.532", + "16.725", + "16.908", + "17.100", + "..." + ], + [ + "81.138", + "80.722", + "81.237", + "81.822", + "82.951", + "82.436", + "81.990", + "82.000", + "81.911", + "82.615", + "..." + ], + [ + "...", + "...", + "...", + "...", + "...", + "...", + "...", + "...", + "...", + "...", + "..." + ] + ] + }, + "columnwidth": [ + 1, + 3 + ], + "header": { + "fill": { + "color": "silver" + }, + "font": { + "size": 13 + }, + "line": { + "color": "silver" + }, + "values": [ + "", + "A", + "AAL", + "AAP", + "..." + ] + }, + "type": "table" + } + ], + "layout": {} + }, + "text/html": [ + "
" + ], + "text/vnd.plotly.v1+html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "project_helper.print_dataframe(close)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Stock Example\n", + "Let's see what a single stock looks like from the closing prices. For this example and future display examples in this project, we'll use Apple's stock (AAPL). If we tried to graph all the stocks, it would be too much information." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "data": [ + { + "line": { + "color": "#2D3ECF" + }, + "name": "Index", + "type": "scatter", + "x": [ + "2013-07-01", + "2013-07-02", + "2013-07-03", + "2013-07-05", + "2013-07-08", + "2013-07-09", + "2013-07-10", + "2013-07-11", + "2013-07-12", + "2013-07-15", + "2013-07-16", + "2013-07-17", + "2013-07-18", + "2013-07-19", + "2013-07-22", + "2013-07-23", + "2013-07-24", + "2013-07-25", + "2013-07-26", + "2013-07-29", + "2013-07-30", + "2013-07-31", + "2013-08-01", + "2013-08-02", + "2013-08-05", + "2013-08-06", + "2013-08-07", + "2013-08-08", + "2013-08-09", + "2013-08-12", + "2013-08-13", + "2013-08-14", + "2013-08-15", + "2013-08-16", + "2013-08-19", + "2013-08-20", + "2013-08-21", + "2013-08-22", + "2013-08-23", + "2013-08-26", + "2013-08-27", + "2013-08-28", + "2013-08-29", + "2013-08-30", + "2013-09-03", + "2013-09-04", + "2013-09-05", + "2013-09-06", + "2013-09-09", + "2013-09-10", + "2013-09-11", + "2013-09-12", + "2013-09-13", + "2013-09-16", + "2013-09-17", + "2013-09-18", + "2013-09-19", + "2013-09-20", + "2013-09-23", + "2013-09-24", + "2013-09-25", + "2013-09-26", + "2013-09-27", + "2013-09-30", + "2013-10-01", + "2013-10-02", + "2013-10-03", + "2013-10-04", + "2013-10-07", + "2013-10-08", + "2013-10-09", + "2013-10-10", + "2013-10-11", + "2013-10-14", + "2013-10-15", + "2013-10-16", + "2013-10-17", + "2013-10-18", + "2013-10-21", + "2013-10-22", + "2013-10-23", + "2013-10-24", + "2013-10-25", + "2013-10-28", + "2013-10-29", + "2013-10-30", + "2013-10-31", + "2013-11-01", + "2013-11-04", + "2013-11-05", + "2013-11-06", + "2013-11-07", + "2013-11-08", + "2013-11-11", + "2013-11-12", + "2013-11-13", + "2013-11-14", + "2013-11-15", + "2013-11-18", + "2013-11-19", + "2013-11-20", + "2013-11-21", + "2013-11-22", + "2013-11-25", + "2013-11-26", + "2013-11-27", + "2013-11-29", + "2013-12-02", + "2013-12-03", + "2013-12-04", + "2013-12-05", + "2013-12-06", + "2013-12-09", + "2013-12-10", + "2013-12-11", + "2013-12-12", + "2013-12-13", + "2013-12-16", + "2013-12-17", + "2013-12-18", + "2013-12-19", + "2013-12-20", + "2013-12-23", + "2013-12-24", + "2013-12-26", + "2013-12-27", + "2013-12-30", + "2013-12-31", + "2014-01-02", + "2014-01-03", + "2014-01-06", + "2014-01-07", + "2014-01-08", + "2014-01-09", + "2014-01-10", + "2014-01-13", + "2014-01-14", + "2014-01-15", + "2014-01-16", + "2014-01-17", + "2014-01-21", + "2014-01-22", + "2014-01-23", + "2014-01-24", + "2014-01-27", + "2014-01-28", + "2014-01-29", + "2014-01-30", + "2014-01-31", + "2014-02-03", + "2014-02-04", + "2014-02-05", + "2014-02-06", + "2014-02-07", + "2014-02-10", + "2014-02-11", + "2014-02-12", + "2014-02-13", + "2014-02-14", + "2014-02-18", + "2014-02-19", + "2014-02-20", + "2014-02-21", + "2014-02-24", + "2014-02-25", + "2014-02-26", + "2014-02-27", + "2014-02-28", + "2014-03-03", + "2014-03-04", + "2014-03-05", + "2014-03-06", + "2014-03-07", + "2014-03-10", + "2014-03-11", + "2014-03-12", + "2014-03-13", + "2014-03-14", + "2014-03-17", + "2014-03-18", + "2014-03-19", + "2014-03-20", + "2014-03-21", + "2014-03-24", + "2014-03-25", + "2014-03-26", + "2014-03-27", + "2014-03-28", + "2014-03-31", + "2014-04-01", + "2014-04-02", + "2014-04-03", + "2014-04-04", + "2014-04-07", + "2014-04-08", + "2014-04-09", + "2014-04-10", + "2014-04-11", + "2014-04-14", + "2014-04-15", + "2014-04-16", + "2014-04-17", + "2014-04-21", + "2014-04-22", + "2014-04-23", + "2014-04-24", + "2014-04-25", + "2014-04-28", + "2014-04-29", + "2014-04-30", + "2014-05-01", + "2014-05-02", + "2014-05-05", + "2014-05-06", + "2014-05-07", + "2014-05-08", + "2014-05-09", + "2014-05-12", + "2014-05-13", + "2014-05-14", + "2014-05-15", + "2014-05-16", + "2014-05-19", + "2014-05-20", + "2014-05-21", + "2014-05-22", + "2014-05-23", + "2014-05-27", + "2014-05-28", + "2014-05-29", + "2014-05-30", + "2014-06-02", + "2014-06-03", + "2014-06-04", + "2014-06-05", + "2014-06-06", + "2014-06-09", + "2014-06-10", + "2014-06-11", + "2014-06-12", + "2014-06-13", + "2014-06-16", + "2014-06-17", + "2014-06-18", + "2014-06-19", + "2014-06-20", + "2014-06-23", + "2014-06-24", + "2014-06-25", + "2014-06-26", + "2014-06-27", + "2014-06-30", + "2014-07-01", + "2014-07-02", + "2014-07-03", + "2014-07-07", + "2014-07-08", + "2014-07-09", + "2014-07-10", + "2014-07-11", + "2014-07-14", + "2014-07-15", + "2014-07-16", + "2014-07-17", + "2014-07-18", + "2014-07-21", + "2014-07-22", + "2014-07-23", + "2014-07-24", + "2014-07-25", + "2014-07-28", + "2014-07-29", + "2014-07-30", + "2014-07-31", + "2014-08-01", + "2014-08-04", + "2014-08-05", + "2014-08-06", + "2014-08-07", + "2014-08-08", + "2014-08-11", + "2014-08-12", + "2014-08-13", + "2014-08-14", + "2014-08-15", + "2014-08-18", + "2014-08-19", + "2014-08-20", + "2014-08-21", + "2014-08-22", + "2014-08-25", + "2014-08-26", + "2014-08-27", + "2014-08-28", + "2014-08-29", + "2014-09-02", + "2014-09-03", + "2014-09-04", + "2014-09-05", + "2014-09-08", + "2014-09-09", + "2014-09-10", + "2014-09-11", + "2014-09-12", + "2014-09-15", + "2014-09-16", + "2014-09-17", + "2014-09-18", + "2014-09-19", + "2014-09-22", + "2014-09-23", + "2014-09-24", + "2014-09-25", + "2014-09-26", + "2014-09-29", + "2014-09-30", + "2014-10-01", + "2014-10-02", + "2014-10-03", + "2014-10-06", + "2014-10-07", + "2014-10-08", + "2014-10-09", + "2014-10-10", + "2014-10-13", + "2014-10-14", + "2014-10-15", + "2014-10-16", + "2014-10-17", + "2014-10-20", + "2014-10-21", + "2014-10-22", + "2014-10-23", + "2014-10-24", + "2014-10-27", + "2014-10-28", + "2014-10-29", + "2014-10-30", + "2014-10-31", + "2014-11-03", + "2014-11-04", + "2014-11-05", + "2014-11-06", + "2014-11-07", + "2014-11-10", + "2014-11-11", + "2014-11-12", + "2014-11-13", + "2014-11-14", + "2014-11-17", + "2014-11-18", + "2014-11-19", + "2014-11-20", + "2014-11-21", + "2014-11-24", + "2014-11-25", + "2014-11-26", + "2014-11-28", + "2014-12-01", + "2014-12-02", + "2014-12-03", + "2014-12-04", + "2014-12-05", + "2014-12-08", + "2014-12-09", + "2014-12-10", + "2014-12-11", + "2014-12-12", + "2014-12-15", + "2014-12-16", + "2014-12-17", + "2014-12-18", + "2014-12-19", + "2014-12-22", + "2014-12-23", + "2014-12-24", + "2014-12-26", + "2014-12-29", + "2014-12-30", + "2014-12-31", + "2015-01-02", + "2015-01-05", + "2015-01-06", + "2015-01-07", + "2015-01-08", + "2015-01-09", + "2015-01-12", + "2015-01-13", + "2015-01-14", + "2015-01-15", + "2015-01-16", + "2015-01-20", + "2015-01-21", + "2015-01-22", + "2015-01-23", + "2015-01-26", + "2015-01-27", + "2015-01-28", + "2015-01-29", + "2015-01-30", + "2015-02-02", + "2015-02-03", + "2015-02-04", + "2015-02-05", + "2015-02-06", + "2015-02-09", + "2015-02-10", + "2015-02-11", + "2015-02-12", + "2015-02-13", + "2015-02-17", + "2015-02-18", + "2015-02-19", + "2015-02-20", + "2015-02-23", + "2015-02-24", + "2015-02-25", + "2015-02-26", + "2015-02-27", + "2015-03-02", + "2015-03-03", + "2015-03-04", + "2015-03-05", + "2015-03-06", + "2015-03-09", + "2015-03-10", + "2015-03-11", + "2015-03-12", + "2015-03-13", + "2015-03-16", + "2015-03-17", + "2015-03-18", + "2015-03-19", + "2015-03-20", + "2015-03-23", + "2015-03-24", + "2015-03-25", + "2015-03-26", + "2015-03-27", + "2015-03-30", + "2015-03-31", + "2015-04-01", + "2015-04-02", + "2015-04-06", + "2015-04-07", + "2015-04-08", + "2015-04-09", + "2015-04-10", + "2015-04-13", + "2015-04-14", + "2015-04-15", + "2015-04-16", + "2015-04-17", + "2015-04-20", + "2015-04-21", + "2015-04-22", + "2015-04-23", + "2015-04-24", + "2015-04-27", + "2015-04-28", + "2015-04-29", + "2015-04-30", + "2015-05-01", + "2015-05-04", + "2015-05-05", + "2015-05-06", + "2015-05-07", + "2015-05-08", + "2015-05-11", + "2015-05-12", + "2015-05-13", + "2015-05-14", + "2015-05-15", + "2015-05-18", + "2015-05-19", + "2015-05-20", + "2015-05-21", + "2015-05-22", + "2015-05-26", + "2015-05-27", + "2015-05-28", + "2015-05-29", + "2015-06-01", + "2015-06-02", + "2015-06-03", + "2015-06-04", + "2015-06-05", + "2015-06-08", + "2015-06-09", + "2015-06-10", + "2015-06-11", + "2015-06-12", + "2015-06-15", + "2015-06-16", + "2015-06-17", + "2015-06-18", + "2015-06-19", + "2015-06-22", + "2015-06-23", + "2015-06-24", + "2015-06-25", + "2015-06-26", + "2015-06-29", + "2015-06-30", + "2015-07-01", + "2015-07-02", + "2015-07-06", + "2015-07-07", + "2015-07-08", + "2015-07-09", + "2015-07-10", + "2015-07-13", + "2015-07-14", + "2015-07-15", + "2015-07-16", + "2015-07-17", + "2015-07-20", + "2015-07-21", + "2015-07-22", + "2015-07-23", + "2015-07-24", + "2015-07-27", + "2015-07-28", + "2015-07-29", + "2015-07-30", + "2015-07-31", + "2015-08-03", + "2015-08-04", + "2015-08-05", + "2015-08-06", + "2015-08-07", + "2015-08-10", + "2015-08-11", + "2015-08-12", + "2015-08-13", + "2015-08-14", + "2015-08-17", + "2015-08-18", + "2015-08-19", + "2015-08-20", + "2015-08-21", + "2015-08-24", + "2015-08-25", + "2015-08-26", + "2015-08-27", + "2015-08-28", + "2015-08-31", + "2015-09-01", + "2015-09-02", + "2015-09-03", + "2015-09-04", + "2015-09-08", + "2015-09-09", + "2015-09-10", + "2015-09-11", + "2015-09-14", + "2015-09-15", + "2015-09-16", + "2015-09-17", + "2015-09-18", + "2015-09-21", + "2015-09-22", + "2015-09-23", + "2015-09-24", + "2015-09-25", + "2015-09-28", + "2015-09-29", + "2015-09-30", + "2015-10-01", + "2015-10-02", + "2015-10-05", + "2015-10-06", + "2015-10-07", + "2015-10-08", + "2015-10-09", + "2015-10-12", + "2015-10-13", + "2015-10-14", + "2015-10-15", + "2015-10-16", + "2015-10-19", + "2015-10-20", + "2015-10-21", + "2015-10-22", + "2015-10-23", + "2015-10-26", + "2015-10-27", + "2015-10-28", + "2015-10-29", + "2015-10-30", + "2015-11-02", + "2015-11-03", + "2015-11-04", + "2015-11-05", + "2015-11-06", + "2015-11-09", + "2015-11-10", + "2015-11-11", + "2015-11-12", + "2015-11-13", + "2015-11-16", + "2015-11-17", + "2015-11-18", + "2015-11-19", + "2015-11-20", + "2015-11-23", + "2015-11-24", + "2015-11-25", + "2015-11-27", + "2015-11-30", + "2015-12-01", + "2015-12-02", + "2015-12-03", + "2015-12-04", + "2015-12-07", + "2015-12-08", + "2015-12-09", + "2015-12-10", + "2015-12-11", + "2015-12-14", + "2015-12-15", + "2015-12-16", + "2015-12-17", + "2015-12-18", + "2015-12-21", + "2015-12-22", + "2015-12-23", + "2015-12-24", + "2015-12-28", + "2015-12-29", + "2015-12-30", + "2015-12-31", + "2016-01-04", + "2016-01-05", + "2016-01-06", + "2016-01-07", + "2016-01-08", + "2016-01-11", + "2016-01-12", + "2016-01-13", + "2016-01-14", + "2016-01-15", + "2016-01-19", + "2016-01-20", + "2016-01-21", + "2016-01-22", + "2016-01-25", + "2016-01-26", + "2016-01-27", + "2016-01-28", + "2016-01-29", + "2016-02-01", + "2016-02-02", + "2016-02-03", + "2016-02-04", + "2016-02-05", + "2016-02-08", + "2016-02-09", + "2016-02-10", + "2016-02-11", + "2016-02-12", + "2016-02-16", + "2016-02-17", + "2016-02-18", + "2016-02-19", + "2016-02-22", + "2016-02-23", + "2016-02-24", + "2016-02-25", + "2016-02-26", + "2016-02-29", + "2016-03-01", + "2016-03-02", + "2016-03-03", + "2016-03-04", + "2016-03-07", + "2016-03-08", + "2016-03-09", + "2016-03-10", + "2016-03-11", + "2016-03-14", + "2016-03-15", + "2016-03-16", + "2016-03-17", + "2016-03-18", + "2016-03-21", + "2016-03-22", + "2016-03-23", + "2016-03-24", + "2016-03-28", + "2016-03-29", + "2016-03-30", + "2016-03-31", + "2016-04-01", + "2016-04-04", + "2016-04-05", + "2016-04-06", + "2016-04-07", + "2016-04-08", + "2016-04-11", + "2016-04-12", + "2016-04-13", + "2016-04-14", + "2016-04-15", + "2016-04-18", + "2016-04-19", + "2016-04-20", + "2016-04-21", + "2016-04-22", + "2016-04-25", + "2016-04-26", + "2016-04-27", + "2016-04-28", + "2016-04-29", + "2016-05-02", + "2016-05-03", + "2016-05-04", + "2016-05-05", + "2016-05-06", + "2016-05-09", + "2016-05-10", + "2016-05-11", + "2016-05-12", + "2016-05-13", + "2016-05-16", + "2016-05-17", + "2016-05-18", + "2016-05-19", + "2016-05-20", + "2016-05-23", + "2016-05-24", + "2016-05-25", + "2016-05-26", + "2016-05-27", + "2016-05-31", + "2016-06-01", + "2016-06-02", + "2016-06-03", + "2016-06-06", + "2016-06-07", + "2016-06-08", + "2016-06-09", + "2016-06-10", + "2016-06-13", + "2016-06-14", + "2016-06-15", + "2016-06-16", + "2016-06-17", + "2016-06-20", + "2016-06-21", + "2016-06-22", + "2016-06-23", + "2016-06-24", + "2016-06-27", + "2016-06-28", + "2016-06-29", + "2016-06-30", + "2016-07-01", + "2016-07-05", + "2016-07-06", + "2016-07-07", + "2016-07-08", + "2016-07-11", + "2016-07-12", + "2016-07-13", + "2016-07-14", + "2016-07-15", + "2016-07-18", + "2016-07-19", + "2016-07-20", + "2016-07-21", + "2016-07-22", + "2016-07-25", + "2016-07-26", + "2016-07-27", + "2016-07-28", + "2016-07-29", + "2016-08-01", + "2016-08-02", + "2016-08-03", + "2016-08-04", + "2016-08-05", + "2016-08-08", + "2016-08-09", + "2016-08-10", + "2016-08-11", + "2016-08-12", + "2016-08-15", + "2016-08-16", + "2016-08-17", + "2016-08-18", + "2016-08-19", + "2016-08-22", + "2016-08-23", + "2016-08-24", + "2016-08-25", + "2016-08-26", + "2016-08-29", + "2016-08-30", + "2016-08-31", + "2016-09-01", + "2016-09-02", + "2016-09-06", + "2016-09-07", + "2016-09-08", + "2016-09-09", + "2016-09-12", + "2016-09-13", + "2016-09-14", + "2016-09-15", + "2016-09-16", + "2016-09-19", + "2016-09-20", + "2016-09-21", + "2016-09-22", + "2016-09-23", + "2016-09-26", + "2016-09-27", + "2016-09-28", + "2016-09-29", + "2016-09-30", + "2016-10-03", + "2016-10-04", + "2016-10-05", + "2016-10-06", + "2016-10-07", + "2016-10-10", + "2016-10-11", + "2016-10-12", + "2016-10-13", + "2016-10-14", + "2016-10-17", + "2016-10-18", + "2016-10-19", + "2016-10-20", + "2016-10-21", + "2016-10-24", + "2016-10-25", + "2016-10-26", + "2016-10-27", + "2016-10-28", + "2016-10-31", + "2016-11-01", + "2016-11-02", + "2016-11-03", + "2016-11-04", + "2016-11-07", + "2016-11-08", + "2016-11-09", + "2016-11-10", + "2016-11-11", + "2016-11-14", + "2016-11-15", + "2016-11-16", + "2016-11-17", + "2016-11-18", + "2016-11-21", + "2016-11-22", + "2016-11-23", + "2016-11-25", + "2016-11-28", + "2016-11-29", + "2016-11-30", + "2016-12-01", + "2016-12-02", + "2016-12-05", + "2016-12-06", + "2016-12-07", + "2016-12-08", + "2016-12-09", + "2016-12-12", + "2016-12-13", + "2016-12-14", + "2016-12-15", + "2016-12-16", + "2016-12-19", + "2016-12-20", + "2016-12-21", + "2016-12-22", + "2016-12-23", + "2016-12-27", + "2016-12-28", + "2016-12-29", + "2016-12-30", + "2017-01-03", + "2017-01-04", + "2017-01-05", + "2017-01-06", + "2017-01-09", + "2017-01-10", + "2017-01-11", + "2017-01-12", + "2017-01-13", + "2017-01-17", + "2017-01-18", + "2017-01-19", + "2017-01-20", + "2017-01-23", + "2017-01-24", + "2017-01-25", + "2017-01-26", + "2017-01-27", + "2017-01-30", + "2017-01-31", + "2017-02-01", + "2017-02-02", + "2017-02-03", + "2017-02-06", + "2017-02-07", + "2017-02-08", + "2017-02-09", + "2017-02-10", + "2017-02-13", + "2017-02-14", + "2017-02-15", + "2017-02-16", + "2017-02-17", + "2017-02-21", + "2017-02-22", + "2017-02-23", + "2017-02-24", + "2017-02-27", + "2017-02-28", + "2017-03-01", + "2017-03-02", + "2017-03-03", + "2017-03-06", + "2017-03-07", + "2017-03-08", + "2017-03-09", + "2017-03-10", + "2017-03-13", + "2017-03-14", + "2017-03-15", + "2017-03-16", + "2017-03-17", + "2017-03-20", + "2017-03-21", + "2017-03-22", + "2017-03-23", + "2017-03-24", + "2017-03-27", + "2017-03-28", + "2017-03-29", + "2017-03-30", + "2017-03-31", + "2017-04-03", + "2017-04-04", + "2017-04-05", + "2017-04-06", + "2017-04-07", + "2017-04-10", + "2017-04-11", + "2017-04-12", + "2017-04-13", + "2017-04-17", + "2017-04-18", + "2017-04-19", + "2017-04-20", + "2017-04-21", + "2017-04-24", + "2017-04-25", + "2017-04-26", + "2017-04-27", + "2017-04-28", + "2017-05-01", + "2017-05-02", + "2017-05-03", + "2017-05-04", + "2017-05-05", + "2017-05-08", + "2017-05-09", + "2017-05-10", + "2017-05-11", + "2017-05-12", + "2017-05-15", + "2017-05-16", + "2017-05-17", + "2017-05-18", + "2017-05-19", + "2017-05-22", + "2017-05-23", + "2017-05-24", + "2017-05-25", + "2017-05-26", + "2017-05-30", + "2017-05-31", + "2017-06-01", + "2017-06-02", + "2017-06-05", + "2017-06-06", + "2017-06-07", + "2017-06-08", + "2017-06-09", + "2017-06-12", + "2017-06-13", + "2017-06-14", + "2017-06-15", + "2017-06-16", + "2017-06-19", + "2017-06-20", + "2017-06-21", + "2017-06-22", + "2017-06-23", + "2017-06-26", + "2017-06-27", + "2017-06-28", + "2017-06-29", + "2017-06-30" + ], + "y": [ + 53.10917319210857, + 54.31224741988544, + 54.61204261580394, + 54.17338124688422, + 53.86579916276005, + 54.81320389445057, + 54.60295791289733, + 55.45406479377765, + 55.35309481004406, + 55.47379157723203, + 55.83133952734264, + 55.846264396403505, + 56.03418796510047, + 55.1506357166965, + 55.327138516025144, + 54.377138154932744, + 57.170035391368344, + 56.90917463647821, + 57.23233049701374, + 58.11484449365696, + 58.83253602328005, + 58.730008661905316, + 59.2680826369175, + 60.02912117755218, + 60.9259111359058, + 60.38082896150852, + 60.345787964582975, + 60.22638901209596, + 59.36939000574175, + 61.05595359903942, + 63.95747005195509, + 65.12408607737322, + 65.04700842283833, + 65.62443763138795, + 66.33120053144529, + 65.45983111492357, + 65.62835683416091, + 65.70674088962014, + 65.45329911030197, + 65.70804729054446, + 63.82944276137168, + 64.13069881451997, + 64.23573344883532, + 63.64994327437006, + 63.82813636044736, + 65.14903833502774, + 64.70211857881773, + 65.08750685149226, + 66.126095586327, + 64.61981532058553, + 61.101677631390636, + 61.75226529170222, + 60.734578971656596, + 58.803718405511006, + 59.48304688615764, + 60.70583815132154, + 61.701315655653715, + 61.062485603661024, + 64.09725495085738, + 63.89606920851203, + 62.90712370880146, + 63.51982574230775, + 63.06650462156856, + 62.2826640669763, + 63.74713950313949, + 63.95616365103077, + 63.1527270825737, + 63.10308384744953, + 63.71970508372877, + 62.83004605426657, + 63.567901296322745, + 63.96635357824047, + 64.38100523161978, + 64.80271144999041, + 65.147601294011, + 65.46557927899059, + 65.90792663196548, + 66.48143663774215, + 68.11077987055458, + 67.91553825241489, + 68.58082292312507, + 69.48877156552777, + 68.71120173537224, + 69.22304961752099, + 67.4988616776029, + 68.57246195720941, + 68.28583759441352, + 67.9367672674351, + 68.81466868857844, + 68.64470592832434, + 68.45148923161734, + 67.34400794611464, + 68.40418343394518, + 68.20549908372212, + 68.3319106875016, + 68.4139074034667, + 69.40286138480192, + 68.98643896029337, + 68.15044039143146, + 68.27146439047607, + 67.67357166989737, + 68.47987271022065, + 68.3043156388595, + 68.82205131338262, + 70.09142355091893, + 71.74187026970324, + 73.07037475432978, + 72.43437458562627, + 74.4175387480381, + 74.24382134658644, + 74.62502723282792, + 73.5894244787882, + 74.43173048733973, + 74.31609409303, + 73.76550717012347, + 73.65775507542577, + 72.85487056493436, + 73.25828389508307, + 72.92845736131329, + 72.37392828860072, + 71.54476277940256, + 72.14396954991659, + 74.91267276367337, + 74.59467267932162, + 74.09927585369927, + 73.59862282833556, + 72.86669701435241, + 73.72082947232198, + 72.68404407334043, + 71.087473401905, + 71.47511813282965, + 70.96362419549942, + 71.41335778586878, + 70.5012757257508, + 70.0309772538934, + 70.39759718585265, + 71.79837441692275, + 73.23988719598835, + 72.83121766609828, + 71.04673785390953, + 72.15053979959329, + 72.47116798381572, + 73.08482930361849, + 71.75632481899196, + 72.33844894034661, + 66.55662922486023, + 65.801050512041, + 65.67385047830028, + 65.78133976301092, + 65.90354640699735, + 66.85754666005259, + 67.35688563548096, + 67.74715846627629, + 68.6949392436332, + 69.92560019721661, + 70.8469435749262, + 70.84165609499674, + 71.96656744999079, + 71.90840517076668, + 72.17277916724002, + 71.03332724243992, + 70.21112411340782, + 69.43122082381146, + 69.7352509197558, + 69.00954429943647, + 68.38694353774177, + 69.7511133595442, + 69.56208595206577, + 69.76301018938551, + 70.22302094324913, + 70.37107038127421, + 70.15824931411316, + 70.1172713446598, + 70.18072110381338, + 70.86412788469698, + 70.93286512378005, + 70.14503061428947, + 69.35719610479893, + 69.62817945118411, + 70.244170862967, + 70.22566468321386, + 69.88726596772797, + 70.43848575037491, + 71.27390757923067, + 72.04059216900335, + 71.3518979081903, + 71.04522407228124, + 70.96591187333921, + 70.95004943355082, + 71.59908759489285, + 71.71805589330587, + 71.22103277993598, + 70.2996894022264, + 69.19592796695021, + 69.19196235700309, + 70.10140890487139, + 69.19724983693257, + 68.68568615375665, + 68.95931324010654, + 68.4675643879663, + 68.60637395481464, + 69.3902428543581, + 70.21376785337256, + 70.28369477543976, + 69.36512732469313, + 75.0518119888347, + 75.60303177148164, + 78.5309737824239, + 78.29832466552736, + 78.00222578947721, + 78.18596571702619, + 78.33137141508655, + 79.43909846030984, + 78.57327362185963, + 78.29832466552736, + 78.15952831737886, + 77.83419039401828, + 78.80289319953012, + 78.9265149640757, + 78.9411368932155, + 78.26985741907009, + 79.42498982111438, + 80.3661103512034, + 80.38206154662863, + 80.59474415229845, + 80.72235371570036, + 81.63423038750979, + 83.16288661576172, + 82.94754547752102, + 84.45892124406228, + 84.14255586812841, + 83.56432503396353, + 84.74604276171655, + 85.71374861751431, + 86.05005298772974, + 85.81344358892204, + 87.18657566177792, + 87.69834318167095, + 87.3354534857468, + 85.87458983805213, + 84.93479857424855, + 85.79084606206962, + 85.67918769409295, + 85.77223633407354, + 85.47448068613575, + 84.59051860632049, + 84.51607969433606, + 84.00431217444302, + 84.07875108642745, + 84.58121374232246, + 85.58613905411241, + 86.47010113392767, + 87.01908810981291, + 86.98186865382071, + 87.49363617371374, + 89.29691881653686, + 88.72187822145702, + 88.75909767744926, + 88.4287750055183, + 88.60091498948229, + 89.74541326124313, + 88.69396362946286, + 88.19150097356787, + 86.61888590925655, + 87.86583073363596, + 87.40896191133145, + 88.13567178957955, + 90.4339731970992, + 90.28509537313032, + 90.88153715540571, + 92.13676330874331, + 91.5412520128678, + 91.32724014091251, + 88.95449982140842, + 89.44765761330534, + 88.94519495741038, + 88.50786634950177, + 88.35898852553288, + 88.34968366153483, + 88.59281361233921, + 89.76170760659109, + 89.74300530268307, + 90.93060160084299, + 91.17373155164742, + 91.62258684544013, + 92.72602277601385, + 94.00713059371395, + 94.04453520153002, + 94.05388635348405, + 94.74587159808115, + 94.95159694106951, + 94.34283694886312, + 95.50331490635638, + 95.61552872980455, + 95.84930752865496, + 96.59739968497615, + 92.52029743302558, + 91.75350297279631, + 92.5483508888876, + 91.97793061969269, + 91.63193799739412, + 94.44663473555269, + 94.84873426957529, + 95.06381076451768, + 95.03575730865565, + 94.31571860819643, + 94.98900154888555, + 95.18537573991988, + 94.40923012773659, + 94.50274164727678, + 95.98022365601116, + 95.1479711321038, + 91.51972417394596, + 94.21285593670228, + 93.61438221164534, + 94.21285593670228, + 92.7447250799219, + 93.41800802061104, + 93.1561757658986, + 93.1561757658986, + 92.34262554589928, + 94.25961169647238, + 94.46533703946068, + 94.19415363279428, + 93.33384765302489, + 92.34262554589928, + 91.21113615946345, + 90.01418870934951, + 91.33270113486564, + 93.2870918932548, + 95.82125407279293, + 96.30751397440169, + 98.02812593394049, + 98.39282086014704, + 98.28995818865288, + 99.81419595715737, + 100.37526507439829, + 100.03862360405373, + 100.99244110336326, + 102.30160237692543, + 101.55351022060415, + 101.79664017140855, + 102.086525881983, + 102.37766500823341, + 102.20861648331379, + 103.02568435375841, + 104.48137998501022, + 105.95585878569756, + 107.23311430731206, + 107.05467419767471, + 108.44462873590228, + 107.693301958482, + 109.23352185219362, + 109.38378720767768, + 111.4076737143536, + 110.44503628078384, + 111.75985814126936, + 111.69411704824509, + 108.06896534719215, + 107.65573561961098, + 108.876641632919, + 108.4634119053378, + 108.00322425416788, + 105.56141222755191, + 107.17676479900557, + 105.138790915253, + 104.82886861956713, + 103.05385910791166, + 101.64042560788971, + 100.25047106966215, + 102.75332839694352, + 105.79620184549576, + 104.97913397505116, + 106.0685578023106, + 105.69289441360044, + 105.19514042355951, + 107.05467419767471, + 106.97954151993272, + 105.67411124416495, + 103.66431211456565, + 102.67819571920151, + 99.78558762613336, + 99.79497921085111, + 101.19432533379644, + 105.08244140694643, + 105.19514042355951, + 102.60306304145948, + 103.5140467590816, + 103.11960020093592, + 100.32090795504531, + 99.54140642347177, + 102.10530905141852, + 102.88481058299207, + 105.56141222755191, + 106.10612414118162, + 106.21882315779465, + 102.4997556095642, + 108.29436338041825, + 111.66594229409183, + 110.03180655320268, + 111.4123695067125, + 111.43115267614799, + 112.28578688546358, + 113.08407158647265, + 112.13180451708513, + 112.87664707630907, + 115.04517604620136, + 117.74169467832836, + 119.23137979677614, + 119.81593977996452, + 120.52306879188593, + 121.35748102595319, + 121.10762877507428, + 122.09289519835148, + 125.39754478073088, + 124.6149886742045, + 121.42819392714532, + 122.96030678630841, + 121.11705716189994, + 121.71104553191392, + 121.96561197620562, + 121.19248425650486, + 119.18423786264805, + 119.36337721233481, + 119.87251010091822, + 117.39284436578043, + 115.25260055636498, + 117.33627404482678, + 116.52543277782353, + 117.80769338610772, + 119.77822623266205, + 121.12648554872551, + 120.20721783322772, + 118.7033901345415, + 119.93850880869756, + 119.44823269376538, + 116.32743665448551, + 117.13827792148876, + 116.20486762575248, + 119.14652431534556, + 117.31741727117551, + 117.14770630831435, + 118.15654369865558, + 120.0705062242562, + 118.8071023896233, + 118.42053852977293, + 119.32566366503237, + 119.83479655361576, + 119.59908688297527, + 119.08052560756624, + 119.53308817519594, + 118.9579565788332, + 117.61912564959532, + 120.30621589489668, + 119.65565720392898, + 121.26791135110982, + 122.25789196779978, + 122.83302356416254, + 125.06755124183422, + 123.09701839527989, + 121.28676812476105, + 117.99626112262008, + 121.57904811635521, + 121.34333844571476, + 118.60910626628531, + 117.86426370706141, + 118.59024949263409, + 120.82458598315468, + 119.59380740786793, + 119.16303490651752, + 119.30031405529951, + 122.08376714094813, + 121.9133516459084, + 123.2577405512217, + 123.1441302211952, + 123.134662693693, + 124.3938438514864, + 125.48260951424012, + 122.71809148359593, + 125.01396690288091, + 124.76307742407243, + 123.34294829874152, + 123.58437025004778, + 123.03998741867096, + 123.19146785870623, + 122.47193576853859, + 121.79974131588196, + 120.99500147819441, + 120.63523543311058, + 122.01749444843271, + 121.7429361508687, + 120.39854724555543, + 120.16185905800027, + 120.80565092815027, + 120.52162510308409, + 121.07074169821207, + 119.85889817792969, + 120.81511845565252, + 120.26600186052454, + 121.2884948307628, + 120.71097565312824, + 120.00091109046276, + 117.899119984973, + 118.74646369642043, + 119.85889817792969, + 119.70741773789436, + 119.29084652779731, + 118.99735317522892, + 116.0434845945406, + 113.67660271898909, + 116.71567904719723, + 118.96895059272232, + 118.92161295521127, + 120.0671837829782, + 121.66719593085104, + 122.71809148359593, + 125.03763572163643, + 123.7879220913452, + 118.55237938262523, + 118.495574217612, + 117.87071740246635, + 116.23283514458471, + 116.8103543222193, + 116.44112074963327, + 115.85413404449648, + 114.84110860176042, + 112.1333957361295, + 108.53573528529114, + 109.2552673754588, + 109.49195556301396, + 109.86285682827562, + 113.85717814647816, + 107.9322681911444, + 109.59656874039543, + 109.51097614071968, + 110.28130953780159, + 111.42254420014518, + 110.79486513585621, + 109.3778320967796, + 107.13340392750388, + 100.58081490788116, + 98.07009865072528, + 98.65973655960278, + 104.31835842705635, + 107.3901817265312, + 107.74206241408714, + 107.2380171048854, + 102.44483152304231, + 106.83858497306512, + 104.96505806905107, + 103.91892629523613, + 106.81005410650654, + 104.75583171428808, + 107.05732161668098, + 108.61700898855057, + 109.6631407623655, + 110.5856387810932, + 110.70927253618044, + 108.34121061181752, + 107.89422703573294, + 109.56803787383686, + 107.84667559146864, + 108.72162216593205, + 109.3683218079267, + 109.0925234311937, + 106.93368786159377, + 103.719210229326, + 104.56562593723083, + 104.21374524967487, + 104.97456835790392, + 105.35497991201844, + 105.85902522122022, + 105.35497991201844, + 104.13766293885195, + 106.62935861830215, + 106.13482359795324, + 106.31551908615766, + 104.81289344740526, + 106.38209110812772, + 105.60224742219292, + 106.25845735304048, + 108.19855627902456, + 108.1890459901717, + 109.84383625056992, + 113.24851965989492, + 109.6346098958069, + 108.94035880954789, + 113.42921514809929, + 114.62751154356009, + 113.64795179171516, + 115.24568031899621, + 116.56761046954416, + 116.02552400493096, + 115.49294782917065, + 115.6266644409477, + 115.15865629972794, + 111.5292054086359, + 110.89882709597256, + 110.52633082030785, + 107.29802976454704, + 109.05067249748228, + 108.58743994954024, + 112.02586710952221, + 113.44899390629247, + 113.94565560717876, + 112.46522169107544, + 113.54450577184751, + 112.73265491462958, + 112.52252881040846, + 112.99053695162821, + 112.07362304229972, + 111.06119726741615, + 110.02966911942156, + 113.68777357018013, + 112.97143457851723, + 112.92367864573968, + 110.4308189547528, + 110.95613421530558, + 108.10032943520949, + 107.43174637632411, + 105.53106025177854, + 106.3429111089965, + 104.08883108189724, + 101.27123104802315, + 102.51288530023886, + 102.4173734346838, + 103.73543717934356, + 103.18146835912424, + 102.02577478590807, + 103.85960260456513, + 102.50333411368335, + 100.53578968324926, + 100.6217503622488, + 98.1002371115954, + 96.1804486139388, + 92.12119432784904, + 92.60830484217982, + 94.10784113139415, + 95.47366080883141, + 93.01900586406654, + 95.05340860038919, + 92.7706750136234, + 92.32176924551466, + 92.44593467073624, + 91.97792652951648, + 96.86813404593521, + 94.97699910794516, + 95.50231436849792, + 89.22718480153091, + 89.8671143007498, + 92.97124993128902, + 92.10209195473804, + 90.23961057641449, + 92.025682462294, + 92.76112382706788, + 90.28365281802198, + 91.23431029823729, + 91.21510509661677, + 90.52371783827834, + 89.97636959209382, + 90.2548450155912, + 92.79953423030891, + 94.22071915022673, + 92.4346353995192, + 92.22337818169359, + 93.02999664975503, + 90.92702707230907, + 92.28099378655511, + 92.914765440032, + 93.0588044521858, + 92.84754723436019, + 96.53494594549831, + 96.74620316332391, + 97.46639822409307, + 98.91639094644171, + 97.82169445407257, + 97.01507598601108, + 97.10149939330336, + 97.14951239735466, + 98.19619588567251, + 98.44586350673912, + 100.42399927365177, + 101.75876078627728, + 101.59551657250292, + 101.71074778222601, + 101.70114518141571, + 102.47895584704644, + 101.91240239924136, + 101.47068276196958, + 101.00975792307732, + 103.40080552483096, + 105.206094477159, + 104.65874623097444, + 105.61900631199998, + 106.70410020355885, + 105.44615949741535, + 106.55045859059477, + 104.22662919451294, + 104.34186040423599, + 104.6875540334052, + 106.05112334846147, + 107.58753947810236, + 107.64515508296387, + 105.48456990065641, + 103.20875350862585, + 102.66140526244128, + 102.87266248026691, + 101.75876078627728, + 101.48028536277988, + 100.90412931416456, + 100.20313945501587, + 93.93264112591906, + 91.06146348365269, + 90.01477999533483, + 89.91875398723228, + 91.39755451201162, + 90.44689703179633, + 90.0819982010066, + 89.5796103946518, + 89.64723952243034, + 90.25590167243713, + 89.3767230113162, + 87.28022005018167, + 87.45412352161215, + 90.70032165498178, + 90.32353080021566, + 91.3572903248304, + 91.00948338196936, + 91.99493638674228, + 93.16395416691408, + 94.58416585026329, + 96.24591013282154, + 97.00915314632212, + 96.95118532251196, + 96.47778142806222, + 95.12519887249157, + 94.41026237883275, + 94.60348845819999, + 95.28944103995373, + 95.67589319868816, + 95.58894146297293, + 96.27489404472662, + 95.48266711932095, + 94.043132828035, + 94.15906847565536, + 93.84990674866778, + 94.2460202113706, + 92.10121073039429, + 91.87900073912192, + 92.66156636055923, + 92.31375941769821, + 92.84513113595811, + 90.23657906450045, + 88.9226417248032, + 90.4201438398993, + 91.2027094613366, + 92.36206593754, + 92.6422437526225, + 91.77272639546995, + 92.2944368097615, + 92.69055027246435, + 93.40548676612312, + 93.69532588517401, + 94.12042325978192, + 93.58905154152201, + 95.44402190344748, + 95.43436059947912, + 96.44879751615713, + 96.4874427320306, + 96.57439446774583, + 96.06234535742266, + 95.31842495185879, + 94.043132828035, + 93.39582546215479, + 99.46312435428604, + 100.80604560588837, + 100.68044865429964, + 102.45812858447823, + 100.94130386144545, + 102.20693468130085, + 102.83491943924436, + 104.39876396835727, + 105.26324945339485, + 105.69063553588532, + 104.90385661130057, + 104.83586337090435, + 105.07869637231941, + 106.34142797967763, + 106.24429477911163, + 106.088881658206, + 105.95289517741355, + 106.22486813899842, + 105.39923593418726, + 105.72948881611171, + 104.93299657147035, + 104.48618384886669, + 103.87424468530077, + 103.75768484462156, + 102.96119259998018, + 103.05832580054621, + 103.67026496411215, + 104.64159696977232, + 104.61245700960251, + 105.25353613333824, + 102.49495323726327, + 100.17346974373545, + 102.41724667681049, + 104.85529001101757, + 108.56577827263949, + 112.2568398941482, + 111.62547409046907, + 110.32388920288444, + 110.3141758828278, + 110.29474924271463, + 111.33407448877102, + 109.47883035796005, + 109.64395679892228, + 109.84793652011093, + 110.6832820449787, + 108.96402439496016, + 109.80908323988452, + 109.2942772768846, + 109.76051663960152, + 109.80908323988452, + 110.62500212463907, + 110.79012856560131, + 112.72307925686508, + 112.96591225828014, + 113.97609754416678, + 113.62641802212907, + 114.2577838258082, + 114.18007726535538, + 114.10237070490255, + 113.7624045029215, + 113.7041245825819, + 113.2573118599782, + 114.2772104659214, + 114.86000966931749, + 112.2762665342614, + 111.1980880079786, + 110.45987568367686, + 110.28503592265804, + 108.29380531105465, + 108.39093851162063, + 107.23505342488501, + 106.26844409327585, + 107.8013498009793, + 108.43599229142977, + 108.26024514022808, + 105.24325237793276, + 105.86813113776093, + 103.21239640849123, + 104.57931869561534, + 107.39127311484205, + 107.3522181923528, + 107.45961922919822, + 109.09016224312485, + 109.15850835748104, + 108.60197571200912, + 109.14874462685871, + 108.9339425531678, + 108.82654151632237, + 107.90875083782473, + 106.90308658372628, + 107.30339953924124, + 106.53206482007832, + 107.3522181923528, + 108.4067010995628, + 109.47094773739514, + 111.25771044127876, + 110.62306795082829, + 112.46841303844582, + 112.46841303844582, + 113.08352806765166, + 113.22998402698641, + 113.88415397868148, + 114.18682962797324, + 114.29423066481873, + 113.54242340690048, + 113.7669892112137, + 114.489505277265, + 114.00131874614927, + 113.97202755428232, + 113.08352806765166, + 113.40573117818806, + 113.27880268009797, + 113.85486278681455, + 115.1241477677155, + 116.17863067492549, + 116.29579544239328, + 116.92067420222143, + 116.43248767110569, + 116.22744932803707, + 117.16476746777931, + 117.155003737157, + 116.94996539408838, + 117.16476746777931, + 117.24287731275784, + 117.13547627591237, + 119.00034882477448, + 119.05893120850841, + 119.06869493913072, + 118.75625555921663, + 118.48287110179182, + 125.70803176230488, + 125.49322968861395, + 126.03023487284128, + 127.21164627814136, + 128.42234887530844, + 128.9202991370465, + 129.8478535461664, + 129.55368079232372, + 130.70095453231022, + 132.39735074613642, + 132.8778329107462, + 132.7160378961327, + 133.08375383843608, + 134.0447181676555, + 134.4467542645739, + 133.87802027381136, + 134.00549513380986, + 134.27025061226828, + 134.32908516303684, + 137.07469753223532, + 136.26081957993722, + 137.0648917737739, + 136.6334384014713, + 136.80994205377692, + 136.3000426137829, + 135.98625834301737, + 136.4373232322428, + 136.49615778301134, + 136.2902368553215, + 137.7316833491507, + 137.95721579376342, + 137.2708127014638, + 138.712259195293, + 137.12372632454245, + 138.6730361614473, + 138.18274823837615, + 137.9081870014563, + 138.14352520453042, + 141.00680667526606, + 141.3205909460316, + 141.13428153526456, + 140.86952605680608, + 140.9087490906518, + 141.95796524602414, + 141.22253336141736, + 140.86952605680608, + 140.55574178604058, + 140.38904389219636, + 138.8789570891372, + 139.0456549829814, + 138.31022309837468, + 139.07507225836568, + 138.457309475296, + 137.947410035302, + 139.67322352451248, + 139.5065256306683, + 140.84991453988326, + 141.72262704294994, + 140.88913757372896, + 140.9970009168046, + 140.85972029834468, + 143.73280752754172, + 144.64474306445405, + 144.20348393369002, + 143.6837787352346, + 146.06657804136043, + 150.03791021823682, + 150.99887454745632, + 150.28305417977242, + 151.57741429668027, + 153.694279777277, + 153.30044433902643, + 153.07398896203242, + 147.9344364928627, + 150.18914437684708, + 150.70113044657282, + 151.61679784050534, + 151.42972600733634, + 150.97681525334818, + 151.49864720903014, + 151.2426541741673, + 151.3017294899049, + 150.4057538678849, + 150.819281078048, + 153.05429719011983, + 151.55772252476774, + 152.06970859449345, + 152.97553010246975, + 152.60138643613172, + 146.68400897641718, + 143.17887357598732, + 144.33084223287017, + 142.92288054112444, + 142.0662884629295, + 140.07741949976423, + 144.08469508396357, + 142.77519225178048, + 143.62193844401918, + 143.38563718106883, + 144.025619768226, + 143.5727090142379, + 141.51491884937872, + 143.58255490019414, + 141.4656894195974, + 141.8004495421104 + ] + } + ], + "layout": { + "title": "AAPL Stock" + } + }, + "text/html": [ + "
" + ], + "text/vnd.plotly.v1+html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "apple_ticker = 'AAPL'\n", + "project_helper.plot_stock(close[apple_ticker], '{} Stock'.format(apple_ticker))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Resample Adjusted Prices\n", + "\n", + "The trading signal you'll develop in this project does not need to be based on daily prices, for instance, you can use month-end prices to perform trading once a month. To do this, you must first resample the daily adjusted closing prices into monthly buckets, and select the last observation of each month.\n", + "\n", + "Implement the `resample_prices` to resample `close_prices` at the sampling frequency of `freq`." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Tests Passed\n" + ] + } + ], + "source": [ + "def resample_prices(close_prices, freq='M'):\n", + " \"\"\"\n", + " Resample close prices for each ticker at specified frequency.\n", + " \n", + " Parameters\n", + " ----------\n", + " close_prices : DataFrame\n", + " Close prices for each ticker and date\n", + " freq : str\n", + " What frequency to sample at\n", + " For valid freq choices, see http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases\n", + " \n", + " Returns\n", + " -------\n", + " prices_resampled : DataFrame\n", + " Resampled prices for each ticker and date\n", + " \"\"\"\n", + " # TODO: Implement Function\n", + " close = pd.DataFrame(close_prices.resample(freq).last())\n", + " return close\n", + "\n", + "project_tests.test_resample_prices(resample_prices)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### View Data\n", + "Let's apply this function to `close` and view the results." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "data": [ + { + "line": { + "color": "#2D3ECF" + }, + "mode": "line", + "name": "Monthly Close", + "type": "scatter", + "x": [ + "2013-07-31", + "2013-08-31", + "2013-09-30", + "2013-10-31", + "2013-11-30", + "2013-12-31", + "2014-01-31", + "2014-02-28", + "2014-03-31", + "2014-04-30", + "2014-05-31", + "2014-06-30", + "2014-07-31", + "2014-08-31", + "2014-09-30", + "2014-10-31", + "2014-11-30", + "2014-12-31", + "2015-01-31", + "2015-02-28", + "2015-03-31", + "2015-04-30", + "2015-05-31", + "2015-06-30", + "2015-07-31", + "2015-08-31", + "2015-09-30", + "2015-10-31", + "2015-11-30", + "2015-12-31", + "2016-01-31", + "2016-02-29", + "2016-03-31", + "2016-04-30", + "2016-05-31", + "2016-06-30", + "2016-07-31", + "2016-08-31", + "2016-09-30", + "2016-10-31", + "2016-11-30", + "2016-12-31", + "2017-01-31", + "2017-02-28", + "2017-03-31", + "2017-04-30", + "2017-05-31", + "2017-06-30" + ], + "y": [ + 58.730008661905316, + 63.64994327437006, + 62.2826640669763, + 68.28583759441352, + 73.07037475432978, + 73.72082947232198, + 65.78133976301092, + 69.56208595206577, + 70.95004943355082, + 78.00222578947721, + 84.14255586812841, + 86.47010113392767, + 88.95449982140842, + 95.84930752865496, + 94.21285593670228, + 100.99244110336326, + 111.69411704824509, + 103.66431211456565, + 110.03180655320268, + 121.11705716189994, + 117.31741727117551, + 117.99626112262008, + 123.34294829874152, + 118.74646369642043, + 114.84110860176042, + 107.2380171048854, + 104.56562593723083, + 113.64795179171516, + 112.99053695162821, + 100.53578968324926, + 92.97124993128902, + 92.84754723436019, + 104.65874623097444, + 90.01477999533483, + 96.47778142806222, + 92.36206593754, + 100.68044865429964, + 103.05832580054621, + 109.80908323988452, + 110.28503592265804, + 107.90875083782473, + 113.08352806765166, + 118.48287110179182, + 134.32908516303684, + 140.86952605680608, + 140.85972029834468, + 150.4057538678849, + 141.8004495421104 + ] + }, + { + "line": { + "color": "#B6B2CF" + }, + "mode": "line", + "name": "Close", + "type": "scatter", + "x": [ + "2013-07-01", + "2013-07-02", + "2013-07-03", + "2013-07-05", + "2013-07-08", + "2013-07-09", + "2013-07-10", + "2013-07-11", + "2013-07-12", + "2013-07-15", + "2013-07-16", + "2013-07-17", + "2013-07-18", + "2013-07-19", + "2013-07-22", + "2013-07-23", + "2013-07-24", + "2013-07-25", + "2013-07-26", + "2013-07-29", + "2013-07-30", + "2013-07-31", + "2013-08-01", + "2013-08-02", + "2013-08-05", + "2013-08-06", + "2013-08-07", + "2013-08-08", + "2013-08-09", + "2013-08-12", + "2013-08-13", + "2013-08-14", + "2013-08-15", + "2013-08-16", + "2013-08-19", + "2013-08-20", + "2013-08-21", + "2013-08-22", + "2013-08-23", + "2013-08-26", + "2013-08-27", + "2013-08-28", + "2013-08-29", + "2013-08-30", + "2013-09-03", + "2013-09-04", + "2013-09-05", + "2013-09-06", + "2013-09-09", + "2013-09-10", + "2013-09-11", + "2013-09-12", + "2013-09-13", + "2013-09-16", + "2013-09-17", + "2013-09-18", + "2013-09-19", + "2013-09-20", + "2013-09-23", + "2013-09-24", + "2013-09-25", + "2013-09-26", + "2013-09-27", + "2013-09-30", + "2013-10-01", + "2013-10-02", + "2013-10-03", + "2013-10-04", + "2013-10-07", + "2013-10-08", + "2013-10-09", + "2013-10-10", + "2013-10-11", + "2013-10-14", + "2013-10-15", + "2013-10-16", + "2013-10-17", + "2013-10-18", + "2013-10-21", + "2013-10-22", + "2013-10-23", + "2013-10-24", + "2013-10-25", + "2013-10-28", + "2013-10-29", + "2013-10-30", + "2013-10-31", + "2013-11-01", + "2013-11-04", + "2013-11-05", + "2013-11-06", + "2013-11-07", + "2013-11-08", + "2013-11-11", + "2013-11-12", + "2013-11-13", + "2013-11-14", + "2013-11-15", + "2013-11-18", + "2013-11-19", + "2013-11-20", + "2013-11-21", + "2013-11-22", + "2013-11-25", + "2013-11-26", + "2013-11-27", + "2013-11-29", + "2013-12-02", + "2013-12-03", + "2013-12-04", + "2013-12-05", + "2013-12-06", + "2013-12-09", + "2013-12-10", + "2013-12-11", + "2013-12-12", + "2013-12-13", + "2013-12-16", + "2013-12-17", + "2013-12-18", + "2013-12-19", + "2013-12-20", + "2013-12-23", + "2013-12-24", + "2013-12-26", + "2013-12-27", + "2013-12-30", + "2013-12-31", + "2014-01-02", + "2014-01-03", + "2014-01-06", + "2014-01-07", + "2014-01-08", + "2014-01-09", + "2014-01-10", + "2014-01-13", + "2014-01-14", + "2014-01-15", + "2014-01-16", + "2014-01-17", + "2014-01-21", + "2014-01-22", + "2014-01-23", + "2014-01-24", + "2014-01-27", + "2014-01-28", + "2014-01-29", + "2014-01-30", + "2014-01-31", + "2014-02-03", + "2014-02-04", + "2014-02-05", + "2014-02-06", + "2014-02-07", + "2014-02-10", + "2014-02-11", + "2014-02-12", + "2014-02-13", + "2014-02-14", + "2014-02-18", + "2014-02-19", + "2014-02-20", + "2014-02-21", + "2014-02-24", + "2014-02-25", + "2014-02-26", + "2014-02-27", + "2014-02-28", + "2014-03-03", + "2014-03-04", + "2014-03-05", + "2014-03-06", + "2014-03-07", + "2014-03-10", + "2014-03-11", + "2014-03-12", + "2014-03-13", + "2014-03-14", + "2014-03-17", + "2014-03-18", + "2014-03-19", + "2014-03-20", + "2014-03-21", + "2014-03-24", + "2014-03-25", + "2014-03-26", + "2014-03-27", + "2014-03-28", + "2014-03-31", + "2014-04-01", + "2014-04-02", + "2014-04-03", + "2014-04-04", + "2014-04-07", + "2014-04-08", + "2014-04-09", + "2014-04-10", + "2014-04-11", + "2014-04-14", + "2014-04-15", + "2014-04-16", + "2014-04-17", + "2014-04-21", + "2014-04-22", + "2014-04-23", + "2014-04-24", + "2014-04-25", + "2014-04-28", + "2014-04-29", + "2014-04-30", + "2014-05-01", + "2014-05-02", + "2014-05-05", + "2014-05-06", + "2014-05-07", + "2014-05-08", + "2014-05-09", + "2014-05-12", + "2014-05-13", + "2014-05-14", + "2014-05-15", + "2014-05-16", + "2014-05-19", + "2014-05-20", + "2014-05-21", + "2014-05-22", + "2014-05-23", + "2014-05-27", + "2014-05-28", + "2014-05-29", + "2014-05-30", + "2014-06-02", + "2014-06-03", + "2014-06-04", + "2014-06-05", + "2014-06-06", + "2014-06-09", + "2014-06-10", + "2014-06-11", + "2014-06-12", + "2014-06-13", + "2014-06-16", + "2014-06-17", + "2014-06-18", + "2014-06-19", + "2014-06-20", + "2014-06-23", + "2014-06-24", + "2014-06-25", + "2014-06-26", + "2014-06-27", + "2014-06-30", + "2014-07-01", + "2014-07-02", + "2014-07-03", + "2014-07-07", + "2014-07-08", + "2014-07-09", + "2014-07-10", + "2014-07-11", + "2014-07-14", + "2014-07-15", + "2014-07-16", + "2014-07-17", + "2014-07-18", + "2014-07-21", + "2014-07-22", + "2014-07-23", + "2014-07-24", + "2014-07-25", + "2014-07-28", + "2014-07-29", + "2014-07-30", + "2014-07-31", + "2014-08-01", + "2014-08-04", + "2014-08-05", + "2014-08-06", + "2014-08-07", + "2014-08-08", + "2014-08-11", + "2014-08-12", + "2014-08-13", + "2014-08-14", + "2014-08-15", + "2014-08-18", + "2014-08-19", + "2014-08-20", + "2014-08-21", + "2014-08-22", + "2014-08-25", + "2014-08-26", + "2014-08-27", + "2014-08-28", + "2014-08-29", + "2014-09-02", + "2014-09-03", + "2014-09-04", + "2014-09-05", + "2014-09-08", + "2014-09-09", + "2014-09-10", + "2014-09-11", + "2014-09-12", + "2014-09-15", + "2014-09-16", + "2014-09-17", + "2014-09-18", + "2014-09-19", + "2014-09-22", + "2014-09-23", + "2014-09-24", + "2014-09-25", + "2014-09-26", + "2014-09-29", + "2014-09-30", + "2014-10-01", + "2014-10-02", + "2014-10-03", + "2014-10-06", + "2014-10-07", + "2014-10-08", + "2014-10-09", + "2014-10-10", + "2014-10-13", + "2014-10-14", + "2014-10-15", + "2014-10-16", + "2014-10-17", + "2014-10-20", + "2014-10-21", + "2014-10-22", + "2014-10-23", + "2014-10-24", + "2014-10-27", + "2014-10-28", + "2014-10-29", + "2014-10-30", + "2014-10-31", + "2014-11-03", + "2014-11-04", + "2014-11-05", + "2014-11-06", + "2014-11-07", + "2014-11-10", + "2014-11-11", + "2014-11-12", + "2014-11-13", + "2014-11-14", + "2014-11-17", + "2014-11-18", + "2014-11-19", + "2014-11-20", + "2014-11-21", + "2014-11-24", + "2014-11-25", + "2014-11-26", + "2014-11-28", + "2014-12-01", + "2014-12-02", + "2014-12-03", + "2014-12-04", + "2014-12-05", + "2014-12-08", + "2014-12-09", + "2014-12-10", + "2014-12-11", + "2014-12-12", + "2014-12-15", + "2014-12-16", + "2014-12-17", + "2014-12-18", + "2014-12-19", + "2014-12-22", + "2014-12-23", + "2014-12-24", + "2014-12-26", + "2014-12-29", + "2014-12-30", + "2014-12-31", + "2015-01-02", + "2015-01-05", + "2015-01-06", + "2015-01-07", + "2015-01-08", + "2015-01-09", + "2015-01-12", + "2015-01-13", + "2015-01-14", + "2015-01-15", + "2015-01-16", + "2015-01-20", + "2015-01-21", + "2015-01-22", + "2015-01-23", + "2015-01-26", + "2015-01-27", + "2015-01-28", + "2015-01-29", + "2015-01-30", + "2015-02-02", + "2015-02-03", + "2015-02-04", + "2015-02-05", + "2015-02-06", + "2015-02-09", + "2015-02-10", + "2015-02-11", + "2015-02-12", + "2015-02-13", + "2015-02-17", + "2015-02-18", + "2015-02-19", + "2015-02-20", + "2015-02-23", + "2015-02-24", + "2015-02-25", + "2015-02-26", + "2015-02-27", + "2015-03-02", + "2015-03-03", + "2015-03-04", + "2015-03-05", + "2015-03-06", + "2015-03-09", + "2015-03-10", + "2015-03-11", + "2015-03-12", + "2015-03-13", + "2015-03-16", + "2015-03-17", + "2015-03-18", + "2015-03-19", + "2015-03-20", + "2015-03-23", + "2015-03-24", + "2015-03-25", + "2015-03-26", + "2015-03-27", + "2015-03-30", + "2015-03-31", + "2015-04-01", + "2015-04-02", + "2015-04-06", + "2015-04-07", + "2015-04-08", + "2015-04-09", + "2015-04-10", + "2015-04-13", + "2015-04-14", + "2015-04-15", + "2015-04-16", + "2015-04-17", + "2015-04-20", + "2015-04-21", + "2015-04-22", + "2015-04-23", + "2015-04-24", + "2015-04-27", + "2015-04-28", + "2015-04-29", + "2015-04-30", + "2015-05-01", + "2015-05-04", + "2015-05-05", + "2015-05-06", + "2015-05-07", + "2015-05-08", + "2015-05-11", + "2015-05-12", + "2015-05-13", + "2015-05-14", + "2015-05-15", + "2015-05-18", + "2015-05-19", + "2015-05-20", + "2015-05-21", + "2015-05-22", + "2015-05-26", + "2015-05-27", + "2015-05-28", + "2015-05-29", + "2015-06-01", + "2015-06-02", + "2015-06-03", + "2015-06-04", + "2015-06-05", + "2015-06-08", + "2015-06-09", + "2015-06-10", + "2015-06-11", + "2015-06-12", + "2015-06-15", + "2015-06-16", + "2015-06-17", + "2015-06-18", + "2015-06-19", + "2015-06-22", + "2015-06-23", + "2015-06-24", + "2015-06-25", + "2015-06-26", + "2015-06-29", + "2015-06-30", + "2015-07-01", + "2015-07-02", + "2015-07-06", + "2015-07-07", + "2015-07-08", + "2015-07-09", + "2015-07-10", + "2015-07-13", + "2015-07-14", + "2015-07-15", + "2015-07-16", + "2015-07-17", + "2015-07-20", + "2015-07-21", + "2015-07-22", + "2015-07-23", + "2015-07-24", + "2015-07-27", + "2015-07-28", + "2015-07-29", + "2015-07-30", + "2015-07-31", + "2015-08-03", + "2015-08-04", + "2015-08-05", + "2015-08-06", + "2015-08-07", + "2015-08-10", + "2015-08-11", + "2015-08-12", + "2015-08-13", + "2015-08-14", + "2015-08-17", + "2015-08-18", + "2015-08-19", + "2015-08-20", + "2015-08-21", + "2015-08-24", + "2015-08-25", + "2015-08-26", + "2015-08-27", + "2015-08-28", + "2015-08-31", + "2015-09-01", + "2015-09-02", + "2015-09-03", + "2015-09-04", + "2015-09-08", + "2015-09-09", + "2015-09-10", + "2015-09-11", + "2015-09-14", + "2015-09-15", + "2015-09-16", + "2015-09-17", + "2015-09-18", + "2015-09-21", + "2015-09-22", + "2015-09-23", + "2015-09-24", + "2015-09-25", + "2015-09-28", + "2015-09-29", + "2015-09-30", + "2015-10-01", + "2015-10-02", + "2015-10-05", + "2015-10-06", + "2015-10-07", + "2015-10-08", + "2015-10-09", + "2015-10-12", + "2015-10-13", + "2015-10-14", + "2015-10-15", + "2015-10-16", + "2015-10-19", + "2015-10-20", + "2015-10-21", + "2015-10-22", + "2015-10-23", + "2015-10-26", + "2015-10-27", + "2015-10-28", + "2015-10-29", + "2015-10-30", + "2015-11-02", + "2015-11-03", + "2015-11-04", + "2015-11-05", + "2015-11-06", + "2015-11-09", + "2015-11-10", + "2015-11-11", + "2015-11-12", + "2015-11-13", + "2015-11-16", + "2015-11-17", + "2015-11-18", + "2015-11-19", + "2015-11-20", + "2015-11-23", + "2015-11-24", + "2015-11-25", + "2015-11-27", + "2015-11-30", + "2015-12-01", + "2015-12-02", + "2015-12-03", + "2015-12-04", + "2015-12-07", + "2015-12-08", + "2015-12-09", + "2015-12-10", + "2015-12-11", + "2015-12-14", + "2015-12-15", + "2015-12-16", + "2015-12-17", + "2015-12-18", + "2015-12-21", + "2015-12-22", + "2015-12-23", + "2015-12-24", + "2015-12-28", + "2015-12-29", + "2015-12-30", + "2015-12-31", + "2016-01-04", + "2016-01-05", + "2016-01-06", + "2016-01-07", + "2016-01-08", + "2016-01-11", + "2016-01-12", + "2016-01-13", + "2016-01-14", + "2016-01-15", + "2016-01-19", + "2016-01-20", + "2016-01-21", + "2016-01-22", + "2016-01-25", + "2016-01-26", + "2016-01-27", + "2016-01-28", + "2016-01-29", + "2016-02-01", + "2016-02-02", + "2016-02-03", + "2016-02-04", + "2016-02-05", + "2016-02-08", + "2016-02-09", + "2016-02-10", + "2016-02-11", + "2016-02-12", + "2016-02-16", + "2016-02-17", + "2016-02-18", + "2016-02-19", + "2016-02-22", + "2016-02-23", + "2016-02-24", + "2016-02-25", + "2016-02-26", + "2016-02-29", + "2016-03-01", + "2016-03-02", + "2016-03-03", + "2016-03-04", + "2016-03-07", + "2016-03-08", + "2016-03-09", + "2016-03-10", + "2016-03-11", + "2016-03-14", + "2016-03-15", + "2016-03-16", + "2016-03-17", + "2016-03-18", + "2016-03-21", + "2016-03-22", + "2016-03-23", + "2016-03-24", + "2016-03-28", + "2016-03-29", + "2016-03-30", + "2016-03-31", + "2016-04-01", + "2016-04-04", + "2016-04-05", + "2016-04-06", + "2016-04-07", + "2016-04-08", + "2016-04-11", + "2016-04-12", + "2016-04-13", + "2016-04-14", + "2016-04-15", + "2016-04-18", + "2016-04-19", + "2016-04-20", + "2016-04-21", + "2016-04-22", + "2016-04-25", + "2016-04-26", + "2016-04-27", + "2016-04-28", + "2016-04-29", + "2016-05-02", + "2016-05-03", + "2016-05-04", + "2016-05-05", + "2016-05-06", + "2016-05-09", + "2016-05-10", + "2016-05-11", + "2016-05-12", + "2016-05-13", + "2016-05-16", + "2016-05-17", + "2016-05-18", + "2016-05-19", + "2016-05-20", + "2016-05-23", + "2016-05-24", + "2016-05-25", + "2016-05-26", + "2016-05-27", + "2016-05-31", + "2016-06-01", + "2016-06-02", + "2016-06-03", + "2016-06-06", + "2016-06-07", + "2016-06-08", + "2016-06-09", + "2016-06-10", + "2016-06-13", + "2016-06-14", + "2016-06-15", + "2016-06-16", + "2016-06-17", + "2016-06-20", + "2016-06-21", + "2016-06-22", + "2016-06-23", + "2016-06-24", + "2016-06-27", + "2016-06-28", + "2016-06-29", + "2016-06-30", + "2016-07-01", + "2016-07-05", + "2016-07-06", + "2016-07-07", + "2016-07-08", + "2016-07-11", + "2016-07-12", + "2016-07-13", + "2016-07-14", + "2016-07-15", + "2016-07-18", + "2016-07-19", + "2016-07-20", + "2016-07-21", + "2016-07-22", + "2016-07-25", + "2016-07-26", + "2016-07-27", + "2016-07-28", + "2016-07-29", + "2016-08-01", + "2016-08-02", + "2016-08-03", + "2016-08-04", + "2016-08-05", + "2016-08-08", + "2016-08-09", + "2016-08-10", + "2016-08-11", + "2016-08-12", + "2016-08-15", + "2016-08-16", + "2016-08-17", + "2016-08-18", + "2016-08-19", + "2016-08-22", + "2016-08-23", + "2016-08-24", + "2016-08-25", + "2016-08-26", + "2016-08-29", + "2016-08-30", + "2016-08-31", + "2016-09-01", + "2016-09-02", + "2016-09-06", + "2016-09-07", + "2016-09-08", + "2016-09-09", + "2016-09-12", + "2016-09-13", + "2016-09-14", + "2016-09-15", + "2016-09-16", + "2016-09-19", + "2016-09-20", + "2016-09-21", + "2016-09-22", + "2016-09-23", + "2016-09-26", + "2016-09-27", + "2016-09-28", + "2016-09-29", + "2016-09-30", + "2016-10-03", + "2016-10-04", + "2016-10-05", + "2016-10-06", + "2016-10-07", + "2016-10-10", + "2016-10-11", + "2016-10-12", + "2016-10-13", + "2016-10-14", + "2016-10-17", + "2016-10-18", + "2016-10-19", + "2016-10-20", + "2016-10-21", + "2016-10-24", + "2016-10-25", + "2016-10-26", + "2016-10-27", + "2016-10-28", + "2016-10-31", + "2016-11-01", + "2016-11-02", + "2016-11-03", + "2016-11-04", + "2016-11-07", + "2016-11-08", + "2016-11-09", + "2016-11-10", + "2016-11-11", + "2016-11-14", + "2016-11-15", + "2016-11-16", + "2016-11-17", + "2016-11-18", + "2016-11-21", + "2016-11-22", + "2016-11-23", + "2016-11-25", + "2016-11-28", + "2016-11-29", + "2016-11-30", + "2016-12-01", + "2016-12-02", + "2016-12-05", + "2016-12-06", + "2016-12-07", + "2016-12-08", + "2016-12-09", + "2016-12-12", + "2016-12-13", + "2016-12-14", + "2016-12-15", + "2016-12-16", + "2016-12-19", + "2016-12-20", + "2016-12-21", + "2016-12-22", + "2016-12-23", + "2016-12-27", + "2016-12-28", + "2016-12-29", + "2016-12-30", + "2017-01-03", + "2017-01-04", + "2017-01-05", + "2017-01-06", + "2017-01-09", + "2017-01-10", + "2017-01-11", + "2017-01-12", + "2017-01-13", + "2017-01-17", + "2017-01-18", + "2017-01-19", + "2017-01-20", + "2017-01-23", + "2017-01-24", + "2017-01-25", + "2017-01-26", + "2017-01-27", + "2017-01-30", + "2017-01-31", + "2017-02-01", + "2017-02-02", + "2017-02-03", + "2017-02-06", + "2017-02-07", + "2017-02-08", + "2017-02-09", + "2017-02-10", + "2017-02-13", + "2017-02-14", + "2017-02-15", + "2017-02-16", + "2017-02-17", + "2017-02-21", + "2017-02-22", + "2017-02-23", + "2017-02-24", + "2017-02-27", + "2017-02-28", + "2017-03-01", + "2017-03-02", + "2017-03-03", + "2017-03-06", + "2017-03-07", + "2017-03-08", + "2017-03-09", + "2017-03-10", + "2017-03-13", + "2017-03-14", + "2017-03-15", + "2017-03-16", + "2017-03-17", + "2017-03-20", + "2017-03-21", + "2017-03-22", + "2017-03-23", + "2017-03-24", + "2017-03-27", + "2017-03-28", + "2017-03-29", + "2017-03-30", + "2017-03-31", + "2017-04-03", + "2017-04-04", + "2017-04-05", + "2017-04-06", + "2017-04-07", + "2017-04-10", + "2017-04-11", + "2017-04-12", + "2017-04-13", + "2017-04-17", + "2017-04-18", + "2017-04-19", + "2017-04-20", + "2017-04-21", + "2017-04-24", + "2017-04-25", + "2017-04-26", + "2017-04-27", + "2017-04-28", + "2017-05-01", + "2017-05-02", + "2017-05-03", + "2017-05-04", + "2017-05-05", + "2017-05-08", + "2017-05-09", + "2017-05-10", + "2017-05-11", + "2017-05-12", + "2017-05-15", + "2017-05-16", + "2017-05-17", + "2017-05-18", + "2017-05-19", + "2017-05-22", + "2017-05-23", + "2017-05-24", + "2017-05-25", + "2017-05-26", + "2017-05-30", + "2017-05-31", + "2017-06-01", + "2017-06-02", + "2017-06-05", + "2017-06-06", + "2017-06-07", + "2017-06-08", + "2017-06-09", + "2017-06-12", + "2017-06-13", + "2017-06-14", + "2017-06-15", + "2017-06-16", + "2017-06-19", + "2017-06-20", + "2017-06-21", + "2017-06-22", + "2017-06-23", + "2017-06-26", + "2017-06-27", + "2017-06-28", + "2017-06-29", + "2017-06-30" + ], + "y": [ + 53.10917319210857, + 54.31224741988544, + 54.61204261580394, + 54.17338124688422, + 53.86579916276005, + 54.81320389445057, + 54.60295791289733, + 55.45406479377765, + 55.35309481004406, + 55.47379157723203, + 55.83133952734264, + 55.846264396403505, + 56.03418796510047, + 55.1506357166965, + 55.327138516025144, + 54.377138154932744, + 57.170035391368344, + 56.90917463647821, + 57.23233049701374, + 58.11484449365696, + 58.83253602328005, + 58.730008661905316, + 59.2680826369175, + 60.02912117755218, + 60.9259111359058, + 60.38082896150852, + 60.345787964582975, + 60.22638901209596, + 59.36939000574175, + 61.05595359903942, + 63.95747005195509, + 65.12408607737322, + 65.04700842283833, + 65.62443763138795, + 66.33120053144529, + 65.45983111492357, + 65.62835683416091, + 65.70674088962014, + 65.45329911030197, + 65.70804729054446, + 63.82944276137168, + 64.13069881451997, + 64.23573344883532, + 63.64994327437006, + 63.82813636044736, + 65.14903833502774, + 64.70211857881773, + 65.08750685149226, + 66.126095586327, + 64.61981532058553, + 61.101677631390636, + 61.75226529170222, + 60.734578971656596, + 58.803718405511006, + 59.48304688615764, + 60.70583815132154, + 61.701315655653715, + 61.062485603661024, + 64.09725495085738, + 63.89606920851203, + 62.90712370880146, + 63.51982574230775, + 63.06650462156856, + 62.2826640669763, + 63.74713950313949, + 63.95616365103077, + 63.1527270825737, + 63.10308384744953, + 63.71970508372877, + 62.83004605426657, + 63.567901296322745, + 63.96635357824047, + 64.38100523161978, + 64.80271144999041, + 65.147601294011, + 65.46557927899059, + 65.90792663196548, + 66.48143663774215, + 68.11077987055458, + 67.91553825241489, + 68.58082292312507, + 69.48877156552777, + 68.71120173537224, + 69.22304961752099, + 67.4988616776029, + 68.57246195720941, + 68.28583759441352, + 67.9367672674351, + 68.81466868857844, + 68.64470592832434, + 68.45148923161734, + 67.34400794611464, + 68.40418343394518, + 68.20549908372212, + 68.3319106875016, + 68.4139074034667, + 69.40286138480192, + 68.98643896029337, + 68.15044039143146, + 68.27146439047607, + 67.67357166989737, + 68.47987271022065, + 68.3043156388595, + 68.82205131338262, + 70.09142355091893, + 71.74187026970324, + 73.07037475432978, + 72.43437458562627, + 74.4175387480381, + 74.24382134658644, + 74.62502723282792, + 73.5894244787882, + 74.43173048733973, + 74.31609409303, + 73.76550717012347, + 73.65775507542577, + 72.85487056493436, + 73.25828389508307, + 72.92845736131329, + 72.37392828860072, + 71.54476277940256, + 72.14396954991659, + 74.91267276367337, + 74.59467267932162, + 74.09927585369927, + 73.59862282833556, + 72.86669701435241, + 73.72082947232198, + 72.68404407334043, + 71.087473401905, + 71.47511813282965, + 70.96362419549942, + 71.41335778586878, + 70.5012757257508, + 70.0309772538934, + 70.39759718585265, + 71.79837441692275, + 73.23988719598835, + 72.83121766609828, + 71.04673785390953, + 72.15053979959329, + 72.47116798381572, + 73.08482930361849, + 71.75632481899196, + 72.33844894034661, + 66.55662922486023, + 65.801050512041, + 65.67385047830028, + 65.78133976301092, + 65.90354640699735, + 66.85754666005259, + 67.35688563548096, + 67.74715846627629, + 68.6949392436332, + 69.92560019721661, + 70.8469435749262, + 70.84165609499674, + 71.96656744999079, + 71.90840517076668, + 72.17277916724002, + 71.03332724243992, + 70.21112411340782, + 69.43122082381146, + 69.7352509197558, + 69.00954429943647, + 68.38694353774177, + 69.7511133595442, + 69.56208595206577, + 69.76301018938551, + 70.22302094324913, + 70.37107038127421, + 70.15824931411316, + 70.1172713446598, + 70.18072110381338, + 70.86412788469698, + 70.93286512378005, + 70.14503061428947, + 69.35719610479893, + 69.62817945118411, + 70.244170862967, + 70.22566468321386, + 69.88726596772797, + 70.43848575037491, + 71.27390757923067, + 72.04059216900335, + 71.3518979081903, + 71.04522407228124, + 70.96591187333921, + 70.95004943355082, + 71.59908759489285, + 71.71805589330587, + 71.22103277993598, + 70.2996894022264, + 69.19592796695021, + 69.19196235700309, + 70.10140890487139, + 69.19724983693257, + 68.68568615375665, + 68.95931324010654, + 68.4675643879663, + 68.60637395481464, + 69.3902428543581, + 70.21376785337256, + 70.28369477543976, + 69.36512732469313, + 75.0518119888347, + 75.60303177148164, + 78.5309737824239, + 78.29832466552736, + 78.00222578947721, + 78.18596571702619, + 78.33137141508655, + 79.43909846030984, + 78.57327362185963, + 78.29832466552736, + 78.15952831737886, + 77.83419039401828, + 78.80289319953012, + 78.9265149640757, + 78.9411368932155, + 78.26985741907009, + 79.42498982111438, + 80.3661103512034, + 80.38206154662863, + 80.59474415229845, + 80.72235371570036, + 81.63423038750979, + 83.16288661576172, + 82.94754547752102, + 84.45892124406228, + 84.14255586812841, + 83.56432503396353, + 84.74604276171655, + 85.71374861751431, + 86.05005298772974, + 85.81344358892204, + 87.18657566177792, + 87.69834318167095, + 87.3354534857468, + 85.87458983805213, + 84.93479857424855, + 85.79084606206962, + 85.67918769409295, + 85.77223633407354, + 85.47448068613575, + 84.59051860632049, + 84.51607969433606, + 84.00431217444302, + 84.07875108642745, + 84.58121374232246, + 85.58613905411241, + 86.47010113392767, + 87.01908810981291, + 86.98186865382071, + 87.49363617371374, + 89.29691881653686, + 88.72187822145702, + 88.75909767744926, + 88.4287750055183, + 88.60091498948229, + 89.74541326124313, + 88.69396362946286, + 88.19150097356787, + 86.61888590925655, + 87.86583073363596, + 87.40896191133145, + 88.13567178957955, + 90.4339731970992, + 90.28509537313032, + 90.88153715540571, + 92.13676330874331, + 91.5412520128678, + 91.32724014091251, + 88.95449982140842, + 89.44765761330534, + 88.94519495741038, + 88.50786634950177, + 88.35898852553288, + 88.34968366153483, + 88.59281361233921, + 89.76170760659109, + 89.74300530268307, + 90.93060160084299, + 91.17373155164742, + 91.62258684544013, + 92.72602277601385, + 94.00713059371395, + 94.04453520153002, + 94.05388635348405, + 94.74587159808115, + 94.95159694106951, + 94.34283694886312, + 95.50331490635638, + 95.61552872980455, + 95.84930752865496, + 96.59739968497615, + 92.52029743302558, + 91.75350297279631, + 92.5483508888876, + 91.97793061969269, + 91.63193799739412, + 94.44663473555269, + 94.84873426957529, + 95.06381076451768, + 95.03575730865565, + 94.31571860819643, + 94.98900154888555, + 95.18537573991988, + 94.40923012773659, + 94.50274164727678, + 95.98022365601116, + 95.1479711321038, + 91.51972417394596, + 94.21285593670228, + 93.61438221164534, + 94.21285593670228, + 92.7447250799219, + 93.41800802061104, + 93.1561757658986, + 93.1561757658986, + 92.34262554589928, + 94.25961169647238, + 94.46533703946068, + 94.19415363279428, + 93.33384765302489, + 92.34262554589928, + 91.21113615946345, + 90.01418870934951, + 91.33270113486564, + 93.2870918932548, + 95.82125407279293, + 96.30751397440169, + 98.02812593394049, + 98.39282086014704, + 98.28995818865288, + 99.81419595715737, + 100.37526507439829, + 100.03862360405373, + 100.99244110336326, + 102.30160237692543, + 101.55351022060415, + 101.79664017140855, + 102.086525881983, + 102.37766500823341, + 102.20861648331379, + 103.02568435375841, + 104.48137998501022, + 105.95585878569756, + 107.23311430731206, + 107.05467419767471, + 108.44462873590228, + 107.693301958482, + 109.23352185219362, + 109.38378720767768, + 111.4076737143536, + 110.44503628078384, + 111.75985814126936, + 111.69411704824509, + 108.06896534719215, + 107.65573561961098, + 108.876641632919, + 108.4634119053378, + 108.00322425416788, + 105.56141222755191, + 107.17676479900557, + 105.138790915253, + 104.82886861956713, + 103.05385910791166, + 101.64042560788971, + 100.25047106966215, + 102.75332839694352, + 105.79620184549576, + 104.97913397505116, + 106.0685578023106, + 105.69289441360044, + 105.19514042355951, + 107.05467419767471, + 106.97954151993272, + 105.67411124416495, + 103.66431211456565, + 102.67819571920151, + 99.78558762613336, + 99.79497921085111, + 101.19432533379644, + 105.08244140694643, + 105.19514042355951, + 102.60306304145948, + 103.5140467590816, + 103.11960020093592, + 100.32090795504531, + 99.54140642347177, + 102.10530905141852, + 102.88481058299207, + 105.56141222755191, + 106.10612414118162, + 106.21882315779465, + 102.4997556095642, + 108.29436338041825, + 111.66594229409183, + 110.03180655320268, + 111.4123695067125, + 111.43115267614799, + 112.28578688546358, + 113.08407158647265, + 112.13180451708513, + 112.87664707630907, + 115.04517604620136, + 117.74169467832836, + 119.23137979677614, + 119.81593977996452, + 120.52306879188593, + 121.35748102595319, + 121.10762877507428, + 122.09289519835148, + 125.39754478073088, + 124.6149886742045, + 121.42819392714532, + 122.96030678630841, + 121.11705716189994, + 121.71104553191392, + 121.96561197620562, + 121.19248425650486, + 119.18423786264805, + 119.36337721233481, + 119.87251010091822, + 117.39284436578043, + 115.25260055636498, + 117.33627404482678, + 116.52543277782353, + 117.80769338610772, + 119.77822623266205, + 121.12648554872551, + 120.20721783322772, + 118.7033901345415, + 119.93850880869756, + 119.44823269376538, + 116.32743665448551, + 117.13827792148876, + 116.20486762575248, + 119.14652431534556, + 117.31741727117551, + 117.14770630831435, + 118.15654369865558, + 120.0705062242562, + 118.8071023896233, + 118.42053852977293, + 119.32566366503237, + 119.83479655361576, + 119.59908688297527, + 119.08052560756624, + 119.53308817519594, + 118.9579565788332, + 117.61912564959532, + 120.30621589489668, + 119.65565720392898, + 121.26791135110982, + 122.25789196779978, + 122.83302356416254, + 125.06755124183422, + 123.09701839527989, + 121.28676812476105, + 117.99626112262008, + 121.57904811635521, + 121.34333844571476, + 118.60910626628531, + 117.86426370706141, + 118.59024949263409, + 120.82458598315468, + 119.59380740786793, + 119.16303490651752, + 119.30031405529951, + 122.08376714094813, + 121.9133516459084, + 123.2577405512217, + 123.1441302211952, + 123.134662693693, + 124.3938438514864, + 125.48260951424012, + 122.71809148359593, + 125.01396690288091, + 124.76307742407243, + 123.34294829874152, + 123.58437025004778, + 123.03998741867096, + 123.19146785870623, + 122.47193576853859, + 121.79974131588196, + 120.99500147819441, + 120.63523543311058, + 122.01749444843271, + 121.7429361508687, + 120.39854724555543, + 120.16185905800027, + 120.80565092815027, + 120.52162510308409, + 121.07074169821207, + 119.85889817792969, + 120.81511845565252, + 120.26600186052454, + 121.2884948307628, + 120.71097565312824, + 120.00091109046276, + 117.899119984973, + 118.74646369642043, + 119.85889817792969, + 119.70741773789436, + 119.29084652779731, + 118.99735317522892, + 116.0434845945406, + 113.67660271898909, + 116.71567904719723, + 118.96895059272232, + 118.92161295521127, + 120.0671837829782, + 121.66719593085104, + 122.71809148359593, + 125.03763572163643, + 123.7879220913452, + 118.55237938262523, + 118.495574217612, + 117.87071740246635, + 116.23283514458471, + 116.8103543222193, + 116.44112074963327, + 115.85413404449648, + 114.84110860176042, + 112.1333957361295, + 108.53573528529114, + 109.2552673754588, + 109.49195556301396, + 109.86285682827562, + 113.85717814647816, + 107.9322681911444, + 109.59656874039543, + 109.51097614071968, + 110.28130953780159, + 111.42254420014518, + 110.79486513585621, + 109.3778320967796, + 107.13340392750388, + 100.58081490788116, + 98.07009865072528, + 98.65973655960278, + 104.31835842705635, + 107.3901817265312, + 107.74206241408714, + 107.2380171048854, + 102.44483152304231, + 106.83858497306512, + 104.96505806905107, + 103.91892629523613, + 106.81005410650654, + 104.75583171428808, + 107.05732161668098, + 108.61700898855057, + 109.6631407623655, + 110.5856387810932, + 110.70927253618044, + 108.34121061181752, + 107.89422703573294, + 109.56803787383686, + 107.84667559146864, + 108.72162216593205, + 109.3683218079267, + 109.0925234311937, + 106.93368786159377, + 103.719210229326, + 104.56562593723083, + 104.21374524967487, + 104.97456835790392, + 105.35497991201844, + 105.85902522122022, + 105.35497991201844, + 104.13766293885195, + 106.62935861830215, + 106.13482359795324, + 106.31551908615766, + 104.81289344740526, + 106.38209110812772, + 105.60224742219292, + 106.25845735304048, + 108.19855627902456, + 108.1890459901717, + 109.84383625056992, + 113.24851965989492, + 109.6346098958069, + 108.94035880954789, + 113.42921514809929, + 114.62751154356009, + 113.64795179171516, + 115.24568031899621, + 116.56761046954416, + 116.02552400493096, + 115.49294782917065, + 115.6266644409477, + 115.15865629972794, + 111.5292054086359, + 110.89882709597256, + 110.52633082030785, + 107.29802976454704, + 109.05067249748228, + 108.58743994954024, + 112.02586710952221, + 113.44899390629247, + 113.94565560717876, + 112.46522169107544, + 113.54450577184751, + 112.73265491462958, + 112.52252881040846, + 112.99053695162821, + 112.07362304229972, + 111.06119726741615, + 110.02966911942156, + 113.68777357018013, + 112.97143457851723, + 112.92367864573968, + 110.4308189547528, + 110.95613421530558, + 108.10032943520949, + 107.43174637632411, + 105.53106025177854, + 106.3429111089965, + 104.08883108189724, + 101.27123104802315, + 102.51288530023886, + 102.4173734346838, + 103.73543717934356, + 103.18146835912424, + 102.02577478590807, + 103.85960260456513, + 102.50333411368335, + 100.53578968324926, + 100.6217503622488, + 98.1002371115954, + 96.1804486139388, + 92.12119432784904, + 92.60830484217982, + 94.10784113139415, + 95.47366080883141, + 93.01900586406654, + 95.05340860038919, + 92.7706750136234, + 92.32176924551466, + 92.44593467073624, + 91.97792652951648, + 96.86813404593521, + 94.97699910794516, + 95.50231436849792, + 89.22718480153091, + 89.8671143007498, + 92.97124993128902, + 92.10209195473804, + 90.23961057641449, + 92.025682462294, + 92.76112382706788, + 90.28365281802198, + 91.23431029823729, + 91.21510509661677, + 90.52371783827834, + 89.97636959209382, + 90.2548450155912, + 92.79953423030891, + 94.22071915022673, + 92.4346353995192, + 92.22337818169359, + 93.02999664975503, + 90.92702707230907, + 92.28099378655511, + 92.914765440032, + 93.0588044521858, + 92.84754723436019, + 96.53494594549831, + 96.74620316332391, + 97.46639822409307, + 98.91639094644171, + 97.82169445407257, + 97.01507598601108, + 97.10149939330336, + 97.14951239735466, + 98.19619588567251, + 98.44586350673912, + 100.42399927365177, + 101.75876078627728, + 101.59551657250292, + 101.71074778222601, + 101.70114518141571, + 102.47895584704644, + 101.91240239924136, + 101.47068276196958, + 101.00975792307732, + 103.40080552483096, + 105.206094477159, + 104.65874623097444, + 105.61900631199998, + 106.70410020355885, + 105.44615949741535, + 106.55045859059477, + 104.22662919451294, + 104.34186040423599, + 104.6875540334052, + 106.05112334846147, + 107.58753947810236, + 107.64515508296387, + 105.48456990065641, + 103.20875350862585, + 102.66140526244128, + 102.87266248026691, + 101.75876078627728, + 101.48028536277988, + 100.90412931416456, + 100.20313945501587, + 93.93264112591906, + 91.06146348365269, + 90.01477999533483, + 89.91875398723228, + 91.39755451201162, + 90.44689703179633, + 90.0819982010066, + 89.5796103946518, + 89.64723952243034, + 90.25590167243713, + 89.3767230113162, + 87.28022005018167, + 87.45412352161215, + 90.70032165498178, + 90.32353080021566, + 91.3572903248304, + 91.00948338196936, + 91.99493638674228, + 93.16395416691408, + 94.58416585026329, + 96.24591013282154, + 97.00915314632212, + 96.95118532251196, + 96.47778142806222, + 95.12519887249157, + 94.41026237883275, + 94.60348845819999, + 95.28944103995373, + 95.67589319868816, + 95.58894146297293, + 96.27489404472662, + 95.48266711932095, + 94.043132828035, + 94.15906847565536, + 93.84990674866778, + 94.2460202113706, + 92.10121073039429, + 91.87900073912192, + 92.66156636055923, + 92.31375941769821, + 92.84513113595811, + 90.23657906450045, + 88.9226417248032, + 90.4201438398993, + 91.2027094613366, + 92.36206593754, + 92.6422437526225, + 91.77272639546995, + 92.2944368097615, + 92.69055027246435, + 93.40548676612312, + 93.69532588517401, + 94.12042325978192, + 93.58905154152201, + 95.44402190344748, + 95.43436059947912, + 96.44879751615713, + 96.4874427320306, + 96.57439446774583, + 96.06234535742266, + 95.31842495185879, + 94.043132828035, + 93.39582546215479, + 99.46312435428604, + 100.80604560588837, + 100.68044865429964, + 102.45812858447823, + 100.94130386144545, + 102.20693468130085, + 102.83491943924436, + 104.39876396835727, + 105.26324945339485, + 105.69063553588532, + 104.90385661130057, + 104.83586337090435, + 105.07869637231941, + 106.34142797967763, + 106.24429477911163, + 106.088881658206, + 105.95289517741355, + 106.22486813899842, + 105.39923593418726, + 105.72948881611171, + 104.93299657147035, + 104.48618384886669, + 103.87424468530077, + 103.75768484462156, + 102.96119259998018, + 103.05832580054621, + 103.67026496411215, + 104.64159696977232, + 104.61245700960251, + 105.25353613333824, + 102.49495323726327, + 100.17346974373545, + 102.41724667681049, + 104.85529001101757, + 108.56577827263949, + 112.2568398941482, + 111.62547409046907, + 110.32388920288444, + 110.3141758828278, + 110.29474924271463, + 111.33407448877102, + 109.47883035796005, + 109.64395679892228, + 109.84793652011093, + 110.6832820449787, + 108.96402439496016, + 109.80908323988452, + 109.2942772768846, + 109.76051663960152, + 109.80908323988452, + 110.62500212463907, + 110.79012856560131, + 112.72307925686508, + 112.96591225828014, + 113.97609754416678, + 113.62641802212907, + 114.2577838258082, + 114.18007726535538, + 114.10237070490255, + 113.7624045029215, + 113.7041245825819, + 113.2573118599782, + 114.2772104659214, + 114.86000966931749, + 112.2762665342614, + 111.1980880079786, + 110.45987568367686, + 110.28503592265804, + 108.29380531105465, + 108.39093851162063, + 107.23505342488501, + 106.26844409327585, + 107.8013498009793, + 108.43599229142977, + 108.26024514022808, + 105.24325237793276, + 105.86813113776093, + 103.21239640849123, + 104.57931869561534, + 107.39127311484205, + 107.3522181923528, + 107.45961922919822, + 109.09016224312485, + 109.15850835748104, + 108.60197571200912, + 109.14874462685871, + 108.9339425531678, + 108.82654151632237, + 107.90875083782473, + 106.90308658372628, + 107.30339953924124, + 106.53206482007832, + 107.3522181923528, + 108.4067010995628, + 109.47094773739514, + 111.25771044127876, + 110.62306795082829, + 112.46841303844582, + 112.46841303844582, + 113.08352806765166, + 113.22998402698641, + 113.88415397868148, + 114.18682962797324, + 114.29423066481873, + 113.54242340690048, + 113.7669892112137, + 114.489505277265, + 114.00131874614927, + 113.97202755428232, + 113.08352806765166, + 113.40573117818806, + 113.27880268009797, + 113.85486278681455, + 115.1241477677155, + 116.17863067492549, + 116.29579544239328, + 116.92067420222143, + 116.43248767110569, + 116.22744932803707, + 117.16476746777931, + 117.155003737157, + 116.94996539408838, + 117.16476746777931, + 117.24287731275784, + 117.13547627591237, + 119.00034882477448, + 119.05893120850841, + 119.06869493913072, + 118.75625555921663, + 118.48287110179182, + 125.70803176230488, + 125.49322968861395, + 126.03023487284128, + 127.21164627814136, + 128.42234887530844, + 128.9202991370465, + 129.8478535461664, + 129.55368079232372, + 130.70095453231022, + 132.39735074613642, + 132.8778329107462, + 132.7160378961327, + 133.08375383843608, + 134.0447181676555, + 134.4467542645739, + 133.87802027381136, + 134.00549513380986, + 134.27025061226828, + 134.32908516303684, + 137.07469753223532, + 136.26081957993722, + 137.0648917737739, + 136.6334384014713, + 136.80994205377692, + 136.3000426137829, + 135.98625834301737, + 136.4373232322428, + 136.49615778301134, + 136.2902368553215, + 137.7316833491507, + 137.95721579376342, + 137.2708127014638, + 138.712259195293, + 137.12372632454245, + 138.6730361614473, + 138.18274823837615, + 137.9081870014563, + 138.14352520453042, + 141.00680667526606, + 141.3205909460316, + 141.13428153526456, + 140.86952605680608, + 140.9087490906518, + 141.95796524602414, + 141.22253336141736, + 140.86952605680608, + 140.55574178604058, + 140.38904389219636, + 138.8789570891372, + 139.0456549829814, + 138.31022309837468, + 139.07507225836568, + 138.457309475296, + 137.947410035302, + 139.67322352451248, + 139.5065256306683, + 140.84991453988326, + 141.72262704294994, + 140.88913757372896, + 140.9970009168046, + 140.85972029834468, + 143.73280752754172, + 144.64474306445405, + 144.20348393369002, + 143.6837787352346, + 146.06657804136043, + 150.03791021823682, + 150.99887454745632, + 150.28305417977242, + 151.57741429668027, + 153.694279777277, + 153.30044433902643, + 153.07398896203242, + 147.9344364928627, + 150.18914437684708, + 150.70113044657282, + 151.61679784050534, + 151.42972600733634, + 150.97681525334818, + 151.49864720903014, + 151.2426541741673, + 151.3017294899049, + 150.4057538678849, + 150.819281078048, + 153.05429719011983, + 151.55772252476774, + 152.06970859449345, + 152.97553010246975, + 152.60138643613172, + 146.68400897641718, + 143.17887357598732, + 144.33084223287017, + 142.92288054112444, + 142.0662884629295, + 140.07741949976423, + 144.08469508396357, + 142.77519225178048, + 143.62193844401918, + 143.38563718106883, + 144.025619768226, + 143.5727090142379, + 141.51491884937872, + 143.58255490019414, + 141.4656894195974, + 141.8004495421104 + ] + } + ], + "layout": { + "title": "AAPL Stock - Close Vs Monthly Close" + } + }, + "text/html": [ + "
" + ], + "text/vnd.plotly.v1+html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "monthly_close = resample_prices(close)\n", + "project_helper.plot_resampled_prices(\n", + " monthly_close.loc[:, apple_ticker],\n", + " close.loc[:, apple_ticker],\n", + " '{} Stock - Close Vs Monthly Close'.format(apple_ticker))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Compute Log Returns\n", + "\n", + "Compute log returns ($R_t$) from prices ($P_t$) as your primary momentum indicator:\n", + "\n", + "$$R_t = log_e(P_t) - log_e(P_{t-1})$$\n", + "\n", + "Implement the `compute_log_returns` function below, such that it accepts a dataframe (like one returned by `resample_prices`), and produces a similar dataframe of log returns. Use Numpy's [log function](https://docs.scipy.org/doc/numpy/reference/generated/numpy.log.html) to help you calculate the log returns." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Tests Passed\n" + ] + } + ], + "source": [ + "def compute_log_returns(prices):\n", + " \"\"\"\n", + " Compute log returns for each ticker.\n", + " \n", + " Parameters\n", + " ----------\n", + " prices : DataFrame\n", + " Prices for each ticker and date\n", + " \n", + " Returns\n", + " -------\n", + " log_returns : DataFrame\n", + " Log returns for each ticker and date\n", + " \"\"\"\n", + " # TODO: Implement Function\n", + " returns = np.log(prices) - np.log(prices.shift(1))\n", + " return returns\n", + "\n", + "project_tests.test_compute_log_returns(compute_log_returns)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### View Data\n", + "Using the same data returned from `resample_prices`, we'll generate the log returns." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "data": [ + { + "line": { + "color": "#2D3ECF" + }, + "mode": "line", + "name": "Returns", + "type": "scatter", + "x": [ + "2013-07-31", + "2013-08-31", + "2013-09-30", + "2013-10-31", + "2013-11-30", + "2013-12-31", + "2014-01-31", + "2014-02-28", + "2014-03-31", + "2014-04-30", + "2014-05-31", + "2014-06-30", + "2014-07-31", + "2014-08-31", + "2014-09-30", + "2014-10-31", + "2014-11-30", + "2014-12-31", + "2015-01-31", + "2015-02-28", + "2015-03-31", + "2015-04-30", + "2015-05-31", + "2015-06-30", + "2015-07-31", + "2015-08-31", + "2015-09-30", + "2015-10-31", + "2015-11-30", + "2015-12-31", + "2016-01-31", + "2016-02-29", + "2016-03-31", + "2016-04-30", + "2016-05-31", + "2016-06-30", + "2016-07-31", + "2016-08-31", + "2016-09-30", + "2016-10-31", + "2016-11-30", + "2016-12-31", + "2017-01-31", + "2017-02-28", + "2017-03-31", + "2017-04-30", + "2017-05-31", + "2017-06-30" + ], + "y": [ + null, + 0.0804476167699244, + -0.02171531209840971, + 0.09201926751761658, + 0.06772062528255329, + 0.008862369904605316, + -0.11394917651344016, + 0.05588346896232643, + 0.0197564234971761, + 0.09476126170131938, + 0.07577509203027688, + 0.027286248480385744, + 0.02832629848810697, + 0.0746522438902959, + -0.017220597751671285, + 0.06948902629742815, + 0.10071836377994803, + -0.0746061267277982, + 0.05961156394817735, + 0.09598801803387769, + -0.0318742630421065, + 0.005769709090243325, + 0.04431573454833959, + -0.03797801003771628, + -0.033441154420311925, + -0.06849868571221762, + -0.025235949245141498, + 0.08329065437079475, + -0.005801456651161274, + -0.11679029105870864, + -0.07822347552032394, + -0.001331433817136407, + 0.11974615040576353, + -0.1507311424066602, + 0.06933885854820687, + -0.04359638501510865, + 0.08623527394698094, + 0.023343471369801527, + 0.06344815310404162, + 0.004324999018601616, + -0.021782279644624758, + 0.046840761742427794, + 0.04664167037496725, + 0.12552424621905978, + 0.04754146618335664, + -6.961122135695774e-05, + 0.06557216424023249, + -0.05891588353659394 + ] + } + ], + "layout": { + "title": "Log Returns of AAPL Stock (Monthly)" + } + }, + "text/html": [ + "
" + ], + "text/vnd.plotly.v1+html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "monthly_close_returns = compute_log_returns(monthly_close)\n", + "project_helper.plot_returns(\n", + " monthly_close_returns.loc[:, apple_ticker],\n", + " 'Log Returns of {} Stock (Monthly)'.format(apple_ticker))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Shift Returns\n", + "Implement the `shift_returns` function to shift the log returns to the previous or future returns in the time series. For example, the parameter `shift_n` is 2 and `returns` is the following:\n", + "\n", + "```\n", + " Returns\n", + " A B C D\n", + "2013-07-08 0.015 0.082 0.096 0.020 ...\n", + "2013-07-09 0.037 0.095 0.027 0.063 ...\n", + "2013-07-10 0.094 0.001 0.093 0.019 ...\n", + "2013-07-11 0.092 0.057 0.069 0.087 ...\n", + "... ... ... ... ...\n", + "```\n", + "\n", + "the output of the `shift_returns` function would be:\n", + "```\n", + " Shift Returns\n", + " A B C D\n", + "2013-07-08 NaN NaN NaN NaN ...\n", + "2013-07-09 NaN NaN NaN NaN ...\n", + "2013-07-10 0.015 0.082 0.096 0.020 ...\n", + "2013-07-11 0.037 0.095 0.027 0.063 ...\n", + "... ... ... ... ...\n", + "```\n", + "Using the same `returns` data as above, the `shift_returns` function should generate the following with `shift_n` as -2:\n", + "```\n", + " Shift Returns\n", + " A B C D\n", + "2013-07-08 0.094 0.001 0.093 0.019 ...\n", + "2013-07-09 0.092 0.057 0.069 0.087 ...\n", + "... ... ... ... ... ...\n", + "... ... ... ... ... ...\n", + "... NaN NaN NaN NaN ...\n", + "... NaN NaN NaN NaN ...\n", + "```\n", + "_Note: The \"...\" represents data points we're not showing._" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Tests Passed\n" + ] + } + ], + "source": [ + "def shift_returns(returns, shift_n):\n", + " \"\"\"\n", + " Generate shifted returns\n", + " \n", + " Parameters\n", + " ----------\n", + " returns : DataFrame\n", + " Returns for each ticker and date\n", + " shift_n : int\n", + " Number of periods to move, can be positive or negative\n", + " \n", + " Returns\n", + " -------\n", + " shifted_returns : DataFrame\n", + " Shifted returns for each ticker and date\n", + " \"\"\"\n", + " # TODO: Implement Function\n", + " \n", + " return returns.shift(shift_n)\n", + "\n", + "project_tests.test_shift_returns(shift_returns)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### View Data\n", + "Let's get the previous month's and next month's returns." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "data": [ + { + "line": { + "color": "#2D3ECF" + }, + "mode": "line", + "name": "Shifted Returns", + "type": "scatter", + "x": [ + "2013-07-31", + "2013-08-31", + "2013-09-30", + "2013-10-31", + "2013-11-30", + "2013-12-31", + "2014-01-31", + "2014-02-28", + "2014-03-31", + "2014-04-30", + "2014-05-31", + "2014-06-30", + "2014-07-31", + "2014-08-31", + "2014-09-30", + "2014-10-31", + "2014-11-30", + "2014-12-31", + "2015-01-31", + "2015-02-28", + "2015-03-31", + "2015-04-30", + "2015-05-31", + "2015-06-30", + "2015-07-31", + "2015-08-31", + "2015-09-30", + "2015-10-31", + "2015-11-30", + "2015-12-31", + "2016-01-31", + "2016-02-29", + "2016-03-31", + "2016-04-30", + "2016-05-31", + "2016-06-30", + "2016-07-31", + "2016-08-31", + "2016-09-30", + "2016-10-31", + "2016-11-30", + "2016-12-31", + "2017-01-31", + "2017-02-28", + "2017-03-31", + "2017-04-30", + "2017-05-31", + "2017-06-30" + ], + "y": [ + null, + null, + 0.0804476167699244, + -0.02171531209840971, + 0.09201926751761658, + 0.06772062528255329, + 0.008862369904605316, + -0.11394917651344016, + 0.05588346896232643, + 0.0197564234971761, + 0.09476126170131938, + 0.07577509203027688, + 0.027286248480385744, + 0.02832629848810697, + 0.0746522438902959, + -0.017220597751671285, + 0.06948902629742815, + 0.10071836377994803, + -0.0746061267277982, + 0.05961156394817735, + 0.09598801803387769, + -0.0318742630421065, + 0.005769709090243325, + 0.04431573454833959, + -0.03797801003771628, + -0.033441154420311925, + -0.06849868571221762, + -0.025235949245141498, + 0.08329065437079475, + -0.005801456651161274, + -0.11679029105870864, + -0.07822347552032394, + -0.001331433817136407, + 0.11974615040576353, + -0.1507311424066602, + 0.06933885854820687, + -0.04359638501510865, + 0.08623527394698094, + 0.023343471369801527, + 0.06344815310404162, + 0.004324999018601616, + -0.021782279644624758, + 0.046840761742427794, + 0.04664167037496725, + 0.12552424621905978, + 0.04754146618335664, + -6.961122135695774e-05, + 0.06557216424023249 + ] + }, + { + "line": { + "color": "#B6B2CF" + }, + "mode": "line", + "name": "Returns", + "type": "scatter", + "x": [ + "2013-07-31", + "2013-08-31", + "2013-09-30", + "2013-10-31", + "2013-11-30", + "2013-12-31", + "2014-01-31", + "2014-02-28", + "2014-03-31", + "2014-04-30", + "2014-05-31", + "2014-06-30", + "2014-07-31", + "2014-08-31", + "2014-09-30", + "2014-10-31", + "2014-11-30", + "2014-12-31", + "2015-01-31", + "2015-02-28", + "2015-03-31", + "2015-04-30", + "2015-05-31", + "2015-06-30", + "2015-07-31", + "2015-08-31", + "2015-09-30", + "2015-10-31", + "2015-11-30", + "2015-12-31", + "2016-01-31", + "2016-02-29", + "2016-03-31", + "2016-04-30", + "2016-05-31", + "2016-06-30", + "2016-07-31", + "2016-08-31", + "2016-09-30", + "2016-10-31", + "2016-11-30", + "2016-12-31", + "2017-01-31", + "2017-02-28", + "2017-03-31", + "2017-04-30", + "2017-05-31", + "2017-06-30" + ], + "y": [ + null, + 0.0804476167699244, + -0.02171531209840971, + 0.09201926751761658, + 0.06772062528255329, + 0.008862369904605316, + -0.11394917651344016, + 0.05588346896232643, + 0.0197564234971761, + 0.09476126170131938, + 0.07577509203027688, + 0.027286248480385744, + 0.02832629848810697, + 0.0746522438902959, + -0.017220597751671285, + 0.06948902629742815, + 0.10071836377994803, + -0.0746061267277982, + 0.05961156394817735, + 0.09598801803387769, + -0.0318742630421065, + 0.005769709090243325, + 0.04431573454833959, + -0.03797801003771628, + -0.033441154420311925, + -0.06849868571221762, + -0.025235949245141498, + 0.08329065437079475, + -0.005801456651161274, + -0.11679029105870864, + -0.07822347552032394, + -0.001331433817136407, + 0.11974615040576353, + -0.1507311424066602, + 0.06933885854820687, + -0.04359638501510865, + 0.08623527394698094, + 0.023343471369801527, + 0.06344815310404162, + 0.004324999018601616, + -0.021782279644624758, + 0.046840761742427794, + 0.04664167037496725, + 0.12552424621905978, + 0.04754146618335664, + -6.961122135695774e-05, + 0.06557216424023249, + -0.05891588353659394 + ] + } + ], + "layout": { + "title": "Previous Returns of AAPL Stock" + } + }, + "text/html": [ + "
" + ], + "text/vnd.plotly.v1+html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.plotly.v1+json": { + "data": [ + { + "line": { + "color": "#2D3ECF" + }, + "mode": "line", + "name": "Shifted Returns", + "type": "scatter", + "x": [ + "2013-07-31", + "2013-08-31", + "2013-09-30", + "2013-10-31", + "2013-11-30", + "2013-12-31", + "2014-01-31", + "2014-02-28", + "2014-03-31", + "2014-04-30", + "2014-05-31", + "2014-06-30", + "2014-07-31", + "2014-08-31", + "2014-09-30", + "2014-10-31", + "2014-11-30", + "2014-12-31", + "2015-01-31", + "2015-02-28", + "2015-03-31", + "2015-04-30", + "2015-05-31", + "2015-06-30", + "2015-07-31", + "2015-08-31", + "2015-09-30", + "2015-10-31", + "2015-11-30", + "2015-12-31", + "2016-01-31", + "2016-02-29", + "2016-03-31", + "2016-04-30", + "2016-05-31", + "2016-06-30", + "2016-07-31", + "2016-08-31", + "2016-09-30", + "2016-10-31", + "2016-11-30", + "2016-12-31", + "2017-01-31", + "2017-02-28", + "2017-03-31", + "2017-04-30", + "2017-05-31", + "2017-06-30" + ], + "y": [ + 0.0804476167699244, + -0.02171531209840971, + 0.09201926751761658, + 0.06772062528255329, + 0.008862369904605316, + -0.11394917651344016, + 0.05588346896232643, + 0.0197564234971761, + 0.09476126170131938, + 0.07577509203027688, + 0.027286248480385744, + 0.02832629848810697, + 0.0746522438902959, + -0.017220597751671285, + 0.06948902629742815, + 0.10071836377994803, + -0.0746061267277982, + 0.05961156394817735, + 0.09598801803387769, + -0.0318742630421065, + 0.005769709090243325, + 0.04431573454833959, + -0.03797801003771628, + -0.033441154420311925, + -0.06849868571221762, + -0.025235949245141498, + 0.08329065437079475, + -0.005801456651161274, + -0.11679029105870864, + -0.07822347552032394, + -0.001331433817136407, + 0.11974615040576353, + -0.1507311424066602, + 0.06933885854820687, + -0.04359638501510865, + 0.08623527394698094, + 0.023343471369801527, + 0.06344815310404162, + 0.004324999018601616, + -0.021782279644624758, + 0.046840761742427794, + 0.04664167037496725, + 0.12552424621905978, + 0.04754146618335664, + -6.961122135695774e-05, + 0.06557216424023249, + -0.05891588353659394, + null + ] + }, + { + "line": { + "color": "#B6B2CF" + }, + "mode": "line", + "name": "Returns", + "type": "scatter", + "x": [ + "2013-07-31", + "2013-08-31", + "2013-09-30", + "2013-10-31", + "2013-11-30", + "2013-12-31", + "2014-01-31", + "2014-02-28", + "2014-03-31", + "2014-04-30", + "2014-05-31", + "2014-06-30", + "2014-07-31", + "2014-08-31", + "2014-09-30", + "2014-10-31", + "2014-11-30", + "2014-12-31", + "2015-01-31", + "2015-02-28", + "2015-03-31", + "2015-04-30", + "2015-05-31", + "2015-06-30", + "2015-07-31", + "2015-08-31", + "2015-09-30", + "2015-10-31", + "2015-11-30", + "2015-12-31", + "2016-01-31", + "2016-02-29", + "2016-03-31", + "2016-04-30", + "2016-05-31", + "2016-06-30", + "2016-07-31", + "2016-08-31", + "2016-09-30", + "2016-10-31", + "2016-11-30", + "2016-12-31", + "2017-01-31", + "2017-02-28", + "2017-03-31", + "2017-04-30", + "2017-05-31", + "2017-06-30" + ], + "y": [ + null, + 0.0804476167699244, + -0.02171531209840971, + 0.09201926751761658, + 0.06772062528255329, + 0.008862369904605316, + -0.11394917651344016, + 0.05588346896232643, + 0.0197564234971761, + 0.09476126170131938, + 0.07577509203027688, + 0.027286248480385744, + 0.02832629848810697, + 0.0746522438902959, + -0.017220597751671285, + 0.06948902629742815, + 0.10071836377994803, + -0.0746061267277982, + 0.05961156394817735, + 0.09598801803387769, + -0.0318742630421065, + 0.005769709090243325, + 0.04431573454833959, + -0.03797801003771628, + -0.033441154420311925, + -0.06849868571221762, + -0.025235949245141498, + 0.08329065437079475, + -0.005801456651161274, + -0.11679029105870864, + -0.07822347552032394, + -0.001331433817136407, + 0.11974615040576353, + -0.1507311424066602, + 0.06933885854820687, + -0.04359638501510865, + 0.08623527394698094, + 0.023343471369801527, + 0.06344815310404162, + 0.004324999018601616, + -0.021782279644624758, + 0.046840761742427794, + 0.04664167037496725, + 0.12552424621905978, + 0.04754146618335664, + -6.961122135695774e-05, + 0.06557216424023249, + -0.05891588353659394 + ] + } + ], + "layout": { + "title": "Lookahead Returns of AAPL Stock" + } + }, + "text/html": [ + "
" + ], + "text/vnd.plotly.v1+html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "prev_returns = shift_returns(monthly_close_returns, 1)\n", + "lookahead_returns = shift_returns(monthly_close_returns, -1)\n", + "\n", + "project_helper.plot_shifted_returns(\n", + " prev_returns.loc[:, apple_ticker],\n", + " monthly_close_returns.loc[:, apple_ticker],\n", + " 'Previous Returns of {} Stock'.format(apple_ticker))\n", + "project_helper.plot_shifted_returns(\n", + " lookahead_returns.loc[:, apple_ticker],\n", + " monthly_close_returns.loc[:, apple_ticker],\n", + " 'Lookahead Returns of {} Stock'.format(apple_ticker))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Generate Trading Signal\n", + "\n", + "A trading signal is a sequence of trading actions, or results that can be used to take trading actions. A common form is to produce a \"long\" and \"short\" portfolio of stocks on each date (e.g. end of each month, or whatever frequency you desire to trade at). This signal can be interpreted as rebalancing your portfolio on each of those dates, entering long (\"buy\") and short (\"sell\") positions as indicated.\n", + "\n", + "Here's a strategy that we will try:\n", + "> For each month-end observation period, rank the stocks by _previous_ returns, from the highest to the lowest. Select the top performing stocks for the long portfolio, and the bottom performing stocks for the short portfolio.\n", + "\n", + "Implement the `get_top_n` function to get the top performing stock for each month. Get the top performing stocks from `prev_returns` by assigning them a value of 1. For all other stocks, give them a value of 0. For example, using the following `prev_returns`:\n", + "\n", + "```\n", + " Previous Returns\n", + " A B C D E F G\n", + "2013-07-08 0.015 0.082 0.096 0.020 0.075 0.043 0.074\n", + "2013-07-09 0.037 0.095 0.027 0.063 0.024 0.086 0.025\n", + "... ... ... ... ... ... ... ...\n", + "```\n", + "\n", + "The function `get_top_n` with `top_n` set to 3 should return the following:\n", + "```\n", + " Previous Returns\n", + " A B C D E F G\n", + "2013-07-08 0 1 1 0 1 0 0\n", + "2013-07-09 0 1 0 1 0 1 0\n", + "... ... ... ... ... ... ... ...\n", + "```\n", + "*Note: You may have to use Panda's [`DataFrame.iterrows`](https://pandas.pydata.org/pandas-docs/version/0.21/generated/pandas.DataFrame.iterrows.html) with [`Series.nlargest`](https://pandas.pydata.org/pandas-docs/version/0.21/generated/pandas.Series.nlargest.html) in order to implement the function. This is one of those cases where creating a vecorization solution is too difficult.*" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Tests Passed\n" + ] + } + ], + "source": [ + "def get_top_n(prev_returns, top_n):\n", + " \"\"\"\n", + " Select the top performing stocks\n", + " \n", + " Parameters\n", + " ----------\n", + " prev_returns : DataFrame\n", + " Previous shifted returns for each ticker and date\n", + " top_n : int\n", + " The number of top performing stocks to get\n", + " \n", + " Returns\n", + " -------\n", + " top_stocks : DataFrame\n", + " Top stocks for each ticker and date marked with a 1\n", + " \"\"\"\n", + " # TODO: Implement Function\n", + " #print(prev_returns.head())\n", + " res = pd.DataFrame(columns=prev_returns.columns)\n", + " \n", + " for index, row in prev_returns.iterrows():\n", + " curr_month = row\n", + " curr_top = pd.Series(curr_month).nlargest(top_n)\n", + " top = list(curr_top.index.values)\n", + " for col in res.columns:\n", + " if(col in top):\n", + " res.loc[index, col] = True\n", + " else:\n", + " res.loc[index, col] = False\n", + " \n", + " for index, row in res.iterrows(): \n", + " res.loc[index] = res.loc[index].astype('int64')\n", + " #print(res.head())\n", + " return res\n", + "\n", + "project_tests.test_get_top_n(get_top_n)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### View Data\n", + "We want to get the best performing and worst performing stocks. To get the best performing stocks, we'll use the `get_top_n` function. To get the worst performing stocks, we'll also use the `get_top_n` function. However, we pass in `-1*prev_returns` instead of just `prev_returns`. Multiplying by negative one will flip all the positive returns to negative and negative returns to positive. Thus, it will return the worst performing stocks." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 Most Longed Stocks:\n", + "INCY, AMD, AVGO, NFX, SWKS, NFLX, ILMN, UAL, NVDA, MU\n", + "10 Most Shorted Stocks:\n", + "RRC, FCX, CHK, MRO, GPS, WYNN, DVN, FTI, SPLS, TRIP\n" + ] + } + ], + "source": [ + "top_bottom_n = 50\n", + "df_long = get_top_n(prev_returns, top_bottom_n)\n", + "df_short = get_top_n(-1*prev_returns, top_bottom_n)\n", + "project_helper.print_top(df_long, 'Longed Stocks')\n", + "project_helper.print_top(df_short, 'Shorted Stocks')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Projected Returns\n", + "It's now time to check if your trading signal has the potential to become profitable!\n", + "\n", + "We'll start by computing the net returns this portfolio would return. For simplicity, we'll assume every stock gets an equal dollar amount of investment. This makes it easier to compute a portfolio's returns as the simple arithmetic average of the individual stock returns.\n", + "\n", + "Implement the `portfolio_returns` function to compute the expected portfolio returns. Using `df_long` to indicate which stocks to long and `df_short` to indicate which stocks to short, calculate the returns using `lookahead_returns`. To help with calculation, we've provided you with `n_stocks` as the number of stocks we're investing in a single period." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Tests Passed\n" + ] + } + ], + "source": [ + "def portfolio_returns(df_long, df_short, lookahead_returns, n_stocks):\n", + " \"\"\"\n", + " Compute expected returns for the portfolio, assuming equal investment in each long/short stock.\n", + " \n", + " Parameters\n", + " ----------\n", + " df_long : DataFrame\n", + " Top stocks for each ticker and date marked with a 1\n", + " df_short : DataFrame\n", + " Bottom stocks for each ticker and date marked with a 1\n", + " lookahead_returns : DataFrame\n", + " Lookahead returns for each ticker and date\n", + " n_stocks: int\n", + " The number number of stocks chosen for each month\n", + " \n", + " Returns\n", + " -------\n", + " portfolio_returns : DataFrame\n", + " Expected portfolio returns for each ticker and date\n", + " \"\"\"\n", + " # TODO: Implement Function\n", + " df_long2 = df_long*lookahead_returns\n", + " df_short2 = df_short*lookahead_returns\n", + " \n", + " \n", + " ret = (df_long2-df_short2)\n", + " ret_avg = ret/n_stocks\n", + " \n", + " return ret_avg\n", + "\n", + "project_tests.test_portfolio_returns(portfolio_returns)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### View Data\n", + "Time to see how the portfolio did." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "data": [ + { + "line": { + "color": "#2D3ECF" + }, + "mode": "line", + "name": "Returns", + "type": "scatter", + "x": [ + "2013-07-31", + "2013-08-31", + "2013-09-30", + "2013-10-31", + "2013-11-30", + "2013-12-31", + "2014-01-31", + "2014-02-28", + "2014-03-31", + "2014-04-30", + "2014-05-31", + "2014-06-30", + "2014-07-31", + "2014-08-31", + "2014-09-30", + "2014-10-31", + "2014-11-30", + "2014-12-31", + "2015-01-31", + "2015-02-28", + "2015-03-31", + "2015-04-30", + "2015-05-31", + "2015-06-30", + "2015-07-31", + "2015-08-31", + "2015-09-30", + "2015-10-31", + "2015-11-30", + "2015-12-31", + "2016-01-31", + "2016-02-29", + "2016-03-31", + "2016-04-30", + "2016-05-31", + "2016-06-30", + "2016-07-31", + "2016-08-31", + "2016-09-30", + "2016-10-31", + "2016-11-30", + "2016-12-31", + "2017-01-31", + "2017-02-28", + "2017-03-31", + "2017-04-30", + "2017-05-31", + "2017-06-30" + ], + "y": [ + 0, + 0, + -0.002364561950000154, + -0.0022274399233187516, + -0.0009682848595743732, + 0.002644290703890742, + -0.004869723041469705, + -0.007614062918999826, + -0.008930449416135376, + -0.007255007281348456, + -0.009384574025405885, + -0.002472281868246124, + 0.01026565789870388, + 0.017063718128497364, + 0.012594151953000999, + 0.033621850536666616, + 0.012017855737879503, + 0.011523131190895052, + -0.01759709185116824, + 0.022544552969585074, + 0.00792112277537717, + 0.025396671262614863, + -0.012030123217369638, + 0.03572642550283469, + -0.0030489344184420207, + 0.03952277374659436, + -0.011829474798826154, + 0.012645697917860774, + -0.0022217155584035547, + -0.01901050600070183, + 0.00987480406280833, + -0.010678938060237285, + -0.025892235227243647, + -0.0024255819500312594, + -0.0005645897832661938, + -0.002552477774413796, + -0.032999620666274126, + 0.0013687279596140767, + 0.009895776024915965, + 0.007437763223292415, + 0.013181132158052392, + -0.010546089504143395, + 0.013530612712879196, + 0.02290161096760456, + 0.010740369231499474, + 0.016457276906924764, + 0.0014763342897174672, + null + ] + } + ], + "layout": { + "title": "Portfolio Returns" + } + }, + "text/html": [ + "
" + ], + "text/vnd.plotly.v1+html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "expected_portfolio_returns = portfolio_returns(df_long, df_short, lookahead_returns, 2*top_bottom_n)\n", + "project_helper.plot_returns(expected_portfolio_returns.T.sum(), 'Portfolio Returns')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Statistical Tests\n", + "### Annualized Rate of Return" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Mean: 0.003253\n", + "Standard Error: 0.002203\n", + "Annualized Rate of Return: 3.98%\n", + "\n" + ] + } + ], + "source": [ + "expected_portfolio_returns_by_date = expected_portfolio_returns.T.sum().dropna()\n", + "portfolio_ret_mean = expected_portfolio_returns_by_date.mean()\n", + "portfolio_ret_ste = expected_portfolio_returns_by_date.sem()\n", + "portfolio_ret_annual_rate = (np.exp(portfolio_ret_mean * 12) - 1) * 100\n", + "\n", + "print(\"\"\"\n", + "Mean: {:.6f}\n", + "Standard Error: {:.6f}\n", + "Annualized Rate of Return: {:.2f}%\n", + "\"\"\".format(portfolio_ret_mean, portfolio_ret_ste, portfolio_ret_annual_rate))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The annualized rate of return allows you to compare the rate of return from this strategy to other quoted rates of return, which are usually quoted on an annual basis. \n", + "\n", + "### T-Test\n", + "Our null hypothesis ($H_0$) is that the actual mean return from the signal is zero. We'll perform a one-sample, one-sided t-test on the observed mean return, to see if we can reject $H_0$.\n", + "\n", + "We'll need to first compute the t-statistic, and then find its corresponding p-value. The p-value will indicate the probability of observing a mean return equally or more extreme than the one we observed if the null hypothesis were true. A small p-value means that the chance of observing the mean we observed under the null hypothesis is small, and thus casts doubt on the null hypothesis. It's good practice to set a desired level of significance or alpha ($\\alpha$) _before_ computing the p-value, and then reject the null hypothesis if $p < \\alpha$.\n", + "\n", + "For this project, we'll use $\\alpha = 0.05$, since it's a common value to use.\n", + "\n", + "Implement the `analyze_alpha` function to perform a t-test on the sample of portfolio returns. We've imported the `scipy.stats` module for you to perform the t-test.\n", + "\n", + "Note: [`scipy.stats.ttest_1samp`](https://docs.scipy.org/doc/scipy-1.0.0/reference/generated/scipy.stats.ttest_1samp.html) performs a two-sided test, so divide the p-value by 2 to get 1-sided p-value" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Tests Passed\n" + ] + } + ], + "source": [ + "from scipy import stats\n", + "\n", + "def analyze_alpha(expected_portfolio_returns_by_date):\n", + " \"\"\"\n", + " Perform a t-test with the null hypothesis being that the expected mean return is zero.\n", + " \n", + " Parameters\n", + " ----------\n", + " expected_portfolio_returns_by_date : Pandas Series\n", + " Expected portfolio returns for each date\n", + " \n", + " Returns\n", + " -------\n", + " t_value\n", + " T-statistic from t-test\n", + " p_value\n", + " Corresponding p-value\n", + " \"\"\"\n", + " # TODO: Implement Function\n", + " expected_null_hypothesis = 0.0\n", + " x = expected_portfolio_returns_by_date\n", + " m, v, s, k = stats.t.stats(10, moments='mvsk')\n", + " t, p = stats.ttest_1samp(x, m)\n", + " \n", + " return (t, p/2)\n", + "\n", + "project_tests.test_analyze_alpha(analyze_alpha)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### View Data\n", + "Let's see what values we get with our portfolio. After you run this, make sure to answer the question below." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Alpha analysis:\n", + " t-value: 1.476\n", + " p-value: 0.073359\n", + "\n" + ] + } + ], + "source": [ + "t_value, p_value = analyze_alpha(expected_portfolio_returns_by_date)\n", + "print(\"\"\"\n", + "Alpha analysis:\n", + " t-value: {:.3f}\n", + " p-value: {:.6f}\n", + "\"\"\".format(t_value, p_value))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Question: What p-value did you observe? And what does that indicate about your signal?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "After performing the t-test, we observe that the t-value is 1.467 and **p_value is 0.073359**. Looking at the p_value (which is above the alpha threshold of 0.05), it indicates that we cannot reject the NULL hypothesis. That means the actual mean return from the signal might be zero." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Submission\n", + "Now that you're done with the project, it's time to submit it. Click the submit button in the bottom right. One of our reviewers will give you feedback on your project with a pass or not passed grade. You can continue to the next section while you wait for feedback." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.6.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/project_1_starter.html b/project_1_starter.html new file mode 100644 index 0000000..879dfb4 --- /dev/null +++ b/project_1_starter.html @@ -0,0 +1,12898 @@ + + + +project_1_starter + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+

Project 1: Trading with Momentum

Instructions

Each problem consists of a function to implement and instructions on how to implement the function. The parts of the function that need to be implemented are marked with a # TODO comment. After implementing the function, run the cell to test it against the unit tests we've provided. For each problem, we provide one or more unit tests from our project_tests package. These unit tests won't tell you if your answer is correct, but will warn you of any major errors. Your code will be checked for the correct solution when you submit it to Udacity.

+

Packages

When you implement the functions, you'll only need to you use the packages you've used in the classroom, like Pandas and Numpy. These packages will be imported for you. We recommend you don't add any import statements, otherwise the grader might not be able to run your code.

+

The other packages that we're importing are helper, project_helper, and project_tests. These are custom packages built to help you solve the problems. The helper and project_helper module contains utility functions and graph functions. The project_tests contains the unit tests for all the problems.

+

Install Packages

+
+
+
+
+
+
In [1]:
+
+
+
import sys
+!{sys.executable} -m pip install -r requirements.txt
+
+ +
+
+
+ +
+
+ + +
+ +
+ + +
+
Requirement already satisfied: colour==0.1.5 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 1))
+Collecting cvxpy==1.0.3 (from -r requirements.txt (line 2))
+  Downloading https://files.pythonhosted.org/packages/a1/59/2613468ffbbe3a818934d06b81b9f4877fe054afbf4f99d2f43f398a0b34/cvxpy-1.0.3.tar.gz (880kB)
+    100% |████████████████████████████████| 880kB 695kB/s ta 0:00:01
+Requirement already satisfied: cycler==0.10.0 in /opt/conda/lib/python3.6/site-packages/cycler-0.10.0-py3.6.egg (from -r requirements.txt (line 3))
+Collecting numpy==1.13.3 (from -r requirements.txt (line 4))
+  Downloading https://files.pythonhosted.org/packages/57/a7/e3e6bd9d595125e1abbe162e323fd2d06f6f6683185294b79cd2cdb190d5/numpy-1.13.3-cp36-cp36m-manylinux1_x86_64.whl (17.0MB)
+    100% |████████████████████████████████| 17.0MB 38kB/s  eta 0:00:01  4% |█▌                              | 808kB 11.8MB/s eta 0:00:02    8% |██▉                             | 1.5MB 17.0MB/s eta 0:00:01    13% |████▍                           | 2.3MB 20.0MB/s eta 0:00:01    19% |██████▎                         | 3.3MB 21.1MB/s eta 0:00:01    61% |███████████████████▋            | 10.4MB 28.7MB/s eta 0:00:01    68% |██████████████████████          | 11.7MB 28.7MB/s eta 0:00:01    75% |████████████████████████▏       | 12.9MB 22.8MB/s eta 0:00:01
+Collecting pandas==0.21.1 (from -r requirements.txt (line 5))
+  Downloading https://files.pythonhosted.org/packages/3a/e1/6c514df670b887c77838ab856f57783c07e8760f2e3d5939203a39735e0e/pandas-0.21.1-cp36-cp36m-manylinux1_x86_64.whl (26.2MB)
+    100% |████████████████████████████████| 26.2MB 24kB/s  eta 0:00:01  3% |█                               | 890kB 20.3MB/s eta 0:00:02    17% |█████▋                          | 4.6MB 28.2MB/s eta 0:00:01    22% |███████                         | 5.8MB 27.8MB/s eta 0:00:01    64% |████████████████████▊           | 16.9MB 26.3MB/s eta 0:00:01    73% |███████████████████████▋        | 19.4MB 25.5MB/s eta 0:00:01
+Collecting plotly==2.2.3 (from -r requirements.txt (line 6))
+  Downloading https://files.pythonhosted.org/packages/99/a6/8214b6564bf4ace9bec8a26e7f89832792be582c042c47c912d3201328a0/plotly-2.2.3.tar.gz (1.1MB)
+    100% |████████████████████████████████| 1.1MB 578kB/s eta 0:00:01    37% |████████████                    | 409kB 20.5MB/s eta 0:00:01
+Requirement already satisfied: pyparsing==2.2.0 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 7))
+Requirement already satisfied: python-dateutil==2.6.1 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 8))
+Requirement already satisfied: pytz==2017.3 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 9))
+Requirement already satisfied: requests==2.18.4 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 10))
+Collecting scipy==1.0.0 (from -r requirements.txt (line 11))
+  Downloading https://files.pythonhosted.org/packages/d8/5e/caa01ba7be11600b6a9d39265440d7b3be3d69206da887c42bef049521f2/scipy-1.0.0-cp36-cp36m-manylinux1_x86_64.whl (50.0MB)
+    100% |████████████████████████████████| 50.0MB 12kB/s  eta 0:00:01   18% |█████▉                          | 9.1MB 24.7MB/s eta 0:00:02    20% |██████▍                         | 10.0MB 20.8MB/s eta 0:00:02    22% |███████                         | 11.1MB 20.6MB/s eta 0:00:02    31% |██████████                      | 15.6MB 21.4MB/s eta 0:00:02    33% |██████████▋                     | 16.6MB 21.7MB/s eta 0:00:02    37% |████████████                    | 18.8MB 20.9MB/s eta 0:00:02    44% |██████████████▏                 | 22.1MB 20.9MB/s eta 0:00:02    48% |███████████████▌                | 24.2MB 22.2MB/s eta 0:00:02    52% |████████████████▉               | 26.2MB 20.2MB/s eta 0:00:02    54% |█████████████████▌              | 27.3MB 21.1MB/s eta 0:00:02    58% |██████████████████▉             | 29.4MB 21.7MB/s eta 0:00:01    60% |███████████████████▌            | 30.5MB 21.2MB/s eta 0:00:01    62% |████████████████████            | 31.4MB 21.0MB/s eta 0:00:01    64% |████████████████████▊           | 32.4MB 20.5MB/s eta 0:00:01    69% |██████████████████████          | 34.5MB 21.2MB/s eta 0:00:01    73% |███████████████████████▌        | 36.7MB 22.5MB/s eta 0:00:01    75% |████████████████████████        | 37.6MB 20.2MB/s eta 0:00:01    77% |████████████████████████▊       | 38.7MB 20.9MB/s eta 0:00:01    81% |██████████████████████████      | 40.7MB 22.1MB/s eta 0:00:01    83% |██████████████████████████▊     | 41.8MB 20.6MB/s eta 0:00:01    85% |███████████████████████████▍    | 42.7MB 21.5MB/s eta 0:00:01    91% |█████████████████████████████▎  | 45.7MB 20.3MB/s eta 0:00:01    95% |██████████████████████████████▌ | 47.7MB 19.1MB/s eta 0:00:01    99% |███████████████████████████████▉| 49.8MB 21.7MB/s eta 0:00:01
+Requirement already satisfied: scikit-learn==0.19.1 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 12))
+Requirement already satisfied: six==1.11.0 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 13))
+Collecting tqdm==4.19.5 (from -r requirements.txt (line 14))
+  Downloading https://files.pythonhosted.org/packages/71/3c/341b4fa23cb3abc335207dba057c790f3bb329f6757e1fcd5d347bcf8308/tqdm-4.19.5-py2.py3-none-any.whl (51kB)
+    100% |████████████████████████████████| 61kB 4.0MB/s eta 0:00:01
+Collecting osqp (from cvxpy==1.0.3->-r requirements.txt (line 2))
+  Downloading https://files.pythonhosted.org/packages/05/42/0ccab82eb6ed0edb83d184928ec864232dc00c3cf968a4b92a02caf0f7ec/osqp-0.4.0-cp36-cp36m-manylinux1_x86_64.whl (146kB)
+    100% |████████████████████████████████| 153kB 3.8MB/s eta 0:00:01
+Collecting ecos>=2 (from cvxpy==1.0.3->-r requirements.txt (line 2))
+  Downloading https://files.pythonhosted.org/packages/b6/b4/988b15513b13e8ea2eac65e97d84221ac515a735a93f046e2a2a3d7863fc/ecos-2.0.5.tar.gz (114kB)
+    100% |████████████████████████████████| 122kB 4.5MB/s eta 0:00:01
+Collecting scs>=1.1.3 (from cvxpy==1.0.3->-r requirements.txt (line 2))
+  Downloading https://files.pythonhosted.org/packages/b3/fd/6e01c4f4a69fcc6c3db130ba55572089e78e77ea8c0921a679f9da1ec04c/scs-2.0.2.tar.gz (133kB)
+    100% |████████████████████████████████| 143kB 3.9MB/s eta 0:00:01
+Collecting multiprocess (from cvxpy==1.0.3->-r requirements.txt (line 2))
+  Downloading https://files.pythonhosted.org/packages/7a/ee/b9bf3e171f936743758ef924622d8dd00516c5532b00a1210a09bce68325/multiprocess-0.70.6.1.tar.gz (1.4MB)
+    100% |████████████████████████████████| 1.4MB 465kB/s eta 0:00:01
+Requirement already satisfied: fastcache in /opt/conda/lib/python3.6/site-packages (from cvxpy==1.0.3->-r requirements.txt (line 2))
+Requirement already satisfied: toolz in /opt/conda/lib/python3.6/site-packages (from cvxpy==1.0.3->-r requirements.txt (line 2))
+Requirement already satisfied: decorator>=4.0.6 in /opt/conda/lib/python3.6/site-packages (from plotly==2.2.3->-r requirements.txt (line 6))
+Requirement already satisfied: nbformat>=4.2 in /opt/conda/lib/python3.6/site-packages (from plotly==2.2.3->-r requirements.txt (line 6))
+Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /opt/conda/lib/python3.6/site-packages (from requests==2.18.4->-r requirements.txt (line 10))
+Requirement already satisfied: idna<2.7,>=2.5 in /opt/conda/lib/python3.6/site-packages (from requests==2.18.4->-r requirements.txt (line 10))
+Requirement already satisfied: urllib3<1.23,>=1.21.1 in /opt/conda/lib/python3.6/site-packages (from requests==2.18.4->-r requirements.txt (line 10))
+Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/lib/python3.6/site-packages (from requests==2.18.4->-r requirements.txt (line 10))
+Requirement already satisfied: future in /opt/conda/lib/python3.6/site-packages (from osqp->cvxpy==1.0.3->-r requirements.txt (line 2))
+Collecting dill>=0.2.8.1 (from multiprocess->cvxpy==1.0.3->-r requirements.txt (line 2))
+  Downloading https://files.pythonhosted.org/packages/6f/78/8b96476f4ae426db71c6e86a8e6a81407f015b34547e442291cd397b18f3/dill-0.2.8.2.tar.gz (150kB)
+    100% |████████████████████████████████| 153kB 3.7MB/s eta 0:00:01
+Requirement already satisfied: jsonschema!=2.5.0,>=2.4 in /opt/conda/lib/python3.6/site-packages (from nbformat>=4.2->plotly==2.2.3->-r requirements.txt (line 6))
+Requirement already satisfied: jupyter-core in /opt/conda/lib/python3.6/site-packages (from nbformat>=4.2->plotly==2.2.3->-r requirements.txt (line 6))
+Requirement already satisfied: traitlets>=4.1 in /opt/conda/lib/python3.6/site-packages (from nbformat>=4.2->plotly==2.2.3->-r requirements.txt (line 6))
+Requirement already satisfied: ipython-genutils in /opt/conda/lib/python3.6/site-packages (from nbformat>=4.2->plotly==2.2.3->-r requirements.txt (line 6))
+Building wheels for collected packages: cvxpy, plotly, ecos, scs, multiprocess, dill
+  Running setup.py bdist_wheel for cvxpy ... done
+  Stored in directory: /root/.cache/pip/wheels/2b/60/0b/0c2596528665e21d698d6f84a3406c52044c7b4ca6ac737cf3
+  Running setup.py bdist_wheel for plotly ... done
+  Stored in directory: /root/.cache/pip/wheels/98/54/81/dd92d5b0858fac680cd7bdb8800eb26c001dd9f5dc8b1bc0ba
+  Running setup.py bdist_wheel for ecos ... done
+  Stored in directory: /root/.cache/pip/wheels/50/91/1b/568de3c087b3399b03d130e71b1fd048ec072c45f72b6b6e9a
+  Running setup.py bdist_wheel for scs ... done
+  Stored in directory: /root/.cache/pip/wheels/ff/f0/aa/530ccd478d7d9900b4e9ef5bc5a39e895ce110bed3d3ac653e
+  Running setup.py bdist_wheel for multiprocess ... done
+  Stored in directory: /root/.cache/pip/wheels/8b/36/e5/96614ab62baf927e9bc06889ea794a8e87552b84bb6bf65e3e
+  Running setup.py bdist_wheel for dill ... done
+  Stored in directory: /root/.cache/pip/wheels/e2/5d/17/f87cb7751896ac629b435a8696f83ee75b11029f5d6f6bda72
+Successfully built cvxpy plotly ecos scs multiprocess dill
+Installing collected packages: numpy, scipy, osqp, ecos, scs, dill, multiprocess, cvxpy, pandas, plotly, tqdm
+  Found existing installation: numpy 1.12.1
+    Uninstalling numpy-1.12.1:
+      Successfully uninstalled numpy-1.12.1
+  Found existing installation: scipy 0.19.1
+    Uninstalling scipy-0.19.1:
+      Successfully uninstalled scipy-0.19.1
+  Found existing installation: dill 0.2.7.1
+    Uninstalling dill-0.2.7.1:
+      Successfully uninstalled dill-0.2.7.1
+  Found existing installation: pandas 0.20.3
+    Uninstalling pandas-0.20.3:
+      Successfully uninstalled pandas-0.20.3
+  Found existing installation: plotly 2.0.15
+    Uninstalling plotly-2.0.15:
+      Successfully uninstalled plotly-2.0.15
+  Found existing installation: tqdm 4.11.2
+    Uninstalling tqdm-4.11.2:
+      Successfully uninstalled tqdm-4.11.2
+Successfully installed cvxpy-1.0.3 dill-0.2.8.2 ecos-2.0.5 multiprocess-0.70.6.1 numpy-1.13.3 osqp-0.4.0 pandas-0.21.1 plotly-2.2.3 scipy-1.0.0 scs-2.0.2 tqdm-4.19.5
+You are using pip version 9.0.1, however version 18.0 is available.
+You should consider upgrading via the 'pip install --upgrade pip' command.
+
+
+
+ +
+
+ +
+
+
+
+
+

Load Packages

+
+
+
+
+
+
In [2]:
+
+
+
import pandas as pd
+import numpy as np
+import helper
+import project_helper
+import project_tests
+
+ +
+
+
+ +
+
+ + +
+ +
+ + + +
+ +
+ +
+ +
+
+ +
+
+
+
+
+

Market Data

Load Data

The data we use for most of the projects is end of day data. This contains data for many stocks, but we'll be looking at stocks in the S&P 500. We also made things a little easier to run by narrowing down our range of time period instead of using all of the data.

+ +
+
+
+
+
+
In [3]:
+
+
+
df = pd.read_csv('../../data/project_1/eod-quotemedia.csv', parse_dates=['date'], index_col=False)
+
+close = df.reset_index().pivot(index='date', columns='ticker', values='adj_close')
+
+print('Loaded Data')
+
+ +
+
+
+ +
+
+ + +
+ +
+ + +
+
Loaded Data
+
+
+
+ +
+
+ +
+
+
+
+
+

View Data

Run the cell below to see what the data looks like for close.

+ +
+
+
+
+
+
In [4]:
+
+
+
project_helper.print_dataframe(close)
+
+ +
+
+
+ +
+
+ + +
+ +
+ + + +
+
+
+ +
+ +
+
+ +
+
+
+
+
+

Stock Example

Let's see what a single stock looks like from the closing prices. For this example and future display examples in this project, we'll use Apple's stock (AAPL). If we tried to graph all the stocks, it would be too much information.

+ +
+
+
+
+
+
In [5]:
+
+
+
apple_ticker = 'AAPL'
+project_helper.plot_stock(close[apple_ticker], '{} Stock'.format(apple_ticker))
+
+ +
+
+
+ +
+
+ + +
+ +
+ + + +
+
+
+ +
+ +
+
+ +
+
+
+
+
+

Resample Adjusted Prices

The trading signal you'll develop in this project does not need to be based on daily prices, for instance, you can use month-end prices to perform trading once a month. To do this, you must first resample the daily adjusted closing prices into monthly buckets, and select the last observation of each month.

+

Implement the resample_prices to resample close_prices at the sampling frequency of freq.

+ +
+
+
+
+
+
In [6]:
+
+
+
def resample_prices(close_prices, freq='M'):
+    """
+    Resample close prices for each ticker at specified frequency.
+    
+    Parameters
+    ----------
+    close_prices : DataFrame
+        Close prices for each ticker and date
+    freq : str
+        What frequency to sample at
+        For valid freq choices, see http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases
+    
+    Returns
+    -------
+    prices_resampled : DataFrame
+        Resampled prices for each ticker and date
+    """
+    # TODO: Implement Function
+    close = pd.DataFrame(close_prices.resample(freq).last())
+    return close
+
+project_tests.test_resample_prices(resample_prices)
+
+ +
+
+
+ +
+
+ + +
+ +
+ + +
+
Tests Passed
+
+
+
+ +
+
+ +
+
+
+
+
+

View Data

Let's apply this function to close and view the results.

+ +
+
+
+
+
+
In [7]:
+
+
+
monthly_close = resample_prices(close)
+project_helper.plot_resampled_prices(
+    monthly_close.loc[:, apple_ticker],
+    close.loc[:, apple_ticker],
+    '{} Stock - Close Vs Monthly Close'.format(apple_ticker))
+
+ +
+
+
+ +
+
+ + +
+ +
+ + + +
+
+
+ +
+ +
+
+ +
+
+
+
+
+

Compute Log Returns

Compute log returns ($R_t$) from prices ($P_t$) as your primary momentum indicator:

+

$$R_t = log_e(P_t) - log_e(P_{t-1})$$

+

Implement the compute_log_returns function below, such that it accepts a dataframe (like one returned by resample_prices), and produces a similar dataframe of log returns. Use Numpy's log function to help you calculate the log returns.

+ +
+
+
+
+
+
In [8]:
+
+
+
def compute_log_returns(prices):
+    """
+    Compute log returns for each ticker.
+    
+    Parameters
+    ----------
+    prices : DataFrame
+        Prices for each ticker and date
+    
+    Returns
+    -------
+    log_returns : DataFrame
+        Log returns for each ticker and date
+    """
+    # TODO: Implement Function
+    returns = np.log(prices) - np.log(prices.shift(1))
+    return returns
+
+project_tests.test_compute_log_returns(compute_log_returns)
+
+ +
+
+
+ +
+
+ + +
+ +
+ + +
+
Tests Passed
+
+
+
+ +
+
+ +
+
+
+
+
+

View Data

Using the same data returned from resample_prices, we'll generate the log returns.

+ +
+
+
+
+
+
In [9]:
+
+
+
monthly_close_returns = compute_log_returns(monthly_close)
+project_helper.plot_returns(
+    monthly_close_returns.loc[:, apple_ticker],
+    'Log Returns of {} Stock (Monthly)'.format(apple_ticker))
+
+ +
+
+
+ +
+
+ + +
+ +
+ + + +
+
+
+ +
+ +
+
+ +
+
+
+
+
+

Shift Returns

Implement the shift_returns function to shift the log returns to the previous or future returns in the time series. For example, the parameter shift_n is 2 and returns is the following:

+ +
                           Returns
+               A         B         C         D
+2013-07-08     0.015     0.082     0.096     0.020     ...
+2013-07-09     0.037     0.095     0.027     0.063     ...
+2013-07-10     0.094     0.001     0.093     0.019     ...
+2013-07-11     0.092     0.057     0.069     0.087     ...
+...            ...       ...       ...       ...
+

the output of the shift_returns function would be:

+ +
                        Shift Returns
+               A         B         C         D
+2013-07-08     NaN       NaN       NaN       NaN       ...
+2013-07-09     NaN       NaN       NaN       NaN       ...
+2013-07-10     0.015     0.082     0.096     0.020     ...
+2013-07-11     0.037     0.095     0.027     0.063     ...
+...            ...       ...       ...       ...
+

Using the same returns data as above, the shift_returns function should generate the following with shift_n as -2:

+ +
                        Shift Returns
+               A         B         C         D
+2013-07-08     0.094     0.001     0.093     0.019     ...
+2013-07-09     0.092     0.057     0.069     0.087     ...
+...            ...       ...       ...       ...       ...
+...            ...       ...       ...       ...       ...
+...            NaN       NaN       NaN       NaN       ...
+...            NaN       NaN       NaN       NaN       ...
+

Note: The "..." represents data points we're not showing.

+ +
+
+
+
+
+
In [10]:
+
+
+
def shift_returns(returns, shift_n):
+    """
+    Generate shifted returns
+    
+    Parameters
+    ----------
+    returns : DataFrame
+        Returns for each ticker and date
+    shift_n : int
+        Number of periods to move, can be positive or negative
+    
+    Returns
+    -------
+    shifted_returns : DataFrame
+        Shifted returns for each ticker and date
+    """
+    # TODO: Implement Function
+    
+    return returns.shift(shift_n)
+
+project_tests.test_shift_returns(shift_returns)
+
+ +
+
+
+ +
+
+ + +
+ +
+ + +
+
Tests Passed
+
+
+
+ +
+
+ +
+
+
+
+
+

View Data

Let's get the previous month's and next month's returns.

+ +
+
+
+
+
+
In [11]:
+
+
+
prev_returns = shift_returns(monthly_close_returns, 1)
+lookahead_returns = shift_returns(monthly_close_returns, -1)
+
+project_helper.plot_shifted_returns(
+    prev_returns.loc[:, apple_ticker],
+    monthly_close_returns.loc[:, apple_ticker],
+    'Previous Returns of {} Stock'.format(apple_ticker))
+project_helper.plot_shifted_returns(
+    lookahead_returns.loc[:, apple_ticker],
+    monthly_close_returns.loc[:, apple_ticker],
+    'Lookahead Returns of {} Stock'.format(apple_ticker))
+
+ +
+
+
+ +
+
+ + +
+ +
+ + + +
+
+
+ +
+ +
+ +
+ + + +
+
+
+ +
+ +
+
+ +
+
+
+
+
+

Generate Trading Signal

A trading signal is a sequence of trading actions, or results that can be used to take trading actions. A common form is to produce a "long" and "short" portfolio of stocks on each date (e.g. end of each month, or whatever frequency you desire to trade at). This signal can be interpreted as rebalancing your portfolio on each of those dates, entering long ("buy") and short ("sell") positions as indicated.

+

Here's a strategy that we will try:

+

For each month-end observation period, rank the stocks by previous returns, from the highest to the lowest. Select the top performing stocks for the long portfolio, and the bottom performing stocks for the short portfolio.

+
+

Implement the get_top_n function to get the top performing stock for each month. Get the top performing stocks from prev_returns by assigning them a value of 1. For all other stocks, give them a value of 0. For example, using the following prev_returns:

+ +
                                     Previous Returns
+               A         B         C         D         E         F         G
+2013-07-08     0.015     0.082     0.096     0.020     0.075     0.043     0.074
+2013-07-09     0.037     0.095     0.027     0.063     0.024     0.086     0.025
+...            ...       ...       ...       ...       ...       ...       ...
+

The function get_top_n with top_n set to 3 should return the following:

+ +
                                     Previous Returns
+               A         B         C         D         E         F         G
+2013-07-08     0         1         1         0         1         0         0
+2013-07-09     0         1         0         1         0         1         0
+...            ...       ...       ...       ...       ...       ...       ...
+

Note: You may have to use Panda's DataFrame.iterrows with Series.nlargest in order to implement the function. This is one of those cases where creating a vecorization solution is too difficult.

+ +
+
+
+
+
+
In [12]:
+
+
+
def get_top_n(prev_returns, top_n):
+    """
+    Select the top performing stocks
+    
+    Parameters
+    ----------
+    prev_returns : DataFrame
+        Previous shifted returns for each ticker and date
+    top_n : int
+        The number of top performing stocks to get
+    
+    Returns
+    -------
+    top_stocks : DataFrame
+        Top stocks for each ticker and date marked with a 1
+    """
+    # TODO: Implement Function
+    #print(prev_returns.head())
+    res = pd.DataFrame(columns=prev_returns.columns)
+    
+    for index, row in prev_returns.iterrows():
+        curr_month = row
+        curr_top = pd.Series(curr_month).nlargest(top_n)
+        top = list(curr_top.index.values)
+        for col in res.columns:
+            if(col in top):
+                res.loc[index, col] = True
+            else:
+                res.loc[index, col] = False
+                
+    for index, row in res.iterrows(): 
+        res.loc[index] = res.loc[index].astype('int64')
+    #print(res.head())
+    return res
+
+project_tests.test_get_top_n(get_top_n)
+
+ +
+
+
+ +
+
+ + +
+ +
+ + +
+
Tests Passed
+
+
+
+ +
+
+ +
+
+
+
+
+

View Data

We want to get the best performing and worst performing stocks. To get the best performing stocks, we'll use the get_top_n function. To get the worst performing stocks, we'll also use the get_top_n function. However, we pass in -1*prev_returns instead of just prev_returns. Multiplying by negative one will flip all the positive returns to negative and negative returns to positive. Thus, it will return the worst performing stocks.

+ +
+
+
+
+
+
In [13]:
+
+
+
top_bottom_n = 50
+df_long = get_top_n(prev_returns, top_bottom_n)
+df_short = get_top_n(-1*prev_returns, top_bottom_n)
+project_helper.print_top(df_long, 'Longed Stocks')
+project_helper.print_top(df_short, 'Shorted Stocks')
+
+ +
+
+
+ +
+
+ + +
+ +
+ + +
+
10 Most Longed Stocks:
+INCY, AMD, AVGO, NFX, SWKS, NFLX, ILMN, UAL, NVDA, MU
+10 Most Shorted Stocks:
+RRC, FCX, CHK, MRO, GPS, WYNN, DVN, FTI, SPLS, TRIP
+
+
+
+ +
+
+ +
+
+
+
+
+

Projected Returns

It's now time to check if your trading signal has the potential to become profitable!

+

We'll start by computing the net returns this portfolio would return. For simplicity, we'll assume every stock gets an equal dollar amount of investment. This makes it easier to compute a portfolio's returns as the simple arithmetic average of the individual stock returns.

+

Implement the portfolio_returns function to compute the expected portfolio returns. Using df_long to indicate which stocks to long and df_short to indicate which stocks to short, calculate the returns using lookahead_returns. To help with calculation, we've provided you with n_stocks as the number of stocks we're investing in a single period.

+ +
+
+
+
+
+
In [30]:
+
+
+
def portfolio_returns(df_long, df_short, lookahead_returns, n_stocks):
+    """
+    Compute expected returns for the portfolio, assuming equal investment in each long/short stock.
+    
+    Parameters
+    ----------
+    df_long : DataFrame
+        Top stocks for each ticker and date marked with a 1
+    df_short : DataFrame
+        Bottom stocks for each ticker and date marked with a 1
+    lookahead_returns : DataFrame
+        Lookahead returns for each ticker and date
+    n_stocks: int
+        The number number of stocks chosen for each month
+    
+    Returns
+    -------
+    portfolio_returns : DataFrame
+        Expected portfolio returns for each ticker and date
+    """
+    # TODO: Implement Function
+    df_long2 = df_long*lookahead_returns
+    df_short2 = df_short*lookahead_returns
+    
+    
+    ret = (df_long2-df_short2)
+    ret_avg = ret/n_stocks
+    
+    return ret_avg
+
+project_tests.test_portfolio_returns(portfolio_returns)
+
+ +
+
+
+ +
+
+ + +
+ +
+ + +
+
Tests Passed
+
+
+
+ +
+
+ +
+
+
+
+
+

View Data

Time to see how the portfolio did.

+ +
+
+
+
+
+
In [31]:
+
+
+
expected_portfolio_returns = portfolio_returns(df_long, df_short, lookahead_returns, 2*top_bottom_n)
+project_helper.plot_returns(expected_portfolio_returns.T.sum(), 'Portfolio Returns')
+
+ +
+
+
+ +
+
+ + +
+ +
+ + + +
+
+
+ +
+ +
+
+ +
+
+
+
+
+

Statistical Tests

Annualized Rate of Return

+
+
+
+
+
+
In [32]:
+
+
+
expected_portfolio_returns_by_date = expected_portfolio_returns.T.sum().dropna()
+portfolio_ret_mean = expected_portfolio_returns_by_date.mean()
+portfolio_ret_ste = expected_portfolio_returns_by_date.sem()
+portfolio_ret_annual_rate = (np.exp(portfolio_ret_mean * 12) - 1) * 100
+
+print("""
+Mean:                       {:.6f}
+Standard Error:             {:.6f}
+Annualized Rate of Return:  {:.2f}%
+""".format(portfolio_ret_mean, portfolio_ret_ste, portfolio_ret_annual_rate))
+
+ +
+
+
+ +
+
+ + +
+ +
+ + +
+
+Mean:                       0.003253
+Standard Error:             0.002203
+Annualized Rate of Return:  3.98%
+
+
+
+
+ +
+
+ +
+
+
+
+
+

The annualized rate of return allows you to compare the rate of return from this strategy to other quoted rates of return, which are usually quoted on an annual basis.

+

T-Test

Our null hypothesis ($H_0$) is that the actual mean return from the signal is zero. We'll perform a one-sample, one-sided t-test on the observed mean return, to see if we can reject $H_0$.

+

We'll need to first compute the t-statistic, and then find its corresponding p-value. The p-value will indicate the probability of observing a mean return equally or more extreme than the one we observed if the null hypothesis were true. A small p-value means that the chance of observing the mean we observed under the null hypothesis is small, and thus casts doubt on the null hypothesis. It's good practice to set a desired level of significance or alpha ($\alpha$) before computing the p-value, and then reject the null hypothesis if $p < \alpha$.

+

For this project, we'll use $\alpha = 0.05$, since it's a common value to use.

+

Implement the analyze_alpha function to perform a t-test on the sample of portfolio returns. We've imported the scipy.stats module for you to perform the t-test.

+

Note: scipy.stats.ttest_1samp performs a two-sided test, so divide the p-value by 2 to get 1-sided p-value

+ +
+
+
+
+
+
In [37]:
+
+
+
from scipy import stats
+
+def analyze_alpha(expected_portfolio_returns_by_date):
+    """
+    Perform a t-test with the null hypothesis being that the expected mean return is zero.
+    
+    Parameters
+    ----------
+    expected_portfolio_returns_by_date : Pandas Series
+        Expected portfolio returns for each date
+    
+    Returns
+    -------
+    t_value
+        T-statistic from t-test
+    p_value
+        Corresponding p-value
+    """
+    # TODO: Implement Function
+    expected_null_hypothesis = 0.0
+    x = expected_portfolio_returns_by_date
+    m, v, s, k = stats.t.stats(10, moments='mvsk')
+    t, p = stats.ttest_1samp(x, m)
+   
+    return (t, p/2)
+
+project_tests.test_analyze_alpha(analyze_alpha)
+
+ +
+
+
+ +
+
+ + +
+ +
+ + +
+
Tests Passed
+
+
+
+ +
+
+ +
+
+
+
+
+

View Data

Let's see what values we get with our portfolio. After you run this, make sure to answer the question below.

+ +
+
+
+
+
+
In [38]:
+
+
+
t_value, p_value = analyze_alpha(expected_portfolio_returns_by_date)
+print("""
+Alpha analysis:
+ t-value:        {:.3f}
+ p-value:        {:.6f}
+""".format(t_value, p_value))
+
+ +
+
+
+ +
+
+ + +
+ +
+ + +
+
+Alpha analysis:
+ t-value:        1.476
+ p-value:        0.073359
+
+
+
+
+ +
+
+ +
+
+
+
+
+

Question: What p-value did you observe? And what does that indicate about your signal?

+
+
+
+
+
+
+
+

After performing the t-test, we observe that the t-value is 1.467 and p_value is 0.073359. Looking at the p_value (which is above the alpha threshold of 0.05), it indicates that we cannot reject the NULL hypothesis. That means the actual mean return from the signal might be zero.

+ +
+
+
+
+
+
+
+

Submission

Now that you're done with the project, it's time to submit it. Click the submit button in the bottom right. One of our reviewers will give you feedback on your project with a pass or not passed grade. You can continue to the next section while you wait for feedback.

+ +
+
+
+
+
+ + + + + + diff --git a/project_1_starter.md b/project_1_starter.md new file mode 100644 index 0000000..add88f0 --- /dev/null +++ b/project_1_starter.md @@ -0,0 +1,599 @@ + +# Project 1: Trading with Momentum +## Instructions +Each problem consists of a function to implement and instructions on how to implement the function. The parts of the function that need to be implemented are marked with a `# TODO` comment. After implementing the function, run the cell to test it against the unit tests we've provided. For each problem, we provide one or more unit tests from our `project_tests` package. These unit tests won't tell you if your answer is correct, but will warn you of any major errors. Your code will be checked for the correct solution when you submit it to Udacity. + +## Packages +When you implement the functions, you'll only need to you use the packages you've used in the classroom, like [Pandas](https://pandas.pydata.org/) and [Numpy](http://www.numpy.org/). These packages will be imported for you. We recommend you don't add any import statements, otherwise the grader might not be able to run your code. + +The other packages that we're importing are `helper`, `project_helper`, and `project_tests`. These are custom packages built to help you solve the problems. The `helper` and `project_helper` module contains utility functions and graph functions. The `project_tests` contains the unit tests for all the problems. + +### Install Packages + + +```python +import sys +!{sys.executable} -m pip install -r requirements.txt +``` + + Requirement already satisfied: colour==0.1.5 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 1)) + Collecting cvxpy==1.0.3 (from -r requirements.txt (line 2)) + Downloading https://files.pythonhosted.org/packages/a1/59/2613468ffbbe3a818934d06b81b9f4877fe054afbf4f99d2f43f398a0b34/cvxpy-1.0.3.tar.gz (880kB) +  100% |████████████████████████████████| 880kB 695kB/s ta 0:00:01 + [?25hRequirement already satisfied: cycler==0.10.0 in /opt/conda/lib/python3.6/site-packages/cycler-0.10.0-py3.6.egg (from -r requirements.txt (line 3)) + Collecting numpy==1.13.3 (from -r requirements.txt (line 4)) + Downloading https://files.pythonhosted.org/packages/57/a7/e3e6bd9d595125e1abbe162e323fd2d06f6f6683185294b79cd2cdb190d5/numpy-1.13.3-cp36-cp36m-manylinux1_x86_64.whl (17.0MB) +  100% |████████████████████████████████| 17.0MB 38kB/s eta 0:00:01 4% |█▌ | 808kB 11.8MB/s eta 0:00:02 8% |██▉ | 1.5MB 17.0MB/s eta 0:00:01 13% |████▍ | 2.3MB 20.0MB/s eta 0:00:01 19% |██████▎ | 3.3MB 21.1MB/s eta 0:00:01 61% |███████████████████▋ | 10.4MB 28.7MB/s eta 0:00:01 68% |██████████████████████ | 11.7MB 28.7MB/s eta 0:00:01 75% |████████████████████████▏ | 12.9MB 22.8MB/s eta 0:00:01 + [?25hCollecting pandas==0.21.1 (from -r requirements.txt (line 5)) + Downloading https://files.pythonhosted.org/packages/3a/e1/6c514df670b887c77838ab856f57783c07e8760f2e3d5939203a39735e0e/pandas-0.21.1-cp36-cp36m-manylinux1_x86_64.whl (26.2MB) +  100% |████████████████████████████████| 26.2MB 24kB/s eta 0:00:01 3% |█ | 890kB 20.3MB/s eta 0:00:02 17% |█████▋ | 4.6MB 28.2MB/s eta 0:00:01 22% |███████ | 5.8MB 27.8MB/s eta 0:00:01 64% |████████████████████▊ | 16.9MB 26.3MB/s eta 0:00:01 73% |███████████████████████▋ | 19.4MB 25.5MB/s eta 0:00:01 + [?25hCollecting plotly==2.2.3 (from -r requirements.txt (line 6)) + Downloading https://files.pythonhosted.org/packages/99/a6/8214b6564bf4ace9bec8a26e7f89832792be582c042c47c912d3201328a0/plotly-2.2.3.tar.gz (1.1MB) +  100% |████████████████████████████████| 1.1MB 578kB/s eta 0:00:01 37% |████████████ | 409kB 20.5MB/s eta 0:00:01 + [?25hRequirement already satisfied: pyparsing==2.2.0 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 7)) + Requirement already satisfied: python-dateutil==2.6.1 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 8)) + Requirement already satisfied: pytz==2017.3 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 9)) + Requirement already satisfied: requests==2.18.4 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 10)) + Collecting scipy==1.0.0 (from -r requirements.txt (line 11)) + Downloading https://files.pythonhosted.org/packages/d8/5e/caa01ba7be11600b6a9d39265440d7b3be3d69206da887c42bef049521f2/scipy-1.0.0-cp36-cp36m-manylinux1_x86_64.whl (50.0MB) +  100% |████████████████████████████████| 50.0MB 12kB/s eta 0:00:01 18% |█████▉ | 9.1MB 24.7MB/s eta 0:00:02 20% |██████▍ | 10.0MB 20.8MB/s eta 0:00:02 22% |███████ | 11.1MB 20.6MB/s eta 0:00:02 31% |██████████ | 15.6MB 21.4MB/s eta 0:00:02 33% |██████████▋ | 16.6MB 21.7MB/s eta 0:00:02 37% |████████████ | 18.8MB 20.9MB/s eta 0:00:02 44% |██████████████▏ | 22.1MB 20.9MB/s eta 0:00:02 48% |███████████████▌ | 24.2MB 22.2MB/s eta 0:00:02 52% |████████████████▉ | 26.2MB 20.2MB/s eta 0:00:02 54% |█████████████████▌ | 27.3MB 21.1MB/s eta 0:00:02 58% |██████████████████▉ | 29.4MB 21.7MB/s eta 0:00:01 60% |███████████████████▌ | 30.5MB 21.2MB/s eta 0:00:01 62% |████████████████████ | 31.4MB 21.0MB/s eta 0:00:01 64% |████████████████████▊ | 32.4MB 20.5MB/s eta 0:00:01 69% |██████████████████████ | 34.5MB 21.2MB/s eta 0:00:01 73% |███████████████████████▌ | 36.7MB 22.5MB/s eta 0:00:01 75% |████████████████████████ | 37.6MB 20.2MB/s eta 0:00:01 77% |████████████████████████▊ | 38.7MB 20.9MB/s eta 0:00:01 81% |██████████████████████████ | 40.7MB 22.1MB/s eta 0:00:01 83% |██████████████████████████▊ | 41.8MB 20.6MB/s eta 0:00:01 85% |███████████████████████████▍ | 42.7MB 21.5MB/s eta 0:00:01 91% |█████████████████████████████▎ | 45.7MB 20.3MB/s eta 0:00:01 95% |██████████████████████████████▌ | 47.7MB 19.1MB/s eta 0:00:01 99% |███████████████████████████████▉| 49.8MB 21.7MB/s eta 0:00:01 + [?25hRequirement already satisfied: scikit-learn==0.19.1 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 12)) + Requirement already satisfied: six==1.11.0 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 13)) + Collecting tqdm==4.19.5 (from -r requirements.txt (line 14)) + Downloading https://files.pythonhosted.org/packages/71/3c/341b4fa23cb3abc335207dba057c790f3bb329f6757e1fcd5d347bcf8308/tqdm-4.19.5-py2.py3-none-any.whl (51kB) +  100% |████████████████████████████████| 61kB 4.0MB/s eta 0:00:01 + [?25hCollecting osqp (from cvxpy==1.0.3->-r requirements.txt (line 2)) + Downloading https://files.pythonhosted.org/packages/05/42/0ccab82eb6ed0edb83d184928ec864232dc00c3cf968a4b92a02caf0f7ec/osqp-0.4.0-cp36-cp36m-manylinux1_x86_64.whl (146kB) +  100% |████████████████████████████████| 153kB 3.8MB/s eta 0:00:01 + [?25hCollecting ecos>=2 (from cvxpy==1.0.3->-r requirements.txt (line 2)) + Downloading https://files.pythonhosted.org/packages/b6/b4/988b15513b13e8ea2eac65e97d84221ac515a735a93f046e2a2a3d7863fc/ecos-2.0.5.tar.gz (114kB) +  100% |████████████████████████████████| 122kB 4.5MB/s eta 0:00:01 + [?25hCollecting scs>=1.1.3 (from cvxpy==1.0.3->-r requirements.txt (line 2)) + Downloading https://files.pythonhosted.org/packages/b3/fd/6e01c4f4a69fcc6c3db130ba55572089e78e77ea8c0921a679f9da1ec04c/scs-2.0.2.tar.gz (133kB) +  100% |████████████████████████████████| 143kB 3.9MB/s eta 0:00:01 + [?25hCollecting multiprocess (from cvxpy==1.0.3->-r requirements.txt (line 2)) + Downloading https://files.pythonhosted.org/packages/7a/ee/b9bf3e171f936743758ef924622d8dd00516c5532b00a1210a09bce68325/multiprocess-0.70.6.1.tar.gz (1.4MB) +  100% |████████████████████████████████| 1.4MB 465kB/s eta 0:00:01 + [?25hRequirement already satisfied: fastcache in /opt/conda/lib/python3.6/site-packages (from cvxpy==1.0.3->-r requirements.txt (line 2)) + Requirement already satisfied: toolz in /opt/conda/lib/python3.6/site-packages (from cvxpy==1.0.3->-r requirements.txt (line 2)) + Requirement already satisfied: decorator>=4.0.6 in /opt/conda/lib/python3.6/site-packages (from plotly==2.2.3->-r requirements.txt (line 6)) + Requirement already satisfied: nbformat>=4.2 in /opt/conda/lib/python3.6/site-packages (from plotly==2.2.3->-r requirements.txt (line 6)) + Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /opt/conda/lib/python3.6/site-packages (from requests==2.18.4->-r requirements.txt (line 10)) + Requirement already satisfied: idna<2.7,>=2.5 in /opt/conda/lib/python3.6/site-packages (from requests==2.18.4->-r requirements.txt (line 10)) + Requirement already satisfied: urllib3<1.23,>=1.21.1 in /opt/conda/lib/python3.6/site-packages (from requests==2.18.4->-r requirements.txt (line 10)) + Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/lib/python3.6/site-packages (from requests==2.18.4->-r requirements.txt (line 10)) + Requirement already satisfied: future in /opt/conda/lib/python3.6/site-packages (from osqp->cvxpy==1.0.3->-r requirements.txt (line 2)) + Collecting dill>=0.2.8.1 (from multiprocess->cvxpy==1.0.3->-r requirements.txt (line 2)) + Downloading https://files.pythonhosted.org/packages/6f/78/8b96476f4ae426db71c6e86a8e6a81407f015b34547e442291cd397b18f3/dill-0.2.8.2.tar.gz (150kB) +  100% |████████████████████████████████| 153kB 3.7MB/s eta 0:00:01 + [?25hRequirement already satisfied: jsonschema!=2.5.0,>=2.4 in /opt/conda/lib/python3.6/site-packages (from nbformat>=4.2->plotly==2.2.3->-r requirements.txt (line 6)) + Requirement already satisfied: jupyter-core in /opt/conda/lib/python3.6/site-packages (from nbformat>=4.2->plotly==2.2.3->-r requirements.txt (line 6)) + Requirement already satisfied: traitlets>=4.1 in /opt/conda/lib/python3.6/site-packages (from nbformat>=4.2->plotly==2.2.3->-r requirements.txt (line 6)) + Requirement already satisfied: ipython-genutils in /opt/conda/lib/python3.6/site-packages (from nbformat>=4.2->plotly==2.2.3->-r requirements.txt (line 6)) + Building wheels for collected packages: cvxpy, plotly, ecos, scs, multiprocess, dill + Running setup.py bdist_wheel for cvxpy ... [?25ldone + [?25h Stored in directory: /root/.cache/pip/wheels/2b/60/0b/0c2596528665e21d698d6f84a3406c52044c7b4ca6ac737cf3 + Running setup.py bdist_wheel for plotly ... [?25ldone + [?25h Stored in directory: /root/.cache/pip/wheels/98/54/81/dd92d5b0858fac680cd7bdb8800eb26c001dd9f5dc8b1bc0ba + Running setup.py bdist_wheel for ecos ... [?25ldone + [?25h Stored in directory: /root/.cache/pip/wheels/50/91/1b/568de3c087b3399b03d130e71b1fd048ec072c45f72b6b6e9a + Running setup.py bdist_wheel for scs ... [?25ldone + [?25h Stored in directory: /root/.cache/pip/wheels/ff/f0/aa/530ccd478d7d9900b4e9ef5bc5a39e895ce110bed3d3ac653e + Running setup.py bdist_wheel for multiprocess ... [?25ldone + [?25h Stored in directory: /root/.cache/pip/wheels/8b/36/e5/96614ab62baf927e9bc06889ea794a8e87552b84bb6bf65e3e + Running setup.py bdist_wheel for dill ... [?25ldone + [?25h Stored in directory: /root/.cache/pip/wheels/e2/5d/17/f87cb7751896ac629b435a8696f83ee75b11029f5d6f6bda72 + Successfully built cvxpy plotly ecos scs multiprocess dill + Installing collected packages: numpy, scipy, osqp, ecos, scs, dill, multiprocess, cvxpy, pandas, plotly, tqdm + Found existing installation: numpy 1.12.1 + Uninstalling numpy-1.12.1: + Successfully uninstalled numpy-1.12.1 + Found existing installation: scipy 0.19.1 + Uninstalling scipy-0.19.1: + Successfully uninstalled scipy-0.19.1 + Found existing installation: dill 0.2.7.1 + Uninstalling dill-0.2.7.1: + Successfully uninstalled dill-0.2.7.1 + Found existing installation: pandas 0.20.3 + Uninstalling pandas-0.20.3: + Successfully uninstalled pandas-0.20.3 + Found existing installation: plotly 2.0.15 + Uninstalling plotly-2.0.15: + Successfully uninstalled plotly-2.0.15 + Found existing installation: tqdm 4.11.2 + Uninstalling tqdm-4.11.2: + Successfully uninstalled tqdm-4.11.2 + Successfully installed cvxpy-1.0.3 dill-0.2.8.2 ecos-2.0.5 multiprocess-0.70.6.1 numpy-1.13.3 osqp-0.4.0 pandas-0.21.1 plotly-2.2.3 scipy-1.0.0 scs-2.0.2 tqdm-4.19.5 + You are using pip version 9.0.1, however version 18.0 is available. + You should consider upgrading via the 'pip install --upgrade pip' command. + + +### Load Packages + + +```python +import pandas as pd +import numpy as np +import helper +import project_helper +import project_tests +``` + + + + + +## Market Data +### Load Data +The data we use for most of the projects is end of day data. This contains data for many stocks, but we'll be looking at stocks in the S&P 500. We also made things a little easier to run by narrowing down our range of time period instead of using all of the data. + + +```python +df = pd.read_csv('../../data/project_1/eod-quotemedia.csv', parse_dates=['date'], index_col=False) + +close = df.reset_index().pivot(index='date', columns='ticker', values='adj_close') + +print('Loaded Data') +``` + + Loaded Data + + +### View Data +Run the cell below to see what the data looks like for `close`. + + +```python +project_helper.print_dataframe(close) +``` + + +
+ + +### Stock Example +Let's see what a single stock looks like from the closing prices. For this example and future display examples in this project, we'll use Apple's stock (AAPL). If we tried to graph all the stocks, it would be too much information. + + +```python +apple_ticker = 'AAPL' +project_helper.plot_stock(close[apple_ticker], '{} Stock'.format(apple_ticker)) +``` + + +
+ + +## Resample Adjusted Prices + +The trading signal you'll develop in this project does not need to be based on daily prices, for instance, you can use month-end prices to perform trading once a month. To do this, you must first resample the daily adjusted closing prices into monthly buckets, and select the last observation of each month. + +Implement the `resample_prices` to resample `close_prices` at the sampling frequency of `freq`. + + +```python +def resample_prices(close_prices, freq='M'): + """ + Resample close prices for each ticker at specified frequency. + + Parameters + ---------- + close_prices : DataFrame + Close prices for each ticker and date + freq : str + What frequency to sample at + For valid freq choices, see http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases + + Returns + ------- + prices_resampled : DataFrame + Resampled prices for each ticker and date + """ + # TODO: Implement Function + close = pd.DataFrame(close_prices.resample(freq).last()) + return close + +project_tests.test_resample_prices(resample_prices) +``` + + Tests Passed + + +### View Data +Let's apply this function to `close` and view the results. + + +```python +monthly_close = resample_prices(close) +project_helper.plot_resampled_prices( + monthly_close.loc[:, apple_ticker], + close.loc[:, apple_ticker], + '{} Stock - Close Vs Monthly Close'.format(apple_ticker)) +``` + + +
+ + +## Compute Log Returns + +Compute log returns ($R_t$) from prices ($P_t$) as your primary momentum indicator: + +$$R_t = log_e(P_t) - log_e(P_{t-1})$$ + +Implement the `compute_log_returns` function below, such that it accepts a dataframe (like one returned by `resample_prices`), and produces a similar dataframe of log returns. Use Numpy's [log function](https://docs.scipy.org/doc/numpy/reference/generated/numpy.log.html) to help you calculate the log returns. + + +```python +def compute_log_returns(prices): + """ + Compute log returns for each ticker. + + Parameters + ---------- + prices : DataFrame + Prices for each ticker and date + + Returns + ------- + log_returns : DataFrame + Log returns for each ticker and date + """ + # TODO: Implement Function + returns = np.log(prices) - np.log(prices.shift(1)) + return returns + +project_tests.test_compute_log_returns(compute_log_returns) +``` + + Tests Passed + + +### View Data +Using the same data returned from `resample_prices`, we'll generate the log returns. + + +```python +monthly_close_returns = compute_log_returns(monthly_close) +project_helper.plot_returns( + monthly_close_returns.loc[:, apple_ticker], + 'Log Returns of {} Stock (Monthly)'.format(apple_ticker)) +``` + + +
+ + +## Shift Returns +Implement the `shift_returns` function to shift the log returns to the previous or future returns in the time series. For example, the parameter `shift_n` is 2 and `returns` is the following: + +``` + Returns + A B C D +2013-07-08 0.015 0.082 0.096 0.020 ... +2013-07-09 0.037 0.095 0.027 0.063 ... +2013-07-10 0.094 0.001 0.093 0.019 ... +2013-07-11 0.092 0.057 0.069 0.087 ... +... ... ... ... ... +``` + +the output of the `shift_returns` function would be: +``` + Shift Returns + A B C D +2013-07-08 NaN NaN NaN NaN ... +2013-07-09 NaN NaN NaN NaN ... +2013-07-10 0.015 0.082 0.096 0.020 ... +2013-07-11 0.037 0.095 0.027 0.063 ... +... ... ... ... ... +``` +Using the same `returns` data as above, the `shift_returns` function should generate the following with `shift_n` as -2: +``` + Shift Returns + A B C D +2013-07-08 0.094 0.001 0.093 0.019 ... +2013-07-09 0.092 0.057 0.069 0.087 ... +... ... ... ... ... ... +... ... ... ... ... ... +... NaN NaN NaN NaN ... +... NaN NaN NaN NaN ... +``` +_Note: The "..." represents data points we're not showing._ + + +```python +def shift_returns(returns, shift_n): + """ + Generate shifted returns + + Parameters + ---------- + returns : DataFrame + Returns for each ticker and date + shift_n : int + Number of periods to move, can be positive or negative + + Returns + ------- + shifted_returns : DataFrame + Shifted returns for each ticker and date + """ + # TODO: Implement Function + + return returns.shift(shift_n) + +project_tests.test_shift_returns(shift_returns) +``` + + Tests Passed + + +### View Data +Let's get the previous month's and next month's returns. + + +```python +prev_returns = shift_returns(monthly_close_returns, 1) +lookahead_returns = shift_returns(monthly_close_returns, -1) + +project_helper.plot_shifted_returns( + prev_returns.loc[:, apple_ticker], + monthly_close_returns.loc[:, apple_ticker], + 'Previous Returns of {} Stock'.format(apple_ticker)) +project_helper.plot_shifted_returns( + lookahead_returns.loc[:, apple_ticker], + monthly_close_returns.loc[:, apple_ticker], + 'Lookahead Returns of {} Stock'.format(apple_ticker)) +``` + + +
+ + + +
+ + +## Generate Trading Signal + +A trading signal is a sequence of trading actions, or results that can be used to take trading actions. A common form is to produce a "long" and "short" portfolio of stocks on each date (e.g. end of each month, or whatever frequency you desire to trade at). This signal can be interpreted as rebalancing your portfolio on each of those dates, entering long ("buy") and short ("sell") positions as indicated. + +Here's a strategy that we will try: +> For each month-end observation period, rank the stocks by _previous_ returns, from the highest to the lowest. Select the top performing stocks for the long portfolio, and the bottom performing stocks for the short portfolio. + +Implement the `get_top_n` function to get the top performing stock for each month. Get the top performing stocks from `prev_returns` by assigning them a value of 1. For all other stocks, give them a value of 0. For example, using the following `prev_returns`: + +``` + Previous Returns + A B C D E F G +2013-07-08 0.015 0.082 0.096 0.020 0.075 0.043 0.074 +2013-07-09 0.037 0.095 0.027 0.063 0.024 0.086 0.025 +... ... ... ... ... ... ... ... +``` + +The function `get_top_n` with `top_n` set to 3 should return the following: +``` + Previous Returns + A B C D E F G +2013-07-08 0 1 1 0 1 0 0 +2013-07-09 0 1 0 1 0 1 0 +... ... ... ... ... ... ... ... +``` +*Note: You may have to use Panda's [`DataFrame.iterrows`](https://pandas.pydata.org/pandas-docs/version/0.21/generated/pandas.DataFrame.iterrows.html) with [`Series.nlargest`](https://pandas.pydata.org/pandas-docs/version/0.21/generated/pandas.Series.nlargest.html) in order to implement the function. This is one of those cases where creating a vecorization solution is too difficult.* + + +```python +def get_top_n(prev_returns, top_n): + """ + Select the top performing stocks + + Parameters + ---------- + prev_returns : DataFrame + Previous shifted returns for each ticker and date + top_n : int + The number of top performing stocks to get + + Returns + ------- + top_stocks : DataFrame + Top stocks for each ticker and date marked with a 1 + """ + # TODO: Implement Function + #print(prev_returns.head()) + res = pd.DataFrame(columns=prev_returns.columns) + + for index, row in prev_returns.iterrows(): + curr_month = row + curr_top = pd.Series(curr_month).nlargest(top_n) + top = list(curr_top.index.values) + for col in res.columns: + if(col in top): + res.loc[index, col] = True + else: + res.loc[index, col] = False + + for index, row in res.iterrows(): + res.loc[index] = res.loc[index].astype('int64') + #print(res.head()) + return res + +project_tests.test_get_top_n(get_top_n) +``` + + Tests Passed + + +### View Data +We want to get the best performing and worst performing stocks. To get the best performing stocks, we'll use the `get_top_n` function. To get the worst performing stocks, we'll also use the `get_top_n` function. However, we pass in `-1*prev_returns` instead of just `prev_returns`. Multiplying by negative one will flip all the positive returns to negative and negative returns to positive. Thus, it will return the worst performing stocks. + + +```python +top_bottom_n = 50 +df_long = get_top_n(prev_returns, top_bottom_n) +df_short = get_top_n(-1*prev_returns, top_bottom_n) +project_helper.print_top(df_long, 'Longed Stocks') +project_helper.print_top(df_short, 'Shorted Stocks') +``` + + 10 Most Longed Stocks: + INCY, AMD, AVGO, NFX, SWKS, NFLX, ILMN, UAL, NVDA, MU + 10 Most Shorted Stocks: + RRC, FCX, CHK, MRO, GPS, WYNN, DVN, FTI, SPLS, TRIP + + +## Projected Returns +It's now time to check if your trading signal has the potential to become profitable! + +We'll start by computing the net returns this portfolio would return. For simplicity, we'll assume every stock gets an equal dollar amount of investment. This makes it easier to compute a portfolio's returns as the simple arithmetic average of the individual stock returns. + +Implement the `portfolio_returns` function to compute the expected portfolio returns. Using `df_long` to indicate which stocks to long and `df_short` to indicate which stocks to short, calculate the returns using `lookahead_returns`. To help with calculation, we've provided you with `n_stocks` as the number of stocks we're investing in a single period. + + +```python +def portfolio_returns(df_long, df_short, lookahead_returns, n_stocks): + """ + Compute expected returns for the portfolio, assuming equal investment in each long/short stock. + + Parameters + ---------- + df_long : DataFrame + Top stocks for each ticker and date marked with a 1 + df_short : DataFrame + Bottom stocks for each ticker and date marked with a 1 + lookahead_returns : DataFrame + Lookahead returns for each ticker and date + n_stocks: int + The number number of stocks chosen for each month + + Returns + ------- + portfolio_returns : DataFrame + Expected portfolio returns for each ticker and date + """ + # TODO: Implement Function + df_long2 = df_long*lookahead_returns + df_short2 = df_short*lookahead_returns + + + ret = (df_long2-df_short2) + ret_avg = ret/n_stocks + + return ret_avg + +project_tests.test_portfolio_returns(portfolio_returns) +``` + + Tests Passed + + +### View Data +Time to see how the portfolio did. + + +```python +expected_portfolio_returns = portfolio_returns(df_long, df_short, lookahead_returns, 2*top_bottom_n) +project_helper.plot_returns(expected_portfolio_returns.T.sum(), 'Portfolio Returns') +``` + + +
+ + +## Statistical Tests +### Annualized Rate of Return + + +```python +expected_portfolio_returns_by_date = expected_portfolio_returns.T.sum().dropna() +portfolio_ret_mean = expected_portfolio_returns_by_date.mean() +portfolio_ret_ste = expected_portfolio_returns_by_date.sem() +portfolio_ret_annual_rate = (np.exp(portfolio_ret_mean * 12) - 1) * 100 + +print(""" +Mean: {:.6f} +Standard Error: {:.6f} +Annualized Rate of Return: {:.2f}% +""".format(portfolio_ret_mean, portfolio_ret_ste, portfolio_ret_annual_rate)) +``` + + + Mean: 0.003253 + Standard Error: 0.002203 + Annualized Rate of Return: 3.98% + + + +The annualized rate of return allows you to compare the rate of return from this strategy to other quoted rates of return, which are usually quoted on an annual basis. + +### T-Test +Our null hypothesis ($H_0$) is that the actual mean return from the signal is zero. We'll perform a one-sample, one-sided t-test on the observed mean return, to see if we can reject $H_0$. + +We'll need to first compute the t-statistic, and then find its corresponding p-value. The p-value will indicate the probability of observing a mean return equally or more extreme than the one we observed if the null hypothesis were true. A small p-value means that the chance of observing the mean we observed under the null hypothesis is small, and thus casts doubt on the null hypothesis. It's good practice to set a desired level of significance or alpha ($\alpha$) _before_ computing the p-value, and then reject the null hypothesis if $p < \alpha$. + +For this project, we'll use $\alpha = 0.05$, since it's a common value to use. + +Implement the `analyze_alpha` function to perform a t-test on the sample of portfolio returns. We've imported the `scipy.stats` module for you to perform the t-test. + +Note: [`scipy.stats.ttest_1samp`](https://docs.scipy.org/doc/scipy-1.0.0/reference/generated/scipy.stats.ttest_1samp.html) performs a two-sided test, so divide the p-value by 2 to get 1-sided p-value + + +```python +from scipy import stats + +def analyze_alpha(expected_portfolio_returns_by_date): + """ + Perform a t-test with the null hypothesis being that the expected mean return is zero. + + Parameters + ---------- + expected_portfolio_returns_by_date : Pandas Series + Expected portfolio returns for each date + + Returns + ------- + t_value + T-statistic from t-test + p_value + Corresponding p-value + """ + # TODO: Implement Function + expected_null_hypothesis = 0.0 + x = expected_portfolio_returns_by_date + m, v, s, k = stats.t.stats(10, moments='mvsk') + t, p = stats.ttest_1samp(x, m) + + return (t, p/2) + +project_tests.test_analyze_alpha(analyze_alpha) +``` + + Tests Passed + + +### View Data +Let's see what values we get with our portfolio. After you run this, make sure to answer the question below. + + +```python +t_value, p_value = analyze_alpha(expected_portfolio_returns_by_date) +print(""" +Alpha analysis: + t-value: {:.3f} + p-value: {:.6f} +""".format(t_value, p_value)) +``` + + + Alpha analysis: + t-value: 1.476 + p-value: 0.073359 + + + +### Question: What p-value did you observe? And what does that indicate about your signal? + +After performing the t-test, we observe that the t-value is 1.467 and **p_value is 0.073359**. Looking at the p_value (which is above the alpha threshold of 0.05), it indicates that we cannot reject the NULL hypothesis. That means the actual mean return from the signal might be zero. + +## Submission +Now that you're done with the project, it's time to submit it. Click the submit button in the bottom right. One of our reviewers will give you feedback on your project with a pass or not passed grade. You can continue to the next section while you wait for feedback.