├── 01_SimpleFetchStockData.ipynb ├── 02_SimpleStockDate.ipynb ├── 03_SimpleStockCharts.ipynb ├── 04_SimpleTechnicalAnalysisLibrary.ipynb ├── 05_SimpleStockCSV.ipynb ├── 06_SimpleStockStyleTable.ipynb ├── 07_SimpleYahooStockScrape.ipynb ├── 08_SimpleFinanceNewsScrape.ipynb ├── 09_SimpleScrapeWikiSP500.ipynb ├── 10_SimpleStockMultiIndex.ipynb ├── 11_SimpleFundamentalAnalysis.ipynb ├── 12_SimpleStockStatistics.ipynb ├── 13_SimpleStockChartScripts.py ├── 14_SimpleStockClasses.ipynb ├── 15_SimpleStockAnalysis_Final.ipynb ├── 16_SimpleStockIndicators.ipynb ├── 17_SimplePivotPoint.ipynb ├── 18_SimpleStockVWAP.ipynb ├── 19_SimpleStockTrendlines.ipynb ├── 20_SimpleStockSignals.ipynb ├── 21_SimpleStockSignalsRSI.ipynb ├── 22_SimpleStockBacktesting.ipynb ├── 23_SimpleTimeseries.ipynb ├── 24_Simple_Kelly_Criterion.ipynb ├── 25_SimpleStockPredictionMachineLearning.ipynb ├── 26_SimpleStockPredictionTensorFlow.ipynb ├── LICENSE ├── Python_01_Dowload__YahooData.py ├── Python_02_Modify_Date.py ├── Python_03_save_csv.py ├── Python_04_Plot_Charts.py ├── Python_05_Plot_Area.py ├── Python_06_Plot_Scatter_Line.py ├── Python_07_Plot_Histogram.py ├── Python_08_Plot_Boxplot.py ├── Python_09_Plot_Candlestick.py ├── Python_10_Plot_Bokeh_Candlestick.py ├── Python_11_scrape_yahoo_Key_Statistics.py ├── Python_12_scrape_finance_news.py ├── README.md ├── Title.PNG ├── candlestick.html └── stock_chart.png /01_SimpleFetchStockData.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "source": [ 6 | "# Simple Download Stock Data Site" 7 | ], 8 | "metadata": {} 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "source": [ 13 | "There are many sites you can download or fetch stock historical data or fundamental data such as yahoo, google, alpha vantage, quandl and other sites. Some are free and some you have to paid. Some you will need to sign up and some you do not need to sign up." 14 | ], 15 | "metadata": {} 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "source": [ 20 | "## 1. fix yahoo is the most common\n", 21 | "https://pypi.org/project/fix-yahoo-finance/" 22 | ], 23 | "metadata": {} 24 | }, 25 | { 26 | "cell_type": "code", 27 | "source": [ 28 | "# Libraries\n", 29 | "import pandas as pd\n", 30 | "import numpy as np\n", 31 | "\n", 32 | "import warnings\n", 33 | "warnings.filterwarnings(\"ignore\")" 34 | ], 35 | "outputs": [], 36 | "execution_count": null, 37 | "metadata": { 38 | "collapsed": false, 39 | "outputHidden": false, 40 | "inputHidden": false 41 | } 42 | }, 43 | { 44 | "cell_type": "code", 45 | "source": [ 46 | "# fix_yahoo_finance is used to fetch data \n", 47 | "import fix_yahoo_finance as yf\n", 48 | "yf.pdr_override()" 49 | ], 50 | "outputs": [], 51 | "execution_count": null, 52 | "metadata": { 53 | "collapsed": false, 54 | "outputHidden": false, 55 | "inputHidden": false 56 | } 57 | }, 58 | { 59 | "cell_type": "code", 60 | "source": [ 61 | "# input\n", 62 | "symbol = 'AAPL'\n", 63 | "start = '2014-01-01'\n", 64 | "end = '2018-01-01'" 65 | ], 66 | "outputs": [], 67 | "execution_count": null, 68 | "metadata": { 69 | "collapsed": false, 70 | "outputHidden": false, 71 | "inputHidden": false 72 | } 73 | }, 74 | { 75 | "cell_type": "code", 76 | "source": [ 77 | "# Read data \n", 78 | "df = yf.download(symbol,start,end)\n", 79 | "\n", 80 | "# Only keep close columns \n", 81 | "df.head()" 82 | ], 83 | "outputs": [], 84 | "execution_count": null, 85 | "metadata": { 86 | "collapsed": false, 87 | "outputHidden": false, 88 | "inputHidden": false 89 | } 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "source": [ 94 | "## 2. pandas_datareader\n", 95 | "This library work sometimes. I recommend not to use to this one.\n", 96 | "\nhttps://pandas-datareader.readthedocs.io/en/latest/" 97 | ], 98 | "metadata": {} 99 | }, 100 | { 101 | "cell_type": "code", 102 | "source": [ 103 | "from pandas_datareader import data as pdr" 104 | ], 105 | "outputs": [], 106 | "execution_count": null, 107 | "metadata": {} 108 | }, 109 | { 110 | "cell_type": "code", 111 | "source": [ 112 | "symbol = 'AAPL'\n", 113 | "start = '2014-01-01'\n", 114 | "end = '2018-01-01'\n", 115 | "data = pdr.get_data_yahoo(symbol, start, end)" 116 | ], 117 | "outputs": [], 118 | "execution_count": null, 119 | "metadata": { 120 | "collapsed": false, 121 | "outputHidden": false, 122 | "inputHidden": false 123 | } 124 | }, 125 | { 126 | "cell_type": "code", 127 | "source": [ 128 | "data.head()" 129 | ], 130 | "outputs": [], 131 | "execution_count": null, 132 | "metadata": { 133 | "collapsed": false, 134 | "outputHidden": false, 135 | "inputHidden": false 136 | } 137 | }, 138 | { 139 | "cell_type": "markdown", 140 | "source": [ 141 | "## 3. alpha_vantage\n", 142 | "https://alpha-vantage.readthedocs.io/en/latest/\n", 143 | "\n", 144 | "For this one, you will need to sign up and is free. You will get a free api key.\n", 145 | "\nhttps://www.alphavantage.co/support/#api-key" 146 | ], 147 | "metadata": {} 148 | }, 149 | { 150 | "cell_type": "code", 151 | "source": [ 152 | "from alpha_vantage.timeseries import TimeSeries" 153 | ], 154 | "outputs": [], 155 | "execution_count": null, 156 | "metadata": {} 157 | }, 158 | { 159 | "cell_type": "code", 160 | "source": [ 161 | "ts = TimeSeries(key='...') # Input your API KEY in ...\n", 162 | "# Get json object with the intraday data and another with the call's metadata\n", 163 | "data, meta_data = ts.get_intraday('AAPL')\n", 164 | "data.head()" 165 | ], 166 | "outputs": [], 167 | "execution_count": null, 168 | "metadata": { 169 | "collapsed": false, 170 | "outputHidden": false, 171 | "inputHidden": false 172 | } 173 | }, 174 | { 175 | "cell_type": "markdown", 176 | "source": [ 177 | "## 4. iexfinance" 178 | ], 179 | "metadata": {} 180 | }, 181 | { 182 | "cell_type": "code", 183 | "source": [ 184 | "from iexfinance import Stock" 185 | ], 186 | "outputs": [], 187 | "execution_count": null, 188 | "metadata": { 189 | "collapsed": false, 190 | "outputHidden": false, 191 | "inputHidden": false 192 | } 193 | }, 194 | { 195 | "cell_type": "code", 196 | "source": [ 197 | "tsla = Stock(symbol)\n", 198 | "tsla.get_open()\n", 199 | "tsla.get_price()" 200 | ], 201 | "outputs": [], 202 | "execution_count": null, 203 | "metadata": { 204 | "collapsed": false, 205 | "outputHidden": false, 206 | "inputHidden": false 207 | } 208 | }, 209 | { 210 | "cell_type": "code", 211 | "source": [ 212 | "from datetime import datetime\n", 213 | "\n", 214 | "start = datetime(2014, 1, 1)\n", 215 | "end = datetime(2018, 1, 1)\n", 216 | "\n", 217 | "df = get_historical_data(\"AAPL\", start=start, end=end, output_format='pandas')\n", 218 | "df.head()" 219 | ], 220 | "outputs": [], 221 | "execution_count": null, 222 | "metadata": { 223 | "collapsed": false, 224 | "outputHidden": false, 225 | "inputHidden": false 226 | } 227 | }, 228 | { 229 | "cell_type": "markdown", 230 | "source": [ 231 | "## 5. quandl \n", 232 | "\nFor this one you need to sign up and is very limited." 233 | ], 234 | "metadata": {} 235 | }, 236 | { 237 | "cell_type": "code", 238 | "source": [ 239 | "# import needed libraries\n", 240 | "import quandl" 241 | ], 242 | "outputs": [], 243 | "execution_count": null, 244 | "metadata": {} 245 | }, 246 | { 247 | "cell_type": "code", 248 | "source": [ 249 | "token = \"...\" # Input your token ...\n", 250 | "data = quandl.get(\"WIKI/AAPL\", start_date=\"2014-01-01\", end_date=\"2018-01-01\", api_key=token)" 251 | ], 252 | "outputs": [], 253 | "execution_count": null, 254 | "metadata": { 255 | "collapsed": false, 256 | "outputHidden": false, 257 | "inputHidden": false 258 | } 259 | }, 260 | { 261 | "cell_type": "markdown", 262 | "source": [ 263 | "## 5. Yahoo, Google, or other sites (download csv)\n", 264 | "This one has historical data and economic data.\n", 265 | "\n", 266 | "For example: https://finance.yahoo.com/quote/AAPL/history?p=AAPL\n", 267 | "\nYou should see: Download Data and click that icon. " 268 | ], 269 | "metadata": {} 270 | }, 271 | { 272 | "cell_type": "code", 273 | "source": [ 274 | "aapl.to_csv('aapl.csv') # Make sure you have the right directory path\n", 275 | "df = pd.read_csv('aapl.csv', header=0, index_col='Date', parse_dates=True)" 276 | ], 277 | "outputs": [], 278 | "execution_count": null, 279 | "metadata": { 280 | "collapsed": false, 281 | "outputHidden": false, 282 | "inputHidden": false 283 | } 284 | }, 285 | { 286 | "cell_type": "markdown", 287 | "source": [ 288 | "## 6. yahoo-finance\n", 289 | "\nhttps://github.com/lukaszbanasiak/yahoo-finance" 290 | ], 291 | "metadata": {} 292 | }, 293 | { 294 | "cell_type": "code", 295 | "source": [ 296 | "from yahoo_finance import Share" 297 | ], 298 | "outputs": [], 299 | "execution_count": null, 300 | "metadata": { 301 | "collapsed": false, 302 | "outputHidden": false, 303 | "inputHidden": false 304 | } 305 | }, 306 | { 307 | "cell_type": "code", 308 | "source": [ 309 | "data = Share('AAPL')\n", 310 | "print(data.get_open())\n", 311 | "print(data.get_price())" 312 | ], 313 | "outputs": [], 314 | "execution_count": null, 315 | "metadata": { 316 | "collapsed": false, 317 | "outputHidden": false, 318 | "inputHidden": false 319 | } 320 | }, 321 | { 322 | "cell_type": "code", 323 | "source": [ 324 | "# Get Historical Data\n", 325 | "# This one does not show nice dataframe\n", 326 | "print(data.get_historical('2014-01-01', '2018-01-01'))" 327 | ], 328 | "outputs": [], 329 | "execution_count": null, 330 | "metadata": { 331 | "collapsed": false, 332 | "outputHidden": false, 333 | "inputHidden": false 334 | } 335 | }, 336 | { 337 | "cell_type": "markdown", 338 | "source": [ 339 | "## 7. Macrotrends\n", 340 | "\n", 341 | "Scrape Data\n", 342 | "\nhttps://www.macrotrends.net/" 343 | ], 344 | "metadata": {} 345 | }, 346 | { 347 | "cell_type": "code", 348 | "source": [ 349 | "symbol = 'AAPL'\n", 350 | "url = 'https://www.macrotrends.net/assets/php/stock_data_export.php?t=' + symbol\n", 351 | "stock_price = pd.read_csv(url, skiprows=10)" 352 | ], 353 | "outputs": [], 354 | "execution_count": 9, 355 | "metadata": { 356 | "collapsed": false, 357 | "outputHidden": false, 358 | "inputHidden": false 359 | } 360 | }, 361 | { 362 | "cell_type": "code", 363 | "source": [ 364 | "stock_price.head()" 365 | ], 366 | "outputs": [ 367 | { 368 | "output_type": "execute_result", 369 | "execution_count": 10, 370 | "data": { 371 | "text/html": [ 372 | "
\n", 373 | "\n", 386 | "\n", 387 | " \n", 388 | " \n", 389 | " \n", 390 | " \n", 391 | " \n", 392 | " \n", 393 | " \n", 394 | " \n", 395 | " \n", 396 | " \n", 397 | " \n", 398 | " \n", 399 | " \n", 400 | " \n", 401 | " \n", 402 | " \n", 403 | " \n", 404 | " \n", 405 | " \n", 406 | " \n", 407 | " \n", 408 | " \n", 409 | " \n", 410 | " \n", 411 | " \n", 412 | " \n", 413 | " \n", 414 | " \n", 415 | " \n", 416 | " \n", 417 | " \n", 418 | " \n", 419 | " \n", 420 | " \n", 421 | " \n", 422 | " \n", 423 | " \n", 424 | " \n", 425 | " \n", 426 | " \n", 427 | " \n", 428 | " \n", 429 | " \n", 430 | " \n", 431 | " \n", 432 | " \n", 433 | " \n", 434 | " \n", 435 | " \n", 436 | " \n", 437 | " \n", 438 | " \n", 439 | " \n", 440 | " \n", 441 | " \n", 442 | " \n", 443 | " \n", 444 | " \n", 445 | "
dateopenhighlowclosevolume
01980-12-120.41640.41820.41640.4164117258400
11980-12-150.39660.39660.39470.394743971200
21980-12-160.36750.36750.36570.365726432000
31980-12-170.37470.37660.37470.374721610400
41980-12-180.38570.38740.38570.385718362400
\n", 446 | "
" 447 | ], 448 | "text/plain": [ 449 | " date open high low close volume\n", 450 | "0 1980-12-12 0.4164 0.4182 0.4164 0.4164 117258400\n", 451 | "1 1980-12-15 0.3966 0.3966 0.3947 0.3947 43971200\n", 452 | "2 1980-12-16 0.3675 0.3675 0.3657 0.3657 26432000\n", 453 | "3 1980-12-17 0.3747 0.3766 0.3747 0.3747 21610400\n", 454 | "4 1980-12-18 0.3857 0.3874 0.3857 0.3857 18362400" 455 | ] 456 | }, 457 | "metadata": {} 458 | } 459 | ], 460 | "execution_count": 10, 461 | "metadata": { 462 | "collapsed": false, 463 | "outputHidden": false, 464 | "inputHidden": false 465 | } 466 | }, 467 | { 468 | "cell_type": "markdown", 469 | "source": [ 470 | "## 8. eoddata-client\n", 471 | "\n", 472 | "This one is not free. You will need to paid for the service.\n", 473 | "\n", 474 | "https://github.com/apologist/eoddata-client\n", 475 | "\nhttp://eoddata.com/" 476 | ], 477 | "metadata": {} 478 | }, 479 | { 480 | "cell_type": "code", 481 | "source": [ 482 | "import os\n", 483 | "\n", 484 | "from eoddata_client import EodDataHttpClient\n", 485 | "\n", 486 | "client = EodDataHttpClient(os.environ['EOD_DATA_LOGIN'],\n", 487 | " os.environ['EOD_DATA_PASSWORD'])\n", 488 | "\n", 489 | "quotes = client.symbol_history('nasdaq', 'aapl', datetime.date(2014, 1, 1))\n", 490 | "quotes['Diff'] = quotes['Close'].shift(1) - quotes['Close']\n", 491 | "print(quotes.tail())" 492 | ], 493 | "outputs": [], 494 | "execution_count": null, 495 | "metadata": { 496 | "collapsed": false, 497 | "outputHidden": false, 498 | "inputHidden": false 499 | } 500 | }, 501 | { 502 | "cell_type": "markdown", 503 | "source": [ 504 | "## 9. yahoo-historical\n", 505 | "\nhttps://pypi.org/project/yahoo-historical/" 506 | ], 507 | "metadata": {} 508 | }, 509 | { 510 | "cell_type": "code", 511 | "source": [ 512 | "from yahoo_historical import Fetcher\n", 513 | "data = Fetcher(\"AAPL\", [2014,1,1], [2018,1,1])\n", 514 | "print(data.getHistorical())" 515 | ], 516 | "outputs": [], 517 | "execution_count": null, 518 | "metadata": {} 519 | }, 520 | { 521 | "cell_type": "markdown", 522 | "source": [ 523 | "## 10. yahoofinancials\n", 524 | "\n", 525 | "This one is to get fundamental data.\n", 526 | "\nhttps://github.com/JECSand/yahoofinancials" 527 | ], 528 | "metadata": {} 529 | }, 530 | { 531 | "cell_type": "code", 532 | "source": [ 533 | "from yahoofinancials import YahooFinancials\n", 534 | "\n", 535 | "ticker = 'AAPL'\n", 536 | "yahoo_financials = YahooFinancials(ticker)" 537 | ], 538 | "outputs": [], 539 | "execution_count": null, 540 | "metadata": {} 541 | }, 542 | { 543 | "cell_type": "markdown", 544 | "source": [ 545 | "## 11. pandas-finance" 546 | ], 547 | "metadata": {} 548 | }, 549 | { 550 | "cell_type": "markdown", 551 | "source": [ 552 | "https://github.com/davidastephens/pandas-finance" 553 | ], 554 | "metadata": {} 555 | }, 556 | { 557 | "cell_type": "code", 558 | "source": [ 559 | "from pandas_finance import Equity\n", 560 | "aapl = Equity('AAPL')\n", 561 | "aapl.annual_dividend\n", 562 | "aapl.dividend_yield\n", 563 | "aapl.price\n", 564 | "aapl.options\n", 565 | "aapl.hist_vol(30)\n", 566 | "aapl.rolling_hist_vol(30)" 567 | ], 568 | "outputs": [], 569 | "execution_count": null, 570 | "metadata": { 571 | "collapsed": false, 572 | "outputHidden": false, 573 | "inputHidden": false 574 | } 575 | }, 576 | { 577 | "cell_type": "markdown", 578 | "source": [ 579 | "## 12. FinanceDataReader" 580 | ], 581 | "metadata": {} 582 | }, 583 | { 584 | "cell_type": "markdown", 585 | "source": [ 586 | "https://github.com/FinanceData/FinanceDataReader" 587 | ], 588 | "metadata": {} 589 | }, 590 | { 591 | "cell_type": "code", 592 | "source": [ 593 | "import FinanceDataReader as fdr\n", 594 | "\n", 595 | "# Apple(AAPL), 2017-01-01 ~ Now\n", 596 | "df = fdr.DataReader('AAPL', '2017')\n", 597 | "\n", 598 | "# AMAZON(AMZN), 2017\n", 599 | "df = fdr.DataReader('AMZN', '2017-01-01', '2017-12-31')" 600 | ], 601 | "outputs": [], 602 | "execution_count": null, 603 | "metadata": { 604 | "collapsed": false, 605 | "outputHidden": false, 606 | "inputHidden": false 607 | } 608 | }, 609 | { 610 | "cell_type": "markdown", 611 | "source": [ 612 | "# If there are more places you can download historical data, I will add more. Let me know. Email me please." 613 | ], 614 | "metadata": {} 615 | } 616 | ], 617 | "metadata": { 618 | "kernel_info": { 619 | "name": "python3" 620 | }, 621 | "language_info": { 622 | "pygments_lexer": "ipython3", 623 | "version": "3.5.5", 624 | "name": "python", 625 | "file_extension": ".py", 626 | "mimetype": "text/x-python", 627 | "codemirror_mode": { 628 | "name": "ipython", 629 | "version": 3 630 | }, 631 | "nbconvert_exporter": "python" 632 | }, 633 | "kernelspec": { 634 | "name": "python3", 635 | "language": "python", 636 | "display_name": "Python 3" 637 | }, 638 | "nteract": { 639 | "version": "0.12.2" 640 | } 641 | }, 642 | "nbformat": 4, 643 | "nbformat_minor": 4 644 | } 645 | -------------------------------------------------------------------------------- /03_SimpleStockCharts.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "source": [ 6 | "# Simple Stock Charts" 7 | ], 8 | "metadata": {} 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "source": [ 13 | "## Types of Stock Charts" 14 | ], 15 | "metadata": {} 16 | }, 17 | { 18 | "cell_type": "code", 19 | "source": [ 20 | "import numpy as np\n", 21 | "import matplotlib.pyplot as plt\n", 22 | "import pandas as pd\n", 23 | "\n", 24 | "import warnings\n", 25 | "warnings.filterwarnings(\"ignore\")\n", 26 | "\n", 27 | "# fix_yahoo_finance is used to fetch data \n", 28 | "import fix_yahoo_finance as yf\n", 29 | "yf.pdr_override()" 30 | ], 31 | "outputs": [], 32 | "execution_count": null, 33 | "metadata": { 34 | "collapsed": false, 35 | "outputHidden": false, 36 | "inputHidden": false 37 | } 38 | }, 39 | { 40 | "cell_type": "code", 41 | "source": [ 42 | "# input\n", 43 | "symbol = 'AAPL'\n", 44 | "start = '2018-12-01'\n", 45 | "end = '2019-01-01'\n", 46 | "\n", 47 | "# Read data \n", 48 | "df = yf.download(symbol,start,end)\n", 49 | "\n", 50 | "# View Columns\n", 51 | "df.head()" 52 | ], 53 | "outputs": [], 54 | "execution_count": null, 55 | "metadata": { 56 | "collapsed": false, 57 | "outputHidden": false, 58 | "inputHidden": false 59 | } 60 | }, 61 | { 62 | "cell_type": "markdown", 63 | "source": [ 64 | "## Line Charts" 65 | ], 66 | "metadata": {} 67 | }, 68 | { 69 | "cell_type": "code", 70 | "source": [ 71 | "plt.figure(figsize=(12,8))\n", 72 | "plt.plot(df['Adj Close'])\n", 73 | "plt.title(\"Stock Line Chart\")\n", 74 | "plt.legend(loc='best')\n", 75 | "plt.xlabel(\"Date\")\n", 76 | "plt.ylabel(\"Price\")\n", 77 | "plt.show()" 78 | ], 79 | "outputs": [], 80 | "execution_count": null, 81 | "metadata": {} 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "source": [ 86 | "## High Low Close Bar Stock Chart (HLC)" 87 | ], 88 | "metadata": {} 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "source": [ 93 | "https://stackoverflow.com/questions/44810875/how-to-draw-a-classic-stock-chart-with-matplotlib" 94 | ], 95 | "metadata": {} 96 | }, 97 | { 98 | "cell_type": "markdown", 99 | "source": [ 100 | "## Open High Low Close Bar Stock Chart (OHLC)" 101 | ], 102 | "metadata": {} 103 | }, 104 | { 105 | "cell_type": "code", 106 | "source": [ 107 | "import plotly.plotly as py\n", 108 | "import plotly.graph_objs as go\n", 109 | "from plotly.offline import init_notebook_mode, iplot\n", 110 | "\n", 111 | "# Plot OHLC Bar Chart\n", 112 | "trace = go.Ohlc(x=df['12-2018'].index,\n", 113 | " open=df['12-2018'].Open,\n", 114 | " high=df['12-2018'].High,\n", 115 | " low=df['12-2018'].Low,\n", 116 | " close=df['12-2018'].Close)\n", 117 | "data = [trace]\n", 118 | "iplot(data, filename='simple_ohlc')" 119 | ], 120 | "outputs": [], 121 | "execution_count": null, 122 | "metadata": { 123 | "collapsed": false, 124 | "outputHidden": false, 125 | "inputHidden": false 126 | } 127 | }, 128 | { 129 | "cell_type": "code", 130 | "source": [ 131 | "py.iplot(data)" 132 | ], 133 | "outputs": [], 134 | "execution_count": null, 135 | "metadata": { 136 | "collapsed": false, 137 | "outputHidden": false, 138 | "inputHidden": false 139 | } 140 | }, 141 | { 142 | "cell_type": "markdown", 143 | "source": [ 144 | "## Japanese Candlesticks Charts" 145 | ], 146 | "metadata": {} 147 | }, 148 | { 149 | "cell_type": "markdown", 150 | "source": [ 151 | "Learn about candlestick:\n", 152 | "\n", 153 | "https://www.quantinsti.com/blog/candlestick-patterns-meaning\n", 154 | "\nhttps://www.investopedia.com/trading/candlestick-charting-what-is-it/" 155 | ], 156 | "metadata": {} 157 | }, 158 | { 159 | "cell_type": "code", 160 | "source": [ 161 | "from mpl_finance import candlestick_ohlc\n", 162 | "from matplotlib import dates as mdates\n", 163 | "import datetime as dt" 164 | ], 165 | "outputs": [], 166 | "execution_count": null, 167 | "metadata": { 168 | "collapsed": false, 169 | "outputHidden": false, 170 | "inputHidden": false 171 | } 172 | }, 173 | { 174 | "cell_type": "code", 175 | "source": [ 176 | "# Converting date to pandas datetime format\n", 177 | "dfc = df.copy()\n", 178 | "dfc = dfc.reset_index()\n", 179 | "dfc['Date'] = mdates.date2num(dfc['Date'].astype(dt.date))\n", 180 | "dfc.head()" 181 | ], 182 | "outputs": [], 183 | "execution_count": null, 184 | "metadata": { 185 | "collapsed": false, 186 | "outputHidden": false, 187 | "inputHidden": false 188 | } 189 | }, 190 | { 191 | "cell_type": "code", 192 | "source": [ 193 | "fig = plt.figure(figsize=(14,10))\n", 194 | "ax1 = plt.subplot(2, 1, 1)\n", 195 | "candlestick_ohlc(ax1,dfc.values, width=0.5, colorup='g', colordown='r', alpha=1.0)\n", 196 | "ax1.xaxis_date()\n", 197 | "ax1.xaxis.set_major_formatter(mdates.DateFormatter('%d-%m-%Y'))\n", 198 | "ax1.set_title('Stock '+ symbol +' Closing Price')\n", 199 | "ax1.set_ylabel('Price')\n", 200 | "ax1.legend(loc='best')" 201 | ], 202 | "outputs": [], 203 | "execution_count": null, 204 | "metadata": { 205 | "collapsed": false, 206 | "outputHidden": false, 207 | "inputHidden": false 208 | } 209 | }, 210 | { 211 | "cell_type": "code", 212 | "source": [ 213 | "# Plot Candlestick Chart\n", 214 | "trace = go.Candlestick(x=df['12-2018'].index,\n", 215 | " open=df['12-2018'].Open,\n", 216 | " high=df['12-2018'].High,\n", 217 | " low=df['12-2018'].Low,\n", 218 | " close=df['12-2018'].Close)\n", 219 | "\n", 220 | "data = [trace]\n", 221 | "iplot(data, filename='simple_ohlc')" 222 | ], 223 | "outputs": [], 224 | "execution_count": null, 225 | "metadata": { 226 | "collapsed": false, 227 | "outputHidden": false, 228 | "inputHidden": false 229 | } 230 | }, 231 | { 232 | "cell_type": "markdown", 233 | "source": [ 234 | "## Point and Figure Chart" 235 | ], 236 | "metadata": {} 237 | }, 238 | { 239 | "cell_type": "markdown", 240 | "source": [ 241 | "https://github.com/pviglucci/pypf" 242 | ], 243 | "metadata": {} 244 | }, 245 | { 246 | "cell_type": "code", 247 | "source": [ 248 | "from pypf.chart import PFChart\n", 249 | "from pypf.instrument import YahooSecurity\n", 250 | "i = YahooSecurity(symbol, force_download, force_cache, period, debug)\n", 251 | "c = PFChart(i, box_size, duration, interval, method, reversal, style, trend_lines, debug)\n", 252 | "c.create_chart()\n", 253 | "print(c.chart)" 254 | ], 255 | "outputs": [], 256 | "execution_count": null, 257 | "metadata": { 258 | "collapsed": false, 259 | "outputHidden": false, 260 | "inputHidden": false 261 | } 262 | }, 263 | { 264 | "cell_type": "markdown", 265 | "source": [ 266 | "## Market Profile Stock Charts" 267 | ], 268 | "metadata": {} 269 | }, 270 | { 271 | "cell_type": "markdown", 272 | "source": [ 273 | "https://github.com/bfolkens/py-market-profile" 274 | ], 275 | "metadata": {} 276 | }, 277 | { 278 | "cell_type": "code", 279 | "source": [ 280 | "from market_profile import MarketProfile" 281 | ], 282 | "outputs": [], 283 | "execution_count": null, 284 | "metadata": { 285 | "collapsed": false, 286 | "outputHidden": false, 287 | "inputHidden": false 288 | } 289 | }, 290 | { 291 | "cell_type": "code", 292 | "source": [ 293 | "mp = MarketProfile(df, tick_size=1)\n", 294 | "mp_slice = mp[df.index.max() - pd.Timedelta(6.5, 'd'):df.index.max()]" 295 | ], 296 | "outputs": [], 297 | "execution_count": null, 298 | "metadata": { 299 | "collapsed": false, 300 | "outputHidden": false, 301 | "inputHidden": false 302 | } 303 | }, 304 | { 305 | "cell_type": "code", 306 | "source": [ 307 | "data = mp_slice.profile\n", 308 | "data.plot(kind='bar')" 309 | ], 310 | "outputs": [], 311 | "execution_count": null, 312 | "metadata": { 313 | "collapsed": false, 314 | "outputHidden": false, 315 | "inputHidden": false 316 | } 317 | } 318 | ], 319 | "metadata": { 320 | "kernel_info": { 321 | "name": "python3" 322 | }, 323 | "language_info": { 324 | "nbconvert_exporter": "python", 325 | "mimetype": "text/x-python", 326 | "codemirror_mode": { 327 | "version": 3, 328 | "name": "ipython" 329 | }, 330 | "pygments_lexer": "ipython3", 331 | "version": "3.5.5", 332 | "file_extension": ".py", 333 | "name": "python" 334 | }, 335 | "kernelspec": { 336 | "name": "python3", 337 | "language": "python", 338 | "display_name": "Python 3" 339 | }, 340 | "nteract": { 341 | "version": "0.12.2" 342 | } 343 | }, 344 | "nbformat": 4, 345 | "nbformat_minor": 4 346 | } 347 | -------------------------------------------------------------------------------- /04_SimpleTechnicalAnalysisLibrary.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "source": [ 6 | "# List Technical Analysis Library" 7 | ], 8 | "metadata": {} 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "source": [ 13 | "Here the list of technical analysis library. It is very simple to use and you do not need to write on your own when you can use these libraries.\n", 14 | "\nThank you for these people that wrote the library for people to use." 15 | ], 16 | "metadata": {} 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "source": [ 21 | "## 1. ta-lib \n", 22 | "Most common library for Technical Analysis\n", 23 | "\n", 24 | "http://mrjbq7.github.io/ta-lib/\n", 25 | "\nhttps://github.com/mrjbq7/ta-lib" 26 | ], 27 | "metadata": {} 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "source": [ 32 | "## 2. ta (Technical Analysis Library in Python)\n", 33 | "\n", 34 | "https://github.com/bukosabino/ta\n", 35 | "\nhttps://technical-analysis-library-in-python.readthedocs.io/en/latest/" 36 | ], 37 | "metadata": {} 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "source": [ 42 | "## 3. pyti\n", 43 | "\nhttps://github.com/kylejusticemagnuson/pyti" 44 | ], 45 | "metadata": {} 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "source": [ 50 | "## 4. finta FinTA (Financial Technical Analysis)\n", 51 | "\nhttps://github.com/peerchemist/finta" 52 | ], 53 | "metadata": {} 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "source": [ 58 | "## 5. stockstats\n", 59 | "\nhttps://github.com/jealous/stockstats" 60 | ], 61 | "metadata": {} 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "source": [ 66 | "There are more libraries out there but these five libraries have the most stars and many people use them. Other libraries, people still working on it or is a fail library.\n", 67 | "\nIf there are more libraries out there and is a pass, I will add more." 68 | ], 69 | "metadata": {} 70 | } 71 | ], 72 | "metadata": { 73 | "kernel_info": { 74 | "name": "python3" 75 | }, 76 | "language_info": { 77 | "name": "python", 78 | "codemirror_mode": { 79 | "name": "ipython", 80 | "version": 3 81 | }, 82 | "pygments_lexer": "ipython3", 83 | "version": "3.5.5", 84 | "file_extension": ".py", 85 | "nbconvert_exporter": "python", 86 | "mimetype": "text/x-python" 87 | }, 88 | "kernelspec": { 89 | "name": "python3", 90 | "language": "python", 91 | "display_name": "Python 3" 92 | }, 93 | "nteract": { 94 | "version": "0.12.2" 95 | } 96 | }, 97 | "nbformat": 4, 98 | "nbformat_minor": 4 99 | } 100 | -------------------------------------------------------------------------------- /05_SimpleStockCSV.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "source": [ 6 | "# Save Stock Data to csv file" 7 | ], 8 | "metadata": {} 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "source": [ 13 | "## Simple save one ticker to csv" 14 | ], 15 | "metadata": {} 16 | }, 17 | { 18 | "cell_type": "code", 19 | "source": [ 20 | "import numpy as np\n", 21 | "import matplotlib.pyplot as plt\n", 22 | "import pandas as pd\n", 23 | "\n", 24 | "import warnings\n", 25 | "warnings.filterwarnings(\"ignore\")\n", 26 | "\n", 27 | "# fix_yahoo_finance is used to fetch data \n", 28 | "import fix_yahoo_finance as yf\n", 29 | "yf.pdr_override()" 30 | ], 31 | "outputs": [], 32 | "execution_count": 1, 33 | "metadata": { 34 | "collapsed": false, 35 | "outputHidden": false, 36 | "inputHidden": false 37 | } 38 | }, 39 | { 40 | "cell_type": "code", 41 | "source": [ 42 | "# input\n", 43 | "symbol = 'AMD'\n", 44 | "start = '2014-01-01'\n", 45 | "end = '2019-01-01'\n", 46 | "\n", 47 | "# Read data \n", 48 | "dataset = yf.download(symbol,start,end)\n", 49 | "\n", 50 | "# View Columns\n", 51 | "dataset.head()" 52 | ], 53 | "outputs": [ 54 | { 55 | "output_type": "stream", 56 | "name": "stdout", 57 | "text": [ 58 | "[*********************100%***********************] 1 of 1 downloaded\n" 59 | ] 60 | }, 61 | { 62 | "output_type": "execute_result", 63 | "execution_count": 2, 64 | "data": { 65 | "text/plain": [ 66 | " Open High Low Close Adj Close Volume\n", 67 | "Date \n", 68 | "2014-01-02 3.85 3.98 3.84 3.95 3.95 20548400\n", 69 | "2014-01-03 3.98 4.00 3.88 4.00 4.00 22887200\n", 70 | "2014-01-06 4.01 4.18 3.99 4.13 4.13 42398300\n", 71 | "2014-01-07 4.19 4.25 4.11 4.18 4.18 42932100\n", 72 | "2014-01-08 4.23 4.26 4.14 4.18 4.18 30678700" 73 | ], 74 | "text/html": [ 75 | "
\n", 76 | "\n", 89 | "\n", 90 | " \n", 91 | " \n", 92 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 97 | " \n", 98 | " \n", 99 | " \n", 100 | " \n", 101 | " \n", 102 | " \n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 108 | " \n", 109 | " \n", 110 | " \n", 111 | " \n", 112 | " \n", 113 | " \n", 114 | " \n", 115 | " \n", 116 | " \n", 117 | " \n", 118 | " \n", 119 | " \n", 120 | " \n", 121 | " \n", 122 | " \n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | " \n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | " \n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | "
OpenHighLowCloseAdj CloseVolume
Date
2014-01-023.853.983.843.953.9520548400
2014-01-033.984.003.884.004.0022887200
2014-01-064.014.183.994.134.1342398300
2014-01-074.194.254.114.184.1842932100
2014-01-084.234.264.144.184.1830678700
\n", 158 | "
" 159 | ] 160 | }, 161 | "metadata": {} 162 | } 163 | ], 164 | "execution_count": 2, 165 | "metadata": { 166 | "collapsed": false, 167 | "outputHidden": false, 168 | "inputHidden": false 169 | } 170 | }, 171 | { 172 | "cell_type": "code", 173 | "source": [ 174 | "# Output data into CSV\n", 175 | "# To save in your certain folder, change the Users name\n", 176 | "dataset.to_csv(\"C:/Users/Finance/Desktop/AMD.csv\") " 177 | ], 178 | "outputs": [], 179 | "execution_count": 3, 180 | "metadata": { 181 | "collapsed": false, 182 | "outputHidden": false, 183 | "inputHidden": false 184 | } 185 | }, 186 | { 187 | "cell_type": "markdown", 188 | "source": [ 189 | "## Save Multi Stocks of \"Adj Close\" to csv" 190 | ], 191 | "metadata": {} 192 | }, 193 | { 194 | "cell_type": "code", 195 | "source": [ 196 | "symbols = ['MMM','AXP','AAPL','BA','CAT','CVX','CSCO','KO','DIS','XOM','GE','GS','HD','IBM','INTC','JNJ','MCD','MRK','NKE','PFE','PG','UTX','UNH','VZ','V','WMT']\n", 197 | "start = '2001-01-11' \n", 198 | "end = '2018-09-17'\n", 199 | "stocks_info = yf.download(symbols, start, end)['Adj Close']\n", 200 | "stocks_data = stocks_info.iloc[::]" 201 | ], 202 | "outputs": [ 203 | { 204 | "output_type": "stream", 205 | "name": "stdout", 206 | "text": [ 207 | "[*********************100%***********************] 26 of 26 downloaded\n" 208 | ] 209 | } 210 | ], 211 | "execution_count": 4, 212 | "metadata": {} 213 | }, 214 | { 215 | "cell_type": "code", 216 | "source": [ 217 | "stocks_data.head()" 218 | ], 219 | "outputs": [ 220 | { 221 | "output_type": "execute_result", 222 | "execution_count": 5, 223 | "data": { 224 | "text/plain": [ 225 | " AAPL AXP BA CAT CSCO CVX \\\n", 226 | "Date \n", 227 | "2001-01-11 0.860995 32.362038 39.449837 12.335097 31.130840 19.006382 \n", 228 | "2001-01-12 0.822131 32.404297 40.450684 11.860015 30.285425 18.889679 \n", 229 | "2001-01-16 0.819141 32.657772 40.700882 12.131493 30.633539 18.904276 \n", 230 | "2001-01-17 0.804193 33.418255 39.199627 12.216325 31.031374 18.729233 \n", 231 | "2001-01-18 0.893880 33.544987 38.282196 11.507934 33.318939 18.539610 \n", 232 | "\n", 233 | " DIS GE GS HD ... MRK \\\n", 234 | "Date ... \n", 235 | "2001-01-11 23.236092 25.899675 90.825935 34.010456 ... 40.302208 \n", 236 | "2001-01-12 24.860649 25.412958 89.387543 34.053780 ... 40.209618 \n", 237 | "2001-01-16 26.042143 26.351603 90.415009 33.880470 ... 41.135406 \n", 238 | "2001-01-17 26.288290 25.969193 90.415009 32.147453 ... 40.117039 \n", 239 | "2001-01-18 26.091373 26.490675 88.456596 30.674391 ... 40.919392 \n", 240 | "\n", 241 | " NKE PFE PG UNH UTX V \\\n", 242 | "Date \n", 243 | "2001-01-11 2.427128 21.983341 20.644518 11.937548 23.863380 NaN \n", 244 | "2001-01-12 2.371967 22.217928 19.952829 11.681551 22.833738 NaN \n", 245 | "2001-01-16 2.340446 22.351967 20.413963 11.573761 22.914494 NaN \n", 246 | "2001-01-17 2.345699 21.849302 20.113068 11.358186 23.298088 NaN \n", 247 | "2001-01-18 2.356206 22.050377 20.292179 11.263871 23.600931 NaN \n", 248 | "\n", 249 | " VZ WMT XOM \n", 250 | "Date \n", 251 | "2001-01-11 20.906065 36.973961 24.954866 \n", 252 | "2001-01-12 20.812313 37.685860 25.279213 \n", 253 | "2001-01-16 20.390440 38.931671 24.973944 \n", 254 | "2001-01-17 20.226379 38.397762 24.496984 \n", 255 | "2001-01-18 20.906065 37.774853 24.153563 \n", 256 | "\n[5 rows x 26 columns]" 257 | ], 258 | "text/html": [ 259 | "
\n", 260 | "\n", 273 | "\n", 274 | " \n", 275 | " \n", 276 | " \n", 277 | " \n", 278 | " \n", 279 | " \n", 280 | " \n", 281 | " \n", 282 | " \n", 283 | " \n", 284 | " \n", 285 | " \n", 286 | " \n", 287 | " \n", 288 | " \n", 289 | " \n", 290 | " \n", 291 | " \n", 292 | " \n", 293 | " \n", 294 | " \n", 295 | " \n", 296 | " \n", 297 | " \n", 298 | " \n", 299 | " \n", 300 | " \n", 301 | " \n", 302 | " \n", 303 | " \n", 304 | " \n", 305 | " \n", 306 | " \n", 307 | " \n", 308 | " \n", 309 | " \n", 310 | " \n", 311 | " \n", 312 | " \n", 313 | " \n", 314 | " \n", 315 | " \n", 316 | " \n", 317 | " \n", 318 | " \n", 319 | " \n", 320 | " \n", 321 | " \n", 322 | " \n", 323 | " \n", 324 | " \n", 325 | " \n", 326 | " \n", 327 | " \n", 328 | " \n", 329 | " \n", 330 | " \n", 331 | " \n", 332 | " \n", 333 | " \n", 334 | " \n", 335 | " \n", 336 | " \n", 337 | " \n", 338 | " \n", 339 | " \n", 340 | " \n", 341 | " \n", 342 | " \n", 343 | " \n", 344 | " \n", 345 | " \n", 346 | " \n", 347 | " \n", 348 | " \n", 349 | " \n", 350 | " \n", 351 | " \n", 352 | " \n", 353 | " \n", 354 | " \n", 355 | " \n", 356 | " \n", 357 | " \n", 358 | " \n", 359 | " \n", 360 | " \n", 361 | " \n", 362 | " \n", 363 | " \n", 364 | " \n", 365 | " \n", 366 | " \n", 367 | " \n", 368 | " \n", 369 | " \n", 370 | " \n", 371 | " \n", 372 | " \n", 373 | " \n", 374 | " \n", 375 | " \n", 376 | " \n", 377 | " \n", 378 | " \n", 379 | " \n", 380 | " \n", 381 | " \n", 382 | " \n", 383 | " \n", 384 | " \n", 385 | " \n", 386 | " \n", 387 | " \n", 388 | " \n", 389 | " \n", 390 | " \n", 391 | " \n", 392 | " \n", 393 | " \n", 394 | " \n", 395 | " \n", 396 | " \n", 397 | " \n", 398 | " \n", 399 | " \n", 400 | " \n", 401 | " \n", 402 | " \n", 403 | " \n", 404 | " \n", 405 | " \n", 406 | " \n", 407 | " \n", 408 | " \n", 409 | " \n", 410 | " \n", 411 | " \n", 412 | " \n", 413 | " \n", 414 | " \n", 415 | " \n", 416 | " \n", 417 | " \n", 418 | " \n", 419 | " \n", 420 | " \n", 421 | " \n", 422 | " \n", 423 | " \n", 424 | " \n", 425 | " \n", 426 | " \n", 427 | " \n", 428 | " \n", 429 | " \n", 430 | " \n", 431 | " \n", 432 | " \n", 433 | " \n", 434 | " \n", 435 | " \n", 436 | " \n", 437 | " \n", 438 | " \n", 439 | " \n", 440 | " \n", 441 | " \n", 442 | " \n", 443 | " \n", 444 | " \n", 445 | " \n", 446 | "
AAPLAXPBACATCSCOCVXDISGEGSHD...MRKNKEPFEPGUNHUTXVVZWMTXOM
Date
2001-01-110.86099532.36203839.44983712.33509731.13084019.00638223.23609225.89967590.82593534.010456...40.3022082.42712821.98334120.64451811.93754823.863380NaN20.90606536.97396124.954866
2001-01-120.82213132.40429740.45068411.86001530.28542518.88967924.86064925.41295889.38754334.053780...40.2096182.37196722.21792819.95282911.68155122.833738NaN20.81231337.68586025.279213
2001-01-160.81914132.65777240.70088212.13149330.63353918.90427626.04214326.35160390.41500933.880470...41.1354062.34044622.35196720.41396311.57376122.914494NaN20.39044038.93167124.973944
2001-01-170.80419333.41825539.19962712.21632531.03137418.72923326.28829025.96919390.41500932.147453...40.1170392.34569921.84930220.11306811.35818623.298088NaN20.22637938.39776224.496984
2001-01-180.89388033.54498738.28219611.50793433.31893918.53961026.09137326.49067588.45659630.674391...40.9193922.35620622.05037720.29217911.26387123.600931NaN20.90606537.77485324.153563
\n", 447 | "

5 rows × 26 columns

\n", 448 | "
" 449 | ] 450 | }, 451 | "metadata": {} 452 | } 453 | ], 454 | "execution_count": 5, 455 | "metadata": { 456 | "collapsed": false, 457 | "outputHidden": false, 458 | "inputHidden": false 459 | } 460 | }, 461 | { 462 | "cell_type": "code", 463 | "source": [ 464 | "# Output data into CSV\n", 465 | "stocks_data.to_csv(\"C:/Users/Finance/Desktop/stocks_data.csv\")" 466 | ], 467 | "outputs": [], 468 | "execution_count": 6, 469 | "metadata": { 470 | "collapsed": false, 471 | "outputHidden": false, 472 | "inputHidden": false 473 | } 474 | }, 475 | { 476 | "cell_type": "markdown", 477 | "source": [ 478 | "## To find the path or current diectory" 479 | ], 480 | "metadata": {} 481 | }, 482 | { 483 | "cell_type": "code", 484 | "source": [ 485 | "import os\n", 486 | "cwd = os.getcwd()" 487 | ], 488 | "outputs": [], 489 | "execution_count": 7, 490 | "metadata": { 491 | "collapsed": false, 492 | "outputHidden": false, 493 | "inputHidden": false 494 | } 495 | }, 496 | { 497 | "cell_type": "code", 498 | "source": [ 499 | "cwd" 500 | ], 501 | "outputs": [ 502 | { 503 | "output_type": "execute_result", 504 | "execution_count": 8, 505 | "data": { 506 | "text/plain": [ 507 | "'C:\\\\WINDOWS'" 508 | ] 509 | }, 510 | "metadata": {} 511 | } 512 | ], 513 | "execution_count": 8, 514 | "metadata": { 515 | "collapsed": false, 516 | "outputHidden": false, 517 | "inputHidden": false 518 | } 519 | }, 520 | { 521 | "cell_type": "code", 522 | "source": [ 523 | "from pathlib import Path\n", 524 | "\nprint(Path.cwd())" 525 | ], 526 | "outputs": [ 527 | { 528 | "output_type": "stream", 529 | "name": "stdout", 530 | "text": [ 531 | "C:\\WINDOWS\n" 532 | ] 533 | } 534 | ], 535 | "execution_count": 9, 536 | "metadata": { 537 | "collapsed": false, 538 | "outputHidden": false, 539 | "inputHidden": false 540 | } 541 | } 542 | ], 543 | "metadata": { 544 | "kernel_info": { 545 | "name": "python3" 546 | }, 547 | "language_info": { 548 | "codemirror_mode": { 549 | "name": "ipython", 550 | "version": 3 551 | }, 552 | "name": "python", 553 | "version": "3.5.5", 554 | "mimetype": "text/x-python", 555 | "nbconvert_exporter": "python", 556 | "pygments_lexer": "ipython3", 557 | "file_extension": ".py" 558 | }, 559 | "kernelspec": { 560 | "name": "python3", 561 | "language": "python", 562 | "display_name": "Python 3" 563 | }, 564 | "nteract": { 565 | "version": "0.12.2" 566 | } 567 | }, 568 | "nbformat": 4, 569 | "nbformat_minor": 4 570 | } 571 | -------------------------------------------------------------------------------- /13_SimpleStockChartScripts.py: -------------------------------------------------------------------------------- 1 | # Library 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | import pandas as pd 5 | 6 | import warnings 7 | warnings.filterwarnings("ignore") 8 | 9 | # fix_yahoo_finance is used to fetch data 10 | import fix_yahoo_finance as yf 11 | yf.pdr_override() 12 | 13 | # input 14 | symbol = 'AAPL' # Pick Symbol 15 | start = '2018-12-01' # Pick Starting Date 16 | end = '2019-01-01' # Pick Ending Date 17 | 18 | df = yf.download(symbol,start,end) 19 | 20 | # Plot Charts 21 | plt.figure(figsize=(12,8)) 22 | plt.plot(df['Adj Close']) 23 | plt.title("Stock Line Chart") 24 | plt.legend(loc='best') 25 | plt.xlabel("Date") 26 | plt.ylabel("Price") 27 | plt.show() 28 | -------------------------------------------------------------------------------- /18_SimpleStockVWAP.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "source": [ 6 | "# Simple Stock VWAP" 7 | ], 8 | "metadata": {} 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "source": [ 13 | "VWAP (Volume-weighted average price) is used for technical analysis. However, VWAP is calculated by adding up the dollars traded for every transaction (price multiplied by the number of shares traded) and then dividing by the total shares traded.\n", 14 | "\n\nTo understand more about VWAP: https://www.investopedia.com/terms/v/vwap.asp" 15 | ], 16 | "metadata": {} 17 | }, 18 | { 19 | "cell_type": "code", 20 | "source": [ 21 | "import pandas as pd, numpy as np\n", 22 | "import matplotlib.pyplot as plt\n", 23 | "import seaborn as sns\n", 24 | "from datetime import datetime\n", 25 | "import statsmodels.api as sm\n", 26 | "%matplotlib inline\n", 27 | "\n", 28 | "import warnings\n", 29 | "warnings.filterwarnings(\"ignore\")\n", 30 | "\n", 31 | "from pandas_datareader import data as pdr\n", 32 | "import fix_yahoo_finance as yf\n", 33 | "yf.pdr_override()" 34 | ], 35 | "outputs": [], 36 | "execution_count": 1, 37 | "metadata": { 38 | "collapsed": false, 39 | "outputHidden": false, 40 | "inputHidden": false 41 | } 42 | }, 43 | { 44 | "cell_type": "code", 45 | "source": [ 46 | "def get_symbol(symbol):\n", 47 | " start = '2018-01-01' \n", 48 | " end = '2018-12-31'\n", 49 | " df = pdr.get_data_yahoo(symbol, start, end)\n", 50 | " return df" 51 | ], 52 | "outputs": [], 53 | "execution_count": 2, 54 | "metadata": { 55 | "collapsed": false, 56 | "outputHidden": false, 57 | "inputHidden": false 58 | } 59 | }, 60 | { 61 | "cell_type": "code", 62 | "source": [ 63 | "stock = get_symbol('AMD')\n", 64 | "stock.head()" 65 | ], 66 | "outputs": [ 67 | { 68 | "output_type": "stream", 69 | "name": "stdout", 70 | "text": [ 71 | "[*********************100%***********************] 1 of 1 downloaded\n" 72 | ] 73 | }, 74 | { 75 | "output_type": "execute_result", 76 | "execution_count": 3, 77 | "data": { 78 | "text/plain": [ 79 | " Open High Low Close Adj Close Volume\n", 80 | "Date \n", 81 | "2018-01-02 10.42 11.02 10.34 10.98 10.98 44146300\n", 82 | "2018-01-03 11.61 12.14 11.36 11.55 11.55 154066700\n", 83 | "2018-01-04 12.10 12.43 11.97 12.12 12.12 109503000\n", 84 | "2018-01-05 12.19 12.22 11.66 11.88 11.88 63808900\n", 85 | "2018-01-08 12.01 12.30 11.85 12.28 12.28 63346000" 86 | ], 87 | "text/html": [ 88 | "
\n", 89 | "\n", 102 | "\n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 108 | " \n", 109 | " \n", 110 | " \n", 111 | " \n", 112 | " \n", 113 | " \n", 114 | " \n", 115 | " \n", 116 | " \n", 117 | " \n", 118 | " \n", 119 | " \n", 120 | " \n", 121 | " \n", 122 | " \n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | " \n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | " \n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | " \n", 159 | " \n", 160 | " \n", 161 | " \n", 162 | " \n", 163 | " \n", 164 | " \n", 165 | " \n", 166 | " \n", 167 | " \n", 168 | " \n", 169 | " \n", 170 | "
OpenHighLowCloseAdj CloseVolume
Date
2018-01-0210.4211.0210.3410.9810.9844146300
2018-01-0311.6112.1411.3611.5511.55154066700
2018-01-0412.1012.4311.9712.1212.12109503000
2018-01-0512.1912.2211.6611.8811.8863808900
2018-01-0812.0112.3011.8512.2812.2863346000
\n", 171 | "
" 172 | ] 173 | }, 174 | "metadata": {} 175 | } 176 | ], 177 | "execution_count": 3, 178 | "metadata": { 179 | "collapsed": false, 180 | "outputHidden": false, 181 | "inputHidden": false 182 | } 183 | }, 184 | { 185 | "cell_type": "code", 186 | "source": [ 187 | "def VWAP():\n", 188 | " df = get_symbol('AAPL')\n", 189 | " df['Typical_Price'] = (df['High']+df['Low']+df['Adj Close'])/3\n", 190 | " df['TP_Volume'] = df['Typical_Price'] * df['Volume']\n", 191 | " Cumulative_TP_V = df['TP_Volume'].sum() \n", 192 | " Cumulative_V = df['Volume'].sum()\n", 193 | " vwap = Cumulative_TP_V/Cumulative_V\n", 194 | " return vwap\n", 195 | "\nVWAP()" 196 | ], 197 | "outputs": [ 198 | { 199 | "output_type": "stream", 200 | "name": "stdout", 201 | "text": [ 202 | "[*********************100%***********************] 1 of 1 downloaded\n" 203 | ] 204 | }, 205 | { 206 | "output_type": "execute_result", 207 | "execution_count": 4, 208 | "data": { 209 | "text/plain": [ 210 | "186.85563818472755" 211 | ] 212 | }, 213 | "metadata": {} 214 | } 215 | ], 216 | "execution_count": 4, 217 | "metadata": { 218 | "collapsed": false, 219 | "outputHidden": false, 220 | "inputHidden": false 221 | } 222 | }, 223 | { 224 | "cell_type": "code", 225 | "source": [ 226 | "def Update_VWAP():\n", 227 | " df = get_symbol('AAPL')\n", 228 | " df['OpenxVolume'] = df['Open']*df['Volume']\n", 229 | " df['HighxVolume'] = df['High']*df['Volume']\n", 230 | " df['LowxVolume'] = df['Low']*df['Volume']\n", 231 | " df['ClosexVolume'] = df['Adj Close']*df['Volume']\n", 232 | " Sum_Volume = df['Volume'].sum()\n", 233 | " Sum_x_OV = df['OpenxVolume'].sum()/ Sum_Volume\n", 234 | " Sum_x_HV = df['HighxVolume'].sum()/ Sum_Volume\n", 235 | " Sum_x_LV = df['LowxVolume'].sum()/ Sum_Volume\n", 236 | " Sum_x_CV = df['ClosexVolume'].sum()/ Sum_Volume\n", 237 | " Average_Volume_Each = (Sum_x_OV + Sum_x_HV + Sum_x_LV + Sum_x_OV)/4\n", 238 | " new_vwap = ((df['Adj Close'][-1] - Average_Volume_Each)+(df['Adj Close'][-1] + Average_Volume_Each))/2\n", 239 | " return new_vwap\n", 240 | "\nUpdate_VWAP()" 241 | ], 242 | "outputs": [ 243 | { 244 | "output_type": "stream", 245 | "name": "stdout", 246 | "text": [ 247 | "[*********************100%***********************] 1 of 1 downloaded\n" 248 | ] 249 | }, 250 | { 251 | "output_type": "execute_result", 252 | "execution_count": 5, 253 | "data": { 254 | "text/plain": [ 255 | "157.740005" 256 | ] 257 | }, 258 | "metadata": {} 259 | } 260 | ], 261 | "execution_count": 5, 262 | "metadata": { 263 | "collapsed": false, 264 | "outputHidden": false, 265 | "inputHidden": false 266 | } 267 | }, 268 | { 269 | "cell_type": "code", 270 | "source": [ 271 | "def VWAP_Column():\n", 272 | " df = get_symbol('AAPL')\n", 273 | " df['OpenxVolume'] = df['Open']*df['Volume']\n", 274 | " df['HighxVolume'] = df['High']*df['Volume']\n", 275 | " df['LowxVolume'] = df['Low']*df['Volume']\n", 276 | " df['ClosexVolume'] = df['Adj Close']*df['Volume']\n", 277 | " vwap_column = (df[['OpenxVolume','HighxVolume','LowxVolume','ClosexVolume']].mean(axis=1))/df['Volume']\n", 278 | " return vwap_column\n", 279 | "\nUpdate_VWAP()" 280 | ], 281 | "outputs": [ 282 | { 283 | "output_type": "stream", 284 | "name": "stdout", 285 | "text": [ 286 | "[*********************100%***********************] 1 of 1 downloaded\n" 287 | ] 288 | }, 289 | { 290 | "output_type": "execute_result", 291 | "execution_count": 6, 292 | "data": { 293 | "text/plain": [ 294 | "157.740005" 295 | ] 296 | }, 297 | "metadata": {} 298 | } 299 | ], 300 | "execution_count": 6, 301 | "metadata": { 302 | "collapsed": false, 303 | "outputHidden": false, 304 | "inputHidden": false 305 | } 306 | } 307 | ], 308 | "metadata": { 309 | "kernel_info": { 310 | "name": "python3" 311 | }, 312 | "kernelspec": { 313 | "name": "python3", 314 | "language": "python", 315 | "display_name": "Python 3" 316 | }, 317 | "language_info": { 318 | "pygments_lexer": "ipython3", 319 | "name": "python", 320 | "codemirror_mode": { 321 | "name": "ipython", 322 | "version": 3 323 | }, 324 | "nbconvert_exporter": "python", 325 | "version": "3.5.5", 326 | "mimetype": "text/x-python", 327 | "file_extension": ".py" 328 | }, 329 | "nteract": { 330 | "version": "0.12.2" 331 | } 332 | }, 333 | "nbformat": 4, 334 | "nbformat_minor": 4 335 | } 336 | -------------------------------------------------------------------------------- /20_SimpleStockSignals.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "source": [ 6 | "# Simple Stock Signals" 7 | ], 8 | "metadata": {} 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "source": [ 13 | "This simple tutorial, we will add buy and sell signals." 14 | ], 15 | "metadata": {} 16 | }, 17 | { 18 | "cell_type": "code", 19 | "source": [ 20 | "import numpy as np\n", 21 | "import pandas as pd\n", 22 | "import matplotlib.pyplot as plt\n", 23 | "\n", 24 | "import warnings\n", 25 | "warnings.filterwarnings(\"ignore\")\n", 26 | "\n", 27 | "# fix_yahoo_finance is used to fetch data \n", 28 | "import fix_yahoo_finance as yf\n", 29 | "yf.pdr_override()" 30 | ], 31 | "outputs": [], 32 | "execution_count": 1, 33 | "metadata": { 34 | "collapsed": false, 35 | "outputHidden": false, 36 | "inputHidden": false 37 | } 38 | }, 39 | { 40 | "cell_type": "code", 41 | "source": [ 42 | "# input\n", 43 | "symbol = 'AMD'\n", 44 | "start = '2018-01-01'\n", 45 | "end = '2018-12-31'\n", 46 | "\n", 47 | "# Read data \n", 48 | "df = yf.download(symbol,start,end)\n", 49 | "\n", 50 | "# View Columns\n", 51 | "df.head()" 52 | ], 53 | "outputs": [ 54 | { 55 | "output_type": "stream", 56 | "name": "stdout", 57 | "text": [ 58 | "[*********************100%***********************] 1 of 1 downloaded\n" 59 | ] 60 | }, 61 | { 62 | "output_type": "execute_result", 63 | "execution_count": 2, 64 | "data": { 65 | "text/html": [ 66 | "
\n", 67 | "\n", 80 | "\n", 81 | " \n", 82 | " \n", 83 | " \n", 84 | " \n", 85 | " \n", 86 | " \n", 87 | " \n", 88 | " \n", 89 | " \n", 90 | " \n", 91 | " \n", 92 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 97 | " \n", 98 | " \n", 99 | " \n", 100 | " \n", 101 | " \n", 102 | " \n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 108 | " \n", 109 | " \n", 110 | " \n", 111 | " \n", 112 | " \n", 113 | " \n", 114 | " \n", 115 | " \n", 116 | " \n", 117 | " \n", 118 | " \n", 119 | " \n", 120 | " \n", 121 | " \n", 122 | " \n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | " \n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | " \n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | "
OpenHighLowCloseAdj CloseVolume
Date
2018-01-0210.4211.0210.3410.9810.9844146300
2018-01-0311.6112.1411.3611.5511.55154066700
2018-01-0412.1012.4311.9712.1212.12109503000
2018-01-0512.1912.2211.6611.8811.8863808900
2018-01-0812.0112.3011.8512.2812.2863346000
\n", 149 | "
" 150 | ], 151 | "text/plain": [ 152 | " Open High Low Close Adj Close Volume\n", 153 | "Date \n", 154 | "2018-01-02 10.42 11.02 10.34 10.98 10.98 44146300\n", 155 | "2018-01-03 11.61 12.14 11.36 11.55 11.55 154066700\n", 156 | "2018-01-04 12.10 12.43 11.97 12.12 12.12 109503000\n", 157 | "2018-01-05 12.19 12.22 11.66 11.88 11.88 63808900\n", 158 | "2018-01-08 12.01 12.30 11.85 12.28 12.28 63346000" 159 | ] 160 | }, 161 | "metadata": {} 162 | } 163 | ], 164 | "execution_count": 2, 165 | "metadata": { 166 | "collapsed": false, 167 | "outputHidden": false, 168 | "inputHidden": false 169 | } 170 | }, 171 | { 172 | "cell_type": "code", 173 | "source": [ 174 | "df.describe()" 175 | ], 176 | "outputs": [ 177 | { 178 | "output_type": "execute_result", 179 | "execution_count": 3, 180 | "data": { 181 | "text/html": [ 182 | "
\n", 183 | "\n", 196 | "\n", 197 | " \n", 198 | " \n", 199 | " \n", 200 | " \n", 201 | " \n", 202 | " \n", 203 | " \n", 204 | " \n", 205 | " \n", 206 | " \n", 207 | " \n", 208 | " \n", 209 | " \n", 210 | " \n", 211 | " \n", 212 | " \n", 213 | " \n", 214 | " \n", 215 | " \n", 216 | " \n", 217 | " \n", 218 | " \n", 219 | " \n", 220 | " \n", 221 | " \n", 222 | " \n", 223 | " \n", 224 | " \n", 225 | " \n", 226 | " \n", 227 | " \n", 228 | " \n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " \n", 250 | " \n", 251 | " \n", 252 | " \n", 253 | " \n", 254 | " \n", 255 | " \n", 256 | " \n", 257 | " \n", 258 | " \n", 259 | " \n", 260 | " \n", 261 | " \n", 262 | " \n", 263 | " \n", 264 | " \n", 265 | " \n", 266 | " \n", 267 | " \n", 268 | " \n", 269 | " \n", 270 | " \n", 271 | " \n", 272 | " \n", 273 | " \n", 274 | " \n", 275 | " \n", 276 | " \n", 277 | " \n", 278 | " \n", 279 | " \n", 280 | " \n", 281 | " \n", 282 | "
OpenHighLowCloseAdj CloseVolume
count251.000000251.000000251.000000251.000000251.0000002.510000e+02
mean17.20968117.66761016.72988017.21450217.2145028.460868e+07
std6.2026846.4304765.9127496.1825156.1825154.636185e+07
min9.0800009.7700009.0400009.5300009.5300002.887510e+07
25%12.00500012.18500011.71000011.95500011.9550004.869910e+07
50%16.18000016.53000115.78000016.27000016.2700007.434780e+07
75%20.15000120.89500119.57499920.14999920.1499991.071805e+08
max33.18000034.13999932.18999932.72000132.7200013.250584e+08
\n", 283 | "
" 284 | ], 285 | "text/plain": [ 286 | " Open High Low Close Adj Close \\\n", 287 | "count 251.000000 251.000000 251.000000 251.000000 251.000000 \n", 288 | "mean 17.209681 17.667610 16.729880 17.214502 17.214502 \n", 289 | "std 6.202684 6.430476 5.912749 6.182515 6.182515 \n", 290 | "min 9.080000 9.770000 9.040000 9.530000 9.530000 \n", 291 | "25% 12.005000 12.185000 11.710000 11.955000 11.955000 \n", 292 | "50% 16.180000 16.530001 15.780000 16.270000 16.270000 \n", 293 | "75% 20.150001 20.895001 19.574999 20.149999 20.149999 \n", 294 | "max 33.180000 34.139999 32.189999 32.720001 32.720001 \n", 295 | "\n", 296 | " Volume \n", 297 | "count 2.510000e+02 \n", 298 | "mean 8.460868e+07 \n", 299 | "std 4.636185e+07 \n", 300 | "min 2.887510e+07 \n", 301 | "25% 4.869910e+07 \n", 302 | "50% 7.434780e+07 \n", 303 | "75% 1.071805e+08 \n", 304 | "max 3.250584e+08 " 305 | ] 306 | }, 307 | "metadata": {} 308 | } 309 | ], 310 | "execution_count": 3, 311 | "metadata": { 312 | "collapsed": false, 313 | "outputHidden": false, 314 | "inputHidden": false 315 | } 316 | }, 317 | { 318 | "cell_type": "code", 319 | "source": [ 320 | "# Create Rules, the max is 34.13 and the min is 1.61\n", 321 | "high = 30\n", 322 | "low = 15" 323 | ], 324 | "outputs": [], 325 | "execution_count": 4, 326 | "metadata": { 327 | "collapsed": false, 328 | "outputHidden": false, 329 | "inputHidden": false 330 | } 331 | }, 332 | { 333 | "cell_type": "code", 334 | "source": [ 335 | "# As default, set everything to 0\n", 336 | "df['Signal'] = 0\n", 337 | " \n", 338 | "# If stock is more than 30, and we set the signal to -1 which means: 'short'\n", 339 | "df.loc[df['Adj Close'] > high, 'Signal'] = -1\n", 340 | " \n", 341 | "# If stock is less than 15, and we set the signal to 1 which means: 'long'\n", 342 | "df.loc[df['Adj Close'] < low, 'Signal'] = 1\n", 343 | " \n", 344 | "buys = df.ix[df['Signal'] == 1]\n", 345 | "sells = df.ix[df['Signal'] == -1]" 346 | ], 347 | "outputs": [], 348 | "execution_count": 5, 349 | "metadata": { 350 | "collapsed": false, 351 | "outputHidden": false, 352 | "inputHidden": false 353 | } 354 | }, 355 | { 356 | "cell_type": "code", 357 | "source": [ 358 | "plt.figure(figsize=(16,8))\n", 359 | "plt.plot(df.index, df['Adj Close'], label='Closing')\n", 360 | "plt.plot(sells.index, df.ix[sells.index]['Adj Close'],'v', markersize=10, color='r', label='Short')\n", 361 | "plt.plot(buys.index, df.ix[buys.index]['Adj Close'], '^', markersize=10, color='g', label='Long')\n", 362 | "plt.title(symbol + ' signals')\n", 363 | "plt.ylabel('Price')\n", 364 | "plt.xlabel('Date')\n", 365 | "plt.legend(loc='best')\n", 366 | "plt.show()" 367 | ], 368 | "outputs": [ 369 | { 370 | "output_type": "display_data", 371 | "data": { 372 | "text/plain": [ 373 | "
" 374 | ], 375 | "image/png": [ 376 | "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e4aeHnkj4TMf6+6W3vrW4e8L5JMsnLf8T//0T1q1apXWrl2rdevW6cUXX9SCBQt06tSpUd9z+/bteuKJJ0b9+vFAgAUAAChUGexJjbg9ilx4UeLawQYxjbDN93tXv08arAp7Nq+X43Mw+WSyH3wM3Qdbt27V448/rldeeUU7duzQ008/rblz547qXinRaJQACwAAgBwaZjJw1OPVT9a+SdHNz58Op+m+8R7BN9qxuNXTrS69et0tp9skh+Lx0EKMycep85aT6urqVF1draKiIklSdXW1Zs2aJUn6+te/rvPOO09r1qzR3r17JUktLS265ZZbtHbtWl1yySXasWOHJOn+++/XBz/4Qd1www2688479Q//8A969NFHtW7dOj366KOjWttYEWABAAAK2RCVIOty6YEN71Wxt1/b8FnfeIfdHtn3vz/jb7T31HWoszeqtk/+jXTFFdK73jV4iPV6GeCEyWuoKuwY937fcMMNOn78uJYuXap7771Xzz77bN9z1dXVeuWVV/SRj3xEX/rSlyRJn/70p7V+/Xrt2LFDn//853XnnXf2Xb9t2zb94he/0I9+9CN99rOf1a233qrt27fr1ltvHfX6xoIACwAAUMiGaAt+5dpb1Fs9TebsgPncc1I4sVfVF4vK/Pu/ZzyA5oXDzZKkdRetlJ59VvrqV6VklehsluorJrNxaslPJxAIaNu2bfrOd76jmpoa3XrrrXrooYckSe94xzskSeeff76OHDkiSdq8ebPuuOMOSdK1116r5uZmtbe3S5JuvvlmFRcXj3ot440ACwAAUOgGaQt+/G0fUJk/zbClK68cfv/eIANoXjjcogVTSzSjwp94YJCjdXrdHnXffgfVV0xuY2zJH4rb7dbVV1+tz3zmM/rGN76hn/70p5LU11bsdrsVjSamjFs78JTn1A+uSktLx7yW8USABQAAKHTJEBnxJI7IsckK0El/pcqK0hybs3Fjor13KGm+CY/HrV460qKLF04dcD9z1jfxcePSyT/7qxF/KUBeObsKO07nHu/bt08HDhzo+3z79u2aP3/+oNdfeeWVevjhhyVJmzZtUnV1tcrLywdcV1ZWps7OzjGtbawIsAAAAEiez5qouFiXS9q4UZ090fQV2JkzpXvuGfEAmj31HWrvjujiRVUD79fvm/i416efrLlepwJTxvxlARNe/yrsOFVf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\n" 377 | ] 378 | }, 379 | "metadata": {} 380 | } 381 | ], 382 | "execution_count": 6, 383 | "metadata": { 384 | "collapsed": false, 385 | "outputHidden": false, 386 | "inputHidden": false 387 | } 388 | } 389 | ], 390 | "metadata": { 391 | "kernel_info": { 392 | "name": "python3" 393 | }, 394 | "language_info": { 395 | "pygments_lexer": "ipython3", 396 | "name": "python", 397 | "mimetype": "text/x-python", 398 | "codemirror_mode": { 399 | "name": "ipython", 400 | "version": 3 401 | }, 402 | "file_extension": ".py", 403 | "nbconvert_exporter": "python", 404 | "version": "3.5.5" 405 | }, 406 | "kernelspec": { 407 | "name": "python3", 408 | "language": "python", 409 | "display_name": "Python 3" 410 | }, 411 | "nteract": { 412 | "version": "0.12.2" 413 | } 414 | }, 415 | "nbformat": 4, 416 | "nbformat_minor": 4 417 | } 418 | -------------------------------------------------------------------------------- /24_Simple_Kelly_Criterion.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "source": [ 6 | "# Simple Kelly Criterion" 7 | ], 8 | "metadata": {} 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "source": [ 13 | "http://www.elem.com/~btilly/kelly-criterion/\n", 14 | "\nhttps://www.investopedia.com/articles/trading/04/091504.asp" 15 | ], 16 | "metadata": {} 17 | }, 18 | { 19 | "cell_type": "code", 20 | "source": [ 21 | "import numpy as np\n", 22 | "import pandas as pd\n", 23 | "import matplotlib.pyplot as plt\n", 24 | "\n", 25 | "import warnings\n", 26 | "warnings.filterwarnings(\"ignore\")\n", 27 | "\n", 28 | "# fix_yahoo_finance is used to fetch data \n", 29 | "import fix_yahoo_finance as yf\n", 30 | "yf.pdr_override()" 31 | ], 32 | "outputs": [], 33 | "execution_count": 1, 34 | "metadata": { 35 | "collapsed": false, 36 | "outputHidden": false, 37 | "inputHidden": false 38 | } 39 | }, 40 | { 41 | "cell_type": "code", 42 | "source": [ 43 | "# input\n", 44 | "symbol = 'BAC'\n", 45 | "start = '2018-01-01'\n", 46 | "end = '2019-01-01'\n", 47 | "\n", 48 | "# Read data \n", 49 | "df = yf.download(symbol,start,end)\n", 50 | "\n", 51 | "# View Columns\n", 52 | "df.head()" 53 | ], 54 | "outputs": [ 55 | { 56 | "output_type": "stream", 57 | "name": "stdout", 58 | "text": [ 59 | "[*********************100%***********************] 1 of 1 downloaded\n" 60 | ] 61 | }, 62 | { 63 | "output_type": "execute_result", 64 | "execution_count": 2, 65 | "data": { 66 | "text/plain": [ 67 | " Open High Low Close Adj Close Volume\n", 68 | "Date \n", 69 | "2018-01-02 29.750000 29.900000 29.610001 29.900000 29.211069 57121600\n", 70 | "2018-01-03 29.900000 29.940001 29.690001 29.799999 29.113373 57865700\n", 71 | "2018-01-04 29.969999 30.440001 29.879999 30.190001 29.494387 76512500\n", 72 | "2018-01-05 30.370001 30.420000 30.049999 30.330000 29.631161 56445200\n", 73 | "2018-01-08 30.230000 30.270000 30.049999 30.120001 29.426003 42914800" 74 | ], 75 | "text/html": [ 76 | "
\n", 77 | "\n", 90 | "\n", 91 | " \n", 92 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 97 | " \n", 98 | " \n", 99 | " \n", 100 | " \n", 101 | " \n", 102 | " \n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 108 | " \n", 109 | " \n", 110 | " \n", 111 | " \n", 112 | " \n", 113 | " \n", 114 | " \n", 115 | " \n", 116 | " \n", 117 | " \n", 118 | " \n", 119 | " \n", 120 | " \n", 121 | " \n", 122 | " \n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | " \n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | " \n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | "
OpenHighLowCloseAdj CloseVolume
Date
2018-01-0229.75000029.90000029.61000129.90000029.21106957121600
2018-01-0329.90000029.94000129.69000129.79999929.11337357865700
2018-01-0429.96999930.44000129.87999930.19000129.49438776512500
2018-01-0530.37000130.42000030.04999930.33000029.63116156445200
2018-01-0830.23000030.27000030.04999930.12000129.42600342914800
\n", 159 | "
" 160 | ] 161 | }, 162 | "metadata": {} 163 | } 164 | ], 165 | "execution_count": 2, 166 | "metadata": { 167 | "collapsed": false, 168 | "outputHidden": false, 169 | "inputHidden": false 170 | } 171 | }, 172 | { 173 | "cell_type": "code", 174 | "source": [ 175 | "df['Returns'] = df['Adj Close'].pct_change()" 176 | ], 177 | "outputs": [], 178 | "execution_count": 3, 179 | "metadata": { 180 | "collapsed": false, 181 | "outputHidden": false, 182 | "inputHidden": false 183 | } 184 | }, 185 | { 186 | "cell_type": "code", 187 | "source": [ 188 | "df = df.dropna()\n", 189 | "df.head()" 190 | ], 191 | "outputs": [ 192 | { 193 | "output_type": "execute_result", 194 | "execution_count": 4, 195 | "data": { 196 | "text/plain": [ 197 | " Open High Low Close Adj Close Volume \\\n", 198 | "Date \n", 199 | "2018-01-03 29.900000 29.940001 29.690001 29.799999 29.113373 57865700 \n", 200 | "2018-01-04 29.969999 30.440001 29.879999 30.190001 29.494387 76512500 \n", 201 | "2018-01-05 30.370001 30.420000 30.049999 30.330000 29.631161 56445200 \n", 202 | "2018-01-08 30.230000 30.270000 30.049999 30.120001 29.426003 42914800 \n", 203 | "2018-01-09 30.200001 30.540001 30.129999 30.270000 29.572544 69479100 \n", 204 | "\n", 205 | " Returns \n", 206 | "Date \n", 207 | "2018-01-03 -0.003344 \n", 208 | "2018-01-04 0.013087 \n", 209 | "2018-01-05 0.004637 \n", 210 | "2018-01-08 -0.006924 \n", 211 | "2018-01-09 0.004980 " 212 | ], 213 | "text/html": [ 214 | "
\n", 215 | "\n", 228 | "\n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " \n", 250 | " \n", 251 | " \n", 252 | " \n", 253 | " \n", 254 | " \n", 255 | " \n", 256 | " \n", 257 | " \n", 258 | " \n", 259 | " \n", 260 | " \n", 261 | " \n", 262 | " \n", 263 | " \n", 264 | " \n", 265 | " \n", 266 | " \n", 267 | " \n", 268 | " \n", 269 | " \n", 270 | " \n", 271 | " \n", 272 | " \n", 273 | " \n", 274 | " \n", 275 | " \n", 276 | " \n", 277 | " \n", 278 | " \n", 279 | " \n", 280 | " \n", 281 | " \n", 282 | " \n", 283 | " \n", 284 | " \n", 285 | " \n", 286 | " \n", 287 | " \n", 288 | " \n", 289 | " \n", 290 | " \n", 291 | " \n", 292 | " \n", 293 | " \n", 294 | " \n", 295 | " \n", 296 | " \n", 297 | " \n", 298 | " \n", 299 | " \n", 300 | " \n", 301 | " \n", 302 | " \n", 303 | "
OpenHighLowCloseAdj CloseVolumeReturns
Date
2018-01-0329.90000029.94000129.69000129.79999929.11337357865700-0.003344
2018-01-0429.96999930.44000129.87999930.19000129.494387765125000.013087
2018-01-0530.37000130.42000030.04999930.33000029.631161564452000.004637
2018-01-0830.23000030.27000030.04999930.12000129.42600342914800-0.006924
2018-01-0930.20000130.54000130.12999930.27000029.572544694791000.004980
\n", 304 | "
" 305 | ] 306 | }, 307 | "metadata": {} 308 | } 309 | ], 310 | "execution_count": 4, 311 | "metadata": { 312 | "collapsed": false, 313 | "outputHidden": false, 314 | "inputHidden": false 315 | } 316 | }, 317 | { 318 | "cell_type": "code", 319 | "source": [ 320 | "returns = np.array(df['Returns'])\n", 321 | "wins = returns[returns > 0]\n", 322 | "losses = returns[returns <= 0]\n", 323 | "# W = Winning probability\n", 324 | "# R = Win/loss ratio\n", 325 | "W = len(wins) / len(returns)\n", 326 | "R = np.mean(wins) / np.abs(np.mean(losses))\n", 327 | "Kelly = W - ( (1 - W) / R )" 328 | ], 329 | "outputs": [], 330 | "execution_count": 5, 331 | "metadata": { 332 | "collapsed": false, 333 | "outputHidden": false, 334 | "inputHidden": false 335 | } 336 | }, 337 | { 338 | "cell_type": "code", 339 | "source": [ 340 | "# Kelly value negative means the expected returns will be negative\n", 341 | "# Kelly value positive means the expected returns will be positive\n", 342 | "print('Kelly Criterion: {}%'.format(np.round(Kelly, 3)))" 343 | ], 344 | "outputs": [ 345 | { 346 | "output_type": "stream", 347 | "name": "stdout", 348 | "text": [ 349 | "Kelly Criterion: -0.056%\n" 350 | ] 351 | } 352 | ], 353 | "execution_count": 6, 354 | "metadata": { 355 | "collapsed": false, 356 | "outputHidden": false, 357 | "inputHidden": false 358 | } 359 | } 360 | ], 361 | "metadata": { 362 | "kernel_info": { 363 | "name": "python3" 364 | }, 365 | "language_info": { 366 | "codemirror_mode": { 367 | "name": "ipython", 368 | "version": 3 369 | }, 370 | "pygments_lexer": "ipython3", 371 | "mimetype": "text/x-python", 372 | "name": "python", 373 | "nbconvert_exporter": "python", 374 | "version": "3.5.5", 375 | "file_extension": ".py" 376 | }, 377 | "kernelspec": { 378 | "name": "python3", 379 | "language": "python", 380 | "display_name": "Python 3" 381 | }, 382 | "nteract": { 383 | "version": "0.12.2" 384 | } 385 | }, 386 | "nbformat": 4, 387 | "nbformat_minor": 4 388 | } 389 | -------------------------------------------------------------------------------- /26_SimpleStockPredictionTensorFlow.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "source": [ 6 | "# Simple Stock Prediction Tensorflow" 7 | ], 8 | "metadata": {} 9 | }, 10 | { 11 | "cell_type": "code", 12 | "source": [ 13 | "import numpy as np\n", 14 | "import pandas as pd\n", 15 | "import matplotlib.pyplot as plt\n", 16 | "\n", 17 | "import warnings\n", 18 | "warnings.filterwarnings(\"ignore\")\n", 19 | "\n", 20 | "# fix_yahoo_finance is used to fetch data \n", 21 | "import fix_yahoo_finance as yf\n", 22 | "yf.pdr_override()" 23 | ], 24 | "outputs": [], 25 | "execution_count": 1, 26 | "metadata": { 27 | "collapsed": false, 28 | "outputHidden": false, 29 | "inputHidden": false 30 | } 31 | }, 32 | { 33 | "cell_type": "code", 34 | "source": [ 35 | "# input\n", 36 | "symbol = 'AAPL'\n", 37 | "start = '2018-01-01'\n", 38 | "end = '2019-01-31'\n", 39 | "\n", 40 | "# Read data \n", 41 | "df = yf.download(symbol,start,end)\n", 42 | "\n", 43 | "# View Columns\n", 44 | "df.head()" 45 | ], 46 | "outputs": [ 47 | { 48 | "output_type": "stream", 49 | "name": "stdout", 50 | "text": [ 51 | "[*********************100%***********************] 1 of 1 downloaded\n" 52 | ] 53 | }, 54 | { 55 | "output_type": "execute_result", 56 | "execution_count": 2, 57 | "data": { 58 | "text/html": [ 59 | "
\n", 60 | "\n", 73 | "\n", 74 | " \n", 75 | " \n", 76 | " \n", 77 | " \n", 78 | " \n", 79 | " \n", 80 | " \n", 81 | " \n", 82 | " \n", 83 | " \n", 84 | " \n", 85 | " \n", 86 | " \n", 87 | " \n", 88 | " \n", 89 | " \n", 90 | " \n", 91 | " \n", 92 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 97 | " \n", 98 | " \n", 99 | " \n", 100 | " \n", 101 | " \n", 102 | " \n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 108 | " \n", 109 | " \n", 110 | " \n", 111 | " \n", 112 | " \n", 113 | " \n", 114 | " \n", 115 | " \n", 116 | " \n", 117 | " \n", 118 | " \n", 119 | " \n", 120 | " \n", 121 | " \n", 122 | " \n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | " \n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | "
OpenHighLowCloseAdj CloseVolume
Date
2018-01-02170.160004172.300003169.259995172.259995168.98732025555900
2018-01-03172.529999174.550003171.960007172.229996168.95788629517900
2018-01-04172.539993173.470001172.080002173.029999169.74270622434600
2018-01-05173.440002175.369995173.050003175.000000171.67527823660000
2018-01-08174.350006175.610001173.929993174.350006171.03762820567800
\n", 142 | "
" 143 | ], 144 | "text/plain": [ 145 | " Open High Low Close Adj Close \\\n", 146 | "Date \n", 147 | "2018-01-02 170.160004 172.300003 169.259995 172.259995 168.987320 \n", 148 | "2018-01-03 172.529999 174.550003 171.960007 172.229996 168.957886 \n", 149 | "2018-01-04 172.539993 173.470001 172.080002 173.029999 169.742706 \n", 150 | "2018-01-05 173.440002 175.369995 173.050003 175.000000 171.675278 \n", 151 | "2018-01-08 174.350006 175.610001 173.929993 174.350006 171.037628 \n", 152 | "\n", 153 | " Volume \n", 154 | "Date \n", 155 | "2018-01-02 25555900 \n", 156 | "2018-01-03 29517900 \n", 157 | "2018-01-04 22434600 \n", 158 | "2018-01-05 23660000 \n", 159 | "2018-01-08 20567800 " 160 | ] 161 | }, 162 | "metadata": {} 163 | } 164 | ], 165 | "execution_count": 2, 166 | "metadata": { 167 | "collapsed": false, 168 | "outputHidden": false, 169 | "inputHidden": false 170 | } 171 | }, 172 | { 173 | "cell_type": "code", 174 | "source": [ 175 | "df.tail()" 176 | ], 177 | "outputs": [ 178 | { 179 | "output_type": "execute_result", 180 | "execution_count": 3, 181 | "data": { 182 | "text/html": [ 183 | "
\n", 184 | "\n", 197 | "\n", 198 | " \n", 199 | " \n", 200 | " \n", 201 | " \n", 202 | " \n", 203 | " \n", 204 | " \n", 205 | " \n", 206 | " \n", 207 | " \n", 208 | " \n", 209 | " \n", 210 | " \n", 211 | " \n", 212 | " \n", 213 | " \n", 214 | " \n", 215 | " \n", 216 | " \n", 217 | " \n", 218 | " \n", 219 | " \n", 220 | " \n", 221 | " \n", 222 | " \n", 223 | " \n", 224 | " \n", 225 | " \n", 226 | " \n", 227 | " \n", 228 | " \n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " \n", 250 | " \n", 251 | " \n", 252 | " \n", 253 | " \n", 254 | " \n", 255 | " \n", 256 | " \n", 257 | " \n", 258 | " \n", 259 | " \n", 260 | " \n", 261 | " \n", 262 | " \n", 263 | " \n", 264 | " \n", 265 | "
OpenHighLowCloseAdj CloseVolume
Date
2019-01-25155.479996158.130005154.320007157.759995157.08628833535500
2019-01-28155.789993156.330002153.660004156.300003155.63252326192100
2019-01-29156.250000158.130005154.110001154.679993154.01944041587200
2019-01-30163.250000166.149994160.229996165.250000164.54429661109800
2019-01-31166.110001169.000000164.559998166.440002165.72921840739600
\n", 266 | "
" 267 | ], 268 | "text/plain": [ 269 | " Open High Low Close Adj Close \\\n", 270 | "Date \n", 271 | "2019-01-25 155.479996 158.130005 154.320007 157.759995 157.086288 \n", 272 | "2019-01-28 155.789993 156.330002 153.660004 156.300003 155.632523 \n", 273 | "2019-01-29 156.250000 158.130005 154.110001 154.679993 154.019440 \n", 274 | "2019-01-30 163.250000 166.149994 160.229996 165.250000 164.544296 \n", 275 | "2019-01-31 166.110001 169.000000 164.559998 166.440002 165.729218 \n", 276 | "\n", 277 | " Volume \n", 278 | "Date \n", 279 | "2019-01-25 33535500 \n", 280 | "2019-01-28 26192100 \n", 281 | "2019-01-29 41587200 \n", 282 | "2019-01-30 61109800 \n", 283 | "2019-01-31 40739600 " 284 | ] 285 | }, 286 | "metadata": {} 287 | } 288 | ], 289 | "execution_count": 3, 290 | "metadata": { 291 | "collapsed": false, 292 | "outputHidden": false, 293 | "inputHidden": false 294 | } 295 | }, 296 | { 297 | "cell_type": "code", 298 | "source": [ 299 | "# Create Data\n", 300 | "df['Open_Close'] = (df['Open'] - df['Adj Close'])/df['Open']\n", 301 | "df['High_Low'] = (df['High'] - df['Low'])/df['Low']\n", 302 | "df['Increase_Decrease'] = np.where(df['Volume'].shift(-1) > df['Volume'],1,0)\n", 303 | "df['Buy_Sell_on_Open'] = np.where(df['Open'].shift(-1) > df['Open'],1,0)\n", 304 | "df['Buy_Sell'] = np.where(df['Adj Close'].shift(-1) > df['Adj Close'],1,0)\n", 305 | "df['Returns'] = df['Adj Close'].pct_change()\n", 306 | "df = df.dropna()\n", 307 | "df.head()" 308 | ], 309 | "outputs": [ 310 | { 311 | "output_type": "execute_result", 312 | "execution_count": 4, 313 | "data": { 314 | "text/html": [ 315 | "
\n", 316 | "\n", 329 | "\n", 330 | " \n", 331 | " \n", 332 | " \n", 333 | " \n", 334 | " \n", 335 | " \n", 336 | " \n", 337 | " \n", 338 | " \n", 339 | " \n", 340 | " \n", 341 | " \n", 342 | " \n", 343 | " \n", 344 | " \n", 345 | " \n", 346 | " \n", 347 | " \n", 348 | " \n", 349 | " \n", 350 | " \n", 351 | " \n", 352 | " \n", 353 | " \n", 354 | " \n", 355 | " \n", 356 | " \n", 357 | " \n", 358 | " \n", 359 | " \n", 360 | " \n", 361 | " \n", 362 | " \n", 363 | " \n", 364 | " \n", 365 | " \n", 366 | " \n", 367 | " \n", 368 | " \n", 369 | " \n", 370 | " \n", 371 | " \n", 372 | " \n", 373 | " \n", 374 | " \n", 375 | " \n", 376 | " \n", 377 | " \n", 378 | " \n", 379 | " \n", 380 | " \n", 381 | " \n", 382 | " \n", 383 | " \n", 384 | " \n", 385 | " \n", 386 | " \n", 387 | " \n", 388 | " \n", 389 | " \n", 390 | " \n", 391 | " \n", 392 | " \n", 393 | " \n", 394 | " \n", 395 | " \n", 396 | " \n", 397 | " \n", 398 | " \n", 399 | " \n", 400 | " \n", 401 | " \n", 402 | " \n", 403 | " \n", 404 | " \n", 405 | " \n", 406 | " \n", 407 | " \n", 408 | " \n", 409 | " \n", 410 | " \n", 411 | " \n", 412 | " \n", 413 | " \n", 414 | " \n", 415 | " \n", 416 | " \n", 417 | " \n", 418 | " \n", 419 | " \n", 420 | " \n", 421 | " \n", 422 | " \n", 423 | " \n", 424 | " \n", 425 | " \n", 426 | " \n", 427 | " \n", 428 | " \n", 429 | " \n", 430 | " \n", 431 | " \n", 432 | " \n", 433 | " \n", 434 | " \n", 435 | " \n", 436 | " \n", 437 | " \n", 438 | " \n", 439 | "
OpenHighLowCloseAdj CloseVolumeOpen_CloseHigh_LowIncrease_DecreaseBuy_Sell_on_OpenBuy_SellReturns
Date
2018-01-03172.529999174.550003171.960007172.229996168.957886295179000.0207040.015062011-0.000174
2018-01-04172.539993173.470001172.080002173.029999169.742706224346000.0162120.0080781110.004645
2018-01-05173.440002175.369995173.050003175.000000171.675278236600000.0101750.0134060100.011385
2018-01-08174.350006175.610001173.929993174.350006171.037628205678000.0189980.009659110-0.003714
2018-01-09174.550003175.059998173.410004174.330002171.018005215840000.0202350.009515100-0.000115
\n", 440 | "
" 441 | ], 442 | "text/plain": [ 443 | " Open High Low Close Adj Close \\\n", 444 | "Date \n", 445 | "2018-01-03 172.529999 174.550003 171.960007 172.229996 168.957886 \n", 446 | "2018-01-04 172.539993 173.470001 172.080002 173.029999 169.742706 \n", 447 | "2018-01-05 173.440002 175.369995 173.050003 175.000000 171.675278 \n", 448 | "2018-01-08 174.350006 175.610001 173.929993 174.350006 171.037628 \n", 449 | "2018-01-09 174.550003 175.059998 173.410004 174.330002 171.018005 \n", 450 | "\n", 451 | " Volume Open_Close High_Low Increase_Decrease \\\n", 452 | "Date \n", 453 | "2018-01-03 29517900 0.020704 0.015062 0 \n", 454 | "2018-01-04 22434600 0.016212 0.008078 1 \n", 455 | "2018-01-05 23660000 0.010175 0.013406 0 \n", 456 | "2018-01-08 20567800 0.018998 0.009659 1 \n", 457 | "2018-01-09 21584000 0.020235 0.009515 1 \n", 458 | "\n", 459 | " Buy_Sell_on_Open Buy_Sell Returns \n", 460 | "Date \n", 461 | "2018-01-03 1 1 -0.000174 \n", 462 | "2018-01-04 1 1 0.004645 \n", 463 | "2018-01-05 1 0 0.011385 \n", 464 | "2018-01-08 1 0 -0.003714 \n", 465 | "2018-01-09 0 0 -0.000115 " 466 | ] 467 | }, 468 | "metadata": {} 469 | } 470 | ], 471 | "execution_count": 4, 472 | "metadata": { 473 | "collapsed": false, 474 | "outputHidden": false, 475 | "inputHidden": false 476 | } 477 | }, 478 | { 479 | "cell_type": "code", 480 | "source": [ 481 | "df.shape" 482 | ], 483 | "outputs": [ 484 | { 485 | "output_type": "execute_result", 486 | "execution_count": 5, 487 | "data": { 488 | "text/plain": [ 489 | "(271, 12)" 490 | ] 491 | }, 492 | "metadata": {} 493 | } 494 | ], 495 | "execution_count": 5, 496 | "metadata": { 497 | "collapsed": false, 498 | "outputHidden": false, 499 | "inputHidden": false 500 | } 501 | }, 502 | { 503 | "cell_type": "markdown", 504 | "source": [ 505 | "Dense is a layer of connected neurons.\n", 506 | "\n", 507 | "Loss Function is used to optimize the parameter values in a neural network model. Therefore, it measures squared or absolute error between a network's output and some target or desired output.\n", 508 | "\nOptimizer generates a new and improved values." 509 | ], 510 | "metadata": {} 511 | }, 512 | { 513 | "cell_type": "code", 514 | "source": [ 515 | "import tensorflow as tf\n", 516 | "from tensorflow import keras" 517 | ], 518 | "outputs": [], 519 | "execution_count": 6, 520 | "metadata": { 521 | "collapsed": false, 522 | "outputHidden": false, 523 | "inputHidden": false 524 | } 525 | }, 526 | { 527 | "cell_type": "code", 528 | "source": [ 529 | "model = tf.keras.Sequential([keras.layers.Dense(units=1, input_shape=[1])])\n", 530 | "model.compile(optimizer='sgd', loss='mean_squared_error')" 531 | ], 532 | "outputs": [], 533 | "execution_count": 7, 534 | "metadata": { 535 | "collapsed": false, 536 | "outputHidden": false, 537 | "inputHidden": false 538 | } 539 | }, 540 | { 541 | "cell_type": "code", 542 | "source": [ 543 | "X = np.array(df['Returns'], dtype = float) # Feature\n", 544 | "Y = np.array(df['Adj Close'], dtype = float) # Target" 545 | ], 546 | "outputs": [], 547 | "execution_count": 8, 548 | "metadata": { 549 | "collapsed": false, 550 | "outputHidden": false, 551 | "inputHidden": false 552 | } 553 | }, 554 | { 555 | "cell_type": "code", 556 | "source": [ 557 | "model.fit(X, Y, epochs=100)" 558 | ], 559 | "outputs": [ 560 | { 561 | "output_type": "stream", 562 | "name": "stdout", 563 | "text": [ 564 | "Epoch 1/100\n", 565 | "271/271 [==============================] - 0s 384us/step - loss: 29862.6151\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 566 | "Epoch 2/100\n", 567 | "271/271 [==============================] - 0s 18us/step - loss: 20882.1033\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 568 | "Epoch 3/100\n", 569 | "271/271 [==============================] - 0s 22us/step - loss: 14649.7054\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 570 | "Epoch 4/100\n", 571 | "271/271 [==============================] - 0s 18us/step - loss: 10321.6915\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 572 | "Epoch 5/100\n", 573 | "271/271 [==============================] - 0s 18us/step - loss: 7311.5090\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 574 | "Epoch 6/100\n", 575 | "271/271 [==============================] - 0s 18us/step - loss: 5232.4851\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 576 | "Epoch 7/100\n", 577 | "271/271 [==============================] - 0s 18us/step - loss: 3778.5427\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 578 | "Epoch 8/100\n", 579 | "271/271 [==============================] - 0s 15us/step - loss: 2781.6663\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 580 | "Epoch 9/100\n", 581 | "271/271 [==============================] - 0s 18us/step - loss: 2081.9986\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 582 | "Epoch 10/100\n", 583 | "271/271 [==============================] - 0s 18us/step - loss: 1600.5304\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 584 | "Epoch 11/100\n", 585 | "271/271 [==============================] - 0s 22us/step - loss: 1257.2099\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 586 | "Epoch 12/100\n", 587 | "271/271 [==============================] - 0s 18us/step - loss: 1016.9080\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 588 | "Epoch 13/100\n", 589 | "271/271 [==============================] - 0s 18us/step - loss: 852.8637\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 590 | "Epoch 14/100\n", 591 | "271/271 [==============================] - 0s 18us/step - loss: 740.1994\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 592 | "Epoch 15/100\n", 593 | "271/271 [==============================] - 0s 18us/step - loss: 660.6490\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 594 | "Epoch 16/100\n", 595 | "271/271 [==============================] - 0s 18us/step - loss: 606.1884\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 596 | "Epoch 17/100\n", 597 | "271/271 [==============================] - 0s 22us/step - loss: 567.5818\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 598 | "Epoch 18/100\n", 599 | "271/271 [==============================] - 0s 22us/step - loss: 541.5006\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 600 | "Epoch 19/100\n", 601 | "271/271 [==============================] - 0s 22us/step - loss: 521.9415\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 602 | "Epoch 20/100\n", 603 | "271/271 [==============================] - 0s 18us/step - loss: 509.4774\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 604 | "Epoch 21/100\n", 605 | "271/271 [==============================] - 0s 22us/step - loss: 500.3909\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 606 | "Epoch 22/100\n", 607 | "271/271 [==============================] - 0s 22us/step - loss: 494.6873\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 608 | "Epoch 23/100\n", 609 | "271/271 [==============================] - 0s 18us/step - loss: 490.1271\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 610 | "Epoch 24/100\n", 611 | "271/271 [==============================] - 0s 18us/step - loss: 486.9333\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 612 | "Epoch 25/100\n", 613 | "271/271 [==============================] - 0s 22us/step - loss: 485.0335\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 614 | "Epoch 26/100\n", 615 | "271/271 [==============================] - 0s 22us/step - loss: 483.2784\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 616 | "Epoch 27/100\n", 617 | "271/271 [==============================] - 0s 18us/step - loss: 482.5049\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 618 | "Epoch 28/100\n", 619 | "271/271 [==============================] - 0s 18us/step - loss: 482.2680\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 620 | "Epoch 29/100\n", 621 | "271/271 [==============================] - 0s 18us/step - loss: 481.4616\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 622 | "Epoch 30/100\n", 623 | "271/271 [==============================] - 0s 22us/step - loss: 481.1853\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 624 | "Epoch 31/100\n", 625 | "271/271 [==============================] - 0s 22us/step - loss: 480.9711\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 626 | "Epoch 32/100\n", 627 | "271/271 [==============================] - 0s 26us/step - loss: 480.9908\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 628 | "Epoch 33/100\n", 629 | "271/271 [==============================] - 0s 26us/step - loss: 480.7881\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 630 | "Epoch 34/100\n", 631 | "271/271 [==============================] - 0s 22us/step - loss: 480.8242\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 632 | "Epoch 35/100\n", 633 | "271/271 [==============================] - 0s 26us/step - loss: 480.9485\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 634 | "Epoch 36/100\n", 635 | "271/271 [==============================] - 0s 26us/step - loss: 480.4828\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 636 | "Epoch 37/100\n", 637 | "271/271 [==============================] - 0s 22us/step - loss: 480.5443\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 638 | "Epoch 38/100\n", 639 | "271/271 [==============================] - 0s 26us/step - loss: 480.7324\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 640 | "Epoch 39/100\n", 641 | "271/271 [==============================] - 0s 26us/step - loss: 480.4960\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 642 | "Epoch 40/100\n", 643 | "271/271 [==============================] - 0s 26us/step - loss: 480.3549\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 644 | "Epoch 41/100\n", 645 | "271/271 [==============================] - 0s 30us/step - loss: 480.6947\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 646 | "Epoch 42/100\n", 647 | "271/271 [==============================] - 0s 26us/step - loss: 480.3781\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 648 | "Epoch 43/100\n", 649 | "271/271 [==============================] - 0s 26us/step - loss: 480.4134\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 650 | "Epoch 44/100\n", 651 | "271/271 [==============================] - 0s 26us/step - loss: 480.2967\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 652 | "Epoch 45/100\n", 653 | "271/271 [==============================] - 0s 26us/step - loss: 480.3472\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 654 | "Epoch 46/100\n", 655 | "271/271 [==============================] - 0s 22us/step - loss: 480.3613\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 656 | "Epoch 47/100\n", 657 | "271/271 [==============================] - 0s 26us/step - loss: 480.5523\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 658 | "Epoch 48/100\n", 659 | "271/271 [==============================] - 0s 30us/step - loss: 480.8593\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 660 | "Epoch 49/100\n", 661 | "271/271 [==============================] - 0s 22us/step - loss: 480.5211\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 662 | "Epoch 50/100\n", 663 | "271/271 [==============================] - 0s 22us/step - loss: 480.4001\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 664 | "Epoch 51/100\n", 665 | "271/271 [==============================] - 0s 22us/step - loss: 480.4453\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 666 | "Epoch 52/100\n", 667 | "271/271 [==============================] - 0s 26us/step - loss: 480.3956\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 668 | "Epoch 53/100\n", 669 | "271/271 [==============================] - 0s 26us/step - loss: 480.3641\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 670 | "Epoch 54/100\n", 671 | "271/271 [==============================] - 0s 22us/step - loss: 480.5318\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 672 | "Epoch 55/100\n", 673 | "271/271 [==============================] - 0s 22us/step - loss: 480.7172\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 674 | "Epoch 56/100\n", 675 | "271/271 [==============================] - 0s 26us/step - loss: 480.2990\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 676 | "Epoch 57/100\n", 677 | "271/271 [==============================] - 0s 22us/step - loss: 480.2599\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 678 | "Epoch 58/100\n", 679 | "271/271 [==============================] - 0s 22us/step - loss: 480.8522\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 680 | "Epoch 59/100\n", 681 | "271/271 [==============================] - 0s 26us/step - loss: 480.4668\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 682 | "Epoch 60/100\n", 683 | "271/271 [==============================] - 0s 22us/step - loss: 480.4831\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 684 | "Epoch 61/100\n", 685 | "271/271 [==============================] - 0s 18us/step - loss: 480.5162\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 686 | "Epoch 62/100\n", 687 | "271/271 [==============================] - 0s 15us/step - loss: 480.5690\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 688 | "Epoch 63/100\n", 689 | "271/271 [==============================] - 0s 18us/step - loss: 480.5871\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 690 | "Epoch 64/100\n", 691 | "271/271 [==============================] - 0s 18us/step - loss: 480.3003\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 692 | "Epoch 65/100\n", 693 | "271/271 [==============================] - 0s 22us/step - loss: 480.3529\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 694 | "Epoch 66/100\n", 695 | "271/271 [==============================] - 0s 18us/step - loss: 480.7579\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 696 | "Epoch 67/100\n", 697 | "271/271 [==============================] - 0s 18us/step - loss: 480.3303\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 698 | "Epoch 68/100\n", 699 | "271/271 [==============================] - 0s 22us/step - loss: 480.3165\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 700 | "Epoch 69/100\n", 701 | "271/271 [==============================] - 0s 18us/step - loss: 480.5297\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 702 | "Epoch 70/100\n", 703 | "271/271 [==============================] - 0s 22us/step - loss: 480.3234\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 704 | "Epoch 71/100\n", 705 | "271/271 [==============================] - 0s 22us/step - loss: 480.2816\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 706 | "Epoch 72/100\n", 707 | "271/271 [==============================] - 0s 18us/step - loss: 480.2696\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 708 | "Epoch 73/100\n", 709 | "271/271 [==============================] - 0s 18us/step - loss: 480.5137\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 710 | "Epoch 74/100\n", 711 | "271/271 [==============================] - 0s 22us/step - loss: 480.2702\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 712 | "Epoch 75/100\n", 713 | "271/271 [==============================] - 0s 22us/step - loss: 480.3494\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 714 | "Epoch 76/100\n", 715 | "271/271 [==============================] - 0s 18us/step - loss: 480.3009\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 716 | "Epoch 77/100\n", 717 | "271/271 [==============================] - 0s 18us/step - loss: 480.3443\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 718 | "Epoch 78/100\n", 719 | "271/271 [==============================] - 0s 18us/step - loss: 480.5458\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 720 | "Epoch 79/100\n", 721 | "271/271 [==============================] - 0s 22us/step - loss: 480.3715\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 722 | "Epoch 80/100\n", 723 | "271/271 [==============================] - 0s 18us/step - loss: 480.5095\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 724 | "Epoch 81/100\n", 725 | "271/271 [==============================] - 0s 18us/step - loss: 480.5246\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 726 | "Epoch 82/100\n", 727 | "271/271 [==============================] - 0s 18us/step - loss: 480.3587\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 728 | "Epoch 83/100\n", 729 | "271/271 [==============================] - 0s 18us/step - loss: 480.3945\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 730 | "Epoch 84/100\n", 731 | "271/271 [==============================] - 0s 18us/step - loss: 480.5273\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 732 | "Epoch 85/100\n", 733 | "271/271 [==============================] - 0s 18us/step - loss: 480.7397\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 734 | "Epoch 86/100\n", 735 | "271/271 [==============================] - 0s 18us/step - loss: 480.4097\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 736 | "Epoch 87/100\n", 737 | "271/271 [==============================] - 0s 18us/step - loss: 480.3180\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 738 | "Epoch 88/100\n", 739 | "271/271 [==============================] - 0s 15us/step - loss: 480.4787\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 740 | "Epoch 89/100\n", 741 | "271/271 [==============================] - 0s 18us/step - loss: 480.5264\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 742 | "Epoch 90/100\n", 743 | "271/271 [==============================] - 0s 18us/step - loss: 480.2346\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 744 | "Epoch 91/100\n", 745 | "271/271 [==============================] - 0s 18us/step - loss: 480.4207\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 746 | "Epoch 92/100\n", 747 | "271/271 [==============================] - 0s 18us/step - loss: 480.3832\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 748 | "Epoch 93/100\n", 749 | "271/271 [==============================] - 0s 18us/step - loss: 480.4108\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 750 | "Epoch 94/100\n", 751 | "271/271 [==============================] - 0s 18us/step - loss: 480.2546\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 752 | "Epoch 95/100\n", 753 | "271/271 [==============================] - 0s 18us/step - loss: 480.2427\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 754 | "Epoch 96/100\n", 755 | "271/271 [==============================] - 0s 22us/step - loss: 480.3454\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 756 | "Epoch 97/100\n", 757 | "271/271 [==============================] - 0s 22us/step - loss: 480.6622\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 758 | "Epoch 98/100\n", 759 | "271/271 [==============================] - 0s 18us/step - loss: 480.4723\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 760 | "Epoch 99/100\n", 761 | "271/271 [==============================] - 0s 18us/step - loss: 480.3588\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n", 762 | "Epoch 100/100\n", 763 | "271/271 [==============================] - 0s 18us/step - loss: 480.4675\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n" 764 | ] 765 | }, 766 | { 767 | "output_type": "execute_result", 768 | "execution_count": 9, 769 | "data": { 770 | "text/plain": [ 771 | "" 772 | ] 773 | }, 774 | "metadata": {} 775 | } 776 | ], 777 | "execution_count": 9, 778 | "metadata": { 779 | "collapsed": false, 780 | "outputHidden": false, 781 | "inputHidden": false 782 | } 783 | }, 784 | { 785 | "cell_type": "code", 786 | "source": [ 787 | "print(model.predict([0])) # Predict on open at 18.15, What the closing price prediction?" 788 | ], 789 | "outputs": [ 790 | { 791 | "output_type": "stream", 792 | "name": "stdout", 793 | "text": [ 794 | "[[ 184.52786255]]\n" 795 | ] 796 | } 797 | ], 798 | "execution_count": 10, 799 | "metadata": { 800 | "collapsed": false, 801 | "outputHidden": false, 802 | "inputHidden": false 803 | } 804 | }, 805 | { 806 | "cell_type": "markdown", 807 | "source": [ 808 | "If the values return nan. Therefore, we need to normalize the data." 809 | ], 810 | "metadata": {} 811 | }, 812 | { 813 | "cell_type": "code", 814 | "source": [ 815 | "from sklearn.preprocessing import MinMaxScaler\n", 816 | "\n", 817 | "scaler = MinMaxScaler()\n", 818 | "normalized_X = scaler.fit_transform(np.array(df['Returns']).reshape(271,-1))\n", 819 | "X = np.array(normalized_X, dtype = float)\n", 820 | "normalized_Y = scaler.fit_transform(np.array(df['Adj Close']).reshape(271,-1))\n", 821 | "Y = np.array(normalized_Y, dtype = float)" 822 | ], 823 | "outputs": [], 824 | "execution_count": 11, 825 | "metadata": { 826 | "collapsed": false, 827 | "outputHidden": false, 828 | "inputHidden": false 829 | } 830 | }, 831 | { 832 | "cell_type": "code", 833 | "source": [ 834 | "print(X.shape)\n", 835 | "print(Y.shape)" 836 | ], 837 | "outputs": [ 838 | { 839 | "output_type": "stream", 840 | "name": "stdout", 841 | "text": [ 842 | "(271, 1)\n", 843 | "(271, 1)\n" 844 | ] 845 | } 846 | ], 847 | "execution_count": 12, 848 | "metadata": { 849 | "collapsed": false, 850 | "outputHidden": false, 851 | "inputHidden": false 852 | } 853 | }, 854 | { 855 | "cell_type": "code", 856 | "source": [ 857 | "def build_model():\n", 858 | " model = keras.Sequential([\n", 859 | " layers.Dense(64, activation=tf.nn.relu, input_shape=[len(train_dataset.keys())]),\n", 860 | " layers.Dense(64, activation=tf.nn.relu),\n", 861 | " layers.Dense(1)\n", 862 | " ])\n", 863 | "\n", 864 | " optimizer = tf.keras.optimizers.RMSprop(0.001)\n", 865 | "\n", 866 | " model.compile(loss='mean_squared_error',\n", 867 | " optimizer=optimizer,\n", 868 | " metrics=['mean_absolute_error', 'mean_squared_error'])\n", 869 | " return model" 870 | ], 871 | "outputs": [], 872 | "execution_count": 13, 873 | "metadata": { 874 | "collapsed": false, 875 | "outputHidden": false, 876 | "inputHidden": false 877 | } 878 | }, 879 | { 880 | "cell_type": "code", 881 | "source": [ 882 | "# Still have nan\n", 883 | "print(model.predict([0])) # Predict on open at 18.15, What the closing price prediction?" 884 | ], 885 | "outputs": [ 886 | { 887 | "output_type": "stream", 888 | "name": "stdout", 889 | "text": [ 890 | "[[ 184.52786255]]\n" 891 | ] 892 | } 893 | ], 894 | "execution_count": 14, 895 | "metadata": { 896 | "collapsed": false, 897 | "outputHidden": false, 898 | "inputHidden": false 899 | } 900 | } 901 | ], 902 | "metadata": { 903 | "kernel_info": { 904 | "name": "python3" 905 | }, 906 | "language_info": { 907 | "codemirror_mode": { 908 | "version": 3, 909 | "name": "ipython" 910 | }, 911 | "mimetype": "text/x-python", 912 | "name": "python", 913 | "pygments_lexer": "ipython3", 914 | "nbconvert_exporter": "python", 915 | "file_extension": ".py", 916 | "version": "3.5.5" 917 | }, 918 | "kernelspec": { 919 | "name": "python3", 920 | "language": "python", 921 | "display_name": "Python 3" 922 | }, 923 | "nteract": { 924 | "version": "0.12.2" 925 | } 926 | }, 927 | "nbformat": 4, 928 | "nbformat_minor": 4 929 | } 930 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 LastAncientOne 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Python_01_Dowload__YahooData.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Fri Nov 27 08:09:11 2020 4 | 5 | @author: Tin 6 | """ 7 | # Download stock historical data from Yahoo Finance 8 | 9 | import yfinance as yf 10 | yf.pdr_override() 11 | 12 | 13 | # input 14 | symbol = 'AAPL' 15 | start = '2014-01-01' 16 | end = '2018-01-01' 17 | 18 | 19 | # dataframe 20 | df = yf.download(symbol,start,end) 21 | 22 | # View the first 5 rows 23 | print('First 5 Rows') 24 | print(df.head()) 25 | print('-'*80) 26 | 27 | # View the last 5 rows 28 | print('Last 5 Rows') 29 | print(df.tail()) -------------------------------------------------------------------------------- /Python_02_Modify_Date.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Fri Nov 27 08:09:11 2020 4 | 5 | @author: Tin 6 | """ 7 | # Modify Yahoo Dataframe Date 8 | import pandas as pd # Dataframe Library 9 | pd.set_option('max_columns', None) # To show all columns 10 | 11 | import yfinance as yf 12 | yf.pdr_override() 13 | 14 | 15 | # input 16 | symbol = 'AAPL' 17 | start = '2014-01-01' 18 | end = '2018-01-01' 19 | 20 | 21 | # dataframe 22 | data = yf.download(symbol,start,end) 23 | 24 | # View the first 5 rows 25 | print('First 5 Rows') 26 | print(data.head()) 27 | print('-'*80) 28 | 29 | 30 | # Date becomes a columns 31 | df = data.copy() # Copy the original data 32 | dfn = df.reset_index() 33 | print(dfn.head()) 34 | print('-'*80) 35 | 36 | 37 | # Add Year, Month, Day 38 | df['Year'] = df.index.year 39 | df['Month'] = df.index.month 40 | df['Day'] = df.index.day 41 | print('Year, Month, & Day') 42 | print(df.head()) 43 | print('-'*80) 44 | 45 | 46 | # Convert Daily to Weekly 47 | weekly = data.copy() 48 | weekly = weekly.resample('W').last() 49 | print('Weekly Data') 50 | print(weekly.head()) 51 | print('-'*80) 52 | 53 | 54 | # Convert Daily to Monthly 55 | monthly = data.copy() 56 | monthly = monthly.resample('1M').mean() 57 | print('Monthly Data') 58 | print(monthly.head()) 59 | print('-'*80) 60 | 61 | 62 | # Choose Particular Year to analyze 63 | monthly = data.copy() 64 | monthly = monthly.reset_index() 65 | y2017 = monthly[monthly['Date'].dt.year==2017] 66 | print("Analyze Particular Year in Historical Data") 67 | print(y2017) 68 | print('-'*80) 69 | 70 | 71 | month_name = data.copy() 72 | # Convert Daily to Monthly 73 | # 'BMS', which stands for "business month start frequency" 74 | # 'BM', which stands for "business month end frequency" 75 | month_name = month_name.asfreq('BM') 76 | print('Number of the Month') 77 | print(month_name.head()) 78 | print('-'*80) 79 | 80 | 81 | import calendar 82 | month_name['Month_Number'] = month_name.index.month 83 | month_name['Month_ABBR'] = month_name['Month_Number'].apply(lambda x: calendar.month_abbr[x]) 84 | print('Abbreviation for Months') 85 | print(month_name.head()) 86 | print('-'*80) 87 | 88 | 89 | print('Month Name') 90 | month_name['Month_Name'] = month_name['Month_Number'].apply(lambda x: calendar.month_name[x]) 91 | print(month_name.head()) 92 | print('-'*80) 93 | 94 | 95 | # Pivot Table Date 96 | df_months = pd.pivot_table(df, index=df.index.month, columns=df.index.year, values = 'Adj Close') # each months 97 | print('Year by Year') 98 | print(df_months) 99 | print('-'*80) 100 | 101 | 102 | df_days = pd.pivot_table(df, index=df.index.day, columns=df.index.year, values = 'Adj Close') # daily for one whole months 103 | print('Year by Year in daily rows') 104 | print(df_days) 105 | print('-'*80) 106 | 107 | 108 | df_all_columns = pd.pivot_table(df, index=df.index.month, columns=df.index.year) 109 | print('All columns in yearly') 110 | print(df_all_columns) 111 | print('-'*80) 112 | 113 | 114 | stock_data = df.copy() 115 | stock_data['Year'] = df.index.year 116 | stock_data['Month'] = df.index.month 117 | stock_data['Day'] = df.index.day 118 | stock_data['Week_Day'] = df.index.dayofweek 119 | stock_data['Week_Day_Name'] = df.index.strftime('%A') 120 | print('Number of day with M-F') 121 | print(stock_data.tail(10)) 122 | print('-'*80) 123 | 124 | 125 | approach1 = stock_data.groupby(['Year', 'Month']).first()['Adj Close'] 126 | print('# of Month') 127 | print(approach1.tail(12)) 128 | print('-'*80) 129 | 130 | 131 | approach2 = stock_data.groupby(['Year', 'Day']).first()['Adj Close'] 132 | print('# of Day') 133 | print(approach2.tail(12)) 134 | print('-'*80) 135 | 136 | 137 | print('Convert Date to String') 138 | string_date = data.copy() 139 | string_date['Date'] = string_date.index 140 | print(string_date.head()) 141 | print('-'*80) 142 | 143 | 144 | string_date['Date'] = string_date['Date'].dt.strftime("%Y%m%d").astype(int) 145 | print('Convert Date to Numbers') 146 | print(string_date.head()) 147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /Python_03_save_csv.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Fri Dec 4 18:55:42 2020 4 | 5 | @author: Tin 6 | """ 7 | # Save Data to CSV 8 | import warnings 9 | warnings.filterwarnings("ignore") 10 | 11 | import yfinance as yf 12 | yf.pdr_override() 13 | 14 | # input 15 | symbol = 'AMD' 16 | start = '2014-01-01' 17 | end = '2019-01-01' 18 | 19 | # Read data 20 | data = yf.download(symbol,start,end) 21 | 22 | # Output data into CSV 23 | # To save in your certain folder, change the Users name 24 | data.to_csv("C:/Users/Finance/Desktop/AMD.csv") 25 | 26 | 27 | 28 | symbols = ['PFE','TGT','MA','UNH','VZ','V','WMT','GS'] 29 | start = '2014-01-11' 30 | end = '2019-01-01' 31 | stocks_info = yf.download(symbols, start, end)['Adj Close'] 32 | stocks_data = stocks_info.iloc[::] 33 | print(stocks_data) 34 | 35 | # Output data into CSV 36 | stocks_data.to_csv("C:/Users/Finance/Desktop/stocks_data.csv") 37 | -------------------------------------------------------------------------------- /Python_04_Plot_Charts.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Fri Nov 27 08:09:11 2020 4 | 5 | @author: Tin 6 | """ 7 | # Plot Line Charts 8 | import pandas as pd # Dataframe Library 9 | import matplotlib.pyplot as plt # Plot Chart Library 10 | 11 | pd.set_option('max_columns', None) # To show all columns 12 | 13 | import yfinance as yf 14 | yf.pdr_override() 15 | 16 | 17 | # input 18 | symbol = 'AAPL' 19 | start = '2014-01-01' 20 | end = '2018-01-01' 21 | 22 | 23 | # dataframe 24 | data = yf.download(symbol,start,end) 25 | 26 | # View the first 5 rows 27 | print('First 5 Rows') 28 | print(data.head()) 29 | print('-'*80) 30 | 31 | print('Line Chart') 32 | plt.figure(figsize=(12,8)) 33 | plt.plot(data['Adj Close']) 34 | plt.title("Stock Line Chart") 35 | plt.legend(loc='best') 36 | plt.xlabel("Date") 37 | plt.ylabel("Price") 38 | plt.show() 39 | print('-'*80) 40 | 41 | 42 | print('Line Chart with Grid') 43 | plt.figure(figsize=(12,8)) 44 | plt.plot(data['Adj Close']) 45 | plt.title("Stock Line Chart") 46 | plt.grid() 47 | plt.legend(loc='best') 48 | plt.xlabel("Date") 49 | plt.ylabel("Price") 50 | plt.show() 51 | print('-'*80) 52 | 53 | 54 | print('Render the grid') 55 | fig, ax = plt.subplots() 56 | data.plot(kind='line', y= 'Adj Close', ax=ax) 57 | # Turn on the grid 58 | ax.grid() 59 | plt.title("Stock Line Chart") 60 | plt.legend(loc='best') 61 | plt.xlabel("Date") 62 | plt.ylabel("Price") 63 | plt.show() 64 | print('-'*80) 65 | 66 | 67 | print('Customize the grid') 68 | fig, ax = plt.subplots() 69 | data.plot(kind='line', y= 'Adj Close', ax=ax) 70 | # Don't allow the axis to be on top of your data 71 | ax.set_axisbelow(True) 72 | # Customize the grid 73 | ax.grid(linestyle='-', linewidth='0.5', color='red') 74 | plt.title("Stock Line Chart") 75 | plt.xlabel("Date") 76 | plt.ylabel("Price") 77 | plt.show() 78 | print('-'*80) 79 | 80 | 81 | print('Major grid & Minor Grid') 82 | plt.figure(figsize=(12,8)) 83 | plt.plot(data['Adj Close']) 84 | plt.minorticks_on() 85 | plt.grid(b=True, which='major', color='b', linestyle='-') 86 | plt.grid(b=True, which='minor', color='r', linestyle='--') 87 | plt.title("Stock Line Chart") 88 | plt.xlabel("Date") 89 | plt.ylabel("Price") 90 | plt.show() 91 | print('-'*80) 92 | 93 | 94 | import seaborn as sns # Plot Library 0.9.0 Version 95 | # conda install -c anaconda seaborn=0.9.0 96 | plt.figure(figsize=(10,5)) 97 | sns.lineplot(data=data, x=data.index, y='Adj Close') 98 | print('-'*80) 99 | 100 | plt.figure(figsize=(10,5)) 101 | top = plt.subplot2grid((4,4), (0, 0), rowspan=3, colspan=4) 102 | bottom = plt.subplot2grid((4,4), (3,0), rowspan=1, colspan=4) 103 | top.plot(data.index, data['Adj Close']) 104 | bottom.bar(data.index, data['Volume']) 105 | 106 | # set the labels 107 | top.axes.get_xaxis().set_visible(False) 108 | top.set_title('Stock Price and Volume') 109 | top.set_ylabel('Adj Closing Price') 110 | bottom.set_ylabel('Volume') 111 | print('-'*80) 112 | 113 | 114 | # Candlestick 115 | from mpl_finance import candlestick_ohlc 116 | from matplotlib import dates as mdates 117 | 118 | # Converting date to pandas datetime format 119 | dfc = data.copy() 120 | dfc = dfc.reset_index() 121 | dfc['Date'] = pd.to_datetime(dfc['Date']) 122 | dfc['Date'] = dfc['Date'].apply(mdates.date2num) 123 | # dfc.head() 124 | 125 | fig = plt.figure(figsize=(14,10)) 126 | ax1 = plt.subplot(2, 1, 1) 127 | candlestick_ohlc(ax1,dfc.values, width=0.5, colorup='g', colordown='r', alpha=1.0) 128 | ax1.xaxis_date() 129 | ax1.xaxis.set_major_formatter(mdates.DateFormatter('%d-%m-%Y')) 130 | ax1.set_title('Stock '+ symbol +' Closing Price') 131 | ax1.set_ylabel('Price') 132 | 133 | 134 | 135 | 136 | import plotly.graph_objs as go 137 | # from plotly.offline import init_notebook_mode, iplot 138 | 139 | df = data.copy() 140 | # Plot OHLC Bar Chart 141 | trace = go.Ohlc(x=df['12-2016'].index, 142 | open=df['12-2016'].Open, 143 | high=df['12-2016'].High, 144 | low=df['12-2016'].Low, 145 | close=df['12-2016'].Close) 146 | data = [trace] 147 | iplot(data, filename='simple_ohlc') 148 | -------------------------------------------------------------------------------- /Python_05_Plot_Area.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Fri Nov 27 08:09:11 2020 4 | 5 | @author: Tin 6 | """ 7 | # Plot Area Chart 8 | import matplotlib.pyplot as plt 9 | import pandas as pd 10 | 11 | pd.set_option('max_columns', None) # To show all columns 12 | 13 | import yfinance as yf 14 | yf.pdr_override() 15 | 16 | 17 | # input 18 | symbol = 'AAPL' 19 | start = '2019-01-01' 20 | end = '2020-01-01' 21 | 22 | 23 | # dataframe 24 | data = yf.download(symbol,start,end) 25 | 26 | print('Plot Histogram Chart') 27 | plt.figure(figsize=(12,8)) 28 | data['Adj Close'].plot.area() 29 | plt.title("Stock Area Chart") 30 | plt.xlabel("Date") 31 | plt.ylabel("Price") 32 | plt.show() 33 | 34 | 35 | data[['Open','High','Low','Adj Close']].plot.area(stacked=False) 36 | plt.title("Stock Area Chart") 37 | plt.xlabel("Date") 38 | plt.ylabel("Price") 39 | plt.legend(loc='best') 40 | plt.show() -------------------------------------------------------------------------------- /Python_06_Plot_Scatter_Line.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Fri Nov 27 08:09:11 2020 4 | 5 | @author: Tin 6 | """ 7 | # Plot Scatter & Line Chart 8 | import pandas as pd # Dataframe Library 9 | import matplotlib.pyplot as plt # Plot Chart Library 10 | 11 | pd.set_option('max_columns', None) # To show all columns 12 | 13 | import yfinance as yf 14 | yf.pdr_override() 15 | 16 | 17 | # input 18 | symbol = 'AAPL' 19 | start = '2019-12-01' 20 | end = '2020-01-01' 21 | 22 | 23 | # dataframe 24 | data = yf.download(symbol,start,end) 25 | 26 | plt.figure(figsize=(14,8)) 27 | plt.scatter(data.index, data['Adj Close'], color='black') 28 | plt.plot(data.index, data['Adj Close'], color='r') 29 | plt.title("Stock Scatter & Line Chart") 30 | plt.xlabel("Date") 31 | plt.ylabel("Price") 32 | plt.show() -------------------------------------------------------------------------------- /Python_07_Plot_Histogram.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Fri Nov 27 08:09:11 2020 4 | 5 | @author: Tin 6 | """ 7 | # Plot Histogram Chart 8 | import matplotlib.pyplot as plt 9 | import yfinance as yf 10 | yf.pdr_override() 11 | 12 | 13 | # input 14 | symbol = 'AAPL' 15 | start = '2019-01-01' 16 | end = '2020-01-01' 17 | 18 | 19 | # dataframe 20 | data = yf.download(symbol,start,end) 21 | 22 | plt.figure(figsize=(14,10)) 23 | plt.bar(data.index, data['Adj Close']) 24 | plt.title("Stock Histogram Chart") 25 | plt.xlabel("Date") 26 | plt.ylabel("Price") 27 | plt.show() 28 | 29 | -------------------------------------------------------------------------------- /Python_08_Plot_Boxplot.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Fri Nov 27 08:09:11 2020 4 | 5 | @author: Tin 6 | """ 7 | # Plot Boxplot Chart 8 | import pandas as pd # Dataframe Library 9 | import matplotlib.pyplot as plt # Plot Chart Library 10 | 11 | pd.set_option('max_columns', None) # To show all columns 12 | 13 | import yfinance as yf 14 | yf.pdr_override() 15 | 16 | 17 | # input 18 | symbol = 'AAPL' 19 | start = '2019-12-01' 20 | end = '2020-01-01' 21 | 22 | 23 | # dataframe 24 | data = yf.download(symbol,start,end) 25 | 26 | plt.figure(figsize=(14,8)) 27 | plt.boxplot(data['Adj Close']) 28 | plt.xlabel("Month of December") 29 | plt.ylabel("Price") 30 | plt.show() -------------------------------------------------------------------------------- /Python_09_Plot_Candlestick.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Fri Nov 27 08:09:11 2020 4 | 5 | @author: Tin 6 | """ 7 | # Plot Candlestick in Matplotlib 8 | import pandas as pd # Dataframe Library 9 | import matplotlib.pyplot as plt # Plot Chart Library 10 | 11 | pd.set_option('max_columns', None) # To show all columns 12 | 13 | import yfinance as yf 14 | yf.pdr_override() 15 | 16 | 17 | # input 18 | symbol = 'AAPL' 19 | start = '2019-01-01' 20 | end = '2020-01-01' 21 | 22 | 23 | # dataframe 24 | data = yf.download(symbol,start,end) 25 | 26 | data['VolumePositive'] = data['Open'] < data['Adj Close'] 27 | 28 | print('Line Chart') 29 | fig = plt.figure(figsize=(14,10)) 30 | ax1 = plt.subplot(3, 1, 1) 31 | ax1.plot(data['Adj Close']) 32 | ax1.set_title('Stock '+ symbol +' Closing Price') 33 | ax1.set_ylabel('Price') 34 | ax1.legend(loc='best') 35 | 36 | ax2 = plt.subplot(3, 1, 2) 37 | ax2.plot(data['Volume'], label='Volume') 38 | ax2.grid() 39 | ax2.legend(loc='best') 40 | ax2.set_ylabel('Volume') 41 | 42 | ax3 = plt.subplot(3, 1, 3) 43 | ax3v = ax3.twinx() 44 | colors = data.VolumePositive.map({True: 'g', False: 'r'}) 45 | ax3v.bar(data.index, data['Volume'], color=colors, alpha=0.4) 46 | ax3.set_ylabel('Volume') 47 | ax3.grid() 48 | ax3.set_xlabel('Date') 49 | 50 | 51 | # Candlestick 52 | print('Candlestick') 53 | from matplotlib import dates as mdates 54 | dfc = data.copy() 55 | dfc['VolumePositive'] = dfc['Open'] < dfc['Adj Close'] 56 | #dfc = dfc.dropna() 57 | dfc = dfc.reset_index() 58 | dfc['Date'] = pd.to_datetime(dfc['Date']) 59 | dfc['Date'] = dfc['Date'].apply(mdates.date2num) 60 | dfc.head() 61 | 62 | from mpl_finance import candlestick_ohlc 63 | 64 | fig = plt.figure(figsize=(14,10)) 65 | ax1 = plt.subplot(3, 1, 1) 66 | candlestick_ohlc(ax1,dfc.values, width=0.5, colorup='g', colordown='r', alpha=1.0) 67 | ax1.xaxis_date() 68 | ax1.xaxis.set_major_formatter(mdates.DateFormatter('%d-%m-%Y')) 69 | ax1.grid(True, which='both') 70 | ax1.minorticks_on() 71 | ax1v = ax1.twinx() 72 | colors = dfc.VolumePositive.map({True: 'g', False: 'r'}) 73 | ax1v.bar(dfc.Date, dfc['Volume'], color=colors, alpha=0.4) 74 | ax1v.axes.yaxis.set_ticklabels([]) 75 | ax1v.set_ylim(0, 3*data.Volume.max()) 76 | ax1.set_title('Stock '+ symbol +' Closing Price') 77 | ax1.set_ylabel('Price') 78 | 79 | ax2 = plt.subplot(3, 1, 2) 80 | ax2.plot(data['Volume'], label='Volume') 81 | ax2.grid() 82 | ax2.legend(loc='best') 83 | ax2.set_ylabel('Volume') 84 | 85 | ax3 = plt.subplot(3, 1, 3) 86 | ax3v = ax3.twinx() 87 | colors = data.VolumePositive.map({True: 'g', False: 'r'}) 88 | ax3v.bar(data.index, data['Volume'], color=colors, alpha=0.4) 89 | ax3.set_ylabel('Volume') 90 | ax3.grid() 91 | ax3.set_xlabel('Date') 92 | -------------------------------------------------------------------------------- /Python_10_Plot_Bokeh_Candlestick.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Fri Nov 27 08:09:11 2020 4 | 5 | @author: Tin 6 | """ 7 | # Plot Candlestick in bokeh 8 | import pandas as pd # Dataframe Library 9 | from math import pi 10 | from bokeh.plotting import figure, show, output_file 11 | 12 | pd.set_option('max_columns', None) # To show all columns 13 | 14 | import yfinance as yf 15 | yf.pdr_override() 16 | 17 | 18 | # input 19 | symbol = 'AAPL' 20 | start = '2019-12-01' 21 | end = '2020-01-01' 22 | 23 | 24 | # dataframe 25 | df = yf.download(symbol,start,end) 26 | 27 | df["Date"] = pd.to_datetime(df.index) 28 | 29 | mids = (df['Open'] + df['Adj Close'])/2 30 | spans = abs(df['Adj Close']-df['Open']) 31 | 32 | inc = df['Adj Close'] > df['Open'] 33 | dec = df['Open'] > df['Adj Close'] 34 | w = 12*60*60*1000 # half day in ms 35 | 36 | TOOLS = "pan,wheel_zoom,box_zoom,reset,save" 37 | 38 | p = figure(x_axis_type="datetime", tools=TOOLS, plot_width=1000, title = symbol + " Candlestick") 39 | p.xaxis.major_label_orientation = pi/4 40 | p.grid.grid_line_alpha=0.3 41 | 42 | p.segment(df.Date, df.High, df.Date, df.Low, color="black") 43 | p.vbar(df.Date[inc], w, df.Open[inc], df['Adj Close'][inc], fill_color="#D5E1DD", line_color="black") 44 | p.vbar(df.Date[dec], w, df.Open[dec], df['Adj Close'][dec], fill_color="#F2583E", line_color="black") 45 | 46 | output_file("candlestick.html", title= symbol + " candlestick") 47 | 48 | show(p) # open a browser -------------------------------------------------------------------------------- /Python_11_scrape_yahoo_Key_Statistics.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Fri Dec 4 19:30:37 2020 4 | 5 | @author: Tin 6 | """ 7 | import pandas as pd 8 | import requests 9 | from bs4 import BeautifulSoup 10 | 11 | res = requests.get('https://finance.yahoo.com/quote/AMD/key-statistics?p=AMD') 12 | soup = BeautifulSoup(res.content,'lxml') 13 | table = soup.find_all('table')[0] 14 | df = pd.read_html(str(table))[0] 15 | 16 | print(df) -------------------------------------------------------------------------------- /Python_12_scrape_finance_news.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Fri Dec 4 19:30:37 2020 4 | 5 | @author: Tin 6 | """ 7 | # pip install newspaper3k 8 | import newspaper 9 | from newspaper import Article 10 | 11 | url = "https://finance.yahoo.com/" 12 | 13 | # download and parse article 14 | article = Article(url) 15 | article.download() 16 | article.parse() 17 | 18 | # print article text 19 | print(article.text) 20 | 21 | site = newspaper.build("https://finance.yahoo.com/") 22 | 23 | # get list of article URLs 24 | print(site.article_urls()) 25 | 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | [![Contributors][contributors-shield]][contributors-url] 3 | [![Forks][forks-shield]][forks-url] 4 | [![Stargazers][stars-shield]][stars-url] 5 | [![Issues][issues-shield]][issues-url] 6 | [![MIT License][license-shield]][license-url] 7 | [![LinkedIn][linkedin-shield]][linkedin-url] 8 | 9 | Buy Me A Coffee 10 | 11 | 12 | 13 | [contributors-shield]: https://img.shields.io/github/contributors/LastAncientOne/SimpleStockAnalysisPython.svg?style=for-the-badge 14 | [contributors-url]: https://github.com/LastAncientOne/SimpleStockAnalysisPython/graphs/contributors 15 | [forks-shield]: https://img.shields.io/github/forks/LastAncientOne/SimpleStockAnalysisPython.svg?style=for-the-badge 16 | [forks-url]: https://github.com/LastAncientOne/SimpleStockAnalysisPython/network/members 17 | [stars-shield]: https://img.shields.io/github/stars/LastAncientOne/SimpleStockAnalysisPython.svg?style=for-the-badge 18 | [stars-url]: https://github.com/LastAncientOne/SimpleStockAnalysisPython/stargazers 19 | [issues-shield]: https://img.shields.io/github/issues/LastAncientOne/SimpleStockAnalysisPython.svg?style=for-the-badge 20 | [issues-url]: https://github.com/LastAncientOne/SimpleStockAnalysisPython/issues 21 | [license-shield]: https://img.shields.io/github/license/LastAncientOne/SimpleStockAnalysisPython.svg?style=for-the-badge 22 | [license-url]: LICENSE 23 | [linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555 24 | [linkedin-url]: https://linkedin.com/in/tin-hang 25 | 26 | 27 | 28 | # Simple Stock Analysis in Python 29 | 30 | #### This is a tutorial on Simple Stock Analysis in Jupyter and Python. There are two versions of the tutorial available: one in Jupyter and the other in Python. Jupyter also provides Jupyter Notebooks, previously known as iPython notebooks. On the other hand, Python is an interpreted high-level programming language known for its simplicity and ease of understanding, especially for beginners interested in learning about stock analysis and becoming quants. This tutorial is designed for individuals who wish to learn Python coding for stock market analysis. However, if you already have knowledge in stock analysis or coding in Python, this tutorial may not be suitable for you. You can explore more advanced coding options here: https://github.com/LastAncientOne/Stock_Analysis_For_Quant. 31 | 32 | ### The order goes from #1 through #26. 33 | #### You learn the number 1 first, and then you proceed in order. Once you have finished, you will know how to write code in Python and understand finance and the stock market. :congratulations: 34 | 35 | ## Prerequistes 36 | Python 3.5+ 37 | Jupyter Notebook Python 3 38 | 39 | ## Dependencies 40 | * fix_yahoo_finance or yfinance 41 | * TensorFlow 1.10.0 42 | * Pandas 43 | * Numpy 44 | * ta-lib 45 | * matlibplot 46 | * sklearn 47 | 48 | 49 | ## How to install library 50 | ### conda install -c ranaroussi yfinance 51 | ### pip install yfinance --upgrade --no-cache-dir 52 | 53 | ### Input 54 | Pick a symbol, you want to analyze. 55 | 56 | ### symbol = '...' <-- ... input a symbol 57 | 58 | Pick a 'start' date and 'end' date for certain time frame to analyze. 59 | 60 | ### start = '...' & end = '...' <-- input a date 61 | ______________________________________________________________________________________________________________________________ 62 | ## Examples 63 | ```python 64 | # Libraries 65 | import numpy as np 66 | import pandas as pd 67 | import matplotlib.pyplot as plt 68 | 69 | import warnings 70 | warnings.filterwarnings("ignore") 71 | 72 | # fix_yahoo_finance is used to fetch data 73 | import fix_yahoo_finance as yf 74 | yf.pdr_override() 75 | 76 | # input 77 | symbol = 'AAPL' # Apple Company 78 | start = '2018-01-01' 79 | end = '2019-01-01' 80 | 81 | # Read data 82 | df = yf.download(symbol,start,end) 83 | 84 | # View Columns 85 | df.head() 86 | ``` 87 | 88 | ## Example Stock Charts: 89 | 90 | 91 | ## Example Stock Scripts 92 | In command DOS drive 'C:\ ' 93 | 94 | Find where you put the code .py in? 95 | 96 | How to run python scripts in command prompt(cmd) or Windows PowerShell? 97 | 98 | ### Type: python SimpleStockChartScripts.py 99 | 100 | ## 🍎 List of questions for simple stock tutorial in python: 101 | ______________________________________________________________________________________________________________________________ 102 | 1. How to get data from yahoo, quandl, or other sites? 103 | 2. How to scrape historical data, fundamental data, and news data? 104 | 3. How to analyze the stock data? 105 | 4. How to make a trendlines? 106 | 5. How to use Technical Analysis and Fundamental Analysis? 107 | 6. How to add and save to csv file? 108 | 7. How to customize table and make beautiful plot? 109 | 8. How to create class and function for stock? 110 | 9. How to create and run scripts? 111 | 10. How to applied statistics and timeseries for stock? 112 | 11. How to create buy and sell signals? 113 | 12. How to create stock prediction in machine learning and deep learning? 114 | 13. How to create simple stock strategy? 115 | 14. Example of python libraries for Technical Analysis and fetching historical stock prices. 116 | 117 | ______________________________________________________________________________________________________________________________ 118 | 119 | :x: If the code does not load or reload, click here: :point_right: https://nbviewer.jupyter.org/ 120 | Paste the link in the box. 121 | 122 | I tried to make it simple as possible to understand finance data and how to analyze the data by using python language. 123 | 124 | If you want to learn different simple function for stock analysis, go to: 125 | https://github.com/LastAncientOne/100_Day_Challenge 126 | 127 | If you want to learn more advance stock analysis or different language in finance, go to: 128 | https://github.com/LastAncientOne/Stock_Analysis_For_Quant 129 | 130 | If you into deep learning or machine learning for finance, go to: 131 | https://github.com/LastAncientOne/Deep-Learning-Machine-Learning-Stock 132 | 133 | If you want to learn about Mathematics behind deep learning or machine learning, go to: 134 | https://github.com/LastAncientOne/Mathematics_for_Machine_Learning 135 | 136 | ## Reading Material 137 | https://www.investopedia.com/terms/s/stock-analysis.asp (Basic Stock Analysis) 138 | 139 | https://www.investopedia.com/articles/investing/093014/stock-quotes-explained.asp (Understand Stock Data) 140 | 141 | https://www.investopedia.com/terms/t/trendline.asp (Understand Trendline) 142 | 143 | Buy Me A Coffee 144 | 145 | ## Authors 146 | ### Tin Hang 147 | 148 | ## Disclaimer 149 | 🔻 Do not use this code for investing or trading in the stock market. Stock market is unpredictable. :chart_with_upwards_trend: :chart_with_downwards_trend: However, if you are interest in the stock market, you should read many :books: books that relate to the stock market, investment, or finance. The more books you read, the more you will understand and the more knowledge you gain. On the other hand, if you are into quant or machine learning, read books about :blue_book: finance engineering, machine trading, algorithmic trading, and quantitative trading. 150 | 151 | ## This is not a get-rich-quick scheme; rather, it is intended for research and educational purposes. 152 | -------------------------------------------------------------------------------- /Title.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LastAncientOne/SimpleStockAnalysisPython/e02dca27e2772cb108f1e94edf7644957d20c8ca/Title.PNG -------------------------------------------------------------------------------- /candlestick.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | AAPL candlestick 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
38 | 39 | 40 | 41 | 42 | 43 | 46 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /stock_chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LastAncientOne/SimpleStockAnalysisPython/e02dca27e2772cb108f1e94edf7644957d20c8ca/stock_chart.png --------------------------------------------------------------------------------