├── day_interval ├── __init__.py ├── DashboardDaily_2020-01-02_AAPL-AMZN-GOOGL-FB-MSFT-NFLX.jpg ├── DashboardDaily_2020-01-02_AAPL-AMZN-GOOGL-FB-MSFT-NFLX.pdf ├── legend.py ├── retrievedaily.py ├── datasdaily.py └── dashboarddaily.py ├── day_interval_fourstocks ├── __init__.py ├── DashboardDaily_2019-12-18_XOM-CVX-BP-SNP.jpg ├── DashboardDaily_2019-12-18_XOM-CVX-BP-SNP.pdf ├── legendfour.py ├── retrievedailyfour.py ├── datasdailyfour.py └── dashboarddailyfour.py ├── min_interval_fourstocks ├── __init__.py ├── Dashboard_2020-05-08_MCD-YUM-CMG-QSR.jpg ├── Dashboard_2020-05-08_MCD-YUM-CMG-QSR.pdf ├── legendfour.py ├── retrievefour.py ├── datasfour.py └── dashboardfour.py ├── pip_install.txt ├── .gitattributes ├── archive ├── Dashboard.jpg ├── Dashboard2.png ├── Dashboard22May.jpg ├── Dashboard22May.pdf ├── Dashboard30May.jpg ├── Dashboard30May.pdf ├── msstock22and25.png ├── sampledashboard.jpg ├── stocksofFAANGM.png ├── PracticeDashboard.png ├── sampledashboard2.jpg ├── sampledashboard2.png ├── Dashboard22May_small.jpg ├── Dashboard_2019-05-28.jpg ├── Dashboard_2019-05-28.pdf ├── Dashboard_2019-06-06.jpg ├── Dashboard_2019-06-06.pdf ├── Dashboard_2019-09-05.jpg ├── Dashboard_2019-09-05.pdf ├── Dashboard_2020-05-07.jpg ├── Dashboard_2020-05-07.pdf ├── Dashboard_2020-05-08.jpg ├── Dashboard_2020-05-08.pdf ├── microsoftstocktoday.jpg ├── DashboardDaily_2019-12-16.jpg ├── DashboardDaily_2019-12-16.pdf ├── DashboardDaily_2020-01-02.jpg ├── DashboardDaily_2020-01-02.pdf ├── Draft_Dashboard_Structure.pdf ├── Draft_Dashboard_Structure.png ├── Dashboard_2019-05-28_linkedin.jpg └── matplotlib markersize and linewidth.png ├── requirements.txt ├── tests ├── Dashboard_2020-05-07_XOM-CVX-BP-PSX.jpg ├── Dashboard_2020-05-07_XOM-CVX-BP-PSX.pdf ├── Dashboard_2020-05-07_XOM-CVX-BP-SHAK.jpg ├── Dashboard_2020-05-07_XOM-CVX-BP-SHAK.pdf ├── Dashboard_2020-05-07_XOM-CVX-BP-SNP.jpg ├── Dashboard_2020-05-07_XOM-CVX-BP-SNP.pdf ├── Dashboard_2020-05-08_XOM-CVX-BP-SNP.jpg ├── Dashboard_2020-05-08_XOM-CVX-BP-SNP.pdf ├── DashboardDaily_2019-12-16_MCD-YUM-CMG-QSR.jpg ├── DashboardDaily_2019-12-16_MCD-YUM-CMG-QSR.pdf ├── Dashboard_2020-05-08_AAPL-AMZN-GOOGL-FB-MSFT-NFLX.jpg ├── Dashboard_2020-05-08_AAPL-AMZN-GOOGL-FB-MSFT-NFLX.pdf ├── DashboardDaily_2019-12-16_DXC-HPQ-TSLA-FB-MSFT-MCD.jpg ├── DashboardDaily_2019-12-16_DXC-HPQ-TSLA-FB-MSFT-MCD.pdf ├── DashboardDaily_2019-12-20_DXC-HPQ-TSLA-FB-MSFT-MCD.jpg ├── DashboardDaily_2019-12-20_DXC-HPQ-TSLA-FB-MSFT-MCD.pdf ├── testminfourstocks.py ├── testmin.py ├── testdayfourstocks.py └── testday.py ├── min_interval ├── Dashboard_2020-05-08_AAPL-AMZN-GOOGL-FB-MSFT-NFLX.jpg ├── Dashboard_2020-05-08_AAPL-AMZN-GOOGL-FB-MSFT-NFLX.pdf ├── legend.py ├── retrieve.py ├── datas.py └── dashboard.py ├── LICENSE └── README.md /day_interval/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /day_interval_fourstocks/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /min_interval_fourstocks/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pip_install.txt: -------------------------------------------------------------------------------- 1 | numpy 2 | matplotlib -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | day_interval/* linguist-vendored 2 | *.ipynb linguist-language=Python -------------------------------------------------------------------------------- /archive/Dashboard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/Dashboard.jpg -------------------------------------------------------------------------------- /archive/Dashboard2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/Dashboard2.png -------------------------------------------------------------------------------- /archive/Dashboard22May.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/Dashboard22May.jpg -------------------------------------------------------------------------------- /archive/Dashboard22May.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/Dashboard22May.pdf -------------------------------------------------------------------------------- /archive/Dashboard30May.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/Dashboard30May.jpg -------------------------------------------------------------------------------- /archive/Dashboard30May.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/Dashboard30May.pdf -------------------------------------------------------------------------------- /archive/msstock22and25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/msstock22and25.png -------------------------------------------------------------------------------- /archive/sampledashboard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/sampledashboard.jpg -------------------------------------------------------------------------------- /archive/stocksofFAANGM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/stocksofFAANGM.png -------------------------------------------------------------------------------- /archive/PracticeDashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/PracticeDashboard.png -------------------------------------------------------------------------------- /archive/sampledashboard2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/sampledashboard2.jpg -------------------------------------------------------------------------------- /archive/sampledashboard2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/sampledashboard2.png -------------------------------------------------------------------------------- /archive/Dashboard22May_small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/Dashboard22May_small.jpg -------------------------------------------------------------------------------- /archive/Dashboard_2019-05-28.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/Dashboard_2019-05-28.jpg -------------------------------------------------------------------------------- /archive/Dashboard_2019-05-28.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/Dashboard_2019-05-28.pdf -------------------------------------------------------------------------------- /archive/Dashboard_2019-06-06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/Dashboard_2019-06-06.jpg -------------------------------------------------------------------------------- /archive/Dashboard_2019-06-06.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/Dashboard_2019-06-06.pdf -------------------------------------------------------------------------------- /archive/Dashboard_2019-09-05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/Dashboard_2019-09-05.jpg -------------------------------------------------------------------------------- /archive/Dashboard_2019-09-05.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/Dashboard_2019-09-05.pdf -------------------------------------------------------------------------------- /archive/Dashboard_2020-05-07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/Dashboard_2020-05-07.jpg -------------------------------------------------------------------------------- /archive/Dashboard_2020-05-07.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/Dashboard_2020-05-07.pdf -------------------------------------------------------------------------------- /archive/Dashboard_2020-05-08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/Dashboard_2020-05-08.jpg -------------------------------------------------------------------------------- /archive/Dashboard_2020-05-08.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/Dashboard_2020-05-08.pdf -------------------------------------------------------------------------------- /archive/microsoftstocktoday.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/microsoftstocktoday.jpg -------------------------------------------------------------------------------- /archive/DashboardDaily_2019-12-16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/DashboardDaily_2019-12-16.jpg -------------------------------------------------------------------------------- /archive/DashboardDaily_2019-12-16.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/DashboardDaily_2019-12-16.pdf -------------------------------------------------------------------------------- /archive/DashboardDaily_2020-01-02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/DashboardDaily_2020-01-02.jpg -------------------------------------------------------------------------------- /archive/DashboardDaily_2020-01-02.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/DashboardDaily_2020-01-02.pdf -------------------------------------------------------------------------------- /archive/Draft_Dashboard_Structure.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/Draft_Dashboard_Structure.pdf -------------------------------------------------------------------------------- /archive/Draft_Dashboard_Structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/Draft_Dashboard_Structure.png -------------------------------------------------------------------------------- /archive/Dashboard_2019-05-28_linkedin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/Dashboard_2019-05-28_linkedin.jpg -------------------------------------------------------------------------------- /archive/matplotlib markersize and linewidth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/archive/matplotlib markersize and linewidth.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | cycler==0.10.0 2 | kiwisolver==1.2.0 3 | matplotlib==3.2.1 4 | numpy==1.18.4 5 | pyparsing==2.4.7 6 | python-dateutil==2.8.1 7 | six==1.14.0 8 | -------------------------------------------------------------------------------- /tests/Dashboard_2020-05-07_XOM-CVX-BP-PSX.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/tests/Dashboard_2020-05-07_XOM-CVX-BP-PSX.jpg -------------------------------------------------------------------------------- /tests/Dashboard_2020-05-07_XOM-CVX-BP-PSX.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/tests/Dashboard_2020-05-07_XOM-CVX-BP-PSX.pdf -------------------------------------------------------------------------------- /tests/Dashboard_2020-05-07_XOM-CVX-BP-SHAK.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/tests/Dashboard_2020-05-07_XOM-CVX-BP-SHAK.jpg -------------------------------------------------------------------------------- /tests/Dashboard_2020-05-07_XOM-CVX-BP-SHAK.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/tests/Dashboard_2020-05-07_XOM-CVX-BP-SHAK.pdf -------------------------------------------------------------------------------- /tests/Dashboard_2020-05-07_XOM-CVX-BP-SNP.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/tests/Dashboard_2020-05-07_XOM-CVX-BP-SNP.jpg -------------------------------------------------------------------------------- /tests/Dashboard_2020-05-07_XOM-CVX-BP-SNP.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/tests/Dashboard_2020-05-07_XOM-CVX-BP-SNP.pdf -------------------------------------------------------------------------------- /tests/Dashboard_2020-05-08_XOM-CVX-BP-SNP.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/tests/Dashboard_2020-05-08_XOM-CVX-BP-SNP.jpg -------------------------------------------------------------------------------- /tests/Dashboard_2020-05-08_XOM-CVX-BP-SNP.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/tests/Dashboard_2020-05-08_XOM-CVX-BP-SNP.pdf -------------------------------------------------------------------------------- /tests/DashboardDaily_2019-12-16_MCD-YUM-CMG-QSR.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/tests/DashboardDaily_2019-12-16_MCD-YUM-CMG-QSR.jpg -------------------------------------------------------------------------------- /tests/DashboardDaily_2019-12-16_MCD-YUM-CMG-QSR.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/tests/DashboardDaily_2019-12-16_MCD-YUM-CMG-QSR.pdf -------------------------------------------------------------------------------- /tests/Dashboard_2020-05-08_AAPL-AMZN-GOOGL-FB-MSFT-NFLX.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/tests/Dashboard_2020-05-08_AAPL-AMZN-GOOGL-FB-MSFT-NFLX.jpg -------------------------------------------------------------------------------- /tests/Dashboard_2020-05-08_AAPL-AMZN-GOOGL-FB-MSFT-NFLX.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/tests/Dashboard_2020-05-08_AAPL-AMZN-GOOGL-FB-MSFT-NFLX.pdf -------------------------------------------------------------------------------- /tests/DashboardDaily_2019-12-16_DXC-HPQ-TSLA-FB-MSFT-MCD.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/tests/DashboardDaily_2019-12-16_DXC-HPQ-TSLA-FB-MSFT-MCD.jpg -------------------------------------------------------------------------------- /tests/DashboardDaily_2019-12-16_DXC-HPQ-TSLA-FB-MSFT-MCD.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/tests/DashboardDaily_2019-12-16_DXC-HPQ-TSLA-FB-MSFT-MCD.pdf -------------------------------------------------------------------------------- /tests/DashboardDaily_2019-12-20_DXC-HPQ-TSLA-FB-MSFT-MCD.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/tests/DashboardDaily_2019-12-20_DXC-HPQ-TSLA-FB-MSFT-MCD.jpg -------------------------------------------------------------------------------- /tests/DashboardDaily_2019-12-20_DXC-HPQ-TSLA-FB-MSFT-MCD.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/tests/DashboardDaily_2019-12-20_DXC-HPQ-TSLA-FB-MSFT-MCD.pdf -------------------------------------------------------------------------------- /min_interval_fourstocks/Dashboard_2020-05-08_MCD-YUM-CMG-QSR.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/min_interval_fourstocks/Dashboard_2020-05-08_MCD-YUM-CMG-QSR.jpg -------------------------------------------------------------------------------- /min_interval_fourstocks/Dashboard_2020-05-08_MCD-YUM-CMG-QSR.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/min_interval_fourstocks/Dashboard_2020-05-08_MCD-YUM-CMG-QSR.pdf -------------------------------------------------------------------------------- /min_interval/Dashboard_2020-05-08_AAPL-AMZN-GOOGL-FB-MSFT-NFLX.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/min_interval/Dashboard_2020-05-08_AAPL-AMZN-GOOGL-FB-MSFT-NFLX.jpg -------------------------------------------------------------------------------- /min_interval/Dashboard_2020-05-08_AAPL-AMZN-GOOGL-FB-MSFT-NFLX.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/min_interval/Dashboard_2020-05-08_AAPL-AMZN-GOOGL-FB-MSFT-NFLX.pdf -------------------------------------------------------------------------------- /day_interval_fourstocks/DashboardDaily_2019-12-18_XOM-CVX-BP-SNP.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/day_interval_fourstocks/DashboardDaily_2019-12-18_XOM-CVX-BP-SNP.jpg -------------------------------------------------------------------------------- /day_interval_fourstocks/DashboardDaily_2019-12-18_XOM-CVX-BP-SNP.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/day_interval_fourstocks/DashboardDaily_2019-12-18_XOM-CVX-BP-SNP.pdf -------------------------------------------------------------------------------- /day_interval/DashboardDaily_2020-01-02_AAPL-AMZN-GOOGL-FB-MSFT-NFLX.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/day_interval/DashboardDaily_2020-01-02_AAPL-AMZN-GOOGL-FB-MSFT-NFLX.jpg -------------------------------------------------------------------------------- /day_interval/DashboardDaily_2020-01-02_AAPL-AMZN-GOOGL-FB-MSFT-NFLX.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kohjiaxuan/Stock-Market-Dashboard/HEAD/day_interval/DashboardDaily_2020-01-02_AAPL-AMZN-GOOGL-FB-MSFT-NFLX.pdf -------------------------------------------------------------------------------- /tests/testminfourstocks.py: -------------------------------------------------------------------------------- 1 | from os.path import dirname, abspath 2 | import sys 3 | 4 | # Get path of parent folder 5 | parentpath = dirname(dirname(abspath(__file__))) 6 | # print(parentpath) 7 | 8 | # Add to directory defined by sys 9 | sys.path.append(parentpath) 10 | 11 | scriptpath = parentpath + "\\min_interval_fourstocks" 12 | # print(scriptpath) 13 | 14 | # Add main script to directory 15 | sys.path.append(scriptpath) 16 | 17 | # parentpath allows you to do absolute import below 18 | from min_interval_fourstocks import dashboardfour 19 | # dashboard does absolute import of retrieve, datas and legend 20 | # scriptpath allows you to do (implicit) absolute import from dashboard.py 21 | 22 | def newclass(stock1, stock2, stock3, stock4, time): 23 | return dashboardfour.main(stock1, stock2, stock3, stock4, time) 24 | 25 | # Simple test 26 | if __name__ == "__main__": 27 | dashboardfour.main('XOM', 'CVX', 'BP', 'PSX') 28 | -------------------------------------------------------------------------------- /tests/testmin.py: -------------------------------------------------------------------------------- 1 | from os.path import dirname, abspath 2 | import sys 3 | 4 | # Get path of parent folder 5 | parentpath = dirname(dirname(abspath(__file__))) 6 | # print(parentpath) 7 | 8 | # Add to directory defined by sys 9 | sys.path.append(parentpath) 10 | 11 | scriptpath = parentpath + "\\min_interval" 12 | # print(scriptpath) 13 | 14 | # Add main script to directory 15 | sys.path.append(scriptpath) 16 | 17 | # parentpath allows you to do absolute import below 18 | from min_interval import dashboard 19 | # dashboard does absolute import of retrieve, datas and legend 20 | # scriptpath allows you to do (implicit) absolute import from dashboard.py 21 | 22 | def newclass(stock1, stock2, stock3, stock4, stock5, stock6, time): 23 | return dashboard.main(stock1, stock2, stock3, stock4, stock5, stock6, time) 24 | 25 | # Simple test 26 | if __name__ == "__main__": 27 | dashboard.main('AAPL', 'AMZN', 'GOOGL', 'FB', 'MSFT', 'NFLX', '10:00') 28 | -------------------------------------------------------------------------------- /tests/testdayfourstocks.py: -------------------------------------------------------------------------------- 1 | from os.path import dirname, abspath 2 | import sys 3 | 4 | # Get path of parent folder 5 | parentpath = dirname(dirname(abspath(__file__))) 6 | # print(parentpath) 7 | 8 | # Add to directory defined by sys 9 | sys.path.append(parentpath) 10 | 11 | scriptpath = parentpath + "\\day_interval_fourstocks" 12 | # print(scriptpath) 13 | 14 | # Add main script to directory 15 | sys.path.append(scriptpath) 16 | 17 | # parentpath allows you to do absolute import below 18 | from day_interval_fourstocks import dashboarddailyfour 19 | # dashboarddaily does absolute import of retrievedaily, datasdaily and legend 20 | # scriptpath allows you to do (implicit) absolute import from dashboarddaily.py 21 | 22 | def newclass(stock1, stock2, stock3, stock4, date): 23 | return dashboarddailyfour.main(stock1, stock2, stock3, stock4) 24 | 25 | # Simple test 26 | if __name__ == "__main__": 27 | dashboarddailyfour.main('MCD','YUM','CMG','QSR') 28 | -------------------------------------------------------------------------------- /tests/testday.py: -------------------------------------------------------------------------------- 1 | from os.path import dirname, abspath 2 | import sys 3 | 4 | # Get path of parent folder 5 | parentpath = dirname(dirname(abspath(__file__))) 6 | # print(parentpath) 7 | 8 | # Add to directory defined by sys 9 | sys.path.append(parentpath) 10 | 11 | scriptpath = parentpath + "\\day_interval" 12 | # print(scriptpath) 13 | 14 | # Add main script to directory 15 | sys.path.append(scriptpath) 16 | 17 | # parentpath allows you to do absolute import below 18 | from day_interval import dashboarddaily 19 | # dashboarddaily does absolute import of retrievedaily, datasdaily and legend 20 | # scriptpath allows you to do (implicit) absolute import from dashboarddaily.py 21 | 22 | def newclass(stock1, stock2, stock3, stock4, stock5, stock6, date): 23 | return dashboarddaily.main(stock1, stock2, stock3, stock4, stock5, stock6, date) 24 | 25 | # Simple test 26 | if __name__ == "__main__": 27 | dashboarddaily.main('DXC', 'HPQ', 'TSLA', 'FB', 'MSFT', 'MCD', '2019-12-20') 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Koh Jia Xuan 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 | -------------------------------------------------------------------------------- /day_interval_fourstocks/legendfour.py: -------------------------------------------------------------------------------- 1 | def legendcalculation(AAPLdailyopen_n, AMZNdailyopen_n, GOOGLdailyopen_n, FBdailyopen_n): 2 | #Determine where to put legend board in relative stock performance graph 3 | stockgoodperformance = 0 4 | #Default location for legends of small graphs is top right, will change to bottom right depending on graph 5 | AAPLlegendloc = 1 6 | AMZNlegendloc = 1 7 | GOOGLlegendloc = 1 8 | FBlegendloc = 1 9 | 10 | #Find number of stocks closing higher than when they opened 11 | if AAPLdailyopen_n[-1] > AAPLdailyopen_n[0]: 12 | stockgoodperformance += 1 13 | AAPLlegendloc = 4 14 | if AMZNdailyopen_n[-1] > AMZNdailyopen_n[0]: 15 | stockgoodperformance += 1 16 | AMZNlegendloc = 4 17 | if GOOGLdailyopen_n[-1] > GOOGLdailyopen_n[0]: 18 | stockgoodperformance += 1 19 | GOOGLlegendloc = 4 20 | if FBdailyopen_n[-1] > FBdailyopen_n[0]: 21 | stockgoodperformance += 1 22 | FBlegendloc = 4 23 | 24 | if stockgoodperformance >= 3: 25 | legendloc = 4 #stocks mostly rised, place legend bottom right 26 | elif stockgoodperformance <= 2: 27 | legendloc = 3 #stocks mostly tumbled, place legend bottom left 28 | 29 | # Auto detect best location 30 | # legendloc = 0 31 | 32 | return {"legendloc": legendloc, 33 | "stockloc": [AAPLlegendloc, AMZNlegendloc, GOOGLlegendloc, FBlegendloc]} -------------------------------------------------------------------------------- /min_interval_fourstocks/legendfour.py: -------------------------------------------------------------------------------- 1 | def legendcalculation(AAPLdailyopen_n, AMZNdailyopen_n, GOOGLdailyopen_n, FBdailyopen_n): 2 | #Determine where to put legend board in relative stock performance graph 3 | stockgoodperformance = 0 4 | #Default location for legends of small graphs is top right, will change to bottom right depending on graph 5 | AAPLlegendloc = 1 6 | AMZNlegendloc = 1 7 | GOOGLlegendloc = 1 8 | FBlegendloc = 1 9 | 10 | #Find number of stocks closing higher than when they opened 11 | if AAPLdailyopen_n[-1] > AAPLdailyopen_n[0]: 12 | stockgoodperformance += 1 13 | AAPLlegendloc = 4 14 | if AMZNdailyopen_n[-1] > AMZNdailyopen_n[0]: 15 | stockgoodperformance += 1 16 | AMZNlegendloc = 4 17 | if GOOGLdailyopen_n[-1] > GOOGLdailyopen_n[0]: 18 | stockgoodperformance += 1 19 | GOOGLlegendloc = 4 20 | if FBdailyopen_n[-1] > FBdailyopen_n[0]: 21 | stockgoodperformance += 1 22 | FBlegendloc = 4 23 | 24 | if stockgoodperformance >= 3: 25 | legendloc = 4 #stocks mostly rised, place legend bottom right 26 | elif stockgoodperformance <= 2: 27 | legendloc = 3 #stocks mostly tumbled, place legend bottom left 28 | 29 | # Auto detect best location 30 | # legendloc = 0 31 | 32 | return {"legendloc": legendloc, 33 | "stockloc": [AAPLlegendloc, AMZNlegendloc, GOOGLlegendloc, FBlegendloc]} -------------------------------------------------------------------------------- /min_interval_fourstocks/retrievefour.py: -------------------------------------------------------------------------------- 1 | # Access and read API contents 2 | 3 | import urllib.request, json 4 | # urllib is for opening URLs to get info 5 | # json is for reading raw string from URL into json file 6 | 7 | def stocks(str1='AAPL', str2='MSFT', str3='AMZN', str4='GOOGL'): 8 | APIKEY_ALPHAVANTAGE = "PUTAPIKEYHERE" 9 | # save url inside variable as raw string 10 | urlAAPL = r"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=" + str1 + r"&interval=5min&apikey=" + APIKEY_ALPHAVANTAGE 11 | urlMSFT = r"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=" + str2 + r"&interval=5min&apikey=" + APIKEY_ALPHAVANTAGE 12 | urlAMZN = r"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=" + str3 + r"&interval=5min&apikey=" + APIKEY_ALPHAVANTAGE 13 | urlGOOGL = r"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=" + str4 + r"&interval=5min&apikey=" + APIKEY_ALPHAVANTAGE 14 | # use urllib.request.urlopen() to access API from URL links 15 | responseAAPL = urllib.request.urlopen(urlAAPL) 16 | responseMSFT = urllib.request.urlopen(urlMSFT) 17 | responseAMZN = urllib.request.urlopen(urlAMZN) 18 | responseGOOGL = urllib.request.urlopen(urlGOOGL) 19 | 20 | # from var saved (HTTPresponse type), use .read() + .decode('utf-8') 21 | stringAAPL = responseAAPL.read().decode('utf-8') 22 | stringMSFT = responseMSFT.read().decode('utf-8') 23 | stringAMZN = responseAMZN.read().decode('utf-8') 24 | stringGOOGL = responseGOOGL.read().decode('utf-8') 25 | 26 | print("Stock data has been retrieved successfully...") 27 | 28 | return [stringAAPL, stringMSFT, stringAMZN, stringGOOGL] -------------------------------------------------------------------------------- /day_interval_fourstocks/retrievedailyfour.py: -------------------------------------------------------------------------------- 1 | # Access and read API contents 2 | 3 | import urllib.request, json 4 | # urllib is for opening URLs to get info 5 | # json is for reading raw string from URL into json file 6 | # time is for waiting 1 min before getting more API data 7 | # Limit of 5 API calls per min 8 | 9 | def stocks(str1='AAPL', str2='MSFT', str3='AMZN', str4='GOOGL'): 10 | APIKEY_ALPHAVANTAGE = "PUTAPIKEYHERE" 11 | # save url inside variable as raw string 12 | urlAAPL = r"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=" + str1 + r"&interval=5min&apikey=" + APIKEY_ALPHAVANTAGE 13 | urlMSFT = r"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=" + str2 + r"&interval=5min&apikey=" + APIKEY_ALPHAVANTAGE 14 | urlAMZN = r"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=" + str3 + r"&interval=5min&apikey=" + APIKEY_ALPHAVANTAGE 15 | urlGOOGL = r"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=" + str4 + r"&interval=5min&apikey=" + APIKEY_ALPHAVANTAGE 16 | 17 | # use urllib.request.urlopen() to access API from URL links 18 | responseAAPL = urllib.request.urlopen(urlAAPL) 19 | responseMSFT = urllib.request.urlopen(urlMSFT) 20 | responseAMZN = urllib.request.urlopen(urlAMZN) 21 | responseGOOGL = urllib.request.urlopen(urlGOOGL) 22 | 23 | # from var saved (HTTPresponse type), use .read() + .decode('utf-8') 24 | stringAAPL = responseAAPL.read().decode('utf-8') 25 | stringMSFT = responseMSFT.read().decode('utf-8') 26 | stringAMZN = responseAMZN.read().decode('utf-8') 27 | stringGOOGL = responseGOOGL.read().decode('utf-8') 28 | 29 | print("Stock data has been retrieved successfully...") 30 | 31 | return [stringAAPL, stringMSFT, stringAMZN, stringGOOGL] -------------------------------------------------------------------------------- /day_interval/legend.py: -------------------------------------------------------------------------------- 1 | def legendcalculation(AAPLdailyopen_n, AMZNdailyopen_n, GOOGLdailyopen_n, FBdailyopen_n, MSFTdailyopen_n, NFLXdailyopen_n): 2 | #Determine where to put legend board in relative stock performance graph 3 | stockgoodperformance = 0 4 | #Default location for legends of small graphs is top right, will change to bottom right depending on graph 5 | AAPLlegendloc = 1 6 | AMZNlegendloc = 1 7 | GOOGLlegendloc = 1 8 | FBlegendloc = 1 9 | MSFTlegendloc = 1 10 | NFLXlegendloc = 1 11 | 12 | #Find number of stocks closing higher than when they opened 13 | if AAPLdailyopen_n[-1] > AAPLdailyopen_n[0]: 14 | stockgoodperformance += 1 15 | AAPLlegendloc = 4 16 | if AMZNdailyopen_n[-1] > AMZNdailyopen_n[0]: 17 | stockgoodperformance += 1 18 | AMZNlegendloc = 4 19 | if GOOGLdailyopen_n[-1] > GOOGLdailyopen_n[0]: 20 | stockgoodperformance += 1 21 | GOOGLlegendloc = 4 22 | if FBdailyopen_n[-1] > FBdailyopen_n[0]: 23 | stockgoodperformance += 1 24 | FBlegendloc = 4 25 | if MSFTdailyopen_n[-1] > MSFTdailyopen_n[0]: 26 | stockgoodperformance += 1 27 | MSFTlegendloc = 4 28 | if NFLXdailyopen_n[-1] > NFLXdailyopen_n[0]: 29 | stockgoodperformance += 1 30 | NFLXlegendloc = 4 31 | 32 | if stockgoodperformance >= 5: 33 | legendloc = 4 #stocks mostly rised, place legend bottom right 34 | elif stockgoodperformance <= 2: 35 | legendloc = 3 #stocks mostly tumbled, place legend bottom left 36 | else: #Mixed, place legend center-left 37 | # legendloc = 9 38 | legendloc = 6 39 | 40 | # Auto detect best location 41 | # legendloc = 0 42 | 43 | return {"legendloc": legendloc, 44 | "stockloc": [AAPLlegendloc, AMZNlegendloc, GOOGLlegendloc, FBlegendloc, MSFTlegendloc, NFLXlegendloc]} -------------------------------------------------------------------------------- /min_interval/legend.py: -------------------------------------------------------------------------------- 1 | def legendcalculation(AAPLdailyopen_n, AMZNdailyopen_n, GOOGLdailyopen_n, FBdailyopen_n, MSFTdailyopen_n, NFLXdailyopen_n): 2 | #Determine where to put legend board in relative stock performance graph 3 | stockgoodperformance = 0 4 | #Default location for legends of small graphs is top right, will change to bottom right depending on graph 5 | AAPLlegendloc = 1 6 | AMZNlegendloc = 1 7 | GOOGLlegendloc = 1 8 | FBlegendloc = 1 9 | MSFTlegendloc = 1 10 | NFLXlegendloc = 1 11 | 12 | #Find number of stocks closing higher than when they opened 13 | if AAPLdailyopen_n[-1] > AAPLdailyopen_n[0]: 14 | stockgoodperformance += 1 15 | AAPLlegendloc = 4 16 | if AMZNdailyopen_n[-1] > AMZNdailyopen_n[0]: 17 | stockgoodperformance += 1 18 | AMZNlegendloc = 4 19 | if GOOGLdailyopen_n[-1] > GOOGLdailyopen_n[0]: 20 | stockgoodperformance += 1 21 | GOOGLlegendloc = 4 22 | if FBdailyopen_n[-1] > FBdailyopen_n[0]: 23 | stockgoodperformance += 1 24 | FBlegendloc = 4 25 | if MSFTdailyopen_n[-1] > MSFTdailyopen_n[0]: 26 | stockgoodperformance += 1 27 | MSFTlegendloc = 4 28 | if NFLXdailyopen_n[-1] > NFLXdailyopen_n[0]: 29 | stockgoodperformance += 1 30 | NFLXlegendloc = 4 31 | 32 | if stockgoodperformance >= 5: 33 | legendloc = 4 #stocks mostly rised, place legend bottom right 34 | elif stockgoodperformance <= 2: 35 | legendloc = 3 #stocks mostly tumbled, place legend bottom left 36 | else: #Mixed, place legend center-left 37 | # legendloc = 9 38 | legendloc = 6 39 | 40 | # Auto detect best location 41 | # legendloc = 0 42 | 43 | return {"legendloc": legendloc, 44 | "stockloc": [AAPLlegendloc, AMZNlegendloc, GOOGLlegendloc, FBlegendloc, MSFTlegendloc, NFLXlegendloc]} -------------------------------------------------------------------------------- /min_interval/retrieve.py: -------------------------------------------------------------------------------- 1 | # Access and read API contents 2 | # Have to read 3 APIs at a time due to limitations of Alpha Vantage API for free use (max 5 accesses per minute) 3 | # Unable to read all 6 stock APIs (FAANGM) at once 4 | 5 | import urllib.request, json 6 | import time 7 | # urllib is for opening URLs to get info 8 | # json is for reading raw string from URL into json file 9 | # time is for waiting 1 min before getting more API data 10 | # Limit of 5 API calls per min, so need to run 3 by 3 11 | 12 | def stocks(str1='AAPL', str2='MSFT', str3='AMZN', str4='GOOGL', str5='FB', str6='NFLX'): 13 | APIKEY_ALPHAVANTAGE = "PUTAPIKEYHERE" 14 | # save url inside variable as raw string 15 | urlAAPL = r"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=" + str1 + r"&interval=5min&apikey=" + APIKEY_ALPHAVANTAGE 16 | urlMSFT = r"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=" + str2 + r"&interval=5min&apikey=" + APIKEY_ALPHAVANTAGE 17 | urlAMZN = r"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=" + str3 + r"&interval=5min&apikey=" + APIKEY_ALPHAVANTAGE 18 | 19 | # use urllib.request.urlopen() to access API from URL links 20 | responseAAPL = urllib.request.urlopen(urlAAPL) 21 | responseMSFT = urllib.request.urlopen(urlMSFT) 22 | responseAMZN = urllib.request.urlopen(urlAMZN) 23 | 24 | # from var saved (HTTPresponse type), use .read() + .decode('utf-8') 25 | stringAAPL = responseAAPL.read().decode('utf-8') 26 | stringMSFT = responseMSFT.read().decode('utf-8') 27 | stringAMZN = responseAMZN.read().decode('utf-8') 28 | 29 | # Access and read API contents 30 | # Have to read 3 APIs at a time due to limitations of Alpha Vantage API for free use (max 5 accesses per minute) 31 | # Unable to read all 6 stock APIs (FAANGM) at once 32 | # Wait for 1 min 33 | time.sleep(60.1) 34 | 35 | # save url inside variable as raw string 36 | urlGOOGL = r"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=" + str4 + r"&interval=5min&apikey=" + APIKEY_ALPHAVANTAGE 37 | urlFB = r"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=" + str5 + r"&interval=5min&apikey=" + APIKEY_ALPHAVANTAGE 38 | urlNFLX = r"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=" + str6 + r"&interval=5min&apikey=" + APIKEY_ALPHAVANTAGE 39 | 40 | # use urllib.request.urlopen() 41 | responseGOOGL = urllib.request.urlopen(urlGOOGL) 42 | responseFB = urllib.request.urlopen(urlFB) 43 | responseNFLX = urllib.request.urlopen(urlNFLX) 44 | 45 | # from var saved (HTTPresponse type), use .read() + .decode('utf-8') 46 | stringGOOGL = responseGOOGL.read().decode('utf-8') 47 | stringFB = responseFB.read().decode('utf-8') 48 | stringNFLX = responseNFLX.read().decode('utf-8') 49 | 50 | print("Stock data has been retrieved successfully...") 51 | 52 | return [stringAAPL, stringMSFT, stringAMZN, stringGOOGL, stringFB, stringNFLX] -------------------------------------------------------------------------------- /day_interval/retrievedaily.py: -------------------------------------------------------------------------------- 1 | # Access and read API contents 2 | # Have to read 3 APIs at a time due to limitations of Alpha Vantage API for free use (max 5 accesses per minute) 3 | # Unable to read all 6 stock APIs (FAANGM) at once 4 | 5 | import urllib.request, json 6 | import time 7 | # urllib is for opening URLs to get info 8 | # json is for reading raw string from URL into json file 9 | # time is for waiting 1 min before getting more API data 10 | # Limit of 5 API calls per min, so need to run 3 by 3 11 | 12 | def stocks(str1='AAPL', str2='MSFT', str3='AMZN', str4='GOOGL', str5='FB', str6='NFLX'): 13 | APIKEY_ALPHAVANTAGE = "PUTAPIKEYHERE" 14 | # save url inside variable as raw string 15 | urlAAPL = r"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=" + str1 + r"&interval=5min&apikey=" + APIKEY_ALPHAVANTAGE 16 | urlMSFT = r"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=" + str2 + r"&interval=5min&apikey=" + APIKEY_ALPHAVANTAGE 17 | urlAMZN = r"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=" + str3 + r"&interval=5min&apikey=" + APIKEY_ALPHAVANTAGE 18 | 19 | # use urllib.request.urlopen() to access API from URL links 20 | responseAAPL = urllib.request.urlopen(urlAAPL) 21 | responseMSFT = urllib.request.urlopen(urlMSFT) 22 | responseAMZN = urllib.request.urlopen(urlAMZN) 23 | 24 | # from var saved (HTTPresponse type), use .read() + .decode('utf-8') 25 | stringAAPL = responseAAPL.read().decode('utf-8') 26 | stringMSFT = responseMSFT.read().decode('utf-8') 27 | stringAMZN = responseAMZN.read().decode('utf-8') 28 | 29 | # Access and read API contents 30 | # Have to read 3 APIs at a time due to limitations of Alpha Vantage API for free use (max 5 accesses per minute) 31 | # Unable to read all 6 stock APIs (FAANGM) at once 32 | # Wait for 1 min 33 | time.sleep(60.1) 34 | 35 | # save url inside variable as raw string 36 | urlGOOGL = r"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=" + str4 + r"&interval=5min&apikey=" + APIKEY_ALPHAVANTAGE 37 | urlFB = r"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=" + str5 + r"&interval=5min&apikey=" + APIKEY_ALPHAVANTAGE 38 | urlNFLX = r"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=" + str6 + r"&interval=5min&apikey=" + APIKEY_ALPHAVANTAGE 39 | 40 | # use urllib.request.urlopen() 41 | responseGOOGL = urllib.request.urlopen(urlGOOGL) 42 | responseFB = urllib.request.urlopen(urlFB) 43 | responseNFLX = urllib.request.urlopen(urlNFLX) 44 | 45 | # from var saved (HTTPresponse type), use .read() + .decode('utf-8') 46 | stringGOOGL = responseGOOGL.read().decode('utf-8') 47 | stringFB = responseFB.read().decode('utf-8') 48 | stringNFLX = responseNFLX.read().decode('utf-8') 49 | 50 | print("Stock data has been retrieved successfully...") 51 | 52 | return [stringAAPL, stringMSFT, stringAMZN, stringGOOGL, stringFB, stringNFLX] -------------------------------------------------------------------------------- /day_interval_fourstocks/datasdailyfour.py: -------------------------------------------------------------------------------- 1 | # Build lists to store information for stock prices at (open, close, high, low) at 5 minute intervals 2 | # This step can be built into a Python Class in the future to allow users to select their own stock names 3 | 4 | # https://www.powercms.in/blog/how-get-json-data-remote-url-python-script 5 | 6 | import json 7 | # from class datetime import subclass datetime 8 | from datetime import datetime 9 | import numpy as np 10 | 11 | def transformdata(string1,string2,string3,string4,startdate): 12 | # load string saved into json data 13 | jsondataAAPL = json.loads(string1) 14 | jsondataAMZN = json.loads(string2) 15 | jsondataGOOGL = json.loads(string3) 16 | jsondataFB = json.loads(string4) 17 | 18 | 19 | # Get all keys of time series (datetime) as string type and save it onto a list 20 | timeAAPL = list(reversed(list(jsondataAAPL['Time Series (Daily)'].keys()))) 21 | timeAMZN = list(reversed(list(jsondataAMZN['Time Series (Daily)'].keys()))) 22 | timeGOOGL = list(reversed(list(jsondataGOOGL['Time Series (Daily)'].keys()))) 23 | timeFB = list(reversed(list(jsondataFB['Time Series (Daily)'].keys()))) 24 | 25 | # Get element index/position for start date 26 | try: 27 | startposition = timeAAPL.index(startdate) 28 | except: 29 | startposition = 0 30 | 31 | 32 | AAPLopen = [] 33 | AAPLhigh = [] 34 | AAPLlow = [] 35 | AAPLclose = [] 36 | AMZNopen = [] 37 | AMZNhigh = [] 38 | AMZNlow = [] 39 | AMZNclose = [] 40 | GOOGLopen = [] 41 | GOOGLhigh = [] 42 | GOOGLlow = [] 43 | GOOGLclose = [] 44 | FBopen = [] 45 | FBhigh = [] 46 | FBlow = [] 47 | FBclose = [] 48 | timeAAPL_s = [] 49 | timeAMZN_s = [] 50 | timeGOOGL_s = [] 51 | timeFB_s = [] 52 | 53 | # Get all the stock information using the datetime key used in the JSON packet 54 | trackposition = -1 55 | for string in timeAAPL: 56 | trackposition += 1 57 | if trackposition < startposition: 58 | continue 59 | timeAAPL_s.append(string[:]) 60 | AAPLopen.append(float(jsondataAAPL['Time Series (Daily)'][string]['1. open'])) 61 | AAPLhigh.append(float(jsondataAAPL['Time Series (Daily)'][string]['2. high'])) 62 | AAPLlow.append(float(jsondataAAPL['Time Series (Daily)'][string]['3. low'])) 63 | AAPLclose.append(float(jsondataAAPL['Time Series (Daily)'][string]['4. close'])) 64 | 65 | trackposition = -1 66 | for string in timeAMZN: 67 | trackposition += 1 68 | if trackposition < startposition: 69 | continue 70 | timeAMZN_s.append(string[:]) 71 | AMZNopen.append(float(jsondataAMZN['Time Series (Daily)'][string]['1. open'])) 72 | AMZNhigh.append(float(jsondataAMZN['Time Series (Daily)'][string]['2. high'])) 73 | AMZNlow.append(float(jsondataAMZN['Time Series (Daily)'][string]['3. low'])) 74 | AMZNclose.append(float(jsondataAMZN['Time Series (Daily)'][string]['4. close'])) 75 | 76 | trackposition = -1 77 | for string in timeGOOGL: 78 | trackposition += 1 79 | if trackposition < startposition: 80 | continue 81 | timeGOOGL_s.append(string[:]) 82 | GOOGLopen.append(float(jsondataGOOGL['Time Series (Daily)'][string]['1. open'])) 83 | GOOGLhigh.append(float(jsondataGOOGL['Time Series (Daily)'][string]['2. high'])) 84 | GOOGLlow.append(float(jsondataGOOGL['Time Series (Daily)'][string]['3. low'])) 85 | GOOGLclose.append(float(jsondataGOOGL['Time Series (Daily)'][string]['4. close'])) 86 | 87 | trackposition = -1 88 | for string in timeFB: 89 | trackposition += 1 90 | if trackposition < startposition: 91 | continue 92 | timeFB_s.append(string[:]) 93 | FBopen.append(float(jsondataFB['Time Series (Daily)'][string]['1. open'])) 94 | FBhigh.append(float(jsondataFB['Time Series (Daily)'][string]['2. high'])) 95 | FBlow.append(float(jsondataFB['Time Series (Daily)'][string]['3. low'])) 96 | FBclose.append(float(jsondataFB['Time Series (Daily)'][string]['4. close'])) 97 | 98 | 99 | # Create normalized list of 9 companies stock prices by the price at opening 100 | # This is used for plotting the relative stock performance chart (% movement in a day) for all 6 stocks 101 | AAPLdailyopen_n = np.array(AAPLopen)/AAPLopen[0] 102 | AMZNdailyopen_n = np.array(AMZNopen)/AMZNopen[0] 103 | GOOGLdailyopen_n = np.array(GOOGLopen)/GOOGLopen[0] 104 | FBdailyopen_n = np.array(FBopen)/FBopen[0] 105 | 106 | # Get percentage change of each stock to show in the title of graphs 107 | AAPL_change = round((AAPLopen[-1] - AAPLopen[0])/AAPLopen[0] * 100,2) 108 | AMZN_change = round((AMZNopen[-1] - AMZNopen[0])/AMZNopen[0] * 100,2) 109 | GOOGL_change = round((GOOGLopen[-1] - GOOGLopen[0])/GOOGLopen[0] * 100,2) 110 | FB_change = round((FBopen[-1] - FBopen[0])/FBopen[0] * 100,2) 111 | 112 | return {"daily": [AAPLdailyopen_n, AMZNdailyopen_n, GOOGLdailyopen_n, FBdailyopen_n], 113 | "change": [AAPL_change, AMZN_change, GOOGL_change, FB_change], 114 | "time": [timeAAPL_s, timeAMZN_s, timeGOOGL_s, timeFB_s], 115 | "open": [AAPLopen, AMZNopen, GOOGLopen, FBopen], 116 | "high": [AAPLhigh, AMZNhigh, GOOGLhigh, FBhigh], 117 | "low": [AAPLlow, AMZNlow, GOOGLlow, FBlow], 118 | "close": [AAPLclose, AMZNclose, GOOGLclose, FBclose] 119 | } -------------------------------------------------------------------------------- /min_interval_fourstocks/datasfour.py: -------------------------------------------------------------------------------- 1 | # Build lists to store information for stock prices at (open, close, high, low) at 5 minute intervals 2 | # This step can be built into a Python Class in the future to allow users to select their own stock names 3 | 4 | # https://www.powercms.in/blog/how-get-json-data-remote-url-python-script 5 | 6 | import json 7 | # from class datetime import subclass datetime 8 | from datetime import datetime 9 | import numpy as np 10 | 11 | def transformdata(string1,string2,string3,string4,startdatetime): 12 | # load string saved into json data 13 | jsondataAAPL = json.loads(string1) 14 | jsondataAMZN = json.loads(string2) 15 | jsondataGOOGL = json.loads(string3) 16 | jsondataFB = json.loads(string4) 17 | 18 | 19 | # Get all keys of time series (datetime) as string type and save it onto a list 20 | timeAAPL = list(reversed(list(jsondataAAPL['Time Series (5min)'].keys()))) 21 | timeAMZN = list(reversed(list(jsondataAMZN['Time Series (5min)'].keys()))) 22 | timeGOOGL = list(reversed(list(jsondataGOOGL['Time Series (5min)'].keys()))) 23 | timeFB = list(reversed(list(jsondataFB['Time Series (5min)'].keys()))) 24 | 25 | # Get element index/position for start datetime 26 | 27 | # Append :00 to the time if less than 2 : are detected, i.e. the seconds are not put 28 | try: 29 | startdatetime = str(startdatetime) 30 | ticker = 0 31 | for letter in startdatetime: 32 | if letter == ':': 33 | ticker += 1 34 | # Only add seconds if a time is put inside, e.g. 2020-05-09 10:00 (1 colon) or 11:30 (1 colon) 35 | if ticker == 1: 36 | startdatetime += ":00" 37 | # print(startdatetime) 38 | except: 39 | startdatetime = "" 40 | 41 | try: 42 | startposition = 0 43 | ticker = 0 44 | for curdatetime in timeAAPL: 45 | if str(curdatetime).find(startdatetime) > -1: 46 | startposition = ticker 47 | break 48 | ticker += 1 49 | except: 50 | startposition = 0 51 | 52 | AAPLopen = [] 53 | AAPLhigh = [] 54 | AAPLlow = [] 55 | AAPLclose = [] 56 | AMZNopen = [] 57 | AMZNhigh = [] 58 | AMZNlow = [] 59 | AMZNclose = [] 60 | GOOGLopen = [] 61 | GOOGLhigh = [] 62 | GOOGLlow = [] 63 | GOOGLclose = [] 64 | FBopen = [] 65 | FBhigh = [] 66 | FBlow = [] 67 | FBclose = [] 68 | timeAAPL_s = [] 69 | timeAMZN_s = [] 70 | timeGOOGL_s = [] 71 | timeFB_s = [] 72 | 73 | # Get all the stock information using the datetime key used in the JSON packet 74 | trackposition = -1 75 | for string in timeAAPL: 76 | trackposition += 1 77 | if trackposition < startposition: 78 | continue 79 | timeAAPL_s.append(string[2:16]) 80 | AAPLopen.append(float(jsondataAAPL['Time Series (5min)'][string]['1. open'])) 81 | AAPLhigh.append(float(jsondataAAPL['Time Series (5min)'][string]['2. high'])) 82 | AAPLlow.append(float(jsondataAAPL['Time Series (5min)'][string]['3. low'])) 83 | AAPLclose.append(float(jsondataAAPL['Time Series (5min)'][string]['4. close'])) 84 | 85 | trackposition = -1 86 | for string in timeAMZN: 87 | trackposition += 1 88 | if trackposition < startposition: 89 | continue 90 | timeAMZN_s.append(string[2:16]) 91 | AMZNopen.append(float(jsondataAMZN['Time Series (5min)'][string]['1. open'])) 92 | AMZNhigh.append(float(jsondataAMZN['Time Series (5min)'][string]['2. high'])) 93 | AMZNlow.append(float(jsondataAMZN['Time Series (5min)'][string]['3. low'])) 94 | AMZNclose.append(float(jsondataAMZN['Time Series (5min)'][string]['4. close'])) 95 | 96 | trackposition = -1 97 | for string in timeGOOGL: 98 | trackposition += 1 99 | if trackposition < startposition: 100 | continue 101 | timeGOOGL_s.append(string[2:16]) 102 | GOOGLopen.append(float(jsondataGOOGL['Time Series (5min)'][string]['1. open'])) 103 | GOOGLhigh.append(float(jsondataGOOGL['Time Series (5min)'][string]['2. high'])) 104 | GOOGLlow.append(float(jsondataGOOGL['Time Series (5min)'][string]['3. low'])) 105 | GOOGLclose.append(float(jsondataGOOGL['Time Series (5min)'][string]['4. close'])) 106 | 107 | trackposition = -1 108 | for string in timeFB: 109 | trackposition += 1 110 | if trackposition < startposition: 111 | continue 112 | timeFB_s.append(string[2:16]) 113 | FBopen.append(float(jsondataFB['Time Series (5min)'][string]['1. open'])) 114 | FBhigh.append(float(jsondataFB['Time Series (5min)'][string]['2. high'])) 115 | FBlow.append(float(jsondataFB['Time Series (5min)'][string]['3. low'])) 116 | FBclose.append(float(jsondataFB['Time Series (5min)'][string]['4. close'])) 117 | 118 | 119 | # Create normalized list of 9 companies stock prices by the price at opening 120 | # This is used for plotting the relative stock performance chart (% movement in a day) for all 6 stocks 121 | AAPLdailyopen_n = np.array(AAPLopen)/AAPLopen[0] 122 | AMZNdailyopen_n = np.array(AMZNopen)/AMZNopen[0] 123 | GOOGLdailyopen_n = np.array(GOOGLopen)/GOOGLopen[0] 124 | FBdailyopen_n = np.array(FBopen)/FBopen[0] 125 | 126 | # Get percentage change of each stock to show in the title of graphs 127 | AAPL_change = round((AAPLopen[-1] - AAPLopen[0])/AAPLopen[0] * 100,2) 128 | AMZN_change = round((AMZNopen[-1] - AMZNopen[0])/AMZNopen[0] * 100,2) 129 | GOOGL_change = round((GOOGLopen[-1] - GOOGLopen[0])/GOOGLopen[0] * 100,2) 130 | FB_change = round((FBopen[-1] - FBopen[0])/FBopen[0] * 100,2) 131 | 132 | return {"daily": [AAPLdailyopen_n, AMZNdailyopen_n, GOOGLdailyopen_n, FBdailyopen_n], 133 | "change": [AAPL_change, AMZN_change, GOOGL_change, FB_change], 134 | "time": [timeAAPL_s, timeAMZN_s, timeGOOGL_s, timeFB_s], 135 | "open": [AAPLopen, AMZNopen, GOOGLopen, FBopen], 136 | "high": [AAPLhigh, AMZNhigh, GOOGLhigh, FBhigh], 137 | "low": [AAPLlow, AMZNlow, GOOGLlow, FBlow], 138 | "close": [AAPLclose, AMZNclose, GOOGLclose, FBclose] 139 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Stock-Market-Dashboard 2 | Creating a stock market dashboard from an external REST API (Alpha Vantage) - only for NYSE stocks - that allows investors to track daily performance of stocks and relative performance between stocks which can be easily transferred in jpg or pdf format. 3 | ## Installation 4 | ``` 5 | pip install -r pip_install.txt 6 | ``` 7 | requirements.txt show all the library dependencies, but using the pip_install.txt will do 8 | ## Motivations 9 | While there are a lot of websites and apps that show great visualisation of stocks, there are many limitations like: 10 |
1. Being able to select and view different stock trends at once 11 |
2. Analyse relative performance (% change) between stocks over the day 12 |
3. Sending stock reports via images/pdf quickly instead of spending time to screenshot an app/saving a website many times. The current applications and terminals out there charge a hefty fee for such features. 13 |
Hence, the motivation to create a dashboard from API of live data to allow investors to analyse stocks and send reports easily! 14 | ## Updates 15 | 12 May 2020 - Code has been refactored significantly to make it more production ready (instead of being in notebooks only) 16 |
Python code to run/import now has four variants: 17 | 18 | | Folder | Main Python File | Number of stocks | Stock Price Time Interval | Stock Time Range | Delay | 19 | | :---: | :---: | :---: | :---: | :---: | :---: | 20 | | min_interval | dashboard.py | 6 | 5 minutes | 1.5 days | 1 min++ | 21 | | min_interval_fourstocks | dashboardfour.py | 4 | 5 minutes | 1.5 days | Minimal delay | 22 | | day_interval | dashboarddaily.py | 6 | 1 day | 6 months | 1 min++ | 23 | | day_interval_fourstocks | dashboarddailyfour.py | 4 | 1 day | 6 months | Minimal delay | 24 | 25 | ## Building a dashboard for daily changing stock prices with API online 26 | JSON file received from REST API has stock information for a particular stock
27 | 1. Receives JSON data file as string and convert it to dictionary format to easily access data
28 | 2. Data cleaning is done to format datetime, store them in correct order for plotting
29 | 3. Stock prices and datetime are stored in Python lists for convenience of plotting
30 | 4. Basic calculation done in numpy to find percentage change for display and relative stock performance graph 31 | ## Dashboard Design - Divided into two halves 32 | ![Stock Prices for June 6, 2019](https://github.com/kohjiaxuan/Stock-Market-Dashboard/blob/master/archive/Dashboard_2019-06-06.jpg) 33 |
34 | 5. The top half has 6 small graphs to show daily movement chart of each tech stock (FAANGM) or stock listing name of your choice
35 | 6. The bottom half has stock index movement normalized by a specific starting stock price in order to track relative performance of each stock to others over the day/months. As per point 12, the starting date/time can be selected. 36 | ## Improvements in code (May 2020) 37 | 7. Tidied up repo into folders, old notebooks and images are now put in archive 38 | 8. Each folder has a main py file called dashboard.py or dashboard(variantname).py to be used directly or imported by another script file (refer to Updates section for more info) 39 | 9. This allows you to plot stock market dashboards for the past 6 months (daily changes) and for the past day (5 min intervals) respectively 40 | 10. Running the Python scripts directly will give a sample jpg/pdf in the same directory 41 | 11. test scripts such as testday.py and testmin.py are in the tests folder (import test on dashboarddaily and dashboard respectively) and show how to import the script and use its "main" function 42 | 12. New feature that allows user to choose a start date (e.g. 2020-01-02) for dashboarddaily.py or start time (e.g. 09:35) for dashboard.py to do percentage change comparison. The graph will be plotted until the current/latest date/datetime 43 | ## Useful information 44 | * To use the code, just run the main Python files (listed in Updates section) directly or import them 45 | * Note that the dashboard py files already have some sample stock market listings inside that will execute by default, this can be changed (look for the line if __name__ == "__main__":) 46 | * Importing the dashboard py files will not activate the generation of stock market dashboard, user can use the main function to generate any comparison/sets of NYSE stock listings 47 | * Delay in the py code is due to the restriction of 5 API calls/min for the basic Alpha Vantage API, user can remove the time delay in the retrieve.py if they are using premium/paid API (remove time.sleep(60.1) in the code) 48 | * User must put the API key in the retrieve.py of each respective folder of dashboard.py before using, under APIKEY_ALPHAVANTAGE = "PUTAPIKEYHERE" 49 | * dashboard.py will use retrieve.py, datas.py and legend.py 50 | * test folder with test py scripts showcase how to call the dashboard.py scripts and export the JPG/PDF in the parent folder of the script importing dashboard.py 51 | * By default, PDF file and matplotlib plot is shown. To stop this, comment out os.startfile(pdf_name) and plt.show() respectively. 52 | * matplotlib plot might show skewed axes/titles/plots due to problems of scaling on the open window, however Juypter Notebook and the exported jpg/pdf will not have this issue 53 | * 9 June 2019 - Latest notebook is FINAL. Using API to build Stock Market Dashboard.ipynb modified on 9 Jun 2019 54 | * Earliest design of dashboard is Draft_Dashboard_Structure.png in Mar 2019 55 | * Older versions of Juypter Notebook are named in alphabetical order (BE, BF, BF2, BF3, BF4, BF5), now stored in notebooks folder 56 | * Older designs of dashboard are also present in the repository in archive folder 57 | ## Libraries used 58 | * Library used include urllib for accessing API, time to delay the script running for a minute so that 3x2 API calls can be made to circumvent the 5 API call limit/min, os to add the parent directory storing the dashboard scripts for absolute imports and opening PDF file, json to convert string into dictionary, datetime for formatting date time, numpy for calculations and matplotlib for graph plotting 59 | * Refer to pip_install.txt and requirements.txt for what to pip install and all the library dependencies respectively 60 | ## Future Plans 61 | * Building a front end interface via a Python app or web browser (Javascript) to increase user friendliness (not run it through a notebook) and allow users to select their stocks 62 | * Using an email library that allows the images/PDF to be sent to the person's email on a hourly/daily/weekly basis 63 | * Productionizing code with cron or Windows scheduler 64 | * Deployment onto the cloud using Flask 65 | -------------------------------------------------------------------------------- /day_interval/datasdaily.py: -------------------------------------------------------------------------------- 1 | # Build lists to store information for stock prices at (open, close, high, low) at 5 minute intervals 2 | # This step can be built into a Python Class in the future to allow users to select their own stock names 3 | 4 | # https://www.powercms.in/blog/how-get-json-data-remote-url-python-script 5 | 6 | import json 7 | # from class datetime import subclass datetime 8 | from datetime import datetime 9 | import numpy as np 10 | 11 | def transformdata(string1,string2,string3,string4,string5,string6,startdate): 12 | # load string saved into json data 13 | jsondataAAPL = json.loads(string1) 14 | jsondataAMZN = json.loads(string2) 15 | jsondataGOOGL = json.loads(string3) 16 | jsondataFB = json.loads(string4) 17 | jsondataMSFT = json.loads(string5) 18 | jsondataNFLX = json.loads(string6) 19 | 20 | 21 | # Get all keys of time series (datetime) as string type and save it onto a list 22 | timeAAPL = list(reversed(list(jsondataAAPL['Time Series (Daily)'].keys()))) 23 | timeAMZN = list(reversed(list(jsondataAMZN['Time Series (Daily)'].keys()))) 24 | timeGOOGL = list(reversed(list(jsondataGOOGL['Time Series (Daily)'].keys()))) 25 | timeFB = list(reversed(list(jsondataFB['Time Series (Daily)'].keys()))) 26 | timeMSFT = list(reversed(list(jsondataMSFT['Time Series (Daily)'].keys()))) 27 | timeNFLX = list(reversed(list(jsondataNFLX['Time Series (Daily)'].keys()))) 28 | 29 | # Get element index/position for start date 30 | try: 31 | startposition = timeAAPL.index(startdate) 32 | except: 33 | startposition = 0 34 | 35 | 36 | AAPLopen = [] 37 | AAPLhigh = [] 38 | AAPLlow = [] 39 | AAPLclose = [] 40 | AMZNopen = [] 41 | AMZNhigh = [] 42 | AMZNlow = [] 43 | AMZNclose = [] 44 | GOOGLopen = [] 45 | GOOGLhigh = [] 46 | GOOGLlow = [] 47 | GOOGLclose = [] 48 | FBopen = [] 49 | FBhigh = [] 50 | FBlow = [] 51 | FBclose = [] 52 | MSFTopen = [] 53 | MSFThigh = [] 54 | MSFTlow = [] 55 | MSFTclose = [] 56 | NFLXopen = [] 57 | NFLXhigh = [] 58 | NFLXlow = [] 59 | NFLXclose = [] 60 | timeAAPL_s = [] 61 | timeAMZN_s = [] 62 | timeGOOGL_s = [] 63 | timeFB_s = [] 64 | timeMSFT_s = [] 65 | timeNFLX_s = [] 66 | 67 | # Get all the stock information using the datetime key used in the JSON packet 68 | trackposition = -1 69 | for string in timeAAPL: 70 | trackposition += 1 71 | if trackposition < startposition: 72 | continue 73 | timeAAPL_s.append(string[:]) 74 | AAPLopen.append(float(jsondataAAPL['Time Series (Daily)'][string]['1. open'])) 75 | AAPLhigh.append(float(jsondataAAPL['Time Series (Daily)'][string]['2. high'])) 76 | AAPLlow.append(float(jsondataAAPL['Time Series (Daily)'][string]['3. low'])) 77 | AAPLclose.append(float(jsondataAAPL['Time Series (Daily)'][string]['4. close'])) 78 | 79 | trackposition = -1 80 | for string in timeAMZN: 81 | trackposition += 1 82 | if trackposition < startposition: 83 | continue 84 | timeAMZN_s.append(string[:]) 85 | AMZNopen.append(float(jsondataAMZN['Time Series (Daily)'][string]['1. open'])) 86 | AMZNhigh.append(float(jsondataAMZN['Time Series (Daily)'][string]['2. high'])) 87 | AMZNlow.append(float(jsondataAMZN['Time Series (Daily)'][string]['3. low'])) 88 | AMZNclose.append(float(jsondataAMZN['Time Series (Daily)'][string]['4. close'])) 89 | 90 | trackposition = -1 91 | for string in timeGOOGL: 92 | trackposition += 1 93 | if trackposition < startposition: 94 | continue 95 | timeGOOGL_s.append(string[:]) 96 | GOOGLopen.append(float(jsondataGOOGL['Time Series (Daily)'][string]['1. open'])) 97 | GOOGLhigh.append(float(jsondataGOOGL['Time Series (Daily)'][string]['2. high'])) 98 | GOOGLlow.append(float(jsondataGOOGL['Time Series (Daily)'][string]['3. low'])) 99 | GOOGLclose.append(float(jsondataGOOGL['Time Series (Daily)'][string]['4. close'])) 100 | 101 | trackposition = -1 102 | for string in timeFB: 103 | trackposition += 1 104 | if trackposition < startposition: 105 | continue 106 | timeFB_s.append(string[:]) 107 | FBopen.append(float(jsondataFB['Time Series (Daily)'][string]['1. open'])) 108 | FBhigh.append(float(jsondataFB['Time Series (Daily)'][string]['2. high'])) 109 | FBlow.append(float(jsondataFB['Time Series (Daily)'][string]['3. low'])) 110 | FBclose.append(float(jsondataFB['Time Series (Daily)'][string]['4. close'])) 111 | 112 | trackposition = -1 113 | for string in timeMSFT: 114 | trackposition += 1 115 | if trackposition < startposition: 116 | continue 117 | timeMSFT_s.append(string[:]) 118 | MSFTopen.append(float(jsondataMSFT['Time Series (Daily)'][string]['1. open'])) 119 | MSFThigh.append(float(jsondataMSFT['Time Series (Daily)'][string]['2. high'])) 120 | MSFTlow.append(float(jsondataMSFT['Time Series (Daily)'][string]['3. low'])) 121 | MSFTclose.append(float(jsondataMSFT['Time Series (Daily)'][string]['4. close'])) 122 | 123 | trackposition = -1 124 | for string in timeNFLX: 125 | trackposition += 1 126 | if trackposition < startposition: 127 | continue 128 | timeNFLX_s.append(string[:]) 129 | NFLXopen.append(float(jsondataNFLX['Time Series (Daily)'][string]['1. open'])) 130 | NFLXhigh.append(float(jsondataNFLX['Time Series (Daily)'][string]['2. high'])) 131 | NFLXlow.append(float(jsondataNFLX['Time Series (Daily)'][string]['3. low'])) 132 | NFLXclose.append(float(jsondataNFLX['Time Series (Daily)'][string]['4. close'])) 133 | 134 | 135 | # Create normalized list of 9 companies stock prices by the price at opening 136 | # This is used for plotting the relative stock performance chart (% movement in a day) for all 6 stocks 137 | AAPLdailyopen_n = np.array(AAPLopen)/AAPLopen[0] 138 | AMZNdailyopen_n = np.array(AMZNopen)/AMZNopen[0] 139 | GOOGLdailyopen_n = np.array(GOOGLopen)/GOOGLopen[0] 140 | FBdailyopen_n = np.array(FBopen)/FBopen[0] 141 | MSFTdailyopen_n = np.array(MSFTopen)/MSFTopen[0] 142 | NFLXdailyopen_n = np.array(NFLXopen)/NFLXopen[0] 143 | 144 | # Get percentage change of each stock to show in the title of graphs 145 | AAPL_change = round((AAPLopen[-1] - AAPLopen[0])/AAPLopen[0] * 100,2) 146 | AMZN_change = round((AMZNopen[-1] - AMZNopen[0])/AMZNopen[0] * 100,2) 147 | GOOGL_change = round((GOOGLopen[-1] - GOOGLopen[0])/GOOGLopen[0] * 100,2) 148 | FB_change = round((FBopen[-1] - FBopen[0])/FBopen[0] * 100,2) 149 | MSFT_change = round((MSFTopen[-1] - MSFTopen[0])/MSFTopen[0] * 100,2) 150 | NFLX_change = round((NFLXopen[-1] - NFLXopen[0])/NFLXopen[0] * 100,2) 151 | 152 | return {"daily": [AAPLdailyopen_n, AMZNdailyopen_n, GOOGLdailyopen_n, FBdailyopen_n, MSFTdailyopen_n, NFLXdailyopen_n], 153 | "change": [AAPL_change, AMZN_change, GOOGL_change, FB_change, MSFT_change, NFLX_change], 154 | "time": [timeAAPL_s, timeAMZN_s, timeGOOGL_s, timeFB_s, timeMSFT_s, timeNFLX_s], 155 | "open": [AAPLopen, AMZNopen, GOOGLopen, FBopen, MSFTopen, NFLXopen], 156 | "high": [AAPLhigh, AMZNhigh, GOOGLhigh, FBhigh, MSFThigh, NFLXhigh], 157 | "low": [AAPLlow, AMZNlow, GOOGLlow, FBlow, MSFTlow, NFLXlow], 158 | "close": [AAPLclose, AMZNclose, GOOGLclose, FBclose, MSFTclose, NFLXclose] 159 | } -------------------------------------------------------------------------------- /min_interval/datas.py: -------------------------------------------------------------------------------- 1 | # Build lists to store information for stock prices at (open, close, high, low) at 5 minute intervals 2 | # This step can be built into a Python Class in the future to allow users to select their own stock names 3 | 4 | # https://www.powercms.in/blog/how-get-json-data-remote-url-python-script 5 | 6 | import json 7 | # from class datetime import subclass datetime 8 | from datetime import datetime 9 | import numpy as np 10 | 11 | def transformdata(string1,string2,string3,string4,string5,string6,startdatetime): 12 | # load string saved into json data 13 | jsondataAAPL = json.loads(string1) 14 | jsondataAMZN = json.loads(string2) 15 | jsondataGOOGL = json.loads(string3) 16 | jsondataFB = json.loads(string4) 17 | jsondataMSFT = json.loads(string5) 18 | jsondataNFLX = json.loads(string6) 19 | 20 | 21 | # Get all keys of time series (datetime) as string type and save it onto a list 22 | timeAAPL = list(reversed(list(jsondataAAPL['Time Series (5min)'].keys()))) 23 | timeAMZN = list(reversed(list(jsondataAMZN['Time Series (5min)'].keys()))) 24 | timeGOOGL = list(reversed(list(jsondataGOOGL['Time Series (5min)'].keys()))) 25 | timeFB = list(reversed(list(jsondataFB['Time Series (5min)'].keys()))) 26 | timeMSFT = list(reversed(list(jsondataMSFT['Time Series (5min)'].keys()))) 27 | timeNFLX = list(reversed(list(jsondataNFLX['Time Series (5min)'].keys()))) 28 | 29 | # Get element index/position for start datetime 30 | 31 | # Append :00 to the time if less than 2 : are detected, i.e. the seconds are not put 32 | try: 33 | startdatetime = str(startdatetime) 34 | ticker = 0 35 | for letter in startdatetime: 36 | if letter == ':': 37 | ticker += 1 38 | # Only add seconds if a time is put inside, e.g. 2020-05-09 10:00 (1 colon) or 11:30 (1 colon) 39 | if ticker == 1: 40 | startdatetime += ":00" 41 | # print(startdatetime) 42 | except: 43 | startdatetime = "" 44 | 45 | try: 46 | startposition = 0 47 | ticker = 0 48 | for curdatetime in timeAAPL: 49 | if str(curdatetime).find(startdatetime) > -1: 50 | startposition = ticker 51 | break 52 | ticker += 1 53 | except: 54 | startposition = 0 55 | 56 | AAPLopen = [] 57 | AAPLhigh = [] 58 | AAPLlow = [] 59 | AAPLclose = [] 60 | AMZNopen = [] 61 | AMZNhigh = [] 62 | AMZNlow = [] 63 | AMZNclose = [] 64 | GOOGLopen = [] 65 | GOOGLhigh = [] 66 | GOOGLlow = [] 67 | GOOGLclose = [] 68 | FBopen = [] 69 | FBhigh = [] 70 | FBlow = [] 71 | FBclose = [] 72 | MSFTopen = [] 73 | MSFThigh = [] 74 | MSFTlow = [] 75 | MSFTclose = [] 76 | NFLXopen = [] 77 | NFLXhigh = [] 78 | NFLXlow = [] 79 | NFLXclose = [] 80 | timeAAPL_s = [] 81 | timeAMZN_s = [] 82 | timeGOOGL_s = [] 83 | timeFB_s = [] 84 | timeMSFT_s = [] 85 | timeNFLX_s = [] 86 | 87 | # Get all the stock information using the datetime key used in the JSON packet 88 | trackposition = -1 89 | for string in timeAAPL: 90 | trackposition += 1 91 | if trackposition < startposition: 92 | continue 93 | timeAAPL_s.append(string[2:16]) 94 | AAPLopen.append(float(jsondataAAPL['Time Series (5min)'][string]['1. open'])) 95 | AAPLhigh.append(float(jsondataAAPL['Time Series (5min)'][string]['2. high'])) 96 | AAPLlow.append(float(jsondataAAPL['Time Series (5min)'][string]['3. low'])) 97 | AAPLclose.append(float(jsondataAAPL['Time Series (5min)'][string]['4. close'])) 98 | 99 | trackposition = -1 100 | for string in timeAMZN: 101 | trackposition += 1 102 | if trackposition < startposition: 103 | continue 104 | timeAMZN_s.append(string[2:16]) 105 | AMZNopen.append(float(jsondataAMZN['Time Series (5min)'][string]['1. open'])) 106 | AMZNhigh.append(float(jsondataAMZN['Time Series (5min)'][string]['2. high'])) 107 | AMZNlow.append(float(jsondataAMZN['Time Series (5min)'][string]['3. low'])) 108 | AMZNclose.append(float(jsondataAMZN['Time Series (5min)'][string]['4. close'])) 109 | 110 | trackposition = -1 111 | for string in timeGOOGL: 112 | trackposition += 1 113 | if trackposition < startposition: 114 | continue 115 | timeGOOGL_s.append(string[2:16]) 116 | GOOGLopen.append(float(jsondataGOOGL['Time Series (5min)'][string]['1. open'])) 117 | GOOGLhigh.append(float(jsondataGOOGL['Time Series (5min)'][string]['2. high'])) 118 | GOOGLlow.append(float(jsondataGOOGL['Time Series (5min)'][string]['3. low'])) 119 | GOOGLclose.append(float(jsondataGOOGL['Time Series (5min)'][string]['4. close'])) 120 | 121 | trackposition = -1 122 | for string in timeFB: 123 | trackposition += 1 124 | if trackposition < startposition: 125 | continue 126 | timeFB_s.append(string[2:16]) 127 | FBopen.append(float(jsondataFB['Time Series (5min)'][string]['1. open'])) 128 | FBhigh.append(float(jsondataFB['Time Series (5min)'][string]['2. high'])) 129 | FBlow.append(float(jsondataFB['Time Series (5min)'][string]['3. low'])) 130 | FBclose.append(float(jsondataFB['Time Series (5min)'][string]['4. close'])) 131 | 132 | trackposition = -1 133 | for string in timeMSFT: 134 | trackposition += 1 135 | if trackposition < startposition: 136 | continue 137 | timeMSFT_s.append(string[2:16]) 138 | MSFTopen.append(float(jsondataMSFT['Time Series (5min)'][string]['1. open'])) 139 | MSFThigh.append(float(jsondataMSFT['Time Series (5min)'][string]['2. high'])) 140 | MSFTlow.append(float(jsondataMSFT['Time Series (5min)'][string]['3. low'])) 141 | MSFTclose.append(float(jsondataMSFT['Time Series (5min)'][string]['4. close'])) 142 | 143 | trackposition = -1 144 | for string in timeNFLX: 145 | trackposition += 1 146 | if trackposition < startposition: 147 | continue 148 | timeNFLX_s.append(string[2:16]) 149 | NFLXopen.append(float(jsondataNFLX['Time Series (5min)'][string]['1. open'])) 150 | NFLXhigh.append(float(jsondataNFLX['Time Series (5min)'][string]['2. high'])) 151 | NFLXlow.append(float(jsondataNFLX['Time Series (5min)'][string]['3. low'])) 152 | NFLXclose.append(float(jsondataNFLX['Time Series (5min)'][string]['4. close'])) 153 | 154 | 155 | # Create normalized list of 9 companies stock prices by the price at opening 156 | # This is used for plotting the relative stock performance chart (% movement in a day) for all 6 stocks 157 | AAPLdailyopen_n = np.array(AAPLopen)/AAPLopen[0] 158 | AMZNdailyopen_n = np.array(AMZNopen)/AMZNopen[0] 159 | GOOGLdailyopen_n = np.array(GOOGLopen)/GOOGLopen[0] 160 | FBdailyopen_n = np.array(FBopen)/FBopen[0] 161 | MSFTdailyopen_n = np.array(MSFTopen)/MSFTopen[0] 162 | NFLXdailyopen_n = np.array(NFLXopen)/NFLXopen[0] 163 | 164 | # Get percentage change of each stock to show in the title of graphs 165 | AAPL_change = round((AAPLopen[-1] - AAPLopen[0])/AAPLopen[0] * 100,2) 166 | AMZN_change = round((AMZNopen[-1] - AMZNopen[0])/AMZNopen[0] * 100,2) 167 | GOOGL_change = round((GOOGLopen[-1] - GOOGLopen[0])/GOOGLopen[0] * 100,2) 168 | FB_change = round((FBopen[-1] - FBopen[0])/FBopen[0] * 100,2) 169 | MSFT_change = round((MSFTopen[-1] - MSFTopen[0])/MSFTopen[0] * 100,2) 170 | NFLX_change = round((NFLXopen[-1] - NFLXopen[0])/NFLXopen[0] * 100,2) 171 | 172 | return {"daily": [AAPLdailyopen_n, AMZNdailyopen_n, GOOGLdailyopen_n, FBdailyopen_n, MSFTdailyopen_n, NFLXdailyopen_n], 173 | "change": [AAPL_change, AMZN_change, GOOGL_change, FB_change, MSFT_change, NFLX_change], 174 | "time": [timeAAPL_s, timeAMZN_s, timeGOOGL_s, timeFB_s, timeMSFT_s, timeNFLX_s], 175 | "open": [AAPLopen, AMZNopen, GOOGLopen, FBopen, MSFTopen, NFLXopen], 176 | "high": [AAPLhigh, AMZNhigh, GOOGLhigh, FBhigh, MSFThigh, NFLXhigh], 177 | "low": [AAPLlow, AMZNlow, GOOGLlow, FBlow, MSFTlow, NFLXlow], 178 | "close": [AAPLclose, AMZNclose, GOOGLclose, FBclose, MSFTclose, NFLXclose] 179 | } -------------------------------------------------------------------------------- /min_interval_fourstocks/dashboardfour.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | from matplotlib.ticker import MaxNLocator 3 | from matplotlib.ticker import LinearLocator 4 | import os 5 | # %matplotlib inline 6 | import retrievefour 7 | import datasfour 8 | import legendfour 9 | 10 | def main(stock1, stock2, stock3, stock4, startdatetime=''): 11 | stockdata = retrievefour.stocks(stock1, stock2, stock3, stock4) 12 | transformed_data = datasfour.transformdata(stockdata[0], stockdata[1], stockdata[2], stockdata[3], startdatetime) 13 | 14 | # Create dashboard of stocks 15 | # A big graph at the bottom comparing the relative performance (in %) of each stock over the day 16 | # Instead of using the candlestick plot, I used a continuous line plot with dotted lines signifying the higher/lower bound 17 | 18 | # Plan of subplot layering (1x1 one for title, 2x1 for overlaid graphs, 4x2 one for small graphs but only occupy top 4 spaces) 19 | 20 | # Create big figure 21 | stocks = plt.figure(1,figsize=(24,30)) 22 | plt.style.use('ggplot') 23 | 24 | #Create big subplot for title and remove frame (frameon=False), remove tick parameters 25 | stocks_title = stocks.add_subplot(111, frameon=False) #remove frame but need remove ticks/axes 26 | stocks_title.tick_params(labelcolor='none', top=False, bottom=False, left=False, right=False) 27 | stocks_title.set_title('Daily Stock Prices (USD)', fontsize=28) 28 | 29 | # Determine where to put legend board in relative stock performance graph 30 | legendjson = legendfour.legendcalculation(transformed_data["daily"][0], transformed_data["daily"][1], transformed_data["daily"][2], transformed_data["daily"][3]) 31 | 32 | #Create big subplot for mega chart using 2x1 plot using normal .add_subplot 33 | #Change x-axis to be integer (year) and y-axis to be integer (price_index) 34 | stocks_big = stocks.add_subplot(212) 35 | #If apple stock is higher than the start (legendjson['stockloc'][0] == 4), add + sign in the stock price 36 | #If apple stock is lower than the start, number has - sign so + sign is omitted 37 | #Repeat for all other stocks 38 | if legendjson['stockloc'][0] == 4: 39 | AAPL_n = stocks_big.plot(transformed_data["time"][0], transformed_data["daily"][0], '-o', label=stock1+' +'+str(transformed_data["change"][0])+'%', linewidth = 4, markersize=8) 40 | else: 41 | AAPL_n = stocks_big.plot(transformed_data["time"][0], transformed_data["daily"][0], '-o', label=stock1+' '+str(transformed_data["change"][0])+'%', linewidth = 4, markersize=8) 42 | 43 | if legendjson['stockloc'][1] == 4: 44 | AMZN_n = stocks_big.plot(transformed_data["time"][1], transformed_data["daily"][1], '-o', label=stock2+' +'+str(transformed_data["change"][1])+'%', linewidth = 4, markersize=8) 45 | else: 46 | AMZN_n = stocks_big.plot(transformed_data["time"][1], transformed_data["daily"][1], '-o', label=stock2+' '+str(transformed_data["change"][1])+'%', linewidth = 4, markersize=8) 47 | 48 | if legendjson['stockloc'][2] == 4: 49 | GOOGL_n = stocks_big.plot(transformed_data["time"][2], transformed_data["daily"][2], '-o', label=stock3+' +'+str(transformed_data["change"][2])+'%', linewidth = 4, markersize=8) 50 | else: 51 | GOOGL_n = stocks_big.plot(transformed_data["time"][2], transformed_data["daily"][2], '-o', label=stock3+' '+str(transformed_data["change"][2])+'%', linewidth = 4, markersize=8) 52 | 53 | if legendjson['stockloc'][3] == 4: 54 | FB_n = stocks_big.plot(transformed_data["time"][3], transformed_data["daily"][3], '-o', label=stock4+' +'+str(transformed_data["change"][3])+'%', linewidth = 4, markersize=8) 55 | else: 56 | FB_n = stocks_big.plot(transformed_data["time"][3], transformed_data["daily"][3], '-o', label=stock4+' '+str(transformed_data["change"][3])+'%', linewidth = 4, markersize=8) 57 | 58 | #Get all handle/variable storing the legend in a tuple from 0-8 and also all label of the legend var in a tuple from 0-8 59 | #Each element n of the tuple has a pair of handle/label associated 60 | handlesN, labelsN = plt.gca().get_legend_handles_labels() 61 | order = [0,1,2,3] 62 | stocks_big.legend([handlesN[idx] for idx in order],[labelsN[idx] for idx in order], loc=legendjson['legendloc'], fontsize=24) 63 | #Possible improvement is to detect initial and final position of graphs and relocate legend loc=1,2,3,4 accordingly every day 64 | stocks_big.tick_params(axis='y', which='major', labelsize=24) 65 | stocks_big.tick_params(axis='x', which='major', labelsize=14) 66 | stocks_big.set_title('Relative Graph of Stock Price Index', fontsize=28) 67 | #Get datetime and add it to x label 68 | stocks_big.set_xlabel('Index for the Day: 20' + transformed_data["time"][0][0][0:8],fontsize=28) 69 | stocks_big.set_ylabel('Stock Price Index',fontsize=28) 70 | stocks_big.xaxis.set_major_locator(MaxNLocator(integer=True)) 71 | stocks_big.yaxis.set_major_locator(MaxNLocator(integer=True)) 72 | 73 | #Horizontal line denoting the starting stock index at beginning of time 74 | stocks_big.axhline(y=1, color='black', linestyle='--') 75 | 76 | 77 | #Create matplotlib figure with subplot size 4x2 plot using fig, axes_small (axes_small is np.array) 78 | #Found out that it is easier to use big figure and overlay many different size of subplot (1x1 title), (2x1 big chart), 79 | #(4x2 small charts) into a single matplotlib figure 80 | #instead of using fig, axes to define fig and axes (matrix size) tgt since there is varying sizes 81 | 82 | 83 | #Plot the individual stock graphs for each stock from position 1 to 4 in 4x2 matrix 84 | #Note that positions 5-8 taken up by big graph. It is equivalent to add_subplot(212) - position 2 in 2x1 matrix 85 | 86 | AAPLplot = stocks.add_subplot(421) 87 | #AAPLplot.set_xlabel('Date & Time',fontsize=14) 88 | AAPLplot.set_ylabel('Stock Price (USD)',fontsize=18) 89 | if legendjson['stockloc'][0] == 4: 90 | AAPLplot.set_title(stock1+' Stock Price +'+str(transformed_data["change"][0])+'%',fontsize=24,color='g') 91 | else: 92 | AAPLplot.set_title(stock1+' Stock Price '+str(transformed_data["change"][0])+'%',fontsize=24,color='r') 93 | AAPLplot.tick_params(axis='y', which='major', labelsize=16) 94 | AAPLplot.tick_params(axis='x', which='major', labelsize=7) 95 | AAPLdailyopen = AAPLplot.plot(transformed_data["time"][0],transformed_data["open"][0],color='blue', label='Open') 96 | AAPLdailyhigh = AAPLplot.plot(transformed_data["time"][0],transformed_data["high"][0],'--',color='green', label='High') 97 | AAPLdailylow = AAPLplot.plot(transformed_data["time"][0],transformed_data["low"][0],'--',color='red', label='Low') 98 | AAPLdailyclose = AAPLplot.plot(transformed_data["time"][0],transformed_data["close"][0],'.', color='black', label='Close') 99 | AAPLplot.legend(loc=legendjson['stockloc'][0], fontsize=14) 100 | #Major locator helps in choosing the right numbers for x and y axis to be more presentable 101 | AAPLplot.xaxis.set_major_locator(MaxNLocator(integer=True)) 102 | AAPLplot.yaxis.set_major_locator(LinearLocator(9)) 103 | 104 | AMZNplot = stocks.add_subplot(422) 105 | #AMZNplot.set_xlabel('Date & Time',fontsize=14) 106 | AMZNplot.set_ylabel('Stock Price (USD)',fontsize=18) 107 | if legendjson['stockloc'][1] == 4: 108 | AMZNplot.set_title(stock2+' Stock Price +'+str(transformed_data["change"][1])+'%',fontsize=24,color='g') 109 | else: 110 | AMZNplot.set_title(stock2+' Stock Price '+str(transformed_data["change"][1])+'%',fontsize=24,color='r') 111 | AMZNplot.tick_params(axis='y', which='major', labelsize=16) 112 | AMZNplot.tick_params(axis='x', which='major', labelsize=7) 113 | AMZNdailyopen = AMZNplot.plot(transformed_data["time"][1],transformed_data["open"][1],color='blue', label='Open') 114 | AMZNdailyhigh = AMZNplot.plot(transformed_data["time"][1],transformed_data["high"][1],'--',color='green', label='High') 115 | AMZNdailylow = AMZNplot.plot(transformed_data["time"][1],transformed_data["low"][1],'--',color='red', label='Low') 116 | AMZNdailyclose = AMZNplot.plot(transformed_data["time"][1],transformed_data["close"][1],'.', color='black', label='Close') 117 | AMZNplot.legend(loc=legendjson['stockloc'][1], fontsize=14) 118 | AMZNplot.xaxis.set_major_locator(MaxNLocator(integer=True)) 119 | AMZNplot.yaxis.set_major_locator(LinearLocator(9)) 120 | 121 | GOOGLplot = stocks.add_subplot(423) 122 | #GOOGLplot.set_xlabel('Date & Time',fontsize=14) 123 | GOOGLplot.set_ylabel('Stock Price (USD)',fontsize=18) 124 | if legendjson['stockloc'][2] == 4: 125 | GOOGLplot.set_title(stock3+' Stock Price +'+str(transformed_data["change"][2])+'%',fontsize=24,color='g') 126 | else: 127 | GOOGLplot.set_title(stock3+' Stock Price '+str(transformed_data["change"][2])+'%',fontsize=24,color='r') 128 | GOOGLplot.tick_params(axis='y', which='major', labelsize=16) 129 | GOOGLplot.tick_params(axis='x', which='major', labelsize=7) 130 | GOOGLdailyopen = GOOGLplot.plot(transformed_data["time"][2],transformed_data["open"][2],color='blue', label='Open') 131 | GOOGLdailyhigh = GOOGLplot.plot(transformed_data["time"][2],transformed_data["high"][2],'--',color='green', label='High') 132 | GOOGLdailylow = GOOGLplot.plot(transformed_data["time"][2],transformed_data["low"][2],'--',color='red', label='Low') 133 | GOOGLdailyclose = GOOGLplot.plot(transformed_data["time"][2],transformed_data["close"][2],'.', color='black', label='Close') 134 | GOOGLplot.legend(loc=legendjson['stockloc'][2], fontsize=14) 135 | GOOGLplot.xaxis.set_major_locator(MaxNLocator(integer=True)) 136 | GOOGLplot.yaxis.set_major_locator(LinearLocator(9)) 137 | 138 | FBplot = stocks.add_subplot(424) 139 | #FBplot.set_xlabel('Date & Time',fontsize=14) 140 | FBplot.set_ylabel('Stock Price (USD)',fontsize=18) 141 | if legendjson['stockloc'][3] == 4: 142 | FBplot.set_title(stock4+' Stock Price +'+str(transformed_data["change"][3])+'%',fontsize=24,color='g') 143 | else: 144 | FBplot.set_title(stock4+' Stock Price '+str(transformed_data["change"][3])+'%',fontsize=24,color='r') 145 | FBplot.tick_params(axis='y', which='major', labelsize=16) 146 | FBplot.tick_params(axis='x', which='major', labelsize=7) 147 | FBdailyopen = FBplot.plot(transformed_data["time"][3],transformed_data["open"][3],color='blue', label='Open') 148 | FBdailyhigh = FBplot.plot(transformed_data["time"][3],transformed_data["high"][3],'--',color='green', label='High') 149 | FBdailylow = FBplot.plot(transformed_data["time"][3],transformed_data["low"][3],'--',color='red', label='Low') 150 | FBdailyclose = FBplot.plot(transformed_data["time"][3],transformed_data["close"][3],'.', color='black', label='Close') 151 | FBplot.legend(loc=legendjson['stockloc'][3], fontsize=14) 152 | FBplot.xaxis.set_major_locator(MaxNLocator(integer=True)) 153 | FBplot.yaxis.set_major_locator(LinearLocator(9)) 154 | 155 | #Save as jpg, pdf with today's date 156 | stocknames = '_'+stock1+'-'+stock2+'-'+stock3+'-'+stock4 157 | jpg_name = 'Dashboard_'+str("20"+transformed_data["time"][0][0][0:8])+stocknames+'.jpg' 158 | pdf_name = 'Dashboard_'+str("20"+transformed_data["time"][0][0][0:8])+stocknames+'.pdf' 159 | stocks.savefig(jpg_name) 160 | stocks.savefig(pdf_name) 161 | 162 | #Show all plots 163 | plt.show() 164 | 165 | #Notification if there are no errors to inform on file names 166 | print('Dashboard saved as: '+jpg_name+' in local directory') 167 | print('Dashboard saved as: '+pdf_name+' in local directory') 168 | 169 | # Open PDF file 170 | os.startfile(pdf_name) 171 | 172 | 173 | if __name__ == "__main__": 174 | main('MCD','YUM','CMG','QSR','10:00') -------------------------------------------------------------------------------- /day_interval_fourstocks/dashboarddailyfour.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | from matplotlib.ticker import MaxNLocator 3 | from matplotlib.ticker import LinearLocator 4 | import os 5 | # %matplotlib inline 6 | import retrievedailyfour 7 | import datasdailyfour 8 | import legendfour 9 | 10 | def main(stock1, stock2, stock3, stock4, startdate=''): 11 | stockdata = retrievedailyfour.stocks(stock1, stock2, stock3, stock4) 12 | transformed_data = datasdailyfour.transformdata(stockdata[0], stockdata[1], stockdata[2], stockdata[3], startdate) 13 | 14 | # Create dashboard of stocks 15 | # A big graph at the bottom comparing the relative performance (in %) of each stock over the day 16 | # Instead of using the candlestick plot, I used a continuous line plot with dotted lines signifying the higher/lower bound 17 | 18 | # Plan of subplot layering (1x1 one for title, 2x1 for overlaid graphs, 4x2 one for small graphs but only occupy top 4 spaces) 19 | 20 | # Create big figure 21 | stocks = plt.figure(1,figsize=(24,30)) 22 | plt.style.use('ggplot') 23 | 24 | #Create big subplot for title and remove frame (frameon=False), remove tick parameters 25 | stocks_title = stocks.add_subplot(111, frameon=False) #remove frame but need remove ticks/axes 26 | stocks_title.tick_params(labelcolor='none', top=False, bottom=False, left=False, right=False) 27 | stocks_title.set_title('Daily Stock Prices (USD)', fontsize=28) 28 | 29 | # Determine where to put legend board in relative stock performance graph 30 | legendjson = legendfour.legendcalculation(transformed_data["daily"][0], transformed_data["daily"][1], transformed_data["daily"][2], transformed_data["daily"][3]) 31 | 32 | #Create big subplot for mega chart using 2x1 plot using normal .add_subplot 33 | #Change x-axis to be integer (year) and y-axis to be integer (price_index) 34 | stocks_big = stocks.add_subplot(212) 35 | #If apple stock is higher than the start (legendjson['stockloc'][0] == 4), add + sign in the stock price 36 | #If apple stock is lower than the start, number has - sign so + sign is omitted 37 | #Repeat for all other stocks 38 | if legendjson['stockloc'][0] == 4: 39 | AAPL_n = stocks_big.plot(transformed_data["time"][0], transformed_data["daily"][0], '-o', label=stock1+' +'+str(transformed_data["change"][0])+'%', linewidth = 4, markersize=8) 40 | else: 41 | AAPL_n = stocks_big.plot(transformed_data["time"][0], transformed_data["daily"][0], '-o', label=stock1+' '+str(transformed_data["change"][0])+'%', linewidth = 4, markersize=8) 42 | 43 | if legendjson['stockloc'][1] == 4: 44 | AMZN_n = stocks_big.plot(transformed_data["time"][1], transformed_data["daily"][1], '-o', label=stock2+' +'+str(transformed_data["change"][1])+'%', linewidth = 4, markersize=8) 45 | else: 46 | AMZN_n = stocks_big.plot(transformed_data["time"][1], transformed_data["daily"][1], '-o', label=stock2+' '+str(transformed_data["change"][1])+'%', linewidth = 4, markersize=8) 47 | 48 | if legendjson['stockloc'][2] == 4: 49 | GOOGL_n = stocks_big.plot(transformed_data["time"][2], transformed_data["daily"][2], '-o', label=stock3+' +'+str(transformed_data["change"][2])+'%', linewidth = 4, markersize=8) 50 | else: 51 | GOOGL_n = stocks_big.plot(transformed_data["time"][2], transformed_data["daily"][2], '-o', label=stock3+' '+str(transformed_data["change"][2])+'%', linewidth = 4, markersize=8) 52 | 53 | if legendjson['stockloc'][3] == 4: 54 | FB_n = stocks_big.plot(transformed_data["time"][3], transformed_data["daily"][3], '-o', label=stock4+' +'+str(transformed_data["change"][3])+'%', linewidth = 4, markersize=8) 55 | else: 56 | FB_n = stocks_big.plot(transformed_data["time"][3], transformed_data["daily"][3], '-o', label=stock4+' '+str(transformed_data["change"][3])+'%', linewidth = 4, markersize=8) 57 | 58 | #Get all handle/variable storing the legend in a tuple from 0-8 and also all label of the legend var in a tuple from 0-8 59 | #Each element n of the tuple has a pair of handle/label associated 60 | handlesN, labelsN = plt.gca().get_legend_handles_labels() 61 | order = [0,1,2,3] 62 | stocks_big.legend([handlesN[idx] for idx in order],[labelsN[idx] for idx in order], loc=legendjson['legendloc'], fontsize=24) 63 | #Possible improvement is to detect initial and final position of graphs and relocate legend loc=1,2,3,4 accordingly every day 64 | stocks_big.tick_params(axis='y', which='major', labelsize=22) 65 | stocks_big.tick_params(axis='x', which='major', labelsize=20) 66 | stocks_big.set_title('Relative Graph of Stock Price Index', fontsize=30) 67 | #Get datetime and add it to x label 68 | stocks_big.set_xlabel('Index starting from date: ' + transformed_data["time"][0][0],fontsize=28) 69 | stocks_big.set_ylabel('Stock Price Index',fontsize=28) 70 | stocks_big.xaxis.set_major_locator(MaxNLocator(integer=True)) 71 | stocks_big.yaxis.set_major_locator(MaxNLocator(integer=True)) 72 | 73 | #Horizontal line denoting the starting stock index at beginning of time 74 | stocks_big.axhline(y=1, color='black', linestyle='--') 75 | 76 | 77 | #Create matplotlib figure with subplot size 4x2 plot using fig, axes_small (axes_small is np.array) 78 | #Found out that it is easier to use big figure and overlay many different size of subplot (1x1 title), (2x1 big chart), 79 | #(4x2 small charts) into a single matplotlib figure 80 | #instead of using fig, axes to define fig and axes (matrix size) tgt since there is varying sizes 81 | 82 | 83 | #Plot the individual stock graphs for each stock from position 1 to 4 in 4x2 matrix 84 | #Note that positions 5-8 taken up by big graph. It is equivalent to add_subplot(212) - position 2 in 2x1 matrix 85 | 86 | AAPLplot = stocks.add_subplot(421) 87 | #AAPLplot.set_xlabel('Date & Time',fontsize=14) 88 | AAPLplot.set_ylabel('Stock Price (USD)',fontsize=18) 89 | if legendjson['stockloc'][0] == 4: 90 | AAPLplot.set_title(stock1+' Stock Price +'+str(transformed_data["change"][0])+'%',fontsize=24,color='g') 91 | else: 92 | AAPLplot.set_title(stock1+' Stock Price '+str(transformed_data["change"][0])+'%',fontsize=24,color='r') 93 | AAPLplot.tick_params(axis='y', which='major', labelsize=16) 94 | AAPLplot.tick_params(axis='x', which='major', labelsize=12) 95 | AAPLdailyopen = AAPLplot.plot(transformed_data["time"][0],transformed_data["open"][0],color='blue', label='Open') 96 | AAPLdailyhigh = AAPLplot.plot(transformed_data["time"][0],transformed_data["high"][0],'--',color='green', label='High') 97 | AAPLdailylow = AAPLplot.plot(transformed_data["time"][0],transformed_data["low"][0],'--',color='red', label='Low') 98 | AAPLdailyclose = AAPLplot.plot(transformed_data["time"][0],transformed_data["close"][0],'.', color='black', label='Close') 99 | AAPLplot.legend(loc=legendjson['stockloc'][0], fontsize=16) 100 | #Major locator helps in choosing the right numbers for x and y axis to be more presentable 101 | AAPLplot.xaxis.set_major_locator(MaxNLocator(integer=True)) 102 | AAPLplot.yaxis.set_major_locator(LinearLocator(9)) 103 | 104 | AMZNplot = stocks.add_subplot(422) 105 | #AMZNplot.set_xlabel('Date & Time',fontsize=14) 106 | AMZNplot.set_ylabel('Stock Price (USD)',fontsize=18) 107 | if legendjson['stockloc'][1] == 4: 108 | AMZNplot.set_title(stock2+' Stock Price +'+str(transformed_data["change"][1])+'%',fontsize=24,color='g') 109 | else: 110 | AMZNplot.set_title(stock2+' Stock Price '+str(transformed_data["change"][1])+'%',fontsize=24,color='r') 111 | AMZNplot.tick_params(axis='y', which='major', labelsize=16) 112 | AMZNplot.tick_params(axis='x', which='major', labelsize=12) 113 | AMZNdailyopen = AMZNplot.plot(transformed_data["time"][1],transformed_data["open"][1],color='blue', label='Open') 114 | AMZNdailyhigh = AMZNplot.plot(transformed_data["time"][1],transformed_data["high"][1],'--',color='green', label='High') 115 | AMZNdailylow = AMZNplot.plot(transformed_data["time"][1],transformed_data["low"][1],'--',color='red', label='Low') 116 | AMZNdailyclose = AMZNplot.plot(transformed_data["time"][1],transformed_data["close"][1],'.', color='black', label='Close') 117 | AMZNplot.legend(loc=legendjson['stockloc'][1], fontsize=16) 118 | AMZNplot.xaxis.set_major_locator(MaxNLocator(integer=True)) 119 | AMZNplot.yaxis.set_major_locator(LinearLocator(9)) 120 | 121 | GOOGLplot = stocks.add_subplot(423) 122 | #GOOGLplot.set_xlabel('Date & Time',fontsize=14) 123 | GOOGLplot.set_ylabel('Stock Price (USD)',fontsize=18) 124 | if legendjson['stockloc'][2] == 4: 125 | GOOGLplot.set_title(stock3+' Stock Price +'+str(transformed_data["change"][2])+'%',fontsize=24,color='g') 126 | else: 127 | GOOGLplot.set_title(stock3+' Stock Price '+str(transformed_data["change"][2])+'%',fontsize=24,color='r') 128 | GOOGLplot.tick_params(axis='y', which='major', labelsize=16) 129 | GOOGLplot.tick_params(axis='x', which='major', labelsize=12) 130 | GOOGLdailyopen = GOOGLplot.plot(transformed_data["time"][2],transformed_data["open"][2],color='blue', label='Open') 131 | GOOGLdailyhigh = GOOGLplot.plot(transformed_data["time"][2],transformed_data["high"][2],'--',color='green', label='High') 132 | GOOGLdailylow = GOOGLplot.plot(transformed_data["time"][2],transformed_data["low"][2],'--',color='red', label='Low') 133 | GOOGLdailyclose = GOOGLplot.plot(transformed_data["time"][2],transformed_data["close"][2],'.', color='black', label='Close') 134 | GOOGLplot.legend(loc=legendjson['stockloc'][2], fontsize=16) 135 | GOOGLplot.xaxis.set_major_locator(MaxNLocator(integer=True)) 136 | GOOGLplot.yaxis.set_major_locator(LinearLocator(9)) 137 | 138 | FBplot = stocks.add_subplot(424) 139 | #FBplot.set_xlabel('Date & Time',fontsize=14) 140 | FBplot.set_ylabel('Stock Price (USD)',fontsize=18) 141 | if legendjson['stockloc'][3] == 4: 142 | FBplot.set_title(stock4+' Stock Price +'+str(transformed_data["change"][3])+'%',fontsize=24,color='g') 143 | else: 144 | FBplot.set_title(stock4+' Stock Price '+str(transformed_data["change"][3])+'%',fontsize=24,color='r') 145 | FBplot.tick_params(axis='y', which='major', labelsize=16) 146 | FBplot.tick_params(axis='x', which='major', labelsize=12) 147 | FBdailyopen = FBplot.plot(transformed_data["time"][3],transformed_data["open"][3],color='blue', label='Open') 148 | FBdailyhigh = FBplot.plot(transformed_data["time"][3],transformed_data["high"][3],'--',color='green', label='High') 149 | FBdailylow = FBplot.plot(transformed_data["time"][3],transformed_data["low"][3],'--',color='red', label='Low') 150 | FBdailyclose = FBplot.plot(transformed_data["time"][3],transformed_data["close"][3],'.', color='black', label='Close') 151 | FBplot.legend(loc=legendjson['stockloc'][3], fontsize=16) 152 | FBplot.xaxis.set_major_locator(MaxNLocator(integer=True)) 153 | FBplot.yaxis.set_major_locator(LinearLocator(9)) 154 | 155 | #Save as jpg, pdf with today's date 156 | stocknames = '_'+stock1+'-'+stock2+'-'+stock3+'-'+stock4 157 | jpg_name = 'DashboardDaily_'+str(transformed_data["time"][0][0][0:10])+stocknames+'.jpg' 158 | pdf_name = 'DashboardDaily_'+str(transformed_data["time"][0][0][0:10])+stocknames+'.pdf' 159 | stocks.savefig(jpg_name) 160 | stocks.savefig(pdf_name) 161 | 162 | #Show all plots 163 | plt.show() 164 | 165 | #Notification if there are no errors to inform on file names 166 | print('Dashboard saved as: '+jpg_name+' in local directory') 167 | print('Dashboard saved as: '+pdf_name+' in local directory') 168 | 169 | # Open PDF file 170 | os.startfile(pdf_name) 171 | 172 | 173 | if __name__ == "__main__": 174 | main('XOM', 'CVX', 'BP', 'SNP', '2019-12-18') -------------------------------------------------------------------------------- /min_interval/dashboard.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | from matplotlib.ticker import MaxNLocator 3 | from matplotlib.ticker import LinearLocator 4 | import os 5 | # %matplotlib inline 6 | import retrieve 7 | import datas 8 | import legend 9 | 10 | def main(stock1, stock2, stock3, stock4, stock5, stock6, startdatetime=''): 11 | print('Retrieving stock takes 1 min due to max 5 API call per min, remove time.sleep(60.1) if using premium API account') 12 | stockdata = retrieve.stocks(stock1, stock2, stock3, stock4, stock5, stock6) 13 | print('Stock data has been successfully retrieved.') 14 | transformed_data = datas.transformdata(stockdata[0], stockdata[1], stockdata[2], stockdata[3], stockdata[4], stockdata[5], startdatetime) 15 | 16 | # Create dashboard of stocks 17 | # There will be 6 small graphs at the top for the daily stock movement for the 6 US tech stocks (FAANGM) 18 | # A big graph at the bottom comparing the relative performance (in %) of each stock over the day 19 | # Instead of using the candlestick plot, I used a continuous line plot with dotted lines signifying the higher/lower bound 20 | 21 | # Plan of subplot layering (1x1 one for title, 2x1 for overlaid graphs, 6x3 one for small graphs but only occupy top 9 spaces) 22 | 23 | # Create big figure 24 | stocks = plt.figure(1,figsize=(24,30)) 25 | plt.style.use('ggplot') 26 | 27 | #Create big subplot for title and remove frame (frameon=False), remove tick parameters 28 | stocks_title = stocks.add_subplot(111, frameon=False) #remove frame but need remove ticks/axes 29 | stocks_title.tick_params(labelcolor='none', top=False, bottom=False, left=False, right=False) 30 | stocks_title.set_title('Daily Stock Prices (USD)', fontsize=24) 31 | 32 | # Determine where to put legend board in relative stock performance graph 33 | legendjson = legend.legendcalculation(transformed_data["daily"][0], transformed_data["daily"][1], transformed_data["daily"][2], transformed_data["daily"][3], transformed_data["daily"][4], transformed_data["daily"][5]) 34 | 35 | #Create big subplot for mega chart using 2x1 plot using normal .add_subplot 36 | #Change x-axis to be integer (year) and y-axis to be integer (price_index) 37 | stocks_big = stocks.add_subplot(212) 38 | #If apple stock is higher than the start (legendjson['stockloc'][0] == 4), add + sign in the stock price 39 | #If apple stock is lower than the start, number has - sign so + sign is omitted 40 | #Repeat for all other stocks 41 | if legendjson['stockloc'][0] == 4: 42 | AAPL_n = stocks_big.plot(transformed_data["time"][0], transformed_data["daily"][0], '-o', label=stock1+' +'+str(transformed_data["change"][0])+'%', linewidth = 4, markersize=8) 43 | else: 44 | AAPL_n = stocks_big.plot(transformed_data["time"][0], transformed_data["daily"][0], '-o', label=stock1+' '+str(transformed_data["change"][0])+'%', linewidth = 4, markersize=8) 45 | 46 | if legendjson['stockloc'][1] == 4: 47 | AMZN_n = stocks_big.plot(transformed_data["time"][1], transformed_data["daily"][1], '-o', label=stock2+' +'+str(transformed_data["change"][1])+'%', linewidth = 4, markersize=8) 48 | else: 49 | AMZN_n = stocks_big.plot(transformed_data["time"][1], transformed_data["daily"][1], '-o', label=stock2+' '+str(transformed_data["change"][1])+'%', linewidth = 4, markersize=8) 50 | 51 | if legendjson['stockloc'][2] == 4: 52 | GOOGL_n = stocks_big.plot(transformed_data["time"][2], transformed_data["daily"][2], '-o', label=stock3+' +'+str(transformed_data["change"][2])+'%', linewidth = 4, markersize=8) 53 | else: 54 | GOOGL_n = stocks_big.plot(transformed_data["time"][2], transformed_data["daily"][2], '-o', label=stock3+' '+str(transformed_data["change"][2])+'%', linewidth = 4, markersize=8) 55 | 56 | if legendjson['stockloc'][3] == 4: 57 | FB_n = stocks_big.plot(transformed_data["time"][3], transformed_data["daily"][3], '-o', label=stock4+' +'+str(transformed_data["change"][3])+'%', linewidth = 4, markersize=8) 58 | else: 59 | FB_n = stocks_big.plot(transformed_data["time"][3], transformed_data["daily"][3], '-o', label=stock4+' '+str(transformed_data["change"][3])+'%', linewidth = 4, markersize=8) 60 | 61 | if legendjson['stockloc'][4] == 4: 62 | MSFT_n = stocks_big.plot(transformed_data["time"][4], transformed_data["daily"][4], '-o', label=stock5+' +'+str(transformed_data["change"][4])+'%', linewidth = 4, markersize=8) 63 | else: 64 | MSFT_n = stocks_big.plot(transformed_data["time"][4], transformed_data["daily"][4], '-o', label=stock5+' '+str(transformed_data["change"][4])+'%', linewidth = 4, markersize=8) 65 | 66 | if legendjson['stockloc'][5] == 4: 67 | NFLX_n = stocks_big.plot(transformed_data["time"][5], transformed_data["daily"][5], '-o', label=stock6+' +'+str(transformed_data["change"][5])+'%', linewidth = 4, markersize=8) 68 | else: 69 | NFLX_n = stocks_big.plot(transformed_data["time"][5], transformed_data["daily"][5], '-o', label=stock6+' '+str(transformed_data["change"][5])+'%', linewidth = 4, markersize=8) 70 | 71 | #Get all handle/variable storing the legend in a tuple from 0-8 and also all label of the legend var in a tuple from 0-8 72 | #Each element n of the tuple has a pair of handle/label associated 73 | handlesN, labelsN = plt.gca().get_legend_handles_labels() 74 | order = [0,1,2,3,4,5] 75 | stocks_big.legend([handlesN[idx] for idx in order],[labelsN[idx] for idx in order], loc=legendjson['legendloc'], fontsize=24) 76 | #Possible improvement is to detect initial and final position of graphs and relocate legend loc=1,2,3,4 accordingly every day 77 | stocks_big.tick_params(axis='y', which='major', labelsize=22) 78 | stocks_big.tick_params(axis='x', which='major', labelsize=12) 79 | stocks_big.set_title('Relative Graph of Stock Price Index', fontsize=26) 80 | #Get datetime and add it to x label 81 | stocks_big.set_xlabel('Index for the Day: 20' + transformed_data["time"][0][0][0:8],fontsize=24) 82 | stocks_big.set_ylabel('Stock Price Index',fontsize=24) 83 | stocks_big.xaxis.set_major_locator(MaxNLocator(integer=True)) 84 | stocks_big.yaxis.set_major_locator(MaxNLocator(integer=True)) 85 | 86 | #Horizontal line denoting the starting stock index at beginning of time 87 | stocks_big.axhline(y=1, color='black', linestyle='--') 88 | 89 | 90 | #Create matplotlib figure with subplot size 6x3 plot using fig, axes_small (axes_small is np.array) 91 | #Found out that it is easier to use big figure and overlay many different size of subplot (1x1 title), (2x1 big chart), 92 | #(6x3 small charts) into a single matplotlib figure 93 | #instead of using fig, axes to define fig and axes (matrix size) tgt since there is varying sizes 94 | 95 | 96 | #Plot the individual stock graphs for each stock from position 1 to 6 in 6x2 matrix 97 | #Note that positions 7-12 taken up by big graph. It is equivalent to add_subplot(212) - position 2 in 2x1 matrix 98 | 99 | AAPLplot = stocks.add_subplot(621) 100 | #AAPLplot.set_xlabel('Date & Time',fontsize=14) 101 | AAPLplot.set_ylabel('Stock Price (USD)',fontsize=14) 102 | if legendjson['stockloc'][0] == 4: 103 | AAPLplot.set_title(stock1+' Stock Price +'+str(transformed_data["change"][0])+'%',fontsize=20,color='g') 104 | else: 105 | AAPLplot.set_title(stock1+' Stock Price '+str(transformed_data["change"][0])+'%',fontsize=20,color='r') 106 | AAPLplot.tick_params(axis='y', which='major', labelsize=14) 107 | AAPLplot.tick_params(axis='x', which='major', labelsize=7) 108 | AAPLdailyopen = AAPLplot.plot(transformed_data["time"][0],transformed_data["open"][0],color='blue', label='Open') 109 | AAPLdailyhigh = AAPLplot.plot(transformed_data["time"][0],transformed_data["high"][0],'--',color='green', label='High') 110 | AAPLdailylow = AAPLplot.plot(transformed_data["time"][0],transformed_data["low"][0],'--',color='red', label='Low') 111 | AAPLdailyclose = AAPLplot.plot(transformed_data["time"][0],transformed_data["close"][0],'.', color='black', label='Close') 112 | AAPLplot.legend(loc=legendjson['stockloc'][0], fontsize=12) 113 | #Major locator helps in choosing the right numbers for x and y axis to be more presentable 114 | AAPLplot.xaxis.set_major_locator(MaxNLocator(integer=True)) 115 | AAPLplot.yaxis.set_major_locator(LinearLocator(9)) 116 | 117 | AMZNplot = stocks.add_subplot(622) 118 | #AMZNplot.set_xlabel('Date & Time',fontsize=14) 119 | AMZNplot.set_ylabel('Stock Price (USD)',fontsize=14) 120 | if legendjson['stockloc'][1] == 4: 121 | AMZNplot.set_title(stock2+' Stock Price +'+str(transformed_data["change"][1])+'%',fontsize=20,color='g') 122 | else: 123 | AMZNplot.set_title(stock2+' Stock Price '+str(transformed_data["change"][1])+'%',fontsize=20,color='r') 124 | AMZNplot.tick_params(axis='y', which='major', labelsize=14) 125 | AMZNplot.tick_params(axis='x', which='major', labelsize=7) 126 | AMZNdailyopen = AMZNplot.plot(transformed_data["time"][1],transformed_data["open"][1],color='blue', label='Open') 127 | AMZNdailyhigh = AMZNplot.plot(transformed_data["time"][1],transformed_data["high"][1],'--',color='green', label='High') 128 | AMZNdailylow = AMZNplot.plot(transformed_data["time"][1],transformed_data["low"][1],'--',color='red', label='Low') 129 | AMZNdailyclose = AMZNplot.plot(transformed_data["time"][1],transformed_data["close"][1],'.', color='black', label='Close') 130 | AMZNplot.legend(loc=legendjson['stockloc'][1], fontsize=12) 131 | AMZNplot.xaxis.set_major_locator(MaxNLocator(integer=True)) 132 | AMZNplot.yaxis.set_major_locator(LinearLocator(9)) 133 | 134 | GOOGLplot = stocks.add_subplot(623) 135 | #GOOGLplot.set_xlabel('Date & Time',fontsize=14) 136 | GOOGLplot.set_ylabel('Stock Price (USD)',fontsize=14) 137 | if legendjson['stockloc'][2] == 4: 138 | GOOGLplot.set_title(stock3+' Stock Price +'+str(transformed_data["change"][2])+'%',fontsize=20,color='g') 139 | else: 140 | GOOGLplot.set_title(stock3+' Stock Price '+str(transformed_data["change"][2])+'%',fontsize=20,color='r') 141 | GOOGLplot.tick_params(axis='y', which='major', labelsize=14) 142 | GOOGLplot.tick_params(axis='x', which='major', labelsize=7) 143 | GOOGLdailyopen = GOOGLplot.plot(transformed_data["time"][2],transformed_data["open"][2],color='blue', label='Open') 144 | GOOGLdailyhigh = GOOGLplot.plot(transformed_data["time"][2],transformed_data["high"][2],'--',color='green', label='High') 145 | GOOGLdailylow = GOOGLplot.plot(transformed_data["time"][2],transformed_data["low"][2],'--',color='red', label='Low') 146 | GOOGLdailyclose = GOOGLplot.plot(transformed_data["time"][2],transformed_data["close"][2],'.', color='black', label='Close') 147 | GOOGLplot.legend(loc=legendjson['stockloc'][2], fontsize=12) 148 | GOOGLplot.xaxis.set_major_locator(MaxNLocator(integer=True)) 149 | GOOGLplot.yaxis.set_major_locator(LinearLocator(9)) 150 | 151 | FBplot = stocks.add_subplot(624) 152 | #FBplot.set_xlabel('Date & Time',fontsize=14) 153 | FBplot.set_ylabel('Stock Price (USD)',fontsize=14) 154 | if legendjson['stockloc'][3] == 4: 155 | FBplot.set_title(stock4+' Stock Price +'+str(transformed_data["change"][3])+'%',fontsize=20,color='g') 156 | else: 157 | FBplot.set_title(stock4+' Stock Price '+str(transformed_data["change"][3])+'%',fontsize=20,color='r') 158 | FBplot.tick_params(axis='y', which='major', labelsize=14) 159 | FBplot.tick_params(axis='x', which='major', labelsize=7) 160 | FBdailyopen = FBplot.plot(transformed_data["time"][3],transformed_data["open"][3],color='blue', label='Open') 161 | FBdailyhigh = FBplot.plot(transformed_data["time"][3],transformed_data["high"][3],'--',color='green', label='High') 162 | FBdailylow = FBplot.plot(transformed_data["time"][3],transformed_data["low"][3],'--',color='red', label='Low') 163 | FBdailyclose = FBplot.plot(transformed_data["time"][3],transformed_data["close"][3],'.', color='black', label='Close') 164 | FBplot.legend(loc=legendjson['stockloc'][3], fontsize=12) 165 | FBplot.xaxis.set_major_locator(MaxNLocator(integer=True)) 166 | FBplot.yaxis.set_major_locator(LinearLocator(9)) 167 | 168 | MSFTplot = stocks.add_subplot(625) 169 | #MSFTplot.set_xlabel('Date & Time',fontsize=14) 170 | MSFTplot.set_ylabel('Stock Price (USD)',fontsize=14) 171 | if legendjson['stockloc'][4] == 4: 172 | MSFTplot.set_title(stock5+' Stock Price +'+str(transformed_data["change"][4])+'%',fontsize=20,color='g') 173 | else: 174 | MSFTplot.set_title(stock5+' Stock Price '+str(transformed_data["change"][4])+'%',fontsize=20,color='r') 175 | MSFTplot.tick_params(axis='y', which='major', labelsize=14) 176 | MSFTplot.tick_params(axis='x', which='major', labelsize=7) 177 | MSFTdailyopen = MSFTplot.plot(transformed_data["time"][4],transformed_data["open"][4],color='blue', label='Open') 178 | MSFTdailyhigh = MSFTplot.plot(transformed_data["time"][4],transformed_data["high"][4],'--',color='green', label='High') 179 | MSFTdailylow = MSFTplot.plot(transformed_data["time"][4],transformed_data["low"][4],'--',color='red', label='Low') 180 | MSFTdailyclose = MSFTplot.plot(transformed_data["time"][4],transformed_data["close"][4],'.', color='black', label='Close') 181 | MSFTplot.legend(loc=legendjson['stockloc'][4], fontsize=12) 182 | MSFTplot.xaxis.set_major_locator(MaxNLocator(integer=True)) 183 | MSFTplot.yaxis.set_major_locator(LinearLocator(9)) 184 | 185 | NFLXplot = stocks.add_subplot(626) 186 | #NFLXplot.set_xlabel('Date & Time',fontsize=14) 187 | NFLXplot.set_ylabel('Stock Price (USD)',fontsize=14) 188 | if legendjson['stockloc'][5] == 4: 189 | NFLXplot.set_title(stock6+' Stock Price +'+str(transformed_data["change"][5])+'%',fontsize=20,color='g') 190 | else: 191 | NFLXplot.set_title(stock6+' Stock Price '+str(transformed_data["change"][5])+'%',fontsize=20,color='r') 192 | NFLXplot.tick_params(axis='y', which='major', labelsize=14) 193 | NFLXplot.tick_params(axis='x', which='major', labelsize=7) 194 | NFLXdailyopen = NFLXplot.plot(transformed_data["time"][5],transformed_data["open"][5],color='blue', label='Open') 195 | NFLXdailyhigh = NFLXplot.plot(transformed_data["time"][5],transformed_data["high"][5],'--',color='green', label='High') 196 | NFLXdailylow = NFLXplot.plot(transformed_data["time"][5],transformed_data["low"][5],'--',color='red', label='Low') 197 | NFLXdailyclose = NFLXplot.plot(transformed_data["time"][5],transformed_data["close"][5],'.', color='black', label='Close') 198 | NFLXplot.legend(loc=legendjson['stockloc'][5], fontsize=12) 199 | NFLXplot.xaxis.set_major_locator(MaxNLocator(integer=True)) 200 | NFLXplot.yaxis.set_major_locator(LinearLocator(9)) 201 | 202 | #Save as jpg, pdf with today's date 203 | stocknames = '_'+stock1+'-'+stock2+'-'+stock3+'-'+stock4+'-'+stock5+'-'+stock6 204 | jpg_name = 'Dashboard_'+str("20"+transformed_data["time"][0][0][0:8])+stocknames+'.jpg' 205 | pdf_name = 'Dashboard_'+str("20"+transformed_data["time"][0][0][0:8])+stocknames+'.pdf' 206 | stocks.savefig(jpg_name) 207 | stocks.savefig(pdf_name) 208 | 209 | #Show all plots 210 | plt.show() 211 | 212 | #Notification if there are no errors to inform on file names 213 | print('Dashboard saved as: '+jpg_name+' in local directory') 214 | print('Dashboard saved as: '+pdf_name+' in local directory') 215 | 216 | # Open PDF file 217 | os.startfile(pdf_name) 218 | 219 | 220 | if __name__ == "__main__": 221 | main('AAPL', 'AMZN', 'GOOGL', 'FB', 'MSFT', 'NFLX', '09:35') -------------------------------------------------------------------------------- /day_interval/dashboarddaily.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | from matplotlib.ticker import MaxNLocator 3 | from matplotlib.ticker import LinearLocator 4 | import os 5 | # %matplotlib inline 6 | import retrievedaily 7 | import datasdaily 8 | import legend 9 | 10 | def main(stock1, stock2, stock3, stock4, stock5, stock6, startdate=''): 11 | print('Retrieving stock takes 1 min due to max 5 API call per min, remove time.sleep(60.1) if using premium API account') 12 | stockdata = retrievedaily.stocks(stock1, stock2, stock3, stock4, stock5, stock6) 13 | print('Stock data has been successfully retrieved.') 14 | transformed_data = datasdaily.transformdata(stockdata[0], stockdata[1], stockdata[2], stockdata[3], stockdata[4], stockdata[5], startdate) 15 | 16 | # Create dashboard of stocks 17 | # There will be 6 small graphs at the top for the daily stock movement for the 6 US tech stocks (FAANGM) 18 | # A big graph at the bottom comparing the relative performance (in %) of each stock over the day 19 | # Instead of using the candlestick plot, I used a continuous line plot with dotted lines signifying the higher/lower bound 20 | 21 | # Plan of subplot layering (1x1 one for title, 2x1 for overlaid graphs, 6x3 one for small graphs but only occupy top 9 spaces) 22 | 23 | # Create big figure 24 | stocks = plt.figure(1,figsize=(24,30)) 25 | plt.style.use('ggplot') 26 | 27 | #Create big subplot for title and remove frame (frameon=False), remove tick parameters 28 | stocks_title = stocks.add_subplot(111, frameon=False) #remove frame but need remove ticks/axes 29 | stocks_title.tick_params(labelcolor='none', top=False, bottom=False, left=False, right=False) 30 | stocks_title.set_title('Daily Stock Prices (USD)', fontsize=24) 31 | 32 | # Determine where to put legend board in relative stock performance graph 33 | legendjson = legend.legendcalculation(transformed_data["daily"][0], transformed_data["daily"][1], transformed_data["daily"][2], transformed_data["daily"][3], transformed_data["daily"][4], transformed_data["daily"][5]) 34 | 35 | #Create big subplot for mega chart using 2x1 plot using normal .add_subplot 36 | #Change x-axis to be integer (year) and y-axis to be integer (price_index) 37 | stocks_big = stocks.add_subplot(212) 38 | #If apple stock is higher than the start (legendjson['stockloc'][0] == 4), add + sign in the stock price 39 | #If apple stock is lower than the start, number has - sign so + sign is omitted 40 | #Repeat for all other stocks 41 | if legendjson['stockloc'][0] == 4: 42 | AAPL_n = stocks_big.plot(transformed_data["time"][0], transformed_data["daily"][0], '-o', label=stock1+' +'+str(transformed_data["change"][0])+'%', linewidth = 4, markersize=8) 43 | else: 44 | AAPL_n = stocks_big.plot(transformed_data["time"][0], transformed_data["daily"][0], '-o', label=stock1+' '+str(transformed_data["change"][0])+'%', linewidth = 4, markersize=8) 45 | 46 | if legendjson['stockloc'][1] == 4: 47 | AMZN_n = stocks_big.plot(transformed_data["time"][1], transformed_data["daily"][1], '-o', label=stock2+' +'+str(transformed_data["change"][1])+'%', linewidth = 4, markersize=8) 48 | else: 49 | AMZN_n = stocks_big.plot(transformed_data["time"][1], transformed_data["daily"][1], '-o', label=stock2+' '+str(transformed_data["change"][1])+'%', linewidth = 4, markersize=8) 50 | 51 | if legendjson['stockloc'][2] == 4: 52 | GOOGL_n = stocks_big.plot(transformed_data["time"][2], transformed_data["daily"][2], '-o', label=stock3+' +'+str(transformed_data["change"][2])+'%', linewidth = 4, markersize=8) 53 | else: 54 | GOOGL_n = stocks_big.plot(transformed_data["time"][2], transformed_data["daily"][2], '-o', label=stock3+' '+str(transformed_data["change"][2])+'%', linewidth = 4, markersize=8) 55 | 56 | if legendjson['stockloc'][3] == 4: 57 | FB_n = stocks_big.plot(transformed_data["time"][3], transformed_data["daily"][3], '-o', label=stock4+' +'+str(transformed_data["change"][3])+'%', linewidth = 4, markersize=8) 58 | else: 59 | FB_n = stocks_big.plot(transformed_data["time"][3], transformed_data["daily"][3], '-o', label=stock4+' '+str(transformed_data["change"][3])+'%', linewidth = 4, markersize=8) 60 | 61 | if legendjson['stockloc'][4] == 4: 62 | MSFT_n = stocks_big.plot(transformed_data["time"][4], transformed_data["daily"][4], '-o', label=stock5+' +'+str(transformed_data["change"][4])+'%', linewidth = 4, markersize=8) 63 | else: 64 | MSFT_n = stocks_big.plot(transformed_data["time"][4], transformed_data["daily"][4], '-o', label=stock5+' '+str(transformed_data["change"][4])+'%', linewidth = 4, markersize=8) 65 | 66 | if legendjson['stockloc'][5] == 4: 67 | NFLX_n = stocks_big.plot(transformed_data["time"][5], transformed_data["daily"][5], '-o', label=stock6+' +'+str(transformed_data["change"][5])+'%', linewidth = 4, markersize=8) 68 | else: 69 | NFLX_n = stocks_big.plot(transformed_data["time"][5], transformed_data["daily"][5], '-o', label=stock6+' '+str(transformed_data["change"][5])+'%', linewidth = 4, markersize=8) 70 | 71 | #Get all handle/variable storing the legend in a tuple from 0-8 and also all label of the legend var in a tuple from 0-8 72 | #Each element n of the tuple has a pair of handle/label associated 73 | handlesN, labelsN = plt.gca().get_legend_handles_labels() 74 | order = [0,1,2,3,4,5] 75 | stocks_big.legend([handlesN[idx] for idx in order],[labelsN[idx] for idx in order], loc=legendjson['legendloc'], fontsize=24) 76 | #Possible improvement is to detect initial and final position of graphs and relocate legend loc=1,2,3,4 accordingly every day 77 | stocks_big.tick_params(axis='y', which='major', labelsize=22) 78 | stocks_big.tick_params(axis='x', which='major', labelsize=12) 79 | stocks_big.set_title('Relative Graph of Stock Price Index', fontsize=26) 80 | #Get datetime and add it to x label 81 | stocks_big.set_xlabel('Index starting from date: ' + transformed_data["time"][0][0],fontsize=24) 82 | stocks_big.set_ylabel('Stock Price Index',fontsize=24) 83 | stocks_big.xaxis.set_major_locator(MaxNLocator(integer=True)) 84 | stocks_big.yaxis.set_major_locator(MaxNLocator(integer=True)) 85 | 86 | #Horizontal line denoting the starting stock index at beginning of time 87 | stocks_big.axhline(y=1, color='black', linestyle='--') 88 | 89 | 90 | #Create matplotlib figure with subplot size 6x3 plot using fig, axes_small (axes_small is np.array) 91 | #Found out that it is easier to use big figure and overlay many different size of subplot (1x1 title), (2x1 big chart), 92 | #(6x3 small charts) into a single matplotlib figure 93 | #instead of using fig, axes to define fig and axes (matrix size) tgt since there is varying sizes 94 | 95 | 96 | #Plot the individual stock graphs for each stock from position 1 to 6 in 6x2 matrix 97 | #Note that positions 7-12 taken up by big graph. It is equivalent to add_subplot(212) - position 2 in 2x1 matrix 98 | 99 | AAPLplot = stocks.add_subplot(621) 100 | #AAPLplot.set_xlabel('Date & Time',fontsize=14) 101 | AAPLplot.set_ylabel('Stock Price (USD)',fontsize=14) 102 | if legendjson['stockloc'][0] == 4: 103 | AAPLplot.set_title(stock1+' Stock Price +'+str(transformed_data["change"][0])+'%',fontsize=20,color='g') 104 | else: 105 | AAPLplot.set_title(stock1+' Stock Price '+str(transformed_data["change"][0])+'%',fontsize=20,color='r') 106 | AAPLplot.tick_params(axis='y', which='major', labelsize=14) 107 | AAPLplot.tick_params(axis='x', which='major', labelsize=9) 108 | AAPLdailyopen = AAPLplot.plot(transformed_data["time"][0],transformed_data["open"][0],color='blue', label='Open') 109 | AAPLdailyhigh = AAPLplot.plot(transformed_data["time"][0],transformed_data["high"][0],'--',color='green', label='High') 110 | AAPLdailylow = AAPLplot.plot(transformed_data["time"][0],transformed_data["low"][0],'--',color='red', label='Low') 111 | AAPLdailyclose = AAPLplot.plot(transformed_data["time"][0],transformed_data["close"][0],'.', color='black', label='Close') 112 | AAPLplot.legend(loc=legendjson['stockloc'][0], fontsize=12) 113 | #Major locator helps in choosing the right numbers for x and y axis to be more presentable 114 | AAPLplot.xaxis.set_major_locator(MaxNLocator(integer=True)) 115 | AAPLplot.yaxis.set_major_locator(LinearLocator(9)) 116 | 117 | AMZNplot = stocks.add_subplot(622) 118 | #AMZNplot.set_xlabel('Date & Time',fontsize=14) 119 | AMZNplot.set_ylabel('Stock Price (USD)',fontsize=14) 120 | if legendjson['stockloc'][1] == 4: 121 | AMZNplot.set_title(stock2+' Stock Price +'+str(transformed_data["change"][1])+'%',fontsize=20,color='g') 122 | else: 123 | AMZNplot.set_title(stock2+' Stock Price '+str(transformed_data["change"][1])+'%',fontsize=20,color='r') 124 | AMZNplot.tick_params(axis='y', which='major', labelsize=14) 125 | AMZNplot.tick_params(axis='x', which='major', labelsize=9) 126 | AMZNdailyopen = AMZNplot.plot(transformed_data["time"][1],transformed_data["open"][1],color='blue', label='Open') 127 | AMZNdailyhigh = AMZNplot.plot(transformed_data["time"][1],transformed_data["high"][1],'--',color='green', label='High') 128 | AMZNdailylow = AMZNplot.plot(transformed_data["time"][1],transformed_data["low"][1],'--',color='red', label='Low') 129 | AMZNdailyclose = AMZNplot.plot(transformed_data["time"][1],transformed_data["close"][1],'.', color='black', label='Close') 130 | AMZNplot.legend(loc=legendjson['stockloc'][1], fontsize=12) 131 | AMZNplot.xaxis.set_major_locator(MaxNLocator(integer=True)) 132 | AMZNplot.yaxis.set_major_locator(LinearLocator(9)) 133 | 134 | GOOGLplot = stocks.add_subplot(623) 135 | #GOOGLplot.set_xlabel('Date & Time',fontsize=14) 136 | GOOGLplot.set_ylabel('Stock Price (USD)',fontsize=14) 137 | if legendjson['stockloc'][2] == 4: 138 | GOOGLplot.set_title(stock3+' Stock Price +'+str(transformed_data["change"][2])+'%',fontsize=20,color='g') 139 | else: 140 | GOOGLplot.set_title(stock3+' Stock Price '+str(transformed_data["change"][2])+'%',fontsize=20,color='r') 141 | GOOGLplot.tick_params(axis='y', which='major', labelsize=14) 142 | GOOGLplot.tick_params(axis='x', which='major', labelsize=9) 143 | GOOGLdailyopen = GOOGLplot.plot(transformed_data["time"][2],transformed_data["open"][2],color='blue', label='Open') 144 | GOOGLdailyhigh = GOOGLplot.plot(transformed_data["time"][2],transformed_data["high"][2],'--',color='green', label='High') 145 | GOOGLdailylow = GOOGLplot.plot(transformed_data["time"][2],transformed_data["low"][2],'--',color='red', label='Low') 146 | GOOGLdailyclose = GOOGLplot.plot(transformed_data["time"][2],transformed_data["close"][2],'.', color='black', label='Close') 147 | GOOGLplot.legend(loc=legendjson['stockloc'][2], fontsize=12) 148 | GOOGLplot.xaxis.set_major_locator(MaxNLocator(integer=True)) 149 | GOOGLplot.yaxis.set_major_locator(LinearLocator(9)) 150 | 151 | FBplot = stocks.add_subplot(624) 152 | #FBplot.set_xlabel('Date & Time',fontsize=14) 153 | FBplot.set_ylabel('Stock Price (USD)',fontsize=14) 154 | if legendjson['stockloc'][3] == 4: 155 | FBplot.set_title(stock4+' Stock Price +'+str(transformed_data["change"][3])+'%',fontsize=20,color='g') 156 | else: 157 | FBplot.set_title(stock4+' Stock Price '+str(transformed_data["change"][3])+'%',fontsize=20,color='r') 158 | FBplot.tick_params(axis='y', which='major', labelsize=14) 159 | FBplot.tick_params(axis='x', which='major', labelsize=9) 160 | FBdailyopen = FBplot.plot(transformed_data["time"][3],transformed_data["open"][3],color='blue', label='Open') 161 | FBdailyhigh = FBplot.plot(transformed_data["time"][3],transformed_data["high"][3],'--',color='green', label='High') 162 | FBdailylow = FBplot.plot(transformed_data["time"][3],transformed_data["low"][3],'--',color='red', label='Low') 163 | FBdailyclose = FBplot.plot(transformed_data["time"][3],transformed_data["close"][3],'.', color='black', label='Close') 164 | FBplot.legend(loc=legendjson['stockloc'][3], fontsize=12) 165 | FBplot.xaxis.set_major_locator(MaxNLocator(integer=True)) 166 | FBplot.yaxis.set_major_locator(LinearLocator(9)) 167 | 168 | MSFTplot = stocks.add_subplot(625) 169 | #MSFTplot.set_xlabel('Date & Time',fontsize=14) 170 | MSFTplot.set_ylabel('Stock Price (USD)',fontsize=14) 171 | if legendjson['stockloc'][4] == 4: 172 | MSFTplot.set_title(stock5+' Stock Price +'+str(transformed_data["change"][4])+'%',fontsize=20,color='g') 173 | else: 174 | MSFTplot.set_title(stock5+' Stock Price '+str(transformed_data["change"][4])+'%',fontsize=20,color='r') 175 | MSFTplot.tick_params(axis='y', which='major', labelsize=14) 176 | MSFTplot.tick_params(axis='x', which='major', labelsize=9) 177 | MSFTdailyopen = MSFTplot.plot(transformed_data["time"][4],transformed_data["open"][4],color='blue', label='Open') 178 | MSFTdailyhigh = MSFTplot.plot(transformed_data["time"][4],transformed_data["high"][4],'--',color='green', label='High') 179 | MSFTdailylow = MSFTplot.plot(transformed_data["time"][4],transformed_data["low"][4],'--',color='red', label='Low') 180 | MSFTdailyclose = MSFTplot.plot(transformed_data["time"][4],transformed_data["close"][4],'.', color='black', label='Close') 181 | MSFTplot.legend(loc=legendjson['stockloc'][4], fontsize=12) 182 | MSFTplot.xaxis.set_major_locator(MaxNLocator(integer=True)) 183 | MSFTplot.yaxis.set_major_locator(LinearLocator(9)) 184 | 185 | NFLXplot = stocks.add_subplot(626) 186 | #NFLXplot.set_xlabel('Date & Time',fontsize=14) 187 | NFLXplot.set_ylabel('Stock Price (USD)',fontsize=14) 188 | if legendjson['stockloc'][5] == 4: 189 | NFLXplot.set_title(stock6+' Stock Price +'+str(transformed_data["change"][5])+'%',fontsize=20,color='g') 190 | else: 191 | NFLXplot.set_title(stock6+' Stock Price '+str(transformed_data["change"][5])+'%',fontsize=20,color='r') 192 | NFLXplot.tick_params(axis='y', which='major', labelsize=14) 193 | NFLXplot.tick_params(axis='x', which='major', labelsize=9) 194 | NFLXdailyopen = NFLXplot.plot(transformed_data["time"][5],transformed_data["open"][5],color='blue', label='Open') 195 | NFLXdailyhigh = NFLXplot.plot(transformed_data["time"][5],transformed_data["high"][5],'--',color='green', label='High') 196 | NFLXdailylow = NFLXplot.plot(transformed_data["time"][5],transformed_data["low"][5],'--',color='red', label='Low') 197 | NFLXdailyclose = NFLXplot.plot(transformed_data["time"][5],transformed_data["close"][5],'.', color='black', label='Close') 198 | NFLXplot.legend(loc=legendjson['stockloc'][5], fontsize=12) 199 | NFLXplot.xaxis.set_major_locator(MaxNLocator(integer=True)) 200 | NFLXplot.yaxis.set_major_locator(LinearLocator(9)) 201 | 202 | #Save as jpg, pdf with today's date 203 | stocknames = '_'+stock1+'-'+stock2+'-'+stock3+'-'+stock4+'-'+stock5+'-'+stock6 204 | jpg_name = 'DashboardDaily_'+str(transformed_data["time"][0][0][0:10])+stocknames+'.jpg' 205 | pdf_name = 'DashboardDaily_'+str(transformed_data["time"][0][0][0:10])+stocknames+'.pdf' 206 | stocks.savefig(jpg_name) 207 | stocks.savefig(pdf_name) 208 | 209 | #Show all plots 210 | plt.show() 211 | 212 | #Notification if there are no errors to inform on file names 213 | print('Dashboard saved as: '+jpg_name+' in local directory') 214 | print('Dashboard saved as: '+pdf_name+' in local directory') 215 | 216 | # Open PDF file 217 | os.startfile(pdf_name) 218 | 219 | 220 | if __name__ == "__main__": 221 | main('AAPL', 'AMZN', 'GOOGL', 'FB', 'MSFT', 'NFLX', '2020-01-02') --------------------------------------------------------------------------------