{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\ritvik\\Anaconda3\\lib\\site-packages\\pandas_datareader\\compat\\__init__.py:7: FutureWarning: pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead.\n",
      "  from pandas.util.testing import assert_frame_equal\n"
     ]
    }
   ],
   "source": [
    "import pandas_datareader.data as web\n",
    "from pandas_datareader.nasdaq_trader import get_nasdaq_symbols\n",
    "from pandas_datareader._utils import RemoteDataError\n",
    "from datetime import datetime, timedelta\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import pickle"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_stock_trend_and_returns(ticker, titles, start_date, end_date, all_returns):\n",
    "    \n",
    "    #get the data for this ticker\n",
    "    prices = web.DataReader(ticker, 'yahoo', start=start_date, end=end_date).Close\n",
    "    prices.index = [d.date() for d in prices.index]\n",
    "    \n",
    "    plt.figure(figsize=(10,6))\n",
    "    \n",
    "    #plot stock price\n",
    "    plt.subplot(2,1,1)\n",
    "    plt.plot(prices)\n",
    "    plt.title(titles[0], fontsize=16)\n",
    "    plt.ylabel('Price ($)', fontsize=14)\n",
    "    \n",
    "    #plot stock returns\n",
    "    plt.subplot(2,1,2)\n",
    "    plt.plot(all_returns[0], all_returns[1], color='g')\n",
    "    plt.title(titles[1], fontsize=16)\n",
    "    plt.ylabel('Pct. Return', fontsize=14)\n",
    "    plt.axhline(0, color='k', linestyle='--')\n",
    "    \n",
    "    plt.tight_layout()\n",
    "    \n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def perform_analysis_for_stock(ticker, start_date, end_date, return_period_weeks, verbose=False):\n",
    "    \"\"\"\n",
    "    Inputs:\n",
    "        ticker: the ticker symbol to analyze\n",
    "        start_date: the first date considered in simulation\n",
    "        end_date: the last date considered in simulation\n",
    "        return_period_weeks: the number of weeks in which to calculate returns\n",
    "        verbose: True if you want to print simulation steps\n",
    "        \n",
    "    Outputs:\n",
    "        average and standard deviation of returns for simulated runs of this ticker within the given date range\n",
    "    \"\"\"\n",
    "    \n",
    "    #get the data for this ticker\n",
    "    try:\n",
    "        prices = web.DataReader(ticker, 'yahoo', start=start_date, end=end_date).Close\n",
    "    #could not find data on this ticker\n",
    "    except (RemoteDataError, KeyError):\n",
    "        #return default values\n",
    "        return -np.inf, np.inf, None\n",
    "    \n",
    "    prices.index = [d.date() for d in prices.index]\n",
    "    \n",
    "    #this will store all simulated returns\n",
    "    pct_return_after_period = []\n",
    "    buy_dates = []\n",
    "\n",
    "    #assume we buy the stock on each day in the range\n",
    "    for buy_date, buy_price in prices.iteritems():\n",
    "        #get price of the stock after given number of weeks\n",
    "        sell_date = buy_date + timedelta(weeks=return_period_weeks)\n",
    "        \n",
    "        try:\n",
    "            sell_price = prices[prices.index == sell_date].iloc[0]\n",
    "        #trying to sell on a non-trading day, skip\n",
    "        except IndexError:\n",
    "            continue\n",
    "        \n",
    "        #compute the percent return\n",
    "        pct_return = (sell_price - buy_price)/buy_price\n",
    "        pct_return_after_period.append(pct_return)\n",
    "        buy_dates.append(buy_date)\n",
    "        \n",
    "        if verbose:\n",
    "            print('Date Buy: %s, Price Buy: %s'%(buy_date,round(buy_price,2)))\n",
    "            print('Date Sell: %s, Price Sell: %s'%(sell_date,round(sell_price,2)))\n",
    "            print('Return: %s%%'%round(pct_return*100,1))\n",
    "            print('-------------------')\n",
    "    \n",
    "    #if no data collected return default values\n",
    "    if len(pct_return_after_period) == 0:\n",
    "        return -np.inf, np.inf, None\n",
    "    \n",
    "    #report average and deviation of the percent returns\n",
    "    return np.mean(pct_return_after_period), np.std(pct_return_after_period), [buy_dates, pct_return_after_period]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# User Input Area"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "#start date for simulation. \n",
    "#Further back means more training data but risk of including patterns that no longer exist\n",
    "#More recent means less training data but only using recent patterns\n",
    "start_date, end_date = datetime(2020,4,1), datetime.now().date()\n",
    "\n",
    "#set number of weeks in which you want to see return\n",
    "return_period_weeks = 4\n",
    "\n",
    "#I want at least this much average return\n",
    "min_avg_return  = 0.1\n",
    "\n",
    "#I want at most this much volatility in return\n",
    "max_dev_return = 0.07"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Download file \"series_tickers.p\" from github or create your own list of tickers\n",
    "series_tickers = pickle.load(open(\"series_tickers.p\", \"rb\" ))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 57260 characters]\n",
      "text/plain": [
       "<Figure size 720x432 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 61292 characters]\n",
      "text/plain": [
       "<Figure size 720x432 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 52848 characters]\n",
      "text/plain": [
       "<Figure size 720x432 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "for ticker, name in series_tickers.iteritems():\n",
    "    avg_return, dev_return, all_returns = perform_analysis_for_stock(ticker, start_date, end_date, return_period_weeks)\n",
    "\n",
    "    if avg_return > min_avg_return and dev_return < max_dev_return:\n",
    "        title_price = '%s\\n%s'%(ticker, name)\n",
    "        title_return = 'Avg Return: %s%% | Dev Return: %s%%'%(round(100*avg_return,2), round(100*dev_return,2))\n",
    "        plot_stock_trend_and_returns(ticker, [title_price, title_return], start_date, end_date, all_returns)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "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.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
