├── src
├── history.js
├── assets
│ ├── Images
│ │ ├── Icons
│ │ │ ├── Icons.png
│ │ │ ├── hacking.jpg
│ │ │ ├── images.jpeg
│ │ │ ├── images.jpg
│ │ │ ├── options.png
│ │ │ ├── tools.png
│ │ │ ├── analytics.jpg
│ │ │ ├── analytics.png
│ │ │ ├── dashboard.png
│ │ │ ├── education.png
│ │ │ ├── artwork_2x.png
│ │ │ ├── commodities.jpg
│ │ │ ├── euro-96594_1280.png
│ │ │ ├── berth-through-put.jpeg
│ │ │ ├── graph-3068300_1920.jpg
│ │ │ ├── 5G-web-design-thum-1.jpg
│ │ │ ├── campaign-3190106_1920.jpg
│ │ │ ├── Bold-and-Vibrant-colors.png
│ │ │ ├── winning-web-design-tips.jpg
│ │ │ ├── runer-silhouette-running-fast.png
│ │ │ ├── custom-web-design-free-template.png
│ │ │ ├── startup-idea-innovation-business-bulb-big-thing.png
│ │ │ ├── depositphotos_68236367-stock-illustration-truck-with-mexican-food.jpg
│ │ │ ├── imports.svg
│ │ │ ├── graphic-design.svg
│ │ │ ├── meeting.svg
│ │ │ ├── vessel-types.svg
│ │ │ ├── users.svg
│ │ │ ├── fast.svg
│ │ │ └── admin.svg
│ │ └── car.svg
│ └── js
│ │ └── ie10-viewport-bug-workaround.js
├── Components
│ ├── NotFound
│ │ ├── bg_purple.png
│ │ ├── overlay_stars.svg
│ │ ├── rocket.svg
│ │ ├── NotFound.js
│ │ ├── earth.svg
│ │ ├── moon.svg
│ │ ├── NotFound.css
│ │ └── astronaut.svg
│ ├── StockAnalytics
│ │ ├── Autocomplete
│ │ │ ├── ValueContainer.js
│ │ │ ├── Menu.js
│ │ │ ├── SingleValue.js
│ │ │ ├── Placeholder.js
│ │ │ ├── Option.js
│ │ │ ├── NoOptionsMessage.js
│ │ │ ├── MultiValue.js
│ │ │ └── Control.js
│ │ ├── DebtRatios.js
│ │ ├── ProfitabilityRatios.js
│ │ ├── ValuationRatios.js
│ │ ├── StockLineChart.js
│ │ ├── Alternative-working-codes-kept-for-backup
│ │ │ ├── StockAnalyticsDashBoard-WITHOUT-auto-suggestions.js
│ │ │ ├── SandP500_PE-HighCharts.js
│ │ │ ├── SandP500_PE-vx-WORKING.js
│ │ │ └── StockAnalyticsDashBoard-WITH-HUGE-autosuggestion.js
│ │ ├── Styles
│ │ │ └── analyticsStyles.js
│ │ ├── SandP500_PE.js
│ │ └── StockAnalyticsDashBoard.js
│ ├── commonStyles
│ │ ├── ModuleItemListStyles.js
│ │ └── BootstrapInput.js
│ ├── UtilFunctions
│ │ ├── snackbar.css
│ │ └── MySnackbarContent.js
│ ├── AppDashBoard.js
│ ├── CSVParsing
│ │ ├── CSVParsingChart.js
│ │ └── CSVParsing.js
│ ├── BitCoin
│ │ ├── AllCryptoCurrencyBarGraph.js
│ │ └── BitCoin.js
│ └── SiteDesign
│ │ ├── SiteDesignStyles.js
│ │ └── SiteDesign.js
├── index.css
├── setupTests.js
├── Dashboard.js
├── index.js
├── Routes
│ └── DashboardRoutes.js
├── App.js
└── registerServiceWorker.js
├── Peek 2019-05-05 22-31.gif
├── vlc-record-2019-05-06-10h12m22s-2019-05-06 09-22-14.flv-.mp4
├── .eslintrc
├── public
├── manifest.json
└── index.html
├── .gitignore
├── MSFT.csv
├── README.md
└── package.json
/src/history.js:
--------------------------------------------------------------------------------
1 | import { createBrowserHistory } from 'history';
2 |
3 | export default createBrowserHistory();
--------------------------------------------------------------------------------
/Peek 2019-05-05 22-31.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/Peek 2019-05-05 22-31.gif
--------------------------------------------------------------------------------
/src/assets/Images/Icons/Icons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/Icons.png
--------------------------------------------------------------------------------
/src/assets/Images/Icons/hacking.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/hacking.jpg
--------------------------------------------------------------------------------
/src/assets/Images/Icons/images.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/images.jpeg
--------------------------------------------------------------------------------
/src/assets/Images/Icons/images.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/images.jpg
--------------------------------------------------------------------------------
/src/assets/Images/Icons/options.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/options.png
--------------------------------------------------------------------------------
/src/assets/Images/Icons/tools.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/tools.png
--------------------------------------------------------------------------------
/src/Components/NotFound/bg_purple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/Components/NotFound/bg_purple.png
--------------------------------------------------------------------------------
/src/assets/Images/Icons/analytics.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/analytics.jpg
--------------------------------------------------------------------------------
/src/assets/Images/Icons/analytics.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/analytics.png
--------------------------------------------------------------------------------
/src/assets/Images/Icons/dashboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/dashboard.png
--------------------------------------------------------------------------------
/src/assets/Images/Icons/education.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/education.png
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | height: 100%;
3 | }
4 | body {
5 | margin: 0;
6 | padding: 0;
7 | font-family: sans-serif;
8 | }
9 |
--------------------------------------------------------------------------------
/src/assets/Images/Icons/artwork_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/artwork_2x.png
--------------------------------------------------------------------------------
/src/assets/Images/Icons/commodities.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/commodities.jpg
--------------------------------------------------------------------------------
/src/assets/Images/Icons/euro-96594_1280.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/euro-96594_1280.png
--------------------------------------------------------------------------------
/src/assets/Images/Icons/berth-through-put.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/berth-through-put.jpeg
--------------------------------------------------------------------------------
/src/assets/Images/Icons/graph-3068300_1920.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/graph-3068300_1920.jpg
--------------------------------------------------------------------------------
/src/assets/Images/Icons/5G-web-design-thum-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/5G-web-design-thum-1.jpg
--------------------------------------------------------------------------------
/src/assets/Images/Icons/campaign-3190106_1920.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/campaign-3190106_1920.jpg
--------------------------------------------------------------------------------
/src/assets/Images/Icons/Bold-and-Vibrant-colors.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/Bold-and-Vibrant-colors.png
--------------------------------------------------------------------------------
/src/assets/Images/Icons/winning-web-design-tips.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/winning-web-design-tips.jpg
--------------------------------------------------------------------------------
/src/assets/Images/Icons/runer-silhouette-running-fast.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/runer-silhouette-running-fast.png
--------------------------------------------------------------------------------
/src/assets/Images/Icons/custom-web-design-free-template.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/custom-web-design-free-template.png
--------------------------------------------------------------------------------
/vlc-record-2019-05-06-10h12m22s-2019-05-06 09-22-14.flv-.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/vlc-record-2019-05-06-10h12m22s-2019-05-06 09-22-14.flv-.mp4
--------------------------------------------------------------------------------
/src/assets/Images/Icons/startup-idea-innovation-business-bulb-big-thing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/startup-idea-innovation-business-bulb-big-thing.png
--------------------------------------------------------------------------------
/src/assets/Images/Icons/depositphotos_68236367-stock-illustration-truck-with-mexican-food.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohan-paul/stock-dashboard-react/HEAD/src/assets/Images/Icons/depositphotos_68236367-stock-illustration-truck-with-mexican-food.jpg
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "airbnb",
3 | "rules": {
4 | "func-names": [
5 | "error",
6 | "never"
7 | ],
8 | "comma-dangle": "off"
9 | },
10 | "globals": {
11 | "localStorage": true,
12 | "fetch": true
13 | }
14 | }
--------------------------------------------------------------------------------
/src/setupTests.js:
--------------------------------------------------------------------------------
1 | import { configure } from "enzyme";
2 | import Adapter from "enzyme-adapter-react-16";
3 | const dotenv = require("dotenv");
4 | // dotenv.config({ path: "../../server/.env" });
5 | require("dotenv").config();
6 |
7 | configure({ adapter: new Adapter() });
8 |
--------------------------------------------------------------------------------
/src/Dashboard.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const Dashboard = () => {
4 | return (
5 |
6 |
Open the side bar to move to different section
7 |
8 | );
9 | };
10 |
11 | export default Dashboard;
12 |
--------------------------------------------------------------------------------
/src/Components/StockAnalytics/Autocomplete/ValueContainer.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 |
3 | function ValueContainer(props) {
4 | return (
5 |
6 | {props.children}
7 |
8 | );
9 | }
10 |
11 | export default ValueContainer;
12 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [{
5 |
6 | "sizes": "64x64 32x32 24x24 16x16",
7 | "type": "image/x-icon"
8 | }],
9 | "start_url": "./index.html",
10 | "display": "standalone",
11 | "theme_color": "#000000",
12 | "background_color": "#ffffff"
13 | }
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import "bootstrap/dist/css/bootstrap.min.css";
4 | import "./index.css";
5 | import App from "./App";
6 | import "react-table/react-table.css";
7 | require("dotenv").config();
8 |
9 | const Dashboard = () => {
10 | return ;
11 | };
12 |
13 | ReactDOM.render(, document.getElementById("root"));
14 |
--------------------------------------------------------------------------------
/src/Components/StockAnalytics/Autocomplete/Menu.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import Paper from "@material-ui/core/Paper";
3 |
4 | function Menu(props) {
5 | return (
6 |
11 | {props.children}
12 |
13 | );
14 | }
15 |
16 | export default Menu;
17 |
--------------------------------------------------------------------------------
/src/Components/StockAnalytics/Autocomplete/SingleValue.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import Typography from "@material-ui/core/Typography";
3 |
4 | function SingleValue(props) {
5 | return (
6 |
10 | {props.children}
11 |
12 | );
13 | }
14 |
15 | export default SingleValue;
16 |
--------------------------------------------------------------------------------
/src/Components/StockAnalytics/Autocomplete/Placeholder.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import Typography from "@material-ui/core/Typography";
3 |
4 | function Placeholder(props) {
5 | return (
6 |
11 | {props.children}
12 |
13 | );
14 | }
15 |
16 | export default Placeholder;
17 |
--------------------------------------------------------------------------------
/src/Components/StockAnalytics/Autocomplete/Option.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import { MenuItem } from "material-ui/Menu";
3 |
4 | function Option(props) {
5 | return (
6 |
17 | );
18 | }
19 |
20 | export default Option;
21 |
--------------------------------------------------------------------------------
/src/Components/StockAnalytics/Autocomplete/NoOptionsMessage.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import TextField from "@material-ui/core/TextField";
3 | import Typography from "@material-ui/core/Typography";
4 |
5 | function NoOptionsMessage(props) {
6 | return (
7 |
12 | {props.children}
13 |
14 | );
15 | }
16 |
17 | export default NoOptionsMessage;
18 |
--------------------------------------------------------------------------------
/src/Components/StockAnalytics/Autocomplete/MultiValue.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import Chip from "@material-ui/core/Chip";
3 | import classNames from "classnames";
4 | import CancelIcon from "@material-ui/icons/Cancel";
5 |
6 | function MultiValue(props) {
7 | return (
8 | }
16 | />
17 | );
18 | }
19 |
20 | export default MultiValue;
21 |
--------------------------------------------------------------------------------
/src/Components/StockAnalytics/Autocomplete/Control.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import TextField from "@material-ui/core/TextField";
3 |
4 | function inputComponent({ inputRef, ...props }) {
5 | return ;
6 | }
7 |
8 | function Control(props) {
9 | return (
10 |
23 | );
24 | }
25 |
26 | export default Control;
27 |
--------------------------------------------------------------------------------
/src/assets/js/ie10-viewport-bug-workaround.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * IE10 viewport hack for Surface/desktop Windows 8 bug
3 | * Copyright 2014-2015 Twitter, Inc.
4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5 | */
6 |
7 | // See the Getting Started docs for more information:
8 | // http://getbootstrap.com/getting-started/#support-ie10-width
9 |
10 | (function () {
11 | 'use strict';
12 |
13 | if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
14 | var msViewportStyle = document.createElement('style')
15 | msViewportStyle.appendChild(
16 | document.createTextNode(
17 | '@-ms-viewport{width:auto!important}'
18 | )
19 | )
20 | document.querySelector('head').appendChild(msViewportStyle)
21 | }
22 |
23 | })();
24 |
--------------------------------------------------------------------------------
/src/Components/commonStyles/ModuleItemListStyles.js:
--------------------------------------------------------------------------------
1 | export const styles = theme => ({
2 | palette: {
3 | primary: { main: "#2196f3" },
4 | secondary: { main: "#0023ff" },
5 | error: { main: "#ee0053" }
6 | },
7 | root: {
8 | width: "100%",
9 | marginTop: theme.spacing.unit * 4,
10 | overflow: "auto"
11 | },
12 | space: {
13 | marginTop: theme.spacing.unit * 2
14 | },
15 | fab: {
16 | margin: theme.spacing.unit
17 | },
18 | fabButton: {
19 | margin: theme.spacing.unit,
20 | marginLeft: "46%"
21 | },
22 | extendedIcon: {
23 | marginRight: theme.spacing.unit
24 | },
25 | lightTooltip: {
26 | background: theme.palette.common.white,
27 | color: theme.palette.text.primary,
28 | boxShadow: theme.shadows[1],
29 | fontSize: 16
30 | }
31 | });
32 |
--------------------------------------------------------------------------------
/src/Routes/DashboardRoutes.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import { Switch, Route } from "react-router-dom";
3 |
4 | import NotFound from "../Components/NotFound/NotFound";
5 | import StockAnalyticsDashBoard from "../Components/StockAnalytics/StockAnalyticsDashBoard";
6 | import AppDashBoard from "../Components/AppDashBoard";
7 | import CSVParsing from "../Components/CSVParsing/CSVParsing";
8 | import BitCoin from "../Components/BitCoin/BitCoin";
9 | import DashBoard from "../Dashboard";
10 |
11 | export class DashboardRoutes extends Component {
12 | render() {
13 | return (
14 |
15 |
16 |
17 |
18 |
23 |
24 |
25 |
26 |
27 |
28 | );
29 | }
30 | }
31 |
32 | export default DashboardRoutes;
33 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | */node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # misc
13 | .DS_Store
14 | .env.local
15 | .env.development.local
16 | .env.test.local
17 | .env.production.local
18 | .env
19 | .env.override
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
25 | # Ignore docs files
26 | _gh_pages
27 | .ruby-version
28 |
29 | # Numerous always-ignore extensions
30 | *.diff
31 | *.err
32 | *.orig
33 | *.log
34 | *.rej
35 | *.swo
36 | *.swp
37 | *.zip
38 | *.vi
39 | *~
40 | *.~lock*
41 | .~lock*
42 |
43 | # OS or Editor folders
44 | .DS_Store
45 | ._*
46 | Thumbs.db
47 | .cache
48 | .project
49 | .settings
50 | .tmproj
51 | *.esproj
52 | nbproject
53 | *.sublime-project
54 | *.sublime-workspace
55 | .idea
56 |
57 | # Komodo
58 | *.komodoproject
59 | .komodotools
60 |
61 | # grunt-html-validation
62 | validation-status.json
63 | validation-report.json
64 |
65 | # Folders to ignore
66 | node_modules
67 | Project-Note-PAUL
68 | .vscode
69 |
70 | # Ignore all logfiles and tempfiles.
71 | !/log/.keep
72 | /tmp
73 | /.gems
74 |
75 |
--------------------------------------------------------------------------------
/src/Components/commonStyles/BootstrapInput.js:
--------------------------------------------------------------------------------
1 | import { withStyles } from "@material-ui/core";
2 | import InputBase from "@material-ui/core/InputBase";
3 |
4 | const BootstrapInput = withStyles(theme => ({
5 | root: {
6 | "label + &": {
7 | marginTop: theme.spacing.unit * 3
8 | }
9 | },
10 | input: {
11 | borderRadius: 4,
12 | position: "relative",
13 | backgroundColor: theme.palette.background.paper,
14 | border: "1px solid #ced4da",
15 | fontSize: 16,
16 | width: "auto",
17 | padding: "10px 26px 10px 12px",
18 | transition: theme.transitions.create(["border-color", "box-shadow"]),
19 | // Use the system font instead of the default Roboto font.
20 | fontFamily: [
21 | "-apple-system",
22 | "BlinkMacSystemFont",
23 | '"Segoe UI"',
24 | "Roboto",
25 | '"Helvetica Neue"',
26 | "Arial",
27 | "sans-serif",
28 | '"Apple Color Emoji"',
29 | '"Segoe UI Emoji"',
30 | '"Segoe UI Symbol"'
31 | ].join(","),
32 | "&:focus": {
33 | borderRadius: 4,
34 | borderColor: "#80bdff",
35 | boxShadow: "0 0 0 0.2rem rgba(0,123,255,.25)"
36 | }
37 | }
38 | }))(InputBase);
39 |
40 | export default BootstrapInput;
41 |
--------------------------------------------------------------------------------
/src/Components/UtilFunctions/snackbar.css:
--------------------------------------------------------------------------------
1 | #snackbar {
2 | visibility: hidden;
3 | min-width: 250px;
4 | margin-left: -250px;
5 | background-color: #333;
6 | color: #fff;
7 | text-align: center;
8 | border-radius: 2px;
9 | padding: 16px;
10 | position: fixed;
11 | z-index: 1;
12 | left: 50%;
13 | top: 100px;
14 | font-size: 17px;
15 | }
16 |
17 | #snackbar.show {
18 | visibility: visible;
19 | -webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s;
20 | animation: fadein 0.5s, fadeout 0.5s 2.5s;
21 | }
22 |
23 | @-webkit-keyframes fadein {
24 | from {
25 | top: 0;
26 | opacity: 0;
27 | }
28 |
29 | to {
30 | top: 80px;
31 | opacity: 1;
32 | }
33 | }
34 |
35 | @keyframes fadein {
36 | from {
37 | top: 0;
38 | opacity: 0;
39 | }
40 |
41 | to {
42 | top: 80px;
43 | opacity: 1;
44 | }
45 | }
46 |
47 | @-webkit-keyframes fadeout {
48 | from {
49 | top: 80px;
50 | opacity: 1;
51 | }
52 |
53 | to {
54 | top: 0;
55 | opacity: 0;
56 | }
57 | }
58 |
59 | @keyframes fadeout {
60 | from {
61 | top: 80px;
62 | opacity: 1;
63 | }
64 |
65 | to {
66 | top: 0;
67 | opacity: 0;
68 | }
69 | }
--------------------------------------------------------------------------------
/src/Components/StockAnalytics/DebtRatios.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | const ReactHighChart = require("react-highcharts");
3 |
4 | export class DebtRatios extends Component {
5 | render() {
6 | const config = {
7 | chart: {
8 | backgroundColor: {
9 | linearGradient: [0, 0, 500, 500],
10 | stops: [[0, "rgb(255, 255, 255)"], [1, "rgb(247, 247, 152)"]]
11 | },
12 | polar: true,
13 | type: "column"
14 | },
15 | xAxis: {
16 | categories: this.props.xSeriesDataForValuationRatios,
17 | crosshair: true,
18 |
19 | labels: {
20 | align: "right",
21 | rotation: "-45"
22 | }
23 | },
24 | yAxis: {
25 | min: 0,
26 | title: {
27 | text: "Numbers in ratio"
28 | }
29 | },
30 | series: this.props.ySeriesDataForDebtRatios,
31 |
32 | plotOptions: {
33 | column: {
34 | pointPadding: 0.2,
35 | borderWidth: 0
36 | }
37 | },
38 |
39 | title: {
40 | text: `${this.props.stockTicker || "Stock Ticker"}`
41 | }
42 | };
43 | return (
44 |
45 | {/*{console.log("FUNDAMENTALS DEBT ", this.props.ySeriesDataForDebtRatios)}*/}
46 |
47 |
48 | );
49 | }
50 | }
51 |
52 | export default DebtRatios;
53 |
--------------------------------------------------------------------------------
/src/Components/AppDashBoard.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import { createMuiTheme, MuiThemeProvider } from "@material-ui/core";
3 | import SiteDesign from "./SiteDesign/SiteDesign";
4 | import CssBaseline from "@material-ui/core/CssBaseline";
5 |
6 | const theme = theme =>
7 | createMuiTheme({
8 | palette: {
9 | type: theme ? "dark" : "light",
10 | text: {
11 | main: "#000000"
12 | },
13 | primary: {
14 | main: theme ? "#f32c2c" : "#f7f71c"
15 | }
16 | },
17 | typography: {
18 | useNextVariants: true
19 | }
20 | });
21 |
22 | class AppDashBoard extends Component {
23 | state = {
24 | themeType: false,
25 | files: [],
26 | data: []
27 | };
28 |
29 | handleThemeTypeChange = () => {
30 | this.state.themeType
31 | ? this.setState({
32 | themeType: false
33 | })
34 | : this.setState({
35 | themeType: true
36 | });
37 | };
38 |
39 | render() {
40 | const { themeType, data } = this.state;
41 |
42 | return (
43 |
44 |
45 |
46 |
50 |
51 |
52 | );
53 | }
54 | }
55 |
56 | export default AppDashBoard;
57 |
--------------------------------------------------------------------------------
/src/Components/StockAnalytics/ProfitabilityRatios.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | const ReactHighChart = require("react-highcharts");
3 |
4 | export class ProfitabilityRatios extends Component {
5 | render() {
6 | const config = {
7 | chart: {
8 | backgroundColor: {
9 | linearGradient: [0, 0, 500, 500],
10 | stops: [[0, "rgb(255, 255, 255)"], [1, "rgb(247, 247, 152)"]]
11 | },
12 | polar: true,
13 | type: "column"
14 | },
15 | xAxis: {
16 | categories: this.props.xSeriesDataForValuationRatios,
17 | crosshair: true,
18 |
19 | labels: {
20 | align: "right",
21 | rotation: "-45"
22 | }
23 | },
24 | yAxis: {
25 | min: 0,
26 | title: {
27 | text: "Numbers in ratio"
28 | }
29 | },
30 | series: this.props.ySeriesDataForProfitabilityRatios,
31 |
32 | plotOptions: {
33 | column: {
34 | pointPadding: 0.2,
35 | borderWidth: 0
36 | }
37 | },
38 |
39 | title: {
40 | text: `${this.props.stockTicker || "Stock Ticker"}`
41 | }
42 | };
43 | return (
44 |
45 | {/* {console.log(
46 | "FUNDAMENTALS PROFITABILITY ",
47 | this.props.ySeriesDataForProfitabilityRatios
48 | )}*/}
49 |
50 |
51 | );
52 | }
53 | }
54 |
55 | export default ProfitabilityRatios;
56 |
--------------------------------------------------------------------------------
/src/Components/StockAnalytics/ValuationRatios.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | const ReactHighChart = require("react-highcharts");
3 |
4 | export class ValuationRatios extends Component {
5 | render() {
6 | const config = {
7 | chart: {
8 | backgroundColor: {
9 | linearGradient: [0, 0, 500, 500],
10 | stops: [[0, "rgb(255, 255, 255)"], [1, "rgb(247, 247, 152)"]]
11 | },
12 | polar: true,
13 | type: "column"
14 | },
15 | xAxis: {
16 | categories: this.props.xSeriesDataForValuationRatios,
17 | crosshair: true,
18 |
19 | labels: {
20 | align: "right",
21 | rotation: "-45"
22 | }
23 | },
24 | yAxis: {
25 | min: 0,
26 | title: {
27 | text: "Numbers in ratio"
28 | }
29 | },
30 | series: this.props.ySeriesDataForValuationRatios,
31 | ...this.props.yAxisData_StockClosingPrice,
32 | plotOptions: {
33 | column: {
34 | pointPadding: 0.2,
35 | borderWidth: 0
36 | }
37 | },
38 |
39 | title: {
40 | text: `${this.props.stockTicker || "Stock Ticker"}`
41 | }
42 | };
43 | return (
44 |
45 | {/*{console.log(
46 | "FUNDAMENTALS VALUATION ",
47 | this.props.ySeriesDataForValuationRatios
48 | )}*/}
49 |
50 |
51 | );
52 | }
53 | }
54 |
55 | export default ValuationRatios;
56 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import { Route, BrowserRouter, Switch, Router } from "react-router-dom";
3 | import history from "./history";
4 | import NotFound from "./Components/NotFound/NotFound";
5 | import StockAnalyticsDashBoard from "./Components/StockAnalytics/StockAnalyticsDashBoard";
6 | import AppDashBoard from "./Components/AppDashBoard";
7 | import CSVParsing from "./Components/CSVParsing/CSVParsing";
8 | import BitCoin from "./Components/BitCoin/BitCoin";
9 | import { library } from "@fortawesome/fontawesome-svg-core";
10 | import {
11 | faFilter,
12 | faDownload,
13 | faCalendarAlt,
14 | faShip,
15 | faAnchor,
16 | faUser
17 | } from "@fortawesome/free-solid-svg-icons";
18 | library.add(faFilter, faDownload, faCalendarAlt, faShip, faAnchor, faUser);
19 | require("dotenv").config();
20 |
21 | class App extends Component {
22 | render() {
23 | return (
24 |
25 |
26 |
27 |
28 |
29 |
30 | {/*
35 |
36 | */}
37 |
38 |
39 |
40 |
41 |
42 | );
43 | }
44 | }
45 |
46 | export default App;
47 |
--------------------------------------------------------------------------------
/src/Components/CSVParsing/CSVParsingChart.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | // const ReactHighstock = require("react-highcharts/ReactHighstock.src");
3 | const ReactHighstock = require("react-highcharts");
4 |
5 | export class CSVParsingChart extends Component {
6 | render() {
7 | const config = {
8 | chart: {
9 | backgroundColor: {
10 | linearGradient: [0, 0, 500, 500],
11 | stops: [[0, "rgb(255, 255, 255)"], [1, "rgb(247, 247, 152)"]]
12 | },
13 | polar: true,
14 | type: "line"
15 | },
16 | xAxis: {
17 | categories: this.props.formattedXAxisDataForChartLine,
18 |
19 | labels: {
20 | align: "right",
21 | rotation: "-45"
22 | }
23 | },
24 | series: [
25 | {
26 | name: "MSFT",
27 | data: this.props.formattedYAxisDataForChartLine,
28 | tooltip: {
29 | valueDecimals: 2
30 | }
31 | }
32 | ],
33 |
34 | title: {
35 | text: "MSFT Stock Price"
36 | }
37 | };
38 | return (
39 |
40 | {/*{console.log("X AXIS", this.props.formattedXAxisDataForChartLine)}
41 | {console.log("Y AXIS", this.props.formattedYAxisDataForChartLine)}*/}
42 |
43 | );
44 |
45 | );
46 | }
47 | }
48 |
49 | export default CSVParsingChart;
50 |
51 | /*
52 | series: [
53 | {
54 | name: "MSFT",
55 | data: this.props.formattedDataForChartStoks,
56 | tooltip: {
57 | valueDecimals: 2
58 | }
59 | }
60 | ]
61 | */
62 |
--------------------------------------------------------------------------------
/src/Components/NotFound/overlay_stars.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/MSFT.csv:
--------------------------------------------------------------------------------
1 | Date,Open,High,Low,Close,Adj Close,Volume
2 | 2019-03-26,118.620003,118.709999,116.849998,117.910004,117.910004,26097700
3 | 2019-03-27,117.879997,118.209999,115.519997,116.769997,116.769997,22733400
4 | 2019-03-28,117.440002,117.580002,116.129997,116.930000,116.930000,18334800
5 | 2019-03-29,118.070000,118.320000,116.959999,117.940002,117.940002,25399800
6 | 2019-04-01,118.949997,119.110001,118.099998,119.019997,119.019997,22789100
7 | 2019-04-02,119.059998,119.480003,118.519997,119.190002,119.190002,18142300
8 | 2019-04-03,119.860001,120.430000,119.150002,119.970001,119.970001,22860700
9 | 2019-04-04,120.099998,120.230003,118.379997,119.360001,119.360001,20112800
10 | 2019-04-05,119.389999,120.230003,119.370003,119.889999,119.889999,15826200
11 | 2019-04-08,119.809998,120.019997,118.639999,119.930000,119.930000,15116200
12 | 2019-04-09,118.629997,119.540001,118.580002,119.279999,119.279999,17612000
13 | 2019-04-10,119.760002,120.349998,119.540001,120.190002,120.190002,16477200
14 | 2019-04-11,120.540001,120.849998,119.919998,120.330002,120.330002,14209100
15 | 2019-04-12,120.639999,120.980003,120.370003,120.949997,120.949997,19745100
16 | 2019-04-15,120.940002,121.580002,120.570000,121.050003,121.050003,15792600
17 | 2019-04-16,121.639999,121.650002,120.099998,120.769997,120.769997,14071800
18 | 2019-04-17,121.239998,121.849998,120.540001,121.769997,121.769997,19300900
19 | 2019-04-18,122.190002,123.519997,121.300003,123.370003,123.370003,27991000
20 | 2019-04-22,122.620003,124.000000,122.570000,123.760002,123.760002,15648700
21 | 2019-04-23,124.099998,125.580002,123.830002,125.440002,125.440002,24025500
22 | 2019-04-24,125.790001,125.849998,124.519997,125.010002,125.010002,31257000
23 | 2019-04-25,130.059998,131.369995,128.830002,129.149994,129.149994,37955200
24 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | React App
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
19 |
20 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/Components/BitCoin/AllCryptoCurrencyBarGraph.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | const ReactHighChart = require("react-highcharts");
3 |
4 | export class AllCryptoCurrencyBarGraph extends Component {
5 | render() {
6 | const config = {
7 | chart: {
8 | backgroundColor: {
9 | linearGradient: [0, 0, 500, 500],
10 | stops: [[0, "rgb(255, 255, 255)"], [1, "rgb(247, 247, 152)"]]
11 | },
12 | polar: true,
13 | type: "column"
14 | },
15 | xAxis: {
16 | categories: this.props.xSeriesDataForValuationRatios,
17 | crosshair: true,
18 |
19 | labels: {
20 | align: "right",
21 | rotation: "-45"
22 | }
23 | },
24 | yAxis: {
25 | min: 0,
26 | title: {
27 | text: "Numbers in dollars"
28 | }
29 | },
30 | series: [
31 | {
32 | name: "Other major Crypto Currency Latest Quotes",
33 | data: this.props.allCryptocurrencyData
34 | }
35 | ],
36 |
37 | plotOptions: {
38 | column: {
39 | pointPadding: 0.2,
40 | borderWidth: 0
41 | }
42 | },
43 |
44 | title: {
45 | text: `Other major Crypto Currency Latest Quotes`
46 | },
47 | subtitle: {
48 | text:
49 | 'Source: financialmodelingprep.com'
50 | }
51 | };
52 | return (
53 |
54 | {/*{console.log("CRYP DATA ", this.props.allCryptocurrencyData)}*/}
55 |
56 |
57 | );
58 | }
59 | }
60 |
61 | export default AllCryptoCurrencyBarGraph;
62 |
63 | // {console.log("FORMATTED CRYP DATA", this.state.allCryptocurrencyData)}
64 |
--------------------------------------------------------------------------------
/src/assets/Images/Icons/imports.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/Images/Icons/graphic-design.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/Components/NotFound/rocket.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/Components/StockAnalytics/StockLineChart.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | const ReactHighChart = require("react-highcharts");
3 | const { ma, dma, ema, sma, wma } = require("moving-averages");
4 |
5 | export class StockLineChart extends Component {
6 | render() {
7 | const config = {
8 | chart: {
9 | backgroundColor: {
10 | linearGradient: [0, 0, 500, 500],
11 | stops: [[0, "rgb(255, 255, 255)"], [1, "rgb(247, 247, 152)"]]
12 | }
13 | },
14 | title: {
15 | text: `Showing end of day closing price and 5-day moving average for stock ${
16 | this.props.stockTicker
17 | } `
18 | },
19 | yAxis: {
20 | title: {
21 | text: "Price in USD"
22 | }
23 | },
24 | xAxis: {
25 | categories: this.props.xAxisData,
26 |
27 | labels: {
28 | align: "right",
29 | rotation: "-45"
30 | }
31 | },
32 | legend: {
33 | layout: "vertical",
34 | align: "right",
35 | verticalAlign: "middle"
36 | },
37 | plotOptions: {
38 | series: {
39 | label: {
40 | connectorAllowed: false
41 | }
42 | }
43 | },
44 | series: [
45 | {
46 | name: `${this.props.stockTicker || "Closing Price"}`,
47 | data: this.props.yAxisData_StockClosingPrice.reverse()
48 | },
49 | {
50 | name: `Moving Averages`,
51 | color: "red",
52 | data: ma(this.props.yAxisData_StockClosingPrice, 5)
53 | .slice(4)
54 | .reverse()
55 | }
56 | ],
57 | responsive: {
58 | rules: [
59 | {
60 | condition: {
61 | maxWidth: 800
62 | },
63 | chartOptions: {
64 | legend: {
65 | layout: "horizontal",
66 | align: "center",
67 | verticalAlign: "bottom"
68 | }
69 | }
70 | }
71 | ]
72 | }
73 | };
74 | return (
75 |
76 | {/*{console.log("X AXIS", this.props.xAxisData)}
77 | {console.log("Y AXIS", this.props.yAxisData_StockClosingPrice)}*/}
78 |
79 |
80 | );
81 | }
82 | }
83 |
84 | export default StockLineChart;
85 |
--------------------------------------------------------------------------------
/src/Components/NotFound/NotFound.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import { Link } from "react-router-dom";
3 | import "./NotFound.css";
4 |
5 | export default class NotFound extends Component {
6 | render() {
7 | return (
8 |
9 |
10 |
11 |
12 |
13 |
})
14 |
15 |
16 |
17 |
18 | -
19 |
20 | Home
21 |
22 |
23 |
24 |
25 |
26 |
27 |
})
32 |
33 | Return to Home Page
34 |
35 |
36 |
37 |
})
42 |
43 |
})
48 |
})
53 |
54 |
55 |
})
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | );
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/Components/StockAnalytics/Alternative-working-codes-kept-for-backup/StockAnalyticsDashBoard-WITHOUT-auto-suggestions.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | // import history from "../../history";
3 | import PropTypes from "prop-types";
4 | import { withStyles } from "@material-ui/core";
5 | import Paper from "@material-ui/core/Paper";
6 | import styles from "./Styles/analyticsStyles.js";
7 | import axios from "axios";
8 | import { Row, Col } from "reactstrap";
9 | import Typography from "@material-ui/core/Typography";
10 | import SandP500_PE from "./SandP500_PE";
11 | import MuiThemeProvider from "material-ui/styles/MuiThemeProvider";
12 | import SearchBar from "material-ui-search-bar-enhanced";
13 |
14 | export class StockAnalyticsDashBoard extends Component {
15 | state = {
16 | stockTicker: ""
17 | };
18 |
19 | render() {
20 | const { classes, theme } = this.props;
21 |
22 | const selectStyles = {
23 | input: base => ({
24 | ...base,
25 | color: theme.palette.text.primary,
26 | "& input": {
27 | font: "inherit"
28 | }
29 | })
30 | };
31 |
32 | return (
33 |
34 |
35 | {console.log("TICKER IS", this.state.stockTicker)}
36 | this.setState({ stockTicker: value })}
38 | onRequestSearch={() => console.log("onRequestSearch")}
39 | style={{
40 | margin: "70px auto 0",
41 | maxWidth: 800
42 | }}
43 | />
44 |
48 |
49 |
50 | Selected Stock
51 |
52 |
53 |
54 |
55 |
56 | S&P 500 P/E ratio during same time
57 |
58 |
59 |
60 |
61 |
62 |
63 | );
64 | }
65 | }
66 |
67 | StockAnalyticsDashBoard.propTypes = {
68 | classes: PropTypes.object.isRequired
69 | };
70 |
71 | export default withStyles(styles, { withTheme: true })(StockAnalyticsDashBoard);
72 |
--------------------------------------------------------------------------------
/src/assets/Images/Icons/meeting.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
--------------------------------------------------------------------------------
/src/Components/NotFound/earth.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/Images/Icons/vessel-types.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
56 |
--------------------------------------------------------------------------------
/src/assets/Images/Icons/users.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
62 |
--------------------------------------------------------------------------------
/src/Components/UtilFunctions/MySnackbarContent.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 | import classNames from "classnames";
4 | import CheckCircleIcon from "@material-ui/icons/CheckCircle";
5 | import ErrorIcon from "@material-ui/icons/Error";
6 | import InfoIcon from "@material-ui/icons/Info";
7 | import CloseIcon from "@material-ui/icons/Close";
8 | import green from "@material-ui/core/colors/green";
9 | import amber from "@material-ui/core/colors/amber";
10 | import IconButton from "@material-ui/core/IconButton";
11 | import SnackbarContent from "@material-ui/core/SnackbarContent";
12 | import WarningIcon from "@material-ui/icons/Warning";
13 | import { withStyles } from "@material-ui/core/styles";
14 |
15 | const variantIcon = {
16 | success: CheckCircleIcon,
17 | warning: WarningIcon,
18 | error: ErrorIcon,
19 | info: InfoIcon
20 | };
21 |
22 | const styles1 = theme => ({
23 | close: {
24 | padding: theme.spacing.unit * 2
25 | },
26 | success: {
27 | backgroundColor: green[600]
28 | },
29 | error: {
30 | backgroundColor: theme.palette.error.dark
31 | },
32 | info: {
33 | backgroundColor: theme.palette.primary.dark
34 | },
35 | warning: {
36 | backgroundColor: amber[700]
37 | },
38 | icon: {
39 | fontSize: 35
40 | },
41 | iconVariant: {
42 | opacity: 1,
43 | marginRight: theme.spacing.unit
44 | },
45 | message: {
46 | display: "flex",
47 | fontSize: 20,
48 | alignItems: "center"
49 | }
50 | });
51 |
52 | function MySnackbarContent(props) {
53 | const { classes, className, message, onClose, variant, ...other } = props;
54 | const Icon = variantIcon[variant];
55 |
56 | return (
57 |
62 |
63 | {message}
64 |
65 | }
66 | action={[
67 |
74 |
75 |
76 | ]}
77 | {...other}
78 | />
79 | );
80 | }
81 |
82 | MySnackbarContent.propTypes = {
83 | classes: PropTypes.object.isRequired,
84 | className: PropTypes.string,
85 | message: PropTypes.node,
86 | onClose: PropTypes.func,
87 | variant: PropTypes.oneOf(["success", "warning", "error", "info"]).isRequired
88 | };
89 |
90 | export default withStyles(styles1)(MySnackbarContent);
91 |
--------------------------------------------------------------------------------
/src/Components/StockAnalytics/Alternative-working-codes-kept-for-backup/SandP500_PE-HighCharts.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import axios from "axios";
3 | const ReactHighstock = require("react-highcharts");
4 |
5 | // Function to re-structure the data received from the API
6 | const getDateAndClosingPrice = obj => {
7 | let xAxis = [];
8 | let yAxis = [];
9 | for (let key in obj) {
10 | if (obj.hasOwnProperty(key)) {
11 | xAxis.push(key);
12 | yAxis.push(parseInt(obj[key].close));
13 | }
14 | }
15 | return [xAxis, yAxis];
16 | };
17 |
18 | export class SandP500_PE extends Component {
19 | state = {
20 | s_and_p_500_index: [],
21 | closingDate: ""
22 | };
23 |
24 | componentDidMount() {
25 | const { fromDate, toDate } = this.props;
26 | const APIkey = process.env.REACT_APP_WORLD_TRADING_DATA_API_TOKEN;
27 |
28 | const url = `https://www.worldtradingdata.com/api/v1/history?symbol=^INX&date_from=${fromDate}&date_to=${toDate}&sort=newest&api_token=${APIkey}`;
29 |
30 | if (fromDate !== "" && toDate !== "") {
31 | axios
32 | .get(url)
33 | .then(res => {
34 | if (
35 | res.data &&
36 | res.data.history &&
37 | Object.entries(res.data.history).length !== 0
38 | ) {
39 | this.setState({
40 | closingDate: getDateAndClosingPrice(res.data.history)[0],
41 | s_and_p_500_index: getDateAndClosingPrice(res.data.history)[1]
42 | });
43 | }
44 | })
45 | .catch(err => console.log("Error while fetching data ", err));
46 | }
47 | }
48 | render() {
49 | const { s_and_p_500_index, closingDate } = this.state;
50 |
51 | const config = {
52 | chart: {
53 | backgroundColor: {
54 | linearGradient: [0, 0, 500, 500],
55 | stops: [[0, "rgb(255, 255, 255)"], [1, "rgb(247, 247, 152)"]]
56 | },
57 | polar: true,
58 | type: "line"
59 | },
60 | xAxis: {
61 | categories: closingDate,
62 |
63 | labels: {
64 | align: "right",
65 | rotation: "-45"
66 | }
67 | },
68 | series: [
69 | {
70 | name: `S&P`,
71 | data: s_and_p_500_index,
72 | tooltip: {
73 | valueDecimals: 2
74 | }
75 | }
76 | ],
77 |
78 | title: {
79 | text: `S&P 500 closing from worldtradingdata.com`
80 | }
81 | };
82 | return (
83 |
84 | {console.log("X DATA", closingDate)}
85 | {console.log("Y DATA", s_and_p_500_index)}
86 |
87 | );
88 |
89 | );
90 | }
91 | }
92 |
93 | export default SandP500_PE;
94 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### [Live Demo](https://stock-analytics-dashboard.netlify.com/)
2 |
3 | #### To run the project in local machine, first you need to get the API-Key's from [worldtradingdata.com](www.worldtradingdata.com). Each API request is authenticated with your own personal API token which you can obtain for free by signing up. Currently you can make 250 free api request per day with their free scheme.
4 |
5 | Then create a .env file at the project root and assign the API-key to the relevant variable like below. (The key you are seeing below is NOT an actual one, its just for example)
6 |
7 | `REACT_APP_WORLD_TRADING_DATA_API_TOKEN=CO9qj6546546arefvref144565ethbdszgffd`
8 |
9 | Then just run `npm install` and then `npm start`
10 |
11 |
12 |
13 | A stock-analytics dashboard with React, Highcharts, @vx (charting lib) and usinng finnancial analytics API data from - [www.worldtradingdata.com](www.worldtradingdata.com), api.iextrading.com and financialmodelingprep.com
14 |
15 | #### Some notes on using [www.quandl.com/api](www.quandl.com/api) - I ultimately did not use Quandl as its free API gives old data
16 |
17 | #### The main disadvantage, of Quandl Free API is that most stocks the "newest_available_date" is "2018-03-27"
18 |
19 | [https://github.com/quantopian/zipline/issues/2145](https://github.com/quantopian/zipline/issues/2145)
20 |
21 | [https://github.com/quantopian/zipline/issues/22](https://github.com/quantopian/zipline/issues/22)
22 |
23 | ```
24 | this is expected behavior as Quandl stopped updating their WIKI pricing dataset,
25 | ```
26 |
27 | 1> The main official doc is at -
28 |
29 | [https://docs.quandl.com/docs/in-depth-usage](https://docs.quandl.com/docs/in-depth-usage)
30 |
31 | – Under API > TIME-SERIES > USAGE
32 |
33 | 2> Lets say, from the big-full-fledged data, which has the following parameters for ‘column_names”
34 |
35 | "column_names": ["Date", "Open", "High", "Low", "Close", "Volume", "Ex-Dividend", "Split Ratio", "Adj. Open", "Adj. High", "Adj. Low", "Adj. Close", "Adj. Volume"],
36 |
37 | I only want the field for ‘Close’
38 |
39 | The above page ( [https://docs.quandl.com/docs/in-depth-usage](https://docs.quandl.com/docs/in-depth-usage)) says -
40 | “You can slice, transform and otherwise customize your time-series dataset prior to download by appending various optional parameters to your query.”
41 |
42 | And now when I click on the hyperlink - ‘parameters’ it takes me to -
43 |
44 | [https://docs.quandl.com/docs/parameters-2](https://docs.quandl.com/docs/parameters-2)
45 |
46 | Here, I have
47 |
48 | column_index - Request a specific column. Column 0 is the date column and is always returned. Data begins at column 1.
49 |
50 | This column_index is the parameter that I have to fileter by for filitering ‘column_names’ array in the response data.
51 |
52 | So my final query becomes -
53 |
54 | [https://www.quandl.com/api/v3/datasets/WIKI/FB.json?&column_index=4&api_key=xVgPxg_akYvyDdHhqEox](https://www.quandl.com/api/v3/datasets/WIKI/FB.json?&column_index=4&api_key=Your-API-KEY)
55 |
56 | And I get a ‘data’ field in the response as below
57 |
58 | "data": [
59 | ["2018-03-27", 152.19],
60 | ["2018-03-26", 160.06],
61 | ...
62 | ...
63 | ]
64 |
--------------------------------------------------------------------------------
/src/Components/StockAnalytics/Styles/analyticsStyles.js:
--------------------------------------------------------------------------------
1 | var styles = theme => ({
2 | root: {
3 | flexGrow: 1
4 | },
5 |
6 | topLeftPaper: {
7 | width: "100%",
8 | height: "145px",
9 | paddingLeft: "15px",
10 | verticalAlign: "center",
11 | textAlign: "center",
12 | color: "white",
13 | backgroundColor: "rgb(255, 87, 34)",
14 | borderRadius: "5px",
15 | fontSize: 20,
16 | cursor: "pointer"
17 | },
18 |
19 | topRightPaper: {
20 | marginLeft: "15px",
21 | width: "100%",
22 | height: "145px",
23 | paddingLeft: "15px",
24 | verticalAlign: "center",
25 | textAlign: "center",
26 | color: "white",
27 | backgroundColor: "rgb(41, 182, 246)",
28 | borderRadius: "5px",
29 | fontSize: 20,
30 | cursor: "pointer"
31 | },
32 |
33 | bottomLeftPaper: {
34 | marginTop: "15px",
35 | width: "100%",
36 | minWidth: "400px",
37 | height: "450px",
38 | paddingLeft: "15px",
39 | verticalAlign: "center",
40 | textAlign: "center",
41 | color: "white",
42 | backgroundColor: "white",
43 | borderRadius: "5px",
44 | fontSize: 20,
45 | cursor: "pointer",
46 | overflow: "auto"
47 | },
48 |
49 | bottomRightPaper: {
50 | marginLeft: "15px",
51 | marginTop: "15px",
52 | width: "100%",
53 | height: "450px",
54 | paddingLeft: "15px",
55 | verticalAlign: "center",
56 | textAlign: "center",
57 | color: "white",
58 | backgroundColor: "white",
59 | borderRadius: "5px",
60 | fontSize: 20,
61 | cursor: "pointer",
62 | overflow: "auto"
63 | },
64 | topSearchBarPaper: {
65 | display: "flex",
66 | flexDirection: "row",
67 | margin: "70px auto 0",
68 | maxWidth: "100%",
69 | height: "75px"
70 | },
71 | reactSelectAndDatePicker: {
72 | display: "flex",
73 | flexDirection: "row",
74 | margin: "auto"
75 | },
76 |
77 | bothDatePicker: {
78 | display: "flex",
79 | flexDirection: "row",
80 | marginLeft: "10px",
81 | marginTop: 0
82 | },
83 |
84 | individualDatePicker: {
85 | marginLeft: "10px",
86 | width: "30%",
87 | marginTop: 0
88 | },
89 |
90 | button: {
91 | marginLeft: "15px"
92 | },
93 |
94 | rightIcon: {
95 | marginLeft: theme.spacing.unit
96 | },
97 |
98 | anchorIcon: {
99 | paddingRight: "15px",
100 | marginTop: "20%",
101 | marginRight: "85%"
102 | },
103 |
104 | portuser: {
105 | marginLeft: "85%",
106 | marginTop: "2%",
107 | marginBottom: "10%",
108 | fontSize: "65px"
109 | },
110 |
111 | ports: {
112 | marginLeft: "80%",
113 | fontSize: "65px"
114 | },
115 |
116 | numberofPorts: {
117 | float: "right",
118 | paddingRight: "3%",
119 | fontSize: "25px"
120 | },
121 |
122 | divider: {
123 | height: theme.spacing.unit * 2
124 | }
125 |
126 | /* styles for the Autocompletion while searching for stock ticker */
127 | /* List: {
128 | border: 1px solid #d9dddd;
129 | },
130 |
131 |
132 | ListItemOdd : {
133 | display: flex;
134 | align-items: center;
135 | justify-content: center;
136 | }
137 |
138 | ListItemEven: {
139 | background-color: #f8f8f0;
140 | } */
141 | });
142 |
143 | export default styles;
144 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "frontend-portal",
3 | "version": "0.1.0",
4 | "private": true,
5 | "proxy": "http://localhost:5000",
6 | "dependencies": {
7 | "@date-io/date-fns": "1.3.5",
8 | "@fortawesome/fontawesome-svg-core": "^1.2.14",
9 | "@fortawesome/free-solid-svg-icons": "^5.7.1",
10 | "@fortawesome/react-fontawesome": "^0.1.4",
11 | "@material-ui/core": "^3.9.2",
12 | "@material-ui/icons": "^3.0.2",
13 | "@vx/curve": "0.0.182",
14 | "@vx/event": "0.0.182",
15 | "@vx/grid": "0.0.184",
16 | "@vx/group": "0.0.183",
17 | "@vx/mock-data": "0.0.185",
18 | "@vx/scale": "0.0.182",
19 | "@vx/shape": "0.0.184",
20 | "@vx/tooltip": "0.0.184",
21 | "axios": "^0.18.0",
22 | "bootstrap": "^4.2.1",
23 | "classnames": "^2.2.6",
24 | "d3": "^5.9.2",
25 | "d3-array": "^2.0.3",
26 | "d3-time-format": "^2.1.3",
27 | "lodash.omit": "^4.5.0",
28 | "data-forge": "^1.7.1",
29 | "date-fns": "2.0.0-alpha.27",
30 | "dotenv": "^7.0.0",
31 | "eslint": "5.12.0",
32 | "eslint-config-airbnb": "^17.1.0",
33 | "eslint-plugin-import": "^2.16.0",
34 | "eslint-plugin-jsx-a11y": "^6.2.1",
35 | "eslint-plugin-react": "^7.12.4",
36 | "file-loader": "^3.0.1",
37 | "highcharts": "^7.1.1",
38 | "highcharts-react-official": "^2.1.3",
39 | "history": "^4.7.2",
40 | "lodash.flatten": "^4.4.0",
41 | "material-ui": "^0.20.2",
42 | "material-ui-pickers": "^2.2.4",
43 | "material-ui-search-bar-enhanced": "^0.5.3",
44 | "moment": "^2.24.0",
45 | "moving-averages": "^4.0.5",
46 | "mui-datatables": "^2.0.0",
47 | "newsapi": "^2.4.0",
48 | "nock": "^10.0.6",
49 | "npm": "^6.7.0",
50 | "papaparse": "^5.2.0",
51 | "prettier-eslint-cli": "^4.7.1",
52 | "prettier-stylelint": "^0.4.2",
53 | "prop-types": "^15.6.2",
54 | "react": "^16.8.1",
55 | "react-autocomplete": "^1.8.1",
56 | "react-csv-reader": "^1.2.2",
57 | "react-data-grid": "^6.1.0",
58 | "react-dom": "^16.8.1",
59 | "react-dropzone": "^10.1.4",
60 | "react-helmet": "^5.2.0",
61 | "react-highcharts": "^16.0.2",
62 | "react-highlight": "^0.12.0",
63 | "react-jsx-highstock": "^3.5.0",
64 | "react-redux": "^6.0.0",
65 | "react-required-if": "^1.0.3",
66 | "react-router": "^5.0.0",
67 | "react-router-dom": "^4.3.1",
68 | "react-scripts": "^2.1.8",
69 | "react-select": "^2.4.3",
70 | "react-table": "^6.10.0",
71 | "react-window": "^1.8.1",
72 | "reactstrap": "^8.0.0",
73 | "sinon": "^7.2.4",
74 | "styled-components": "^4.1.3"
75 | },
76 | "scripts": {
77 | "start": "react-scripts start",
78 | "build": "react-scripts build",
79 | "test": "react-scripts test --env=jsdom",
80 | "eject": "react-scripts eject"
81 | },
82 | "browserslist": [
83 | ">0.2%",
84 | "not dead",
85 | "not ie <= 11",
86 | "not op_mini all"
87 | ],
88 | "devDependencies": {
89 | "enzyme": "^3.9.0",
90 | "enzyme-adapter-react-16": "^1.9.1",
91 | "react-test-renderer": "^16.8.3"
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/assets/Images/Icons/fast.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/Components/SiteDesign/SiteDesignStyles.js:
--------------------------------------------------------------------------------
1 | const drawerWidth = 300;
2 | module.exports = {
3 | styles: theme => ({
4 | palette: {
5 | primary: { main: "#9E9E9E" },
6 | secondary: { main: "#ee0053" },
7 | error: { main: "#ee0053" }
8 | },
9 | root: {
10 | display: "flex"
11 | },
12 | appRoot: {
13 | flexGrow: 1
14 | },
15 | title: {
16 | flexGrow: 1
17 | },
18 | profileNameIcon: {
19 | display: "flex",
20 | justifyContent: "space-around",
21 | alignItems: "center",
22 | marginRight: 10
23 | },
24 | profileIconButton: {
25 | borderRadius: 0
26 | },
27 | profileButtonIconText: {
28 | marginLeft: 10
29 | },
30 | myAccountIcon: {
31 | paddingRight: "15px",
32 | fontSize: "35px",
33 | height: "20px"
34 | },
35 | portIcon: {
36 | paddingRight: "15px",
37 | fontSize: "30px",
38 | height: "20px"
39 | },
40 | appBar: {
41 | zIndex: theme.zIndex.drawer + 1,
42 | transition: theme.transitions.create(["width", "margin"], {
43 | easing: theme.transitions.easing.sharp,
44 | duration: theme.transitions.duration.leavingScreen
45 | })
46 | },
47 | appBarShift: {
48 | marginLeft: drawerWidth,
49 | width: `calc(100% - ${drawerWidth}px)`,
50 | transition: theme.transitions.create(["width", "margin"], {
51 | easing: theme.transitions.easing.sharp,
52 | duration: theme.transitions.duration.enteringScreen
53 | })
54 | },
55 | menuButton: {
56 | marginLeft: 12,
57 | marginRight: 36
58 | },
59 | hide: {
60 | display: "none"
61 | },
62 | drawer: {
63 | width: drawerWidth,
64 | flexShrink: 0,
65 | whiteSpace: "nowrap"
66 | },
67 | /* PROBLEM STARTS HERE */
68 | drawerOpen: {
69 | width: drawerWidth,
70 | transition: theme.transitions.create("width", {
71 | easing: theme.transitions.easing.sharp,
72 | duration: theme.transitions.duration.enteringScreen
73 | })
74 | },
75 | /* The below for the width of the side-drawer when the drawer is completely closed */
76 | drawerClose: {
77 | transition: theme.transitions.create("width", {
78 | easing: theme.transitions.easing.sharp,
79 | duration: theme.transitions.duration.leavingScreen
80 | }),
81 | overflowX: "hidden",
82 | width: theme.spacing.unit * 10 + 1
83 | },
84 | toolbar: {
85 | display: "flex",
86 | alignItems: "center",
87 | justifyContent: "flex-end",
88 | padding: "0 8px"
89 | },
90 | /* END */
91 | content: {
92 | flexGrow: 1,
93 | width: "100%",
94 | padding: theme.spacing.unit * 2
95 | },
96 | nested: {
97 | paddingLeft: theme.spacing.unit * 3
98 | },
99 | nestedProfile: {
100 | paddingLeft: theme.spacing.unit * 1
101 | },
102 | menuList: {
103 | position: "relative",
104 | right: 80
105 | },
106 | sideNavBarImageContainer: {
107 | display: "flex",
108 | margin: "auto auto auto 10px"
109 | },
110 | sideNavBarImage: {
111 | height: 44,
112 | width: 44,
113 | marginRight: 30
114 | },
115 | sideNavBarText: {
116 | marginBottom: 0
117 | },
118 | sideNavBarIcon: {
119 | marginTop: "15px",
120 | height: 35,
121 | width: 35
122 | },
123 | sideNavBarIconDashboard: {
124 | marginTop: "15px",
125 | height: 35,
126 | width: 35
127 | },
128 | sideNavBarIconAdmin: {
129 | height: 35,
130 | width: 35
131 | }
132 | })
133 | };
134 |
--------------------------------------------------------------------------------
/src/Components/StockAnalytics/SandP500_PE.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import axios from "axios";
3 | const ReactHighstock = require("react-highcharts");
4 |
5 | // Function to re-structure the data received from the API
6 | const getDateAndClosingPrice = obj => {
7 | let xAxis = [];
8 | let yAxis = [];
9 | for (let key in obj) {
10 | if (obj.hasOwnProperty(key)) {
11 | xAxis.push(key);
12 | yAxis.push(parseInt(obj[key].close));
13 | }
14 | }
15 | return [xAxis, yAxis];
16 | };
17 |
18 | export class SandP500_PE extends Component {
19 | state = {
20 | s_and_p_500_index: [],
21 | closingDate: ""
22 | };
23 |
24 | componentDidUpdate(prevProps, prevState) {
25 | if (
26 | this.props.fromDate !== prevProps.fromDate ||
27 | this.props.toDate !== prevProps.toDate
28 | ) {
29 | const { fromDate, toDate } = this.props;
30 | const APIkey = process.env.REACT_APP_WORLD_TRADING_DATA_API_TOKEN;
31 |
32 | const url = `https://www.worldtradingdata.com/api/v1/history?symbol=^INX&date_from=${fromDate}&date_to=${toDate}&sort=newest&api_token=${APIkey}`;
33 |
34 | if (fromDate !== "" && toDate !== "") {
35 | axios
36 | .get(url)
37 | .then(res => {
38 | if (
39 | res.data &&
40 | res.data.history &&
41 | Object.entries(res.data.history).length !== 0
42 | ) {
43 | this.setState({
44 | closingDate: getDateAndClosingPrice(res.data.history)[0],
45 | s_and_p_500_index: getDateAndClosingPrice(res.data.history)[1]
46 | });
47 | }
48 | })
49 | .catch(err => console.log("Error while fetching data ", err));
50 | }
51 | }
52 | }
53 |
54 | componentDidMount() {
55 | const { fromDate, toDate } = this.props;
56 | const APIkey = process.env.REACT_APP_WORLD_TRADING_DATA_API_TOKEN;
57 |
58 | const url = `https://www.worldtradingdata.com/api/v1/history?symbol=^INX&date_from=${fromDate}&date_to=${toDate}&sort=newest&api_token=${APIkey}`;
59 |
60 | if (fromDate !== "" && toDate !== "") {
61 | axios
62 | .get(url)
63 | .then(res => {
64 | if (
65 | res.data &&
66 | res.data.history &&
67 | Object.entries(res.data.history).length !== 0
68 | ) {
69 | this.setState({
70 | closingDate: getDateAndClosingPrice(res.data.history)[0],
71 | s_and_p_500_index: getDateAndClosingPrice(res.data.history)[1]
72 | });
73 | }
74 | })
75 | .catch(err => console.log("Error while fetching data ", err));
76 | }
77 | }
78 |
79 | render() {
80 | const { s_and_p_500_index, closingDate } = this.state;
81 |
82 | const config = {
83 | chart: {
84 | backgroundColor: {
85 | linearGradient: [0, 0, 500, 500],
86 | stops: [[0, "rgb(255, 255, 255)"], [1, "rgb(247, 247, 152)"]]
87 | },
88 | polar: true,
89 | type: "line"
90 | },
91 | xAxis: {
92 | categories: closingDate,
93 |
94 | labels: {
95 | align: "right",
96 | rotation: "-45"
97 | }
98 | },
99 | series: [
100 | {
101 | name: `S&P`,
102 | data: s_and_p_500_index,
103 | tooltip: {
104 | valueDecimals: 2
105 | }
106 | }
107 | ],
108 |
109 | title: {
110 | text: `S&P 500 closing from worldtradingdata.com`
111 | }
112 | };
113 | return (
114 |
115 | {/*{console.log("X DATA", closingDate)}
116 | {console.log("Y DATA", s_and_p_500_index)}*/}
117 |
118 | );
119 |
120 | );
121 | }
122 | }
123 |
124 | export default SandP500_PE;
125 |
--------------------------------------------------------------------------------
/src/assets/Images/Icons/admin.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
85 |
--------------------------------------------------------------------------------
/src/registerServiceWorker.js:
--------------------------------------------------------------------------------
1 | // // In production, we register a service worker to serve assets from local cache.
2 | //
3 | // // This lets the app load faster on subsequent visits in production, and gives
4 | // // it offline capabilities. However, it also means that developers (and users)
5 | // // will only see deployed updates on the "N+1" visit to a page, since previously
6 | // // cached resources are updated in the background.
7 | //
8 | // // To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
9 | // // This link also includes instructions on opting out of this behavior.
10 | //
11 | // const isLocalhost = Boolean(
12 | // window.location.hostname === 'localhost' ||
13 | // // [::1] is the IPv6 localhost address.
14 | // window.location.hostname === '[::1]' ||
15 | // // 127.0.0.1/8 is considered localhost for IPv4.
16 | // window.location.hostname.match(
17 | // /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
18 | // )
19 | // );
20 | //
21 | // export default function register() {
22 | // if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
23 | // // The URL constructor is available in all browsers that support SW.
24 | // const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
25 | // if (publicUrl.origin !== window.location.origin) {
26 | // // Our service worker won't work if PUBLIC_URL is on a different origin
27 | // // from what our page is served on. This might happen if a CDN is used to
28 | // // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
29 | // return;
30 | // }
31 | //
32 | // window.addEventListener('load', () => {
33 | // const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
34 | //
35 | // if (isLocalhost) {
36 | // // This is running on localhost. Lets check if a service worker still exists or not.
37 | // checkValidServiceWorker(swUrl);
38 | //
39 | // // Add some additional logging to localhost, pointing developers to the
40 | // // service worker/PWA documentation.
41 | // navigator.serviceWorker.ready.then(() => {
42 | // console.log(
43 | // 'This web app is being served cache-first by a service ' +
44 | // 'worker. To learn more, visit https://goo.gl/SC7cgQ'
45 | // );
46 | // });
47 | // } else {
48 | // // Is not local host. Just register service worker
49 | // registerValidSW(swUrl);
50 | // }
51 | // });
52 | // }
53 | // }
54 | //
55 | // function registerValidSW(swUrl) {
56 | // navigator.serviceWorker
57 | // .register(swUrl)
58 | // .then(registration => {
59 | // registration.onupdatefound = () => {
60 | // const installingWorker = registration.installing;
61 | // installingWorker.onstatechange = () => {
62 | // if (installingWorker.state === 'installed') {
63 | // if (navigator.serviceWorker.controller) {
64 | // // At this point, the old content will have been purged and
65 | // // the fresh content will have been added to the cache.
66 | // // It's the perfect time to display a "New content is
67 | // // available; please refresh." message in your web app.
68 | // console.log('New content is available; please refresh.');
69 | // } else {
70 | // // At this point, everything has been precached.
71 | // // It's the perfect time to display a
72 | // // "Content is cached for offline use." message.
73 | // console.log('Content is cached for offline use.');
74 | // }
75 | // }
76 | // };
77 | // };
78 | // })
79 | // .catch(error => {
80 | // console.error('Error during service worker registration:', error);
81 | // });
82 | // }
83 | //
84 | // function checkValidServiceWorker(swUrl) {
85 | // // Check if the service worker can be found. If it can't reload the page.
86 | // fetch(swUrl)
87 | // .then(response => {
88 | // // Ensure service worker exists, and that we really are getting a JS file.
89 | // if (
90 | // response.status === 404 ||
91 | // response.headers.get('content-type').indexOf('javascript') === -1
92 | // ) {
93 | // // No service worker found. Probably a different app. Reload the page.
94 | // navigator.serviceWorker.ready.then(registration => {
95 | // registration.unregister().then(() => {
96 | // window.location.reload();
97 | // });
98 | // });
99 | // } else {
100 | // // Service worker found. Proceed as normal.
101 | // registerValidSW(swUrl);
102 | // }
103 | // })
104 | // .catch(() => {
105 | // console.log(
106 | // 'No internet connection found. App is running in offline mode.'
107 | // );
108 | // });
109 | // }
110 | //
111 | // export function unregister() {
112 | // if ('serviceWorker' in navigator) {
113 | // navigator.serviceWorker.ready.then(registration => {
114 | // registration.unregister();
115 | // });
116 | // }
117 | // }
118 |
--------------------------------------------------------------------------------
/src/Components/NotFound/moon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/Components/CSVParsing/CSVParsing.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import Dropzone from "react-dropzone";
3 | import { parse } from "papaparse";
4 | import MUIDataTable from "mui-datatables";
5 | import { Row, Col } from "reactstrap";
6 | import { styles } from "../commonStyles/ModuleItemListStyles";
7 | import { withStyles } from "@material-ui/core";
8 | import CSVParsingChart from "./CSVParsingChart";
9 | const omit = require("lodash.omit");
10 | const flatten = require("lodash.flatten");
11 |
12 | // Function to return the data as an array of arrays for rendering the ReactHighstock data. But if I am not rendering the stock data (instead only a horizontal line chart then use the next two functions instead formattedDataForXAxisForHighChart() and formattedDataForYAxisForHighChart() )
13 | const formattedDataForHighChartsStocks = data => {
14 | return data.map(obj => {
15 | let omittedObject = omit(obj, [
16 | "Open",
17 | "High",
18 | "Low",
19 | "Adj Close",
20 | "Volume"
21 | ]);
22 | return Object.values(omittedObject);
23 | });
24 | };
25 |
26 | // Two Functions to return the data as an array XAxis values and YAxis values for rendering the ReactHighChart data. But if I am rendering the stock data - then use the above function instead formattedDataForHighChartsStocks ()
27 | const formattedDataForXAxisForHighChart = data => {
28 | let result = [];
29 | data.map((obj, index) => {
30 | let omittedObject = omit(obj, [
31 | "Open",
32 | "High",
33 | "Low",
34 | "Close",
35 | "Adj Close",
36 | "Volume"
37 | ]);
38 | return (result[index] = Object.values(omittedObject));
39 | });
40 | return flatten(result);
41 | };
42 |
43 | const formattedDataForYAxisForHighChart = data => {
44 | let result = [];
45 | data.map((obj, index) => {
46 | let omittedObject = omit(obj, [
47 | "Date",
48 | "Open",
49 | "High",
50 | "Low",
51 | "Adj Close",
52 | "Volume"
53 | ]);
54 | return (result[index] = Object.values(omittedObject));
55 | });
56 | return flatten(result);
57 | };
58 |
59 | // const resultData = _.flatten(formattedDataForHighChartsLodash(data));
60 |
61 | const dropzoneStyle = {
62 | width: 250,
63 | height: 90,
64 | borderWidth: 2,
65 | borderColor: "rgb(102, 102, 102)",
66 | borderStyle: "dashed",
67 | borderRadius: 5,
68 | margin: "0 auto"
69 | };
70 |
71 | class CSVParsing extends Component {
72 | state = {
73 | files: [],
74 | data: [],
75 | tableState: {},
76 | rowsPerPage: 10
77 | };
78 |
79 | onChangeRowsPerPage = rowsPerPage => {
80 | this.setState({ rowsPerPage });
81 | };
82 |
83 | // Function to use the browser's FileReader api to capture the uploaded file
84 | onDrop = files => {
85 | const file = files[0];
86 | if (file.type === "text/csv") {
87 | const reader = new FileReader();
88 | reader.onload = () => {
89 | const csv = reader.result;
90 | const {
91 | data,
92 | meta: { fields }
93 | } = parse(csv, {
94 | header: true,
95 | dynamicTyping: true,
96 | skipEmptyLines: true
97 | });
98 |
99 | this.setState({
100 | data: data
101 | });
102 | };
103 | reader.onabort = () => alert("File reading was aborted.");
104 | reader.onerror = () => alert("File reading has failed.");
105 | reader.readAsBinaryString(file);
106 | }
107 | };
108 |
109 | render() {
110 | const { classes } = this.props;
111 | const { data } = this.state;
112 |
113 | const dataForTableRendering =
114 | data.length !== 0 ? data.map(i => Object.values(i)) : null;
115 |
116 | const formattedDataForChartStoks = formattedDataForHighChartsStocks(data);
117 |
118 | const formattedXAxisDataForChartLine = formattedDataForXAxisForHighChart(
119 | data
120 | );
121 | const formattedYAxisDataForChartLine = formattedDataForYAxisForHighChart(
122 | data
123 | );
124 |
125 | // console.log("PARSED DATA IS ", formattedDataForChart);
126 |
127 | const columns = data.length !== 0 ? data.map(i => Object.keys(i))[0] : null;
128 |
129 | const options = {
130 | filterType: "dropdown",
131 | responsive: "scroll",
132 | selectableRows: true,
133 | rowsPerPage: this.state.tableState
134 | ? this.state.tableState.rowsPerPage
135 | : 10,
136 | onChangeRowsPerPage: this.onChangeRowsPerPage,
137 | activeColumn: this.state.tableState
138 | ? this.state.tableState.activeColumn
139 | : 0,
140 | onTableChange: (action, tableState) => {
141 | // console.log("taBLE STATE IS ", JSON.stringify(tableState));
142 | this.setState({
143 | tableState: tableState
144 | });
145 | }
146 | };
147 |
148 | return (
149 |
150 |
151 |
152 |
153 | {({ getRootProps, getInputProps }) => (
154 |
155 |
156 |
157 |
158 | Drag 'n' drop some files here, or click to select files
159 |
160 |
161 |
162 | )}
163 |
164 |
165 | {data.length !== 0 ? (
166 |
167 |
173 |
178 |
179 | ) : null}
180 |
181 |
182 | );
183 | }
184 | }
185 |
186 | export default withStyles(styles)(CSVParsing);
187 |
188 | /*
189 | {console.log("FORMATTED DATA IS ", dataForTableRendering)}
190 | */
191 |
192 | /* 1> Explanation of why I need to the function formattedDataForHighChartsStocks()
193 |
194 | I get the data as below
195 |
196 | const data = [
197 | {
198 | Date: "2019-03-26",
199 | Open: 118.620003,
200 | High: 118.709999,
201 | Low: 116.849998,
202 | Close: 117.910004
203 | },
204 | {
205 | Date: "2019-03-27",
206 | Open: 117.879997,
207 | High: 118.209999,
208 | Low: 115.519997,
209 | Close: 116.769997
210 | }
211 | ];
212 |
213 | But for HighChartsStocks - i.e. when I am using the below way of importing
214 |
215 | const ReactHighstock = require("react-highcharts/ReactHighstock.src")
216 |
217 | I need the data as below
218 |
219 | formattedData = [ [ '2019-03-26', 117.910004 ], [ '2019-03-27', 116.769997 ] ]
220 |
221 |
222 | 2>
223 |
224 | */
225 |
--------------------------------------------------------------------------------
/src/Components/NotFound/NotFound.css:
--------------------------------------------------------------------------------
1 | /* The below google font is overwriting my fonts in main comopnent, hence commented out */
2 | /* @import url('https://fonts.googleapis.com/css?family=Dosis:300,400,500'); */
3 |
4 | @-moz-keyframes rocket-movement {
5 | 100% {
6 | -moz-transform: translate(1200px, -600px);
7 | }
8 | }
9 |
10 | @-webkit-keyframes rocket-movement {
11 | 100% {
12 | -webkit-transform: translate(1200px, -600px);
13 | }
14 | }
15 |
16 | @keyframes rocket-movement {
17 | 100% {
18 | transform: translate(1200px, -600px);
19 | }
20 | }
21 |
22 | @-moz-keyframes spin-earth {
23 | 100% {
24 | -moz-transform: rotate(-360deg);
25 | transition: transform 20s;
26 | }
27 | }
28 |
29 | @-webkit-keyframes spin-earth {
30 | 100% {
31 | -webkit-transform: rotate(-360deg);
32 | transition: transform 20s;
33 | }
34 | }
35 |
36 | @keyframes spin-earth {
37 | 100% {
38 | -webkit-transform: rotate(-360deg);
39 | transform: rotate(-360deg);
40 | transition: transform 20s;
41 | }
42 | }
43 |
44 | @-moz-keyframes move-astronaut {
45 | 100% {
46 | -moz-transform: translate(-160px, -160px);
47 | }
48 | }
49 |
50 | @-webkit-keyframes move-astronaut {
51 | 100% {
52 | -webkit-transform: translate(-160px, -160px);
53 | }
54 | }
55 |
56 | @keyframes move-astronaut {
57 | 100% {
58 | -webkit-transform: translate(-160px, -160px);
59 | transform: translate(-160px, -160px);
60 | }
61 | }
62 |
63 | @-moz-keyframes rotate-astronaut {
64 | 100% {
65 | -moz-transform: rotate(-720deg);
66 | }
67 | }
68 |
69 | @-webkit-keyframes rotate-astronaut {
70 | 100% {
71 | -webkit-transform: rotate(-720deg);
72 | }
73 | }
74 |
75 | @keyframes rotate-astronaut {
76 | 100% {
77 | -webkit-transform: rotate(-720deg);
78 | transform: rotate(-720deg);
79 | }
80 | }
81 |
82 | @-moz-keyframes glow-star {
83 | 40% {
84 | -moz-opacity: 0.3;
85 | }
86 |
87 | 90%,
88 | 100% {
89 | -moz-opacity: 1;
90 | -moz-transform: scale(1.2);
91 | }
92 | }
93 |
94 | @-webkit-keyframes glow-star {
95 | 40% {
96 | -webkit-opacity: 0.3;
97 | }
98 |
99 | 90%,
100 | 100% {
101 | -webkit-opacity: 1;
102 | -webkit-transform: scale(1.2);
103 | }
104 | }
105 |
106 | @keyframes glow-star {
107 | 40% {
108 | -webkit-opacity: 0.3;
109 | opacity: 0.3;
110 | }
111 |
112 | 90%,
113 | 100% {
114 | -webkit-opacity: 1;
115 | opacity: 1;
116 | -webkit-transform: scale(1.2);
117 | transform: scale(1.2);
118 | border-radius: 999999px;
119 | }
120 | }
121 |
122 | .spin-earth-on-hover {
123 |
124 | transition: ease 200s !important;
125 | transform: rotate(-3600deg) !important;
126 | }
127 |
128 | html,
129 | body {
130 | margin: 0;
131 | width: 100%;
132 | height: 100%;
133 | font-family: 'Dosis', sans-serif;
134 | font-weight: 300;
135 | -webkit-user-select: none;
136 | /* Safari 3.1+ */
137 | -moz-user-select: none;
138 | /* Firefox 2+ */
139 | -ms-user-select: none;
140 | /* IE 10+ */
141 | user-select: none;
142 | /* Standard syntax */
143 | }
144 |
145 | .bg-purple {
146 | background: url("./bg_purple.png");
147 | background-repeat: repeat-x;
148 | background-size: cover;
149 | background-position: left top;
150 | height: 100vh;
151 | overflow: hidden;
152 |
153 | }
154 |
155 | /* --------------------------- */
156 |
157 |
158 | .custom-navbar {
159 | padding-top: 15px;
160 | }
161 |
162 | .brand-logo {
163 | margin-left: 25px;
164 | margin-top: 5px;
165 | display: inline-block;
166 | }
167 |
168 | .navbar-links {
169 | display: inline-block;
170 | float: right;
171 | margin-right: 15px;
172 | text-transform: uppercase;
173 |
174 |
175 | }
176 |
177 | ul {
178 | list-style-type: none;
179 | margin: 0;
180 | padding: 0;
181 | align-items: center;
182 | }
183 |
184 | li {
185 |
186 | padding: 0px 15px;
187 | }
188 |
189 | li a {
190 | display: block;
191 | color: white;
192 | text-align: center;
193 | text-decoration: none;
194 | letter-spacing: 2px;
195 | font-size: 12px;
196 |
197 | -webkit-transition: all 0.3s ease-in;
198 | -moz-transition: all 0.3s ease-in;
199 | -ms-transition: all 0.3s ease-in;
200 | -o-transition: all 0.3s ease-in;
201 | transition: all 0.3s ease-in;
202 | }
203 |
204 | li a:hover {
205 | color: #ffcb39;
206 | }
207 |
208 | /* clear */
209 | .btn-request {
210 | padding: 10px 25px;
211 | border: 1px solid #FFCB39;
212 | border-radius: 100px;
213 | font-weight: 400;
214 | }
215 |
216 | .btn-request:hover {
217 | background-color: #FFCB39;
218 | color: #fff;
219 | transform: scale(1.05);
220 | box-shadow: 0px 20px 20px rgba(0, 0, 0, 0.1);
221 | }
222 |
223 | .btn-go-home {
224 | position: relative;
225 | z-index: 200;
226 | margin: 15px auto;
227 | width: 100px;
228 | padding: 10px 15px;
229 | border: 1px solid #FFCB39;
230 | border-radius: 100px;
231 | font-weight: 400;
232 | display: block;
233 | color: white;
234 | text-align: center;
235 | text-decoration: none;
236 | letter-spacing: 2px;
237 | font-size: 11px;
238 |
239 | -webkit-transition: all 0.3s ease-in;
240 | -moz-transition: all 0.3s ease-in;
241 | -ms-transition: all 0.3s ease-in;
242 | -o-transition: all 0.3s ease-in;
243 | transition: all 0.3s ease-in;
244 | }
245 |
246 | .btn-go-home:hover {
247 | background-color: #FFCB39;
248 | color: #fff;
249 | transform: scale(1.05);
250 | box-shadow: 0px 20px 20px rgba(0, 0, 0, 0.1);
251 | }
252 |
253 | /* clear */
254 | .central-body {
255 | /* width: 100%;*/
256 | padding: 17% 5% 10% 5%;
257 | text-align: center;
258 | }
259 |
260 | .objects img {
261 | z-index: 90;
262 | pointer-events: none;
263 | }
264 |
265 | /* ============================= */
266 | .object_rocket {
267 | z-index: 95;
268 | position: absolute;
269 | transform: translateX(-50px);
270 | top: 75%;
271 | pointer-events: none;
272 | animation: rocket-movement 200s linear infinite both running;
273 | }
274 |
275 | .object_earth {
276 | position: absolute;
277 | top: 20%;
278 | left: 15%;
279 | z-index: 90;
280 | /* animation: spin-earth 100s infinite linear both;*/
281 | }
282 |
283 | .object_moon {
284 | position: absolute;
285 | top: 12%;
286 | left: 25%;
287 | /*
288 | transform: rotate(0deg);
289 | transition: transform ease-in 99999999999s;
290 | */
291 | }
292 |
293 | .earth-moon {}
294 |
295 | .object_astronaut {
296 | animation: rotate-astronaut 200s infinite linear both alternate;
297 | }
298 |
299 | .box_astronaut {
300 | z-index: 110 !important;
301 | position: absolute;
302 | top: 60%;
303 | right: 20%;
304 | will-change: transform;
305 | animation: move-astronaut 50s infinite linear both alternate;
306 | }
307 |
308 | .image-404 {
309 | position: relative;
310 | z-index: 100;
311 | pointer-events: none;
312 | }
313 |
314 | .stars {
315 | background: url("./overlay_stars.svg");
316 | background-repeat: repeat;
317 | background-size: contain;
318 | background-position: left top;
319 | }
320 |
321 | .glowing_stars .star {
322 | position: absolute;
323 | border-radius: 100%;
324 | background-color: #fff;
325 | width: 3px;
326 | height: 3px;
327 | opacity: 0.3;
328 | will-change: opacity;
329 | }
330 |
331 | .glowing_stars .star:nth-child(1) {
332 | top: 80%;
333 | left: 25%;
334 | animation: glow-star 2s infinite ease-in-out alternate 1s;
335 | }
336 |
337 | .glowing_stars .star:nth-child(2) {
338 | top: 20%;
339 | left: 40%;
340 | animation: glow-star 2s infinite ease-in-out alternate 3s;
341 | }
342 |
343 | .glowing_stars .star:nth-child(3) {
344 | top: 25%;
345 | left: 25%;
346 | animation: glow-star 2s infinite ease-in-out alternate 5s;
347 | }
348 |
349 | .glowing_stars .star:nth-child(4) {
350 | top: 75%;
351 | left: 80%;
352 | animation: glow-star 2s infinite ease-in-out alternate 7s;
353 | }
354 |
355 | .glowing_stars .star:nth-child(5) {
356 | top: 90%;
357 | left: 50%;
358 | animation: glow-star 2s infinite ease-in-out alternate 9s;
359 | }
360 |
361 | @media only screen and (max-width: 600px) {
362 | .navbar-links {
363 | display: none;
364 | }
365 |
366 | .custom-navbar {
367 | text-align: center;
368 | }
369 |
370 | .brand-logo img {
371 | width: 120px;
372 | }
373 |
374 | .box_astronaut {
375 | top: 70%;
376 | }
377 |
378 | .central-body {
379 | padding-top: 25%;
380 | }
381 | }
--------------------------------------------------------------------------------
/src/Components/StockAnalytics/Alternative-working-codes-kept-for-backup/SandP500_PE-vx-WORKING.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { AreaClosed, Line, Bar } from "@vx/shape";
3 | import { curveMonotoneX } from "@vx/curve";
4 | import { GridRows, GridColumns } from "@vx/grid";
5 | import { scaleTime, scaleLinear } from "@vx/scale";
6 | import { withTooltip, Tooltip } from "@vx/tooltip";
7 | import { localPoint } from "@vx/event";
8 | import { bisector } from "d3-array";
9 | import { timeFormat } from "d3-time-format";
10 | import axios from "axios";
11 |
12 | // util
13 | const formatDate = timeFormat("%b %d, '%y");
14 | const min = (arr, fn) => Math.min(...arr.map(fn));
15 | const max = (arr, fn) => Math.max(...arr.map(fn));
16 | const extent = (arr, fn) => [min(arr, fn), max(arr, fn)];
17 |
18 | // accessors
19 | const xStock = d => new Date(d.date);
20 | const yStock = d => d.close;
21 | const bisectDate = bisector(d => new Date(d.date)).left;
22 |
23 | const getDateAndClosingPrice = obj => {
24 | let result = [];
25 | for (let key in obj) {
26 | if (obj.hasOwnProperty(key)) {
27 | result.push([key, obj[key].close]);
28 | }
29 | }
30 | return result.map(i => ({
31 | date: i[0],
32 | close: i[1]
33 | }));
34 | };
35 |
36 | class SandP500_PE extends React.Component {
37 | constructor(props) {
38 | super(props);
39 | this.state = {
40 | s_and_p_500_index: []
41 | };
42 | this.handleTooltip = this.handleTooltip.bind(this);
43 | }
44 |
45 | // VERY IMPORTANT - THE BELOW 'WORLDTRADINGDATA' WILL ONLY GIVE ME 250 FREE API CALLS PER DAY, AND IN THE BELOW GRAPH WHEN I MOVE MY MOUSE OVER, IT TRIGGERS THE API CALL WITH EACH MOVE OF MOUSE OVER THE DATE.
46 | // AND I THINK handleToolTip() functions is the reason behind this.
47 | componentDidMount() {
48 | const { fromDate, toDate } = this.props;
49 | const APIkey = process.env.REACT_APP_WORLD_TRADING_DATA_API_TOKEN;
50 |
51 | const url = `https://www.worldtradingdata.com/api/v1/history?symbol=^INX&date_from=${fromDate}&date_to=${toDate}&sort=newest&api_token=${APIkey}`;
52 |
53 | if (fromDate !== "" && toDate !== "") {
54 | axios
55 | .get(url)
56 | .then(res => {
57 | if (
58 | res.data &&
59 | res.data.history &&
60 | Object.entries(res.data.history).length !== 0
61 | ) {
62 | const formattedDataFromAPI_response = getDateAndClosingPrice(
63 | res.data.history
64 | );
65 | this.setState({
66 | s_and_p_500_index: formattedDataFromAPI_response.reverse()
67 | });
68 | }
69 | })
70 | .catch(err => console.log("Error while fetching data ", err));
71 | }
72 | }
73 |
74 | handleTooltip({ event, data, xStock, xScale, yScale }) {
75 | const { showTooltip } = this.props;
76 | const { x } = localPoint(event);
77 | const x0 = xScale.invert(x);
78 | const index = bisectDate(data, x0, 1);
79 | const d0 = data[index - 1];
80 | const d1 = data[index];
81 | let d = d0;
82 | if (d1 && d1.date) {
83 | d = x0 - xStock(d0.date) > xStock(d1.date) - x0 ? d1 : d0;
84 | }
85 | showTooltip({
86 | tooltipData: d,
87 | tooltipLeft: x,
88 | tooltipTop: yScale(d.close)
89 | });
90 | }
91 | render() {
92 | const width = 500;
93 | const height = 200;
94 | const margin = {
95 | top: 2,
96 | bottom: 2,
97 | left: 2,
98 | right: 2
99 | };
100 |
101 | const {
102 | hideTooltip,
103 | tooltipData,
104 | tooltipTop,
105 | tooltipLeft,
106 | events
107 | } = this.props;
108 | if (width < 10) return null;
109 |
110 | // bounds
111 | const xMax = width - margin.left - margin.right;
112 | const yMax = height - margin.top - margin.bottom;
113 |
114 | // scales
115 | const xScale = scaleTime({
116 | range: [0, xMax],
117 | domain: extent(this.state.s_and_p_500_index, xStock)
118 | });
119 | const yScale = scaleLinear({
120 | range: [yMax, 0],
121 | domain: [0, max(this.state.s_and_p_500_index, yStock) + yMax / 3],
122 | nice: true
123 | });
124 |
125 | return (
126 |
127 |
238 | {tooltipData && (
239 |
240 |
248 | {`$${yStock(tooltipData)}`}
249 |
250 |
257 | {formatDate(xStock(tooltipData))}
258 |
259 |
260 | )}
261 |
262 | );
263 | }
264 | }
265 |
266 | export default withTooltip(SandP500_PE);
267 |
268 | /* Explanation of the getDateAndClosingPrice function above after getting the response from the API data ********
269 |
270 | Original data received from API
271 |
272 | const data = {
273 | "2019-03-29": {
274 | open: "2828.27",
275 | close: "2834.40",
276 | high: "2836.03",
277 | low: "2819.23",
278 | volume: "0"
279 | },
280 | "2019-03-28": {
281 | open: "2809.40",
282 | close: "2815.44",
283 | high: "2819.71",
284 | low: "2798.77",
285 | volume: "0"
286 | }
287 | };
288 |
289 | BUT I need data in following format
290 |
291 | [ { date: '2019-03-29', close: '2834.40' },
292 | { date: '2019-03-28', close: '2815.44' } ]
293 |
294 |
295 | */
296 |
--------------------------------------------------------------------------------
/src/assets/Images/car.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/Components/SiteDesign/SiteDesign.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import history from "../../history";
3 | import { Link } from "react-router-dom";
4 | import PropTypes from "prop-types";
5 | import classNames from "classnames";
6 | import { styles } from "./SiteDesignStyles";
7 | import { withStyles } from "@material-ui/core/styles";
8 | import {
9 | AppBar,
10 | Collapse,
11 | CssBaseline,
12 | Divider,
13 | Drawer,
14 | Grow,
15 | IconButton,
16 | List,
17 | ListItem,
18 | ListItemIcon,
19 | ListItemText,
20 | Paper,
21 | Popper,
22 | Switch,
23 | Toolbar,
24 | Typography,
25 | MenuItem,
26 | MenuList
27 | } from "@material-ui/core";
28 | import AccountCircle from "@material-ui/icons/AccountCircle";
29 | import ExitToApp from "@material-ui/icons/ExitToApp";
30 | import ClickAwayListener from "@material-ui/core/ClickAwayListener";
31 | import { Menu } from "@material-ui/icons";
32 | import ChevronLeftIcon from "@material-ui/icons/ChevronLeft";
33 | import ChevronRightIcon from "@material-ui/icons/ChevronRight";
34 | import SiteLogo from "../../assets/Images/car.svg";
35 | import ToolsIcon from "../../assets/Images/Icons/images.jpg";
36 | import DepartmentsIcon from "../../assets/Images/Icons/Bold-and-Vibrant-colors.png";
37 | import TransportIcon from "../../assets/Images/Icons/bitcoin.svg";
38 | import AllRoutes from "../../Routes/DashboardRoutes";
39 |
40 | class SiteDesign extends React.Component {
41 | state = {
42 | open: false,
43 | openDashboard: false,
44 | openAdmin: false,
45 | openOptions: false,
46 | openWebAdmin: false,
47 | anchorEl: null
48 | };
49 |
50 | handleDrawerOpen = () => {
51 | this.setState({
52 | open: true,
53 | openAdmin: true
54 | });
55 | };
56 |
57 | handleDrawerClose = () => {
58 | this.setState({
59 | open: false,
60 | openDashboard: false,
61 | openAdmin: false,
62 | openOptions: false,
63 | openWebAdmin: false
64 | });
65 | };
66 |
67 | handleClickDashboard = () => {
68 | this.setState(state => ({
69 | openDashboard: !state.openDashboard,
70 | openAdmin: false,
71 | openOptions: false,
72 | openWebAdmin: false
73 | }));
74 | };
75 |
76 | handleClickAdmin = () => {
77 | this.setState(state => ({
78 | openAdmin: !state.openAdmin,
79 | openDashboard: false,
80 | openOptions: false,
81 | openWebAdmin: false
82 | }));
83 | };
84 |
85 | handleClickOptions = () => {
86 | this.setState(state => ({
87 | openOptions: !state.openOptions,
88 | openAdmin: false,
89 | openDashboard: false,
90 | openWebAdmin: false
91 | }));
92 | };
93 |
94 | handleMenu = event => {
95 | this.setState({ anchorEl: event.currentTarget });
96 | };
97 |
98 | handleClose = () => {
99 | this.setState({ anchorEl: null });
100 | };
101 |
102 | render() {
103 | const open = Boolean(this.state.anchorEl);
104 | const {
105 | classes,
106 | children,
107 | theme,
108 | themeType,
109 | handleThemeTypeChange
110 | } = this.props;
111 |
112 | return (
113 |
114 |
115 |
116 |
122 |
123 |
131 |
132 |
133 | {this.state.open ? (
134 |
140 | ) : (
141 |
147 | REACT APP
148 |
149 | )}
150 |
156 |
157 |
158 |
159 |
167 |
175 |
179 | Rohan | Paul
180 |
181 |
182 |
183 |
184 |
190 | {({ TransitionProps, placement }) => (
191 |
225 | )}
226 |
227 |
228 |
229 |
230 |
231 |
232 |
246 |
247 |
248 |

253 |
REACT APP
254 |
255 |
256 | {theme.direction === "rtl" ? (
257 |
258 | ) : (
259 |
260 | )}
261 |
262 |
263 |
264 |
265 |
266 |
267 |
273 |
274 |
279 |
280 |
281 |
282 |
288 |
289 |
294 |
295 |
296 |
297 |
303 |
304 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 | );
320 | }
321 | }
322 |
323 | SiteDesign.propTypes = {
324 | classes: PropTypes.object.isRequired,
325 | theme: PropTypes.object.isRequired
326 | };
327 |
328 | export default withStyles(styles, { withTheme: true })(SiteDesign);
329 |
--------------------------------------------------------------------------------
/src/Components/BitCoin/BitCoin.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Paper from "@material-ui/core/Paper";
3 | import Typography from "@material-ui/core/Typography";
4 | import { AreaClosed, Line, Bar } from "@vx/shape";
5 | import { curveMonotoneX } from "@vx/curve";
6 | import { GridRows, GridColumns } from "@vx/grid";
7 | import { scaleTime, scaleLinear } from "@vx/scale";
8 | import { withTooltip, Tooltip } from "@vx/tooltip";
9 | import { localPoint } from "@vx/event";
10 | import { bisector } from "d3-array";
11 | import { timeFormat } from "d3-time-format";
12 | import { Row, Col } from "reactstrap";
13 | import { styles } from "../commonStyles/ModuleItemListStyles";
14 | import axios from "axios";
15 | import { withStyles } from "@material-ui/core";
16 | import AllCryptoCurrencyBarGraph from "./AllCryptoCurrencyBarGraph";
17 | const omit = require("lodash.omit");
18 |
19 | // util
20 | const formatDate = timeFormat("%b %d, '%y");
21 | const min = (arr, fn) => Math.min(...arr.map(fn));
22 | const max = (arr, fn) => Math.max(...arr.map(fn));
23 | const extent = (arr, fn) => [min(arr, fn), max(arr, fn)];
24 |
25 | // accessors
26 | const xStock = d => new Date(d.date);
27 | const yStock = d => d && d.close;
28 | const bisectDate = bisector(d => new Date(d.date)).left;
29 |
30 | // Function to format the data received from "financialmodelingprep" for all crypto currency price
31 | const getDateAndClosingPrice = obj => {
32 | let result = [];
33 | for (let key in obj) {
34 | if (obj.hasOwnProperty(key)) {
35 | // Filter out currencies that are too small in terms of their closing price
36 | if (obj[key].Price > 20) {
37 | result.push([obj[key].name, obj[key].Price]);
38 | }
39 | }
40 | }
41 | return result;
42 | };
43 |
44 | class BitCoin extends React.Component {
45 | state = {
46 | data: [],
47 | allCryptocurrencyData: []
48 | };
49 |
50 | constructor(props) {
51 | super(props);
52 | this.handleTooltip = this.handleTooltip.bind(this);
53 | }
54 |
55 | async componentDidMount() {
56 | const res = await fetch(
57 | "https://api.coindesk.com/v1/bpi/historical/close.json"
58 | );
59 | const data = await res.json();
60 |
61 | axios
62 | .get(`https://financialmodelingprep.com/api/cryptocurrency?datatype=json`)
63 | .then(res => {
64 | let crypData = omit(res.data, ["BTC"]);
65 | // const crypData = res.data;
66 | // console.log("RECEIVED DATA ", crypData);
67 | this.setState({
68 | data: Object.keys(data.bpi).map(item => {
69 | return {
70 | date: item,
71 | close: data && data.bpi && data.bpi[item]
72 | };
73 | }),
74 | allCryptocurrencyData: getDateAndClosingPrice(crypData)
75 | });
76 | })
77 | .catch(err => {
78 | console.log("Error happened while fetching data", err);
79 | });
80 | }
81 |
82 | handleTooltip({ event, data, xStock, xScale, yScale }) {
83 | const { showTooltip } = this.props;
84 | const { x } = localPoint(event);
85 | const x0 = xScale.invert(x);
86 | const index = bisectDate(data, x0, 1);
87 | const d0 = data[index - 1];
88 | const d1 = data[index];
89 | let d = d0;
90 | if (d1 && d1.date) {
91 | d = x0 - xStock(d0.date) > xStock(d1.date) - x0 ? d1 : d0;
92 | }
93 | showTooltip({
94 | tooltipData: d,
95 | tooltipLeft: x,
96 | tooltipTop: d && yScale(d.close)
97 | });
98 | }
99 | render() {
100 | const width = 1200;
101 | const height = 250;
102 | const margin = {
103 | top: 60,
104 | bottom: 2,
105 | left: 80,
106 | right: 0
107 | };
108 |
109 | const {
110 | classes,
111 | hideTooltip,
112 | tooltipData,
113 | tooltipTop,
114 | tooltipLeft,
115 | events
116 | } = this.props;
117 | if (width < 10) return null;
118 |
119 | // bounds
120 | const xMax = width - margin.left - margin.right;
121 | const yMax = height - margin.top - margin.bottom;
122 |
123 | // scales
124 | const xScale = scaleTime({
125 | range: [0, xMax],
126 | domain: extent(this.state.data, xStock)
127 | });
128 | const yScale = scaleLinear({
129 | range: [yMax, 0],
130 | domain: [0, max(this.state.data, yStock) + yMax / 3],
131 | nice: true
132 | });
133 |
134 | return (
135 |
136 |
137 |
138 | Bit Coin Price Graph
139 |
140 |
141 |
142 |
258 | {tooltipData && (
259 |
260 |
268 | {`$${yStock(tooltipData)}`}
269 |
270 |
277 | {formatDate(xStock(tooltipData))}
278 |
279 |
280 | )}
281 |
282 |
283 |
284 |
285 |
288 |
289 |
290 | );
291 | }
292 | }
293 |
294 | // export default withTooltip(BitCoin);
295 | export default withStyles(styles)(withTooltip(BitCoin));
296 |
297 | /* Understanding the setState mechanism - Basically I have to convert and plain object to an array of objects with 2 fields added ('date' and 'close')
298 |
299 | A> From Coindesk API - I will get the below data
300 |
301 | const data = {
302 | bpi: {
303 | "2019-03-26": 3945.325,
304 | "2019-03-27": 4051.9033,
305 | "2019-03-28": 4039.0017,
306 | "2019-03-29": 4119.0183,
307 | "2019-03-30": 4117.8483
308 | },
309 | disclaimer:
310 | "This data was produced from the CoinDesk Bitcoin Price Index. BPI value data returned as USD.",
311 | time: {
312 | updated: "Apr 26, 2019 00:03:00 UTC",
313 | updatedISO: "2019-04-26T00:03:00+00:00"
314 | }
315 | };
316 |
317 | B> But I need the data (i.e. my state) in the below format
318 |
319 | [ { date: '2019-03-26', close: 3945.325 },
320 | { date: '2019-03-27', close: 4051.9033 },
321 | { date: '2019-03-28', close: 4039.0017 },
322 | { date: '2019-03-29', close: 4119.0183 },
323 | { date: '2019-03-30', close: 4117.8483 } ]
324 |
325 | C> Hence, first I get all the dates from the API-data with Object.keys() which will return me all the keys of the original received objects as an array
326 |
327 | this.setState({
328 | data: Object.keys(data.bpi).map(item => {
329 | return {
330 | date: item,
331 | close: data.bpi[item]
332 | };
333 | })
334 | });
335 | */
336 |
--------------------------------------------------------------------------------
/src/Components/NotFound/astronaut.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/Components/StockAnalytics/Alternative-working-codes-kept-for-backup/StockAnalyticsDashBoard-WITH-HUGE-autosuggestion.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import PropTypes from "prop-types";
3 | import { withStyles } from "@material-ui/core";
4 | import Paper from "@material-ui/core/Paper";
5 | import styles from "./Styles/analyticsStyles.js";
6 | import axios from "axios";
7 | import Typography from "@material-ui/core/Typography";
8 | import SandP500_PE from "./SandP500_PE";
9 | import Select, { createFilter } from "react-select";
10 | import { FixedSizeList as List } from "react-window";
11 | import { MuiPickersUtilsProvider, DatePicker } from "material-ui-pickers";
12 | import DateFnsUtils from "@date-io/date-fns";
13 | import Button from "@material-ui/core/Button";
14 | import Icon from "@material-ui/core/Icon";
15 | import StockLineChart from "./StockLineChart";
16 | import ValuationRatios from "./ValuationRatios";
17 | import ProfitabilityRatios from "./ProfitabilityRatios";
18 | import DebtRatios from "./DebtRatios";
19 |
20 | const height = 35;
21 |
22 | // I had to resort to this special way of rendering react-select for handling 30,000 rows of data in the autosuggestion
23 | class MenuList extends Component {
24 | render() {
25 | const { options, children, maxHeight, getValue } = this.props;
26 | const [value] = getValue();
27 | const initialOffset = options.indexOf(value) * height;
28 | // const initialOffset = height;
29 |
30 | return (
31 |
37 | {({ index, style }) => {children[index]}
}
38 |
39 | );
40 | }
41 | }
42 |
43 | // Function to convert the date format that I received from "material-ui-pickers" package to the YYYY-MM-DD required by the Quandl API
44 | const convertDateFromStringToAPIFormat = str => {
45 | const date = new Date(str);
46 | const month = ("0" + (date.getMonth() + 1)).slice(-2);
47 | const day = ("0" + date.getDate()).slice(-2);
48 | return [date.getFullYear(), month, day].join("-");
49 | };
50 |
51 | const getYSeriesDataValuationMatrix = obj => {
52 | let set1,
53 | set2,
54 | set3,
55 | set4,
56 | set5 = {};
57 | let yAxisSeries = [];
58 |
59 | for (let key in obj) {
60 | if (obj.hasOwnProperty(key)) {
61 | yAxisSeries.push([key, obj[key].investmentValuationRatios]);
62 | }
63 | }
64 | const priceBookValueRatio = yAxisSeries.map(i => i[1].priceBookValueRatio);
65 | const arrPriceEarningRatio = yAxisSeries.map(i => i[1].priceEarningsRatio);
66 | const arrPriceSalesRatio = yAxisSeries.map(i => i[1].priceSalesRatio);
67 | const arrEnterpriseValueMultiple = yAxisSeries.map(
68 | i => i[1].enterpriseValueMultiple
69 | );
70 | const priceEarningsToGrowthRatio = yAxisSeries.map(
71 | i => i[1].priceEarningsToGrowthRatio
72 | );
73 |
74 | set1 = { name: "Price to Book-Value Ratio", data: priceBookValueRatio };
75 | set2 = { name: "Price Earnings Ratio", data: arrPriceEarningRatio };
76 | set3 = { name: "Price Sales Ratio", data: arrPriceSalesRatio };
77 | set4 = {
78 | name: "Enterprise Value Multiple",
79 | data: arrEnterpriseValueMultiple
80 | };
81 | set5 = {
82 | name: "PriceEarnings To GrowthRatio",
83 | data: priceEarningsToGrowthRatio
84 | };
85 |
86 | return [set1, set2, set3, set4, set5];
87 | };
88 |
89 | const getYSeriesDataProfitabilityMatrix = obj => {
90 | let set1,
91 | set2,
92 | set3,
93 | set4,
94 | set5 = {};
95 | let yAxisSeries = [];
96 |
97 | for (let key in obj) {
98 | if (obj.hasOwnProperty(key)) {
99 | yAxisSeries.push([key, obj[key].profitabilityIndicatorRatios]);
100 | }
101 | }
102 | const grossProfitMargin = yAxisSeries.map(i => i[1].grossProfitMargin);
103 | const operatingProfitMargin = yAxisSeries.map(
104 | i => i[1].operatingProfitMargin
105 | );
106 | const netProfitMargin = yAxisSeries.map(i => i[1].netProfitMargin);
107 | const returnOnEquity = yAxisSeries.map(i => i[1].returnOnEquity);
108 | const eBITperRevenue = yAxisSeries.map(i => i[1].eBITperRevenue);
109 |
110 | set1 = { name: "Gross Profit Margin", data: grossProfitMargin };
111 | set2 = { name: "Operating Profit Margin", data: operatingProfitMargin };
112 | set3 = { name: "Net Profit Margin", data: netProfitMargin };
113 | set4 = {
114 | name: "Return on Equity",
115 | data: returnOnEquity
116 | };
117 | set5 = {
118 | name: "EBIT per Revenue",
119 | data: eBITperRevenue
120 | };
121 |
122 | return [set1, set2, set3, set4, set5];
123 | };
124 |
125 | const getYSeriesDataDebtMatrix = obj => {
126 | let set1,
127 | set2,
128 | set3,
129 | set4 = {};
130 | let yAxisSeries = [];
131 |
132 | for (let key in obj) {
133 | if (obj.hasOwnProperty(key)) {
134 | yAxisSeries.push([key, obj[key].debtRatios]);
135 | }
136 | }
137 | const debtRatio = yAxisSeries.map(i => i[1].debtRatio);
138 | const debtEquityRatio = yAxisSeries.map(i => i[1].debtEquityRatio);
139 | const totalDebtToCapitalization = yAxisSeries.map(
140 | i => i[1].totalDebtToCapitalization
141 | );
142 | const companyEquityMultiplier = yAxisSeries.map(
143 | i => i[1].companyEquityMultiplier
144 | );
145 |
146 | set1 = { name: "Debt Ratio", data: debtRatio };
147 | set2 = { name: "Debt to Equity Ratio", data: debtEquityRatio };
148 | set3 = {
149 | name: "Total Debt To Capitalization ratio",
150 | data: totalDebtToCapitalization
151 | };
152 | set4 = {
153 | name: "Company Equity Multiplier",
154 | data: companyEquityMultiplier
155 | };
156 |
157 | return [set1, set2, set3, set4];
158 | };
159 |
160 | export class StockAnalyticsDashBoard extends Component {
161 | state = {
162 | stockTicker: "",
163 | stockTickerAndLabel: "",
164 | symbolList: [],
165 | fromDate: "",
166 | toDate: "",
167 | xAxisData: [],
168 | yAxisData_StockClosingPrice: [],
169 | shouldSandP_Data_fetch: false,
170 | ySeriesDataForValuationRatios: [],
171 | xSeriesDataForValuationRatios: [],
172 | ySeriesDataForProfitabilityRatios: [],
173 | ySeriesDataForDebtRatios: []
174 | };
175 |
176 | // Higher order function to handle Autocompletion field value change
177 | handleAutocompletionChange = name => value => {
178 | this.setState(
179 | {
180 | stockTicker: value.value
181 | },
182 | () => {
183 | const stockTickerWithName = this.state.symbolList.filter(i => {
184 | return i.value === this.state.stockTicker;
185 | })[0].label;
186 | this.setState({
187 | stockTickerAndLabel: stockTickerWithName
188 | });
189 | }
190 | );
191 | };
192 |
193 | componentDidMount() {
194 | axios
195 | .get("https://api.iextrading.com/1.0/ref-data/symbols?filter=symbol,name")
196 | .then(res => {
197 | this.setState({
198 | symbolList: res.data.map(item => ({
199 | value: item.symbol,
200 | label: `${item.symbol} ${item.name}`
201 | }))
202 | });
203 | });
204 | }
205 |
206 | handleSubmitToFetchAPI = () => {
207 | const { stockTicker, fromDate, toDate } = this.state;
208 | const APIkey = process.env.REACT_APP_QUANDL_API_KEY;
209 |
210 | if (stockTicker !== "" && fromDate !== "" && toDate !== "") {
211 | const url_stockPrice = `https://www.quandl.com/api/v3/datasets/WIKI/${stockTicker}.json?start_date=${fromDate}&end_date=${toDate}&column_index=4&api_key=${APIkey}`;
212 |
213 | const url_stockFundamentalsValuationRatios = `https://financialmodelingprep.com/api/financial-ratios/${stockTicker}?datatype=json`;
214 |
215 | axios
216 | .all([
217 | axios.get(url_stockPrice),
218 | axios.get(url_stockFundamentalsValuationRatios)
219 | ])
220 | .then(
221 | axios.spread((stockPriceData, stockFundamentalsData) => {
222 | const receivedStockClosingData = stockPriceData.data.dataset.data;
223 | const closingPriceDate = receivedStockClosingData.map(i => i[0]);
224 | const closingPrice = receivedStockClosingData.map(i => i[1]);
225 | this.setState({
226 | xAxisData: closingPriceDate,
227 | yAxisData_StockClosingPrice: closingPrice,
228 | ySeriesDataForValuationRatios: getYSeriesDataValuationMatrix(
229 | stockFundamentalsData.data.financialRatios
230 | ),
231 | xSeriesDataForValuationRatios: Object.keys(
232 | stockFundamentalsData.data.financialRatios
233 | ),
234 | ySeriesDataForProfitabilityRatios: getYSeriesDataProfitabilityMatrix(
235 | stockFundamentalsData.data.financialRatios
236 | ),
237 | ySeriesDataForDebtRatios: getYSeriesDataDebtMatrix(
238 | stockFundamentalsData.data.financialRatios
239 | ),
240 | shouldSandP_Data_fetch: true
241 | });
242 | })
243 | )
244 | .catch(function(error) {
245 | console.log(error);
246 | });
247 | }
248 | };
249 |
250 | handleFromDateChange = date => {
251 | const fromDateFormatted = convertDateFromStringToAPIFormat(date);
252 | this.setState({
253 | fromDate: fromDateFormatted
254 | });
255 | };
256 |
257 | handleToDateChange = date => {
258 | const toDateFormatted = convertDateFromStringToAPIFormat(date);
259 | this.setState({
260 | toDate: toDateFormatted
261 | });
262 | };
263 |
264 | render() {
265 | const { classes, theme } = this.props;
266 |
267 | const selectStyles = {
268 | input: base => ({
269 | ...base,
270 | width: "20em",
271 | margin: "auto",
272 |
273 | color: theme.palette.text.primary,
274 | "& input": {
275 | font: "inherit"
276 | }
277 | })
278 | };
279 |
280 | return (
281 |
282 |
283 |
284 |
285 |
286 |
295 |
296 |
297 |
302 | value
303 | ? [
304 | /\d/,
305 | /\d/,
306 | "/",
307 | /\d/,
308 | /\d/,
309 | "/",
310 | /\d/,
311 | /\d/,
312 | /\d/,
313 | /\d/
314 | ]
315 | : []
316 | }
317 | label="From Date"
318 | disableOpenOnEnter
319 | animateYearScrolling={false}
320 | value={this.state.fromDate}
321 | onChange={this.handleFromDateChange}
322 | />
323 |
328 | value
329 | ? [
330 | /\d/,
331 | /\d/,
332 | "/",
333 | /\d/,
334 | /\d/,
335 | "/",
336 | /\d/,
337 | /\d/,
338 | /\d/,
339 | /\d/
340 | ]
341 | : []
342 | }
343 | label="To Date"
344 | disableOpenOnEnter
345 | animateYearScrolling={false}
346 | value={this.state.toDate}
347 | onChange={this.handleToDateChange}
348 | />
349 |
360 |
361 |
362 |
363 |
364 |
368 |
369 |
370 | End of Day Closing Price of {this.state.stockTickerAndLabel}
371 |
378 |
379 |
380 |
381 |
382 |
383 | S&P 500 P/E index EOD closing price during same time
384 | {this.state.fromDate !== "" &&
385 | this.state.toDate !== "" &&
386 | this.state.shouldSandP_Data_fetch === true ? (
387 |
391 | ) : null}
392 |
393 |
394 |
395 |
396 |
397 |
398 | Key Valuation matrix for past five years matrix{" "}
399 | {this.state.stockTickerAndLabel}
400 |
412 |
413 |
414 |
415 |
416 |
417 |
418 | Key Profitabilty matrix for past five years matrix{" "}
419 | {this.state.stockTickerAndLabel}
420 |
429 |
430 |
431 |
432 |
433 |
434 |
435 | Key Debt matrix for past five years matrix{" "}
436 | {this.state.stockTickerAndLabel}
437 |
444 |
445 |
446 |
447 |
448 |
449 | );
450 | }
451 | }
452 |
453 | StockAnalyticsDashBoard.propTypes = {
454 | classes: PropTypes.object.isRequired
455 | };
456 |
457 | export default withStyles(styles, { withTheme: true })(StockAnalyticsDashBoard);
458 |
459 | /* 1> Explanation on the two function getXAxis and getYAxis
460 |
461 | Received data from API will be as below
462 | "data": [
463 | ["2018-02-23", 183.29],
464 | ["2018-02-22", 178.99], ]
465 |
466 | But for the line-graph I need
467 |
468 | var config = {
469 | xAxis: {
470 | categories: ["2018-02-23", '2018-02-22']
471 | },
472 | series: [{
473 | data: [29.9, 71.5 ]
474 | }]
475 | };
476 |
477 | */
478 |
--------------------------------------------------------------------------------
/src/Components/StockAnalytics/StockAnalyticsDashBoard.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import PropTypes from "prop-types";
3 | import { withStyles } from "@material-ui/core";
4 | import Paper from "@material-ui/core/Paper";
5 | import styles from "./Styles/analyticsStyles.js";
6 | import axios from "axios";
7 | import Typography from "@material-ui/core/Typography";
8 | import SandP500_PE from "./SandP500_PE";
9 | import Select, { createFilter } from "react-select";
10 | import { FixedSizeList as List } from "react-window";
11 | import { MuiPickersUtilsProvider, DatePicker } from "material-ui-pickers";
12 | import DateFnsUtils from "@date-io/date-fns";
13 | import Button from "@material-ui/core/Button";
14 | import Icon from "@material-ui/core/Icon";
15 | import StockLineChart from "./StockLineChart";
16 | import ValuationRatios from "./ValuationRatios";
17 | import ProfitabilityRatios from "./ProfitabilityRatios";
18 | import DebtRatios from "./DebtRatios";
19 |
20 | const height = 35;
21 |
22 | // I had to resort to this special way of rendering react-select for handling 30,000 rows of data in the autosuggestion
23 | class MenuList extends Component {
24 | render() {
25 | const { options, children, maxHeight, getValue } = this.props;
26 | const [value] = getValue();
27 | const initialOffset = options.indexOf(value) * height;
28 | // const initialOffset = height;
29 |
30 | return (
31 |
37 | {({ index, style }) => {children[index]}
}
38 |
39 | );
40 | }
41 | }
42 |
43 | // Function to convert the date format that I received from "material-ui-pickers" package to the YYYY-MM-DD required by the Quandl API
44 | const convertDateFromStringToAPIFormat = str => {
45 | const date = new Date(str);
46 | const month = ("0" + (date.getMonth() + 1)).slice(-2);
47 | const day = ("0" + date.getDate()).slice(-2);
48 | return [date.getFullYear(), month, day].join("-");
49 | };
50 |
51 | const getDateAndClosingPrice = obj => {
52 | let date = [];
53 | let closingPrice = [];
54 | for (let key in obj) {
55 | if (obj.hasOwnProperty(key)) {
56 | date.push(key);
57 | closingPrice.push(parseInt(obj[key].close));
58 | }
59 | }
60 | return [date, closingPrice];
61 | };
62 |
63 | const getYSeriesDataValuationMatrix = obj => {
64 | let set1,
65 | set2,
66 | set3,
67 | set4,
68 | set5 = {};
69 | let yAxisSeries = [];
70 |
71 | for (let key in obj) {
72 | if (obj.hasOwnProperty(key)) {
73 | yAxisSeries.push([key, obj[key].investmentValuationRatios]);
74 | }
75 | }
76 | const priceBookValueRatio = yAxisSeries.map(i => i[1].priceBookValueRatio);
77 | const arrPriceEarningRatio = yAxisSeries.map(i => i[1].priceEarningsRatio);
78 | const arrPriceSalesRatio = yAxisSeries.map(i => i[1].priceSalesRatio);
79 | const arrEnterpriseValueMultiple = yAxisSeries.map(
80 | i => i[1].enterpriseValueMultiple
81 | );
82 | const priceEarningsToGrowthRatio = yAxisSeries.map(
83 | i => i[1].priceEarningsToGrowthRatio
84 | );
85 |
86 | set1 = { name: "Price to Book-Value Ratio", data: priceBookValueRatio };
87 | set2 = { name: "Price Earnings Ratio", data: arrPriceEarningRatio };
88 | set3 = { name: "Price Sales Ratio", data: arrPriceSalesRatio };
89 | set4 = {
90 | name: "Enterprise Value Multiple",
91 | data: arrEnterpriseValueMultiple
92 | };
93 | set5 = {
94 | name: "PriceEarnings To GrowthRatio",
95 | data: priceEarningsToGrowthRatio
96 | };
97 |
98 | return [set1, set2, set3, set4, set5];
99 | };
100 |
101 | const getYSeriesDataProfitabilityMatrix = obj => {
102 | let set1,
103 | set2,
104 | set3,
105 | set4,
106 | set5 = {};
107 | let yAxisSeries = [];
108 |
109 | for (let key in obj) {
110 | if (obj.hasOwnProperty(key)) {
111 | yAxisSeries.push([key, obj[key].profitabilityIndicatorRatios]);
112 | }
113 | }
114 | const grossProfitMargin = yAxisSeries.map(i => i[1].grossProfitMargin);
115 | const operatingProfitMargin = yAxisSeries.map(
116 | i => i[1].operatingProfitMargin
117 | );
118 | const netProfitMargin = yAxisSeries.map(i => i[1].netProfitMargin);
119 | const returnOnEquity = yAxisSeries.map(i => i[1].returnOnEquity);
120 | const eBITperRevenue = yAxisSeries.map(i => i[1].eBITperRevenue);
121 |
122 | set1 = { name: "Gross Profit Margin", data: grossProfitMargin };
123 | set2 = { name: "Operating Profit Margin", data: operatingProfitMargin };
124 | set3 = { name: "Net Profit Margin", data: netProfitMargin };
125 | set4 = {
126 | name: "Return on Equity",
127 | data: returnOnEquity
128 | };
129 | set5 = {
130 | name: "EBIT per Revenue",
131 | data: eBITperRevenue
132 | };
133 |
134 | return [set1, set2, set3, set4, set5];
135 | };
136 |
137 | const getYSeriesDataDebtMatrix = obj => {
138 | let set1,
139 | set2,
140 | set3,
141 | set4 = {};
142 | let yAxisSeries = [];
143 |
144 | for (let key in obj) {
145 | if (obj.hasOwnProperty(key)) {
146 | yAxisSeries.push([key, obj[key].debtRatios]);
147 | }
148 | }
149 | const debtRatio = yAxisSeries.map(i => i[1].debtRatio);
150 | const debtEquityRatio = yAxisSeries.map(i => i[1].debtEquityRatio);
151 | const totalDebtToCapitalization = yAxisSeries.map(
152 | i => i[1].totalDebtToCapitalization
153 | );
154 | const companyEquityMultiplier = yAxisSeries.map(
155 | i => i[1].companyEquityMultiplier
156 | );
157 |
158 | set1 = { name: "Debt Ratio", data: debtRatio };
159 | set2 = { name: "Debt to Equity Ratio", data: debtEquityRatio };
160 | set3 = {
161 | name: "Total Debt To Capitalization ratio",
162 | data: totalDebtToCapitalization
163 | };
164 | set4 = {
165 | name: "Company Equity Multiplier",
166 | data: companyEquityMultiplier
167 | };
168 |
169 | return [set1, set2, set3, set4];
170 | };
171 |
172 | export class StockAnalyticsDashBoard extends Component {
173 | state = {
174 | stockTicker: "",
175 | stockTickerAndLabel: "",
176 | symbolList: [],
177 | fromDate: "",
178 | toDate: "",
179 | xAxisData: [],
180 | yAxisData_StockClosingPrice: [],
181 | shouldSandP_Data_fetch: false,
182 | ySeriesDataForValuationRatios: [],
183 | xSeriesDataForValuationRatios: [],
184 | ySeriesDataForProfitabilityRatios: [],
185 | ySeriesDataForDebtRatios: []
186 | };
187 |
188 | // Higher order function to handle Autocompletion field value change
189 | handleAutocompletionChange = name => value => {
190 | this.setState(
191 | {
192 | stockTicker: value.value
193 | },
194 | () => {
195 | const stockTickerWithName = this.state.symbolList.filter(i => {
196 | return i.value === this.state.stockTicker;
197 | })[0].label;
198 | this.setState({
199 | stockTickerAndLabel: stockTickerWithName
200 | });
201 | }
202 | );
203 | };
204 |
205 | componentDidMount() {
206 | axios
207 | .get("https://api.iextrading.com/1.0/ref-data/symbols?filter=symbol,name")
208 | .then(res => {
209 | this.setState({
210 | symbolList: res.data.map(item => ({
211 | value: item.symbol,
212 | label: `${item.symbol} ${item.name}`
213 | }))
214 | });
215 | });
216 | }
217 |
218 | componentDidUpdate(prevProps, prevState) {
219 | if (
220 | (this.state.fromDate !== prevState.fromDate &&
221 | this.state.shouldSandP_Data_fetch) ||
222 | (this.state.toDate !== prevState.toDate &&
223 | this.state.shouldSandP_Data_fetch)
224 | ) {
225 | const { stockTicker, fromDate, toDate } = this.state;
226 | const APIkey = process.env.REACT_APP_WORLD_TRADING_DATA_API_TOKEN;
227 |
228 | if (stockTicker !== "" && fromDate !== "" && toDate !== "") {
229 | const url_stockPrice = `https://www.worldtradingdata.com/api/v1/history?symbol=${stockTicker}&date_from=${fromDate}&date_to=${toDate}&output=json&sort=newest&api_token=${APIkey}`;
230 |
231 | axios
232 | .get(url_stockPrice)
233 | .then(res => {
234 | const closingPriceDate = getDateAndClosingPrice(
235 | res.data.history
236 | )[0];
237 | const closingPrice = getDateAndClosingPrice(res.data.history)[1];
238 | this.setState({
239 | xAxisData: closingPriceDate,
240 | yAxisData_StockClosingPrice: closingPrice,
241 | shouldSandP_Data_fetch: true
242 | });
243 | })
244 | .catch(function(error) {
245 | console.log(error);
246 | });
247 | }
248 | }
249 | }
250 |
251 | handleSubmitToFetchAPI = () => {
252 | const { stockTicker, fromDate, toDate } = this.state;
253 | const APIkey = process.env.REACT_APP_WORLD_TRADING_DATA_API_TOKEN;
254 |
255 | if (stockTicker !== "" && fromDate !== "" && toDate !== "") {
256 | const url_stockPrice = `https://www.worldtradingdata.com/api/v1/history?symbol=${stockTicker}&date_from=${fromDate}&date_to=${toDate}&output=json&sort=newest&api_token=${APIkey}`;
257 |
258 | const url_stockFundamentalsValuationRatios = `https://financialmodelingprep.com/api/financial-ratios/${stockTicker}?datatype=json`;
259 |
260 | axios
261 | .all([
262 | axios.get(url_stockPrice),
263 | axios.get(url_stockFundamentalsValuationRatios)
264 | ])
265 | .then(
266 | axios.spread((stockPriceData, stockFundamentalsData) => {
267 | console.log("RECEIVED DATA ", stockPriceData.data.history);
268 | const closingPriceDate = getDateAndClosingPrice(
269 | stockPriceData.data.history
270 | )[0];
271 | const closingPrice = getDateAndClosingPrice(
272 | stockPriceData.data.history
273 | )[1];
274 | this.setState({
275 | xAxisData: closingPriceDate,
276 | yAxisData_StockClosingPrice: closingPrice,
277 | ySeriesDataForValuationRatios: getYSeriesDataValuationMatrix(
278 | stockFundamentalsData.data.financialRatios
279 | ),
280 | xSeriesDataForValuationRatios: Object.keys(
281 | stockFundamentalsData.data.financialRatios
282 | ),
283 | ySeriesDataForProfitabilityRatios: getYSeriesDataProfitabilityMatrix(
284 | stockFundamentalsData.data.financialRatios
285 | ),
286 | ySeriesDataForDebtRatios: getYSeriesDataDebtMatrix(
287 | stockFundamentalsData.data.financialRatios
288 | ),
289 | shouldSandP_Data_fetch: true
290 | });
291 | })
292 | )
293 | .catch(function(error) {
294 | console.log(error);
295 | });
296 | }
297 | };
298 |
299 | handleFromDateChange = date => {
300 | const fromDateFormatted = convertDateFromStringToAPIFormat(date);
301 | this.setState({
302 | fromDate: fromDateFormatted
303 | });
304 | };
305 |
306 | handleToDateChange = date => {
307 | const toDateFormatted = convertDateFromStringToAPIFormat(date);
308 | this.setState({
309 | toDate: toDateFormatted
310 | });
311 | };
312 |
313 | render() {
314 | const { classes, theme } = this.props;
315 |
316 | const selectStyles = {
317 | input: base => ({
318 | ...base,
319 | width: "20em",
320 | margin: "auto",
321 |
322 | color: theme.palette.text.primary,
323 | "& input": {
324 | font: "inherit"
325 | }
326 | })
327 | };
328 |
329 | return (
330 |
331 | {console.log("CLOSING PRICE ", this.state.yAxisData_StockClosingPrice)}
332 |
333 |
334 |
335 |
336 |
345 |
346 |
347 |
352 | value
353 | ? [
354 | /\d/,
355 | /\d/,
356 | "/",
357 | /\d/,
358 | /\d/,
359 | "/",
360 | /\d/,
361 | /\d/,
362 | /\d/,
363 | /\d/
364 | ]
365 | : []
366 | }
367 | label="From Date"
368 | disableOpenOnEnter
369 | animateYearScrolling={false}
370 | value={this.state.fromDate}
371 | onChange={this.handleFromDateChange}
372 | />
373 |
378 | value
379 | ? [
380 | /\d/,
381 | /\d/,
382 | "/",
383 | /\d/,
384 | /\d/,
385 | "/",
386 | /\d/,
387 | /\d/,
388 | /\d/,
389 | /\d/
390 | ]
391 | : []
392 | }
393 | label="To Date"
394 | disableOpenOnEnter
395 | animateYearScrolling={false}
396 | value={this.state.toDate}
397 | onChange={this.handleToDateChange}
398 | />
399 |
410 |
411 |
412 |
413 |
414 |
418 |
419 |
420 | End of Day Closing Price of {this.state.stockTickerAndLabel}
421 |
428 |
429 |
430 |
431 |
432 |
433 | S&P 500 P/E index EOD closing price during same time
434 | {this.state.fromDate !== "" &&
435 | this.state.toDate !== "" &&
436 | this.state.shouldSandP_Data_fetch === true ? (
437 |
441 | ) : null}
442 |
443 |
444 |
445 |
446 |
447 |
448 | Key Valuation matrix for past five years matrix{" "}
449 | {this.state.stockTickerAndLabel}
450 |
462 |
463 |
464 |
465 |
466 |
467 |
468 | Key Profitabilty matrix for past five years matrix{" "}
469 | {this.state.stockTickerAndLabel}
470 |
479 |
480 |
481 |
482 |
483 |
484 |
485 | Key Debt matrix for past five years matrix{" "}
486 | {this.state.stockTickerAndLabel}
487 |
494 |
495 |
496 |
497 |
498 |
499 | );
500 | }
501 | }
502 |
503 | StockAnalyticsDashBoard.propTypes = {
504 | classes: PropTypes.object.isRequired
505 | };
506 |
507 | export default withStyles(styles, { withTheme: true })(StockAnalyticsDashBoard);
508 |
509 | /* 1> Explanation on the two function getXAxis and getYAxis
510 |
511 | Received data from API will be as below
512 | "data": [
513 | ["2018-02-23", 183.29],
514 | ["2018-02-22", 178.99], ]
515 |
516 | But for the line-graph I need
517 |
518 | var config = {
519 | xAxis: {
520 | categories: ["2018-02-23", '2018-02-22']
521 | },
522 | series: [{
523 | data: [29.9, 71.5 ]
524 | }]
525 | };
526 |
527 | */
528 |
--------------------------------------------------------------------------------