├── 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 | " date | \n",
391 | " open | \n",
392 | " high | \n",
393 | " low | \n",
394 | " close | \n",
395 | " volume | \n",
396 | "
\n",
397 | " \n",
398 | " \n",
399 | " \n",
400 | " 0 | \n",
401 | " 1980-12-12 | \n",
402 | " 0.4164 | \n",
403 | " 0.4182 | \n",
404 | " 0.4164 | \n",
405 | " 0.4164 | \n",
406 | " 117258400 | \n",
407 | "
\n",
408 | " \n",
409 | " 1 | \n",
410 | " 1980-12-15 | \n",
411 | " 0.3966 | \n",
412 | " 0.3966 | \n",
413 | " 0.3947 | \n",
414 | " 0.3947 | \n",
415 | " 43971200 | \n",
416 | "
\n",
417 | " \n",
418 | " 2 | \n",
419 | " 1980-12-16 | \n",
420 | " 0.3675 | \n",
421 | " 0.3675 | \n",
422 | " 0.3657 | \n",
423 | " 0.3657 | \n",
424 | " 26432000 | \n",
425 | "
\n",
426 | " \n",
427 | " 3 | \n",
428 | " 1980-12-17 | \n",
429 | " 0.3747 | \n",
430 | " 0.3766 | \n",
431 | " 0.3747 | \n",
432 | " 0.3747 | \n",
433 | " 21610400 | \n",
434 | "
\n",
435 | " \n",
436 | " 4 | \n",
437 | " 1980-12-18 | \n",
438 | " 0.3857 | \n",
439 | " 0.3874 | \n",
440 | " 0.3857 | \n",
441 | " 0.3857 | \n",
442 | " 18362400 | \n",
443 | "
\n",
444 | " \n",
445 | "
\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 | " Open | \n",
94 | " High | \n",
95 | " Low | \n",
96 | " Close | \n",
97 | " Adj Close | \n",
98 | " Volume | \n",
99 | "
\n",
100 | " \n",
101 | " Date | \n",
102 | " | \n",
103 | " | \n",
104 | " | \n",
105 | " | \n",
106 | " | \n",
107 | " | \n",
108 | "
\n",
109 | " \n",
110 | " \n",
111 | " \n",
112 | " 2014-01-02 | \n",
113 | " 3.85 | \n",
114 | " 3.98 | \n",
115 | " 3.84 | \n",
116 | " 3.95 | \n",
117 | " 3.95 | \n",
118 | " 20548400 | \n",
119 | "
\n",
120 | " \n",
121 | " 2014-01-03 | \n",
122 | " 3.98 | \n",
123 | " 4.00 | \n",
124 | " 3.88 | \n",
125 | " 4.00 | \n",
126 | " 4.00 | \n",
127 | " 22887200 | \n",
128 | "
\n",
129 | " \n",
130 | " 2014-01-06 | \n",
131 | " 4.01 | \n",
132 | " 4.18 | \n",
133 | " 3.99 | \n",
134 | " 4.13 | \n",
135 | " 4.13 | \n",
136 | " 42398300 | \n",
137 | "
\n",
138 | " \n",
139 | " 2014-01-07 | \n",
140 | " 4.19 | \n",
141 | " 4.25 | \n",
142 | " 4.11 | \n",
143 | " 4.18 | \n",
144 | " 4.18 | \n",
145 | " 42932100 | \n",
146 | "
\n",
147 | " \n",
148 | " 2014-01-08 | \n",
149 | " 4.23 | \n",
150 | " 4.26 | \n",
151 | " 4.14 | \n",
152 | " 4.18 | \n",
153 | " 4.18 | \n",
154 | " 30678700 | \n",
155 | "
\n",
156 | " \n",
157 | "
\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 | " AAPL | \n",
278 | " AXP | \n",
279 | " BA | \n",
280 | " CAT | \n",
281 | " CSCO | \n",
282 | " CVX | \n",
283 | " DIS | \n",
284 | " GE | \n",
285 | " GS | \n",
286 | " HD | \n",
287 | " ... | \n",
288 | " MRK | \n",
289 | " NKE | \n",
290 | " PFE | \n",
291 | " PG | \n",
292 | " UNH | \n",
293 | " UTX | \n",
294 | " V | \n",
295 | " VZ | \n",
296 | " WMT | \n",
297 | " XOM | \n",
298 | "
\n",
299 | " \n",
300 | " Date | \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 | " 2001-01-11 | \n",
327 | " 0.860995 | \n",
328 | " 32.362038 | \n",
329 | " 39.449837 | \n",
330 | " 12.335097 | \n",
331 | " 31.130840 | \n",
332 | " 19.006382 | \n",
333 | " 23.236092 | \n",
334 | " 25.899675 | \n",
335 | " 90.825935 | \n",
336 | " 34.010456 | \n",
337 | " ... | \n",
338 | " 40.302208 | \n",
339 | " 2.427128 | \n",
340 | " 21.983341 | \n",
341 | " 20.644518 | \n",
342 | " 11.937548 | \n",
343 | " 23.863380 | \n",
344 | " NaN | \n",
345 | " 20.906065 | \n",
346 | " 36.973961 | \n",
347 | " 24.954866 | \n",
348 | "
\n",
349 | " \n",
350 | " 2001-01-12 | \n",
351 | " 0.822131 | \n",
352 | " 32.404297 | \n",
353 | " 40.450684 | \n",
354 | " 11.860015 | \n",
355 | " 30.285425 | \n",
356 | " 18.889679 | \n",
357 | " 24.860649 | \n",
358 | " 25.412958 | \n",
359 | " 89.387543 | \n",
360 | " 34.053780 | \n",
361 | " ... | \n",
362 | " 40.209618 | \n",
363 | " 2.371967 | \n",
364 | " 22.217928 | \n",
365 | " 19.952829 | \n",
366 | " 11.681551 | \n",
367 | " 22.833738 | \n",
368 | " NaN | \n",
369 | " 20.812313 | \n",
370 | " 37.685860 | \n",
371 | " 25.279213 | \n",
372 | "
\n",
373 | " \n",
374 | " 2001-01-16 | \n",
375 | " 0.819141 | \n",
376 | " 32.657772 | \n",
377 | " 40.700882 | \n",
378 | " 12.131493 | \n",
379 | " 30.633539 | \n",
380 | " 18.904276 | \n",
381 | " 26.042143 | \n",
382 | " 26.351603 | \n",
383 | " 90.415009 | \n",
384 | " 33.880470 | \n",
385 | " ... | \n",
386 | " 41.135406 | \n",
387 | " 2.340446 | \n",
388 | " 22.351967 | \n",
389 | " 20.413963 | \n",
390 | " 11.573761 | \n",
391 | " 22.914494 | \n",
392 | " NaN | \n",
393 | " 20.390440 | \n",
394 | " 38.931671 | \n",
395 | " 24.973944 | \n",
396 | "
\n",
397 | " \n",
398 | " 2001-01-17 | \n",
399 | " 0.804193 | \n",
400 | " 33.418255 | \n",
401 | " 39.199627 | \n",
402 | " 12.216325 | \n",
403 | " 31.031374 | \n",
404 | " 18.729233 | \n",
405 | " 26.288290 | \n",
406 | " 25.969193 | \n",
407 | " 90.415009 | \n",
408 | " 32.147453 | \n",
409 | " ... | \n",
410 | " 40.117039 | \n",
411 | " 2.345699 | \n",
412 | " 21.849302 | \n",
413 | " 20.113068 | \n",
414 | " 11.358186 | \n",
415 | " 23.298088 | \n",
416 | " NaN | \n",
417 | " 20.226379 | \n",
418 | " 38.397762 | \n",
419 | " 24.496984 | \n",
420 | "
\n",
421 | " \n",
422 | " 2001-01-18 | \n",
423 | " 0.893880 | \n",
424 | " 33.544987 | \n",
425 | " 38.282196 | \n",
426 | " 11.507934 | \n",
427 | " 33.318939 | \n",
428 | " 18.539610 | \n",
429 | " 26.091373 | \n",
430 | " 26.490675 | \n",
431 | " 88.456596 | \n",
432 | " 30.674391 | \n",
433 | " ... | \n",
434 | " 40.919392 | \n",
435 | " 2.356206 | \n",
436 | " 22.050377 | \n",
437 | " 20.292179 | \n",
438 | " 11.263871 | \n",
439 | " 23.600931 | \n",
440 | " NaN | \n",
441 | " 20.906065 | \n",
442 | " 37.774853 | \n",
443 | " 24.153563 | \n",
444 | "
\n",
445 | " \n",
446 | "
\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 | " Open | \n",
107 | " High | \n",
108 | " Low | \n",
109 | " Close | \n",
110 | " Adj Close | \n",
111 | " Volume | \n",
112 | "
\n",
113 | " \n",
114 | " Date | \n",
115 | " | \n",
116 | " | \n",
117 | " | \n",
118 | " | \n",
119 | " | \n",
120 | " | \n",
121 | "
\n",
122 | " \n",
123 | " \n",
124 | " \n",
125 | " 2018-01-02 | \n",
126 | " 10.42 | \n",
127 | " 11.02 | \n",
128 | " 10.34 | \n",
129 | " 10.98 | \n",
130 | " 10.98 | \n",
131 | " 44146300 | \n",
132 | "
\n",
133 | " \n",
134 | " 2018-01-03 | \n",
135 | " 11.61 | \n",
136 | " 12.14 | \n",
137 | " 11.36 | \n",
138 | " 11.55 | \n",
139 | " 11.55 | \n",
140 | " 154066700 | \n",
141 | "
\n",
142 | " \n",
143 | " 2018-01-04 | \n",
144 | " 12.10 | \n",
145 | " 12.43 | \n",
146 | " 11.97 | \n",
147 | " 12.12 | \n",
148 | " 12.12 | \n",
149 | " 109503000 | \n",
150 | "
\n",
151 | " \n",
152 | " 2018-01-05 | \n",
153 | " 12.19 | \n",
154 | " 12.22 | \n",
155 | " 11.66 | \n",
156 | " 11.88 | \n",
157 | " 11.88 | \n",
158 | " 63808900 | \n",
159 | "
\n",
160 | " \n",
161 | " 2018-01-08 | \n",
162 | " 12.01 | \n",
163 | " 12.30 | \n",
164 | " 11.85 | \n",
165 | " 12.28 | \n",
166 | " 12.28 | \n",
167 | " 63346000 | \n",
168 | "
\n",
169 | " \n",
170 | "
\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 | " Open | \n",
85 | " High | \n",
86 | " Low | \n",
87 | " Close | \n",
88 | " Adj Close | \n",
89 | " Volume | \n",
90 | "
\n",
91 | " \n",
92 | " Date | \n",
93 | " | \n",
94 | " | \n",
95 | " | \n",
96 | " | \n",
97 | " | \n",
98 | " | \n",
99 | "
\n",
100 | " \n",
101 | " \n",
102 | " \n",
103 | " 2018-01-02 | \n",
104 | " 10.42 | \n",
105 | " 11.02 | \n",
106 | " 10.34 | \n",
107 | " 10.98 | \n",
108 | " 10.98 | \n",
109 | " 44146300 | \n",
110 | "
\n",
111 | " \n",
112 | " 2018-01-03 | \n",
113 | " 11.61 | \n",
114 | " 12.14 | \n",
115 | " 11.36 | \n",
116 | " 11.55 | \n",
117 | " 11.55 | \n",
118 | " 154066700 | \n",
119 | "
\n",
120 | " \n",
121 | " 2018-01-04 | \n",
122 | " 12.10 | \n",
123 | " 12.43 | \n",
124 | " 11.97 | \n",
125 | " 12.12 | \n",
126 | " 12.12 | \n",
127 | " 109503000 | \n",
128 | "
\n",
129 | " \n",
130 | " 2018-01-05 | \n",
131 | " 12.19 | \n",
132 | " 12.22 | \n",
133 | " 11.66 | \n",
134 | " 11.88 | \n",
135 | " 11.88 | \n",
136 | " 63808900 | \n",
137 | "
\n",
138 | " \n",
139 | " 2018-01-08 | \n",
140 | " 12.01 | \n",
141 | " 12.30 | \n",
142 | " 11.85 | \n",
143 | " 12.28 | \n",
144 | " 12.28 | \n",
145 | " 63346000 | \n",
146 | "
\n",
147 | " \n",
148 | "
\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 | " Open | \n",
201 | " High | \n",
202 | " Low | \n",
203 | " Close | \n",
204 | " Adj Close | \n",
205 | " Volume | \n",
206 | "
\n",
207 | " \n",
208 | " \n",
209 | " \n",
210 | " count | \n",
211 | " 251.000000 | \n",
212 | " 251.000000 | \n",
213 | " 251.000000 | \n",
214 | " 251.000000 | \n",
215 | " 251.000000 | \n",
216 | " 2.510000e+02 | \n",
217 | "
\n",
218 | " \n",
219 | " mean | \n",
220 | " 17.209681 | \n",
221 | " 17.667610 | \n",
222 | " 16.729880 | \n",
223 | " 17.214502 | \n",
224 | " 17.214502 | \n",
225 | " 8.460868e+07 | \n",
226 | "
\n",
227 | " \n",
228 | " std | \n",
229 | " 6.202684 | \n",
230 | " 6.430476 | \n",
231 | " 5.912749 | \n",
232 | " 6.182515 | \n",
233 | " 6.182515 | \n",
234 | " 4.636185e+07 | \n",
235 | "
\n",
236 | " \n",
237 | " min | \n",
238 | " 9.080000 | \n",
239 | " 9.770000 | \n",
240 | " 9.040000 | \n",
241 | " 9.530000 | \n",
242 | " 9.530000 | \n",
243 | " 2.887510e+07 | \n",
244 | "
\n",
245 | " \n",
246 | " 25% | \n",
247 | " 12.005000 | \n",
248 | " 12.185000 | \n",
249 | " 11.710000 | \n",
250 | " 11.955000 | \n",
251 | " 11.955000 | \n",
252 | " 4.869910e+07 | \n",
253 | "
\n",
254 | " \n",
255 | " 50% | \n",
256 | " 16.180000 | \n",
257 | " 16.530001 | \n",
258 | " 15.780000 | \n",
259 | " 16.270000 | \n",
260 | " 16.270000 | \n",
261 | " 7.434780e+07 | \n",
262 | "
\n",
263 | " \n",
264 | " 75% | \n",
265 | " 20.150001 | \n",
266 | " 20.895001 | \n",
267 | " 19.574999 | \n",
268 | " 20.149999 | \n",
269 | " 20.149999 | \n",
270 | " 1.071805e+08 | \n",
271 | "
\n",
272 | " \n",
273 | " max | \n",
274 | " 33.180000 | \n",
275 | " 34.139999 | \n",
276 | " 32.189999 | \n",
277 | " 32.720001 | \n",
278 | " 32.720001 | \n",
279 | " 3.250584e+08 | \n",
280 | "
\n",
281 | " \n",
282 | "
\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 | " Open | \n",
95 | " High | \n",
96 | " Low | \n",
97 | " Close | \n",
98 | " Adj Close | \n",
99 | " Volume | \n",
100 | "
\n",
101 | " \n",
102 | " Date | \n",
103 | " | \n",
104 | " | \n",
105 | " | \n",
106 | " | \n",
107 | " | \n",
108 | " | \n",
109 | "
\n",
110 | " \n",
111 | " \n",
112 | " \n",
113 | " 2018-01-02 | \n",
114 | " 29.750000 | \n",
115 | " 29.900000 | \n",
116 | " 29.610001 | \n",
117 | " 29.900000 | \n",
118 | " 29.211069 | \n",
119 | " 57121600 | \n",
120 | "
\n",
121 | " \n",
122 | " 2018-01-03 | \n",
123 | " 29.900000 | \n",
124 | " 29.940001 | \n",
125 | " 29.690001 | \n",
126 | " 29.799999 | \n",
127 | " 29.113373 | \n",
128 | " 57865700 | \n",
129 | "
\n",
130 | " \n",
131 | " 2018-01-04 | \n",
132 | " 29.969999 | \n",
133 | " 30.440001 | \n",
134 | " 29.879999 | \n",
135 | " 30.190001 | \n",
136 | " 29.494387 | \n",
137 | " 76512500 | \n",
138 | "
\n",
139 | " \n",
140 | " 2018-01-05 | \n",
141 | " 30.370001 | \n",
142 | " 30.420000 | \n",
143 | " 30.049999 | \n",
144 | " 30.330000 | \n",
145 | " 29.631161 | \n",
146 | " 56445200 | \n",
147 | "
\n",
148 | " \n",
149 | " 2018-01-08 | \n",
150 | " 30.230000 | \n",
151 | " 30.270000 | \n",
152 | " 30.049999 | \n",
153 | " 30.120001 | \n",
154 | " 29.426003 | \n",
155 | " 42914800 | \n",
156 | "
\n",
157 | " \n",
158 | "
\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 | " Open | \n",
233 | " High | \n",
234 | " Low | \n",
235 | " Close | \n",
236 | " Adj Close | \n",
237 | " Volume | \n",
238 | " Returns | \n",
239 | "
\n",
240 | " \n",
241 | " Date | \n",
242 | " | \n",
243 | " | \n",
244 | " | \n",
245 | " | \n",
246 | " | \n",
247 | " | \n",
248 | " | \n",
249 | "
\n",
250 | " \n",
251 | " \n",
252 | " \n",
253 | " 2018-01-03 | \n",
254 | " 29.900000 | \n",
255 | " 29.940001 | \n",
256 | " 29.690001 | \n",
257 | " 29.799999 | \n",
258 | " 29.113373 | \n",
259 | " 57865700 | \n",
260 | " -0.003344 | \n",
261 | "
\n",
262 | " \n",
263 | " 2018-01-04 | \n",
264 | " 29.969999 | \n",
265 | " 30.440001 | \n",
266 | " 29.879999 | \n",
267 | " 30.190001 | \n",
268 | " 29.494387 | \n",
269 | " 76512500 | \n",
270 | " 0.013087 | \n",
271 | "
\n",
272 | " \n",
273 | " 2018-01-05 | \n",
274 | " 30.370001 | \n",
275 | " 30.420000 | \n",
276 | " 30.049999 | \n",
277 | " 30.330000 | \n",
278 | " 29.631161 | \n",
279 | " 56445200 | \n",
280 | " 0.004637 | \n",
281 | "
\n",
282 | " \n",
283 | " 2018-01-08 | \n",
284 | " 30.230000 | \n",
285 | " 30.270000 | \n",
286 | " 30.049999 | \n",
287 | " 30.120001 | \n",
288 | " 29.426003 | \n",
289 | " 42914800 | \n",
290 | " -0.006924 | \n",
291 | "
\n",
292 | " \n",
293 | " 2018-01-09 | \n",
294 | " 30.200001 | \n",
295 | " 30.540001 | \n",
296 | " 30.129999 | \n",
297 | " 30.270000 | \n",
298 | " 29.572544 | \n",
299 | " 69479100 | \n",
300 | " 0.004980 | \n",
301 | "
\n",
302 | " \n",
303 | "
\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 | " Open | \n",
78 | " High | \n",
79 | " Low | \n",
80 | " Close | \n",
81 | " Adj Close | \n",
82 | " Volume | \n",
83 | "
\n",
84 | " \n",
85 | " Date | \n",
86 | " | \n",
87 | " | \n",
88 | " | \n",
89 | " | \n",
90 | " | \n",
91 | " | \n",
92 | "
\n",
93 | " \n",
94 | " \n",
95 | " \n",
96 | " 2018-01-02 | \n",
97 | " 170.160004 | \n",
98 | " 172.300003 | \n",
99 | " 169.259995 | \n",
100 | " 172.259995 | \n",
101 | " 168.987320 | \n",
102 | " 25555900 | \n",
103 | "
\n",
104 | " \n",
105 | " 2018-01-03 | \n",
106 | " 172.529999 | \n",
107 | " 174.550003 | \n",
108 | " 171.960007 | \n",
109 | " 172.229996 | \n",
110 | " 168.957886 | \n",
111 | " 29517900 | \n",
112 | "
\n",
113 | " \n",
114 | " 2018-01-04 | \n",
115 | " 172.539993 | \n",
116 | " 173.470001 | \n",
117 | " 172.080002 | \n",
118 | " 173.029999 | \n",
119 | " 169.742706 | \n",
120 | " 22434600 | \n",
121 | "
\n",
122 | " \n",
123 | " 2018-01-05 | \n",
124 | " 173.440002 | \n",
125 | " 175.369995 | \n",
126 | " 173.050003 | \n",
127 | " 175.000000 | \n",
128 | " 171.675278 | \n",
129 | " 23660000 | \n",
130 | "
\n",
131 | " \n",
132 | " 2018-01-08 | \n",
133 | " 174.350006 | \n",
134 | " 175.610001 | \n",
135 | " 173.929993 | \n",
136 | " 174.350006 | \n",
137 | " 171.037628 | \n",
138 | " 20567800 | \n",
139 | "
\n",
140 | " \n",
141 | "
\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 | " Open | \n",
202 | " High | \n",
203 | " Low | \n",
204 | " Close | \n",
205 | " Adj Close | \n",
206 | " Volume | \n",
207 | "
\n",
208 | " \n",
209 | " Date | \n",
210 | " | \n",
211 | " | \n",
212 | " | \n",
213 | " | \n",
214 | " | \n",
215 | " | \n",
216 | "
\n",
217 | " \n",
218 | " \n",
219 | " \n",
220 | " 2019-01-25 | \n",
221 | " 155.479996 | \n",
222 | " 158.130005 | \n",
223 | " 154.320007 | \n",
224 | " 157.759995 | \n",
225 | " 157.086288 | \n",
226 | " 33535500 | \n",
227 | "
\n",
228 | " \n",
229 | " 2019-01-28 | \n",
230 | " 155.789993 | \n",
231 | " 156.330002 | \n",
232 | " 153.660004 | \n",
233 | " 156.300003 | \n",
234 | " 155.632523 | \n",
235 | " 26192100 | \n",
236 | "
\n",
237 | " \n",
238 | " 2019-01-29 | \n",
239 | " 156.250000 | \n",
240 | " 158.130005 | \n",
241 | " 154.110001 | \n",
242 | " 154.679993 | \n",
243 | " 154.019440 | \n",
244 | " 41587200 | \n",
245 | "
\n",
246 | " \n",
247 | " 2019-01-30 | \n",
248 | " 163.250000 | \n",
249 | " 166.149994 | \n",
250 | " 160.229996 | \n",
251 | " 165.250000 | \n",
252 | " 164.544296 | \n",
253 | " 61109800 | \n",
254 | "
\n",
255 | " \n",
256 | " 2019-01-31 | \n",
257 | " 166.110001 | \n",
258 | " 169.000000 | \n",
259 | " 164.559998 | \n",
260 | " 166.440002 | \n",
261 | " 165.729218 | \n",
262 | " 40739600 | \n",
263 | "
\n",
264 | " \n",
265 | "
\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 | " Open | \n",
334 | " High | \n",
335 | " Low | \n",
336 | " Close | \n",
337 | " Adj Close | \n",
338 | " Volume | \n",
339 | " Open_Close | \n",
340 | " High_Low | \n",
341 | " Increase_Decrease | \n",
342 | " Buy_Sell_on_Open | \n",
343 | " Buy_Sell | \n",
344 | " Returns | \n",
345 | "
\n",
346 | " \n",
347 | " Date | \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 | " 2018-01-03 | \n",
365 | " 172.529999 | \n",
366 | " 174.550003 | \n",
367 | " 171.960007 | \n",
368 | " 172.229996 | \n",
369 | " 168.957886 | \n",
370 | " 29517900 | \n",
371 | " 0.020704 | \n",
372 | " 0.015062 | \n",
373 | " 0 | \n",
374 | " 1 | \n",
375 | " 1 | \n",
376 | " -0.000174 | \n",
377 | "
\n",
378 | " \n",
379 | " 2018-01-04 | \n",
380 | " 172.539993 | \n",
381 | " 173.470001 | \n",
382 | " 172.080002 | \n",
383 | " 173.029999 | \n",
384 | " 169.742706 | \n",
385 | " 22434600 | \n",
386 | " 0.016212 | \n",
387 | " 0.008078 | \n",
388 | " 1 | \n",
389 | " 1 | \n",
390 | " 1 | \n",
391 | " 0.004645 | \n",
392 | "
\n",
393 | " \n",
394 | " 2018-01-05 | \n",
395 | " 173.440002 | \n",
396 | " 175.369995 | \n",
397 | " 173.050003 | \n",
398 | " 175.000000 | \n",
399 | " 171.675278 | \n",
400 | " 23660000 | \n",
401 | " 0.010175 | \n",
402 | " 0.013406 | \n",
403 | " 0 | \n",
404 | " 1 | \n",
405 | " 0 | \n",
406 | " 0.011385 | \n",
407 | "
\n",
408 | " \n",
409 | " 2018-01-08 | \n",
410 | " 174.350006 | \n",
411 | " 175.610001 | \n",
412 | " 173.929993 | \n",
413 | " 174.350006 | \n",
414 | " 171.037628 | \n",
415 | " 20567800 | \n",
416 | " 0.018998 | \n",
417 | " 0.009659 | \n",
418 | " 1 | \n",
419 | " 1 | \n",
420 | " 0 | \n",
421 | " -0.003714 | \n",
422 | "
\n",
423 | " \n",
424 | " 2018-01-09 | \n",
425 | " 174.550003 | \n",
426 | " 175.059998 | \n",
427 | " 173.410004 | \n",
428 | " 174.330002 | \n",
429 | " 171.018005 | \n",
430 | " 21584000 | \n",
431 | " 0.020235 | \n",
432 | " 0.009515 | \n",
433 | " 1 | \n",
434 | " 0 | \n",
435 | " 0 | \n",
436 | " -0.000115 | \n",
437 | "
\n",
438 | " \n",
439 | "
\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 |
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 |
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
--------------------------------------------------------------------------------