diff --git a/README.md b/README.md index e092159..33bc4ff 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,10 @@ # StockMarket This project coded in java uses java's built in swift package and Yahoo Finance to display different companies stock value. Then, it analyzes trends and predicts what the stock value will be in the next couple of months. + + To run: download project and navigate to src/main/java/me/dhruvarora/Main.java file. + Next, run the main method and the wait for project to compile. + Finally, the project should have finished compling and will automatically open a new window you can enjoy! + + Debugging: make sure that you have a java development kit (JDK) and java runtime environment (JRE) installed on your computer + + Packaging: unfortunately this project cannot be packaged into a jar due to complications with importing files and reading them inside the jar. \ No newline at end of file diff --git a/pom.xml b/pom.xml index 966c89b..1e1d291 100644 --- a/pom.xml +++ b/pom.xml @@ -26,11 +26,6 @@ 4.11 test - - commons-io - commons-io - 2.11.0 - com.googlecode.json-simple diff --git a/src/main/java/me/dhruvarora/UI/ChangeStocksPage.java b/src/main/java/me/dhruvarora/UI/ChangeStocksPage.java index 81590a1..3baf0cd 100644 --- a/src/main/java/me/dhruvarora/UI/ChangeStocksPage.java +++ b/src/main/java/me/dhruvarora/UI/ChangeStocksPage.java @@ -20,18 +20,14 @@ import me.dhruvarora.Utility.ChangeStockPage.InputField; public class ChangeStocksPage extends JPanel { - // stores the frame content - private final JComponent content; - // stores the frame instance - private final Frame frame; - // stores global variable for cluster component constraints + /* Global variables */ + private final JComponent content; // stores the frame content + private final Frame frame; // stores the frame instance private GridBagConstraints constraints; - // stores instance of invisible red text reading "Invalid Ticker Symbol!" - private final JLabel invalidFieldInput; - // stores instance of input field - private final InputField InputField = new InputField(); - // stores instance of button to submit field - private final ChangeStockButton changeStockButton; + + private final JLabel invalidFieldInput; // stores instance of invisible red text reading "Invalid Ticker Symbol!" + private final InputField InputField = new InputField(); // stores instance of input field + private final ChangeStockButton changeStockButton; // stores instance of submit field button private final StockData stockData; /* @@ -94,21 +90,19 @@ public ChangeStocksPage(JComponent content, Frame frame, StockData stockData) (frame.getHeight() / 2) - (cluster.getHeight() / 2)); this.add(cluster); - /* - * creates button to navigate back to mainPage - * - * end of cluster (back button is added straight to extended JPanel) - */ + /* end of cluster */ + + // creates button to navigate back to mainPage this.add(new BackButton(frame)); // creates invisible text for invalid input invalidFieldInput = invalidInput(); - // setting location below cluster + // setting location of text below cluster invalidFieldInput.setLocation( (int) Math.round(cluster.getLocation().getX() + ((cluster.getSize().width / 2) - invalidFieldInput.getSize().getWidth() / 2)), (int) cluster.getLocation().getY() + cluster.getSize().height + 20); - this.add(invalidFieldInput); + this.add(invalidFieldInput); // adding it to JPanel } @@ -171,6 +165,7 @@ private JLabel invalidInput() { /* * Function to make invalidInput visible + * used in ChangeStockButton class */ public void inputIsInvalid() { invalidFieldInput.setVisible(true); diff --git a/src/main/java/me/dhruvarora/UI/Frame.java b/src/main/java/me/dhruvarora/UI/Frame.java index 903c1c1..1c42a44 100644 --- a/src/main/java/me/dhruvarora/UI/Frame.java +++ b/src/main/java/me/dhruvarora/UI/Frame.java @@ -25,6 +25,8 @@ public class Frame extends JFrame { * stocks that they would like to watch in form of a graph. */ private ChangeStocksPage changeStocksPage; + // instance of StockData class (this instance is avalible throughout the entire + // project) private StockData stockData; /* @@ -57,7 +59,7 @@ public Frame() throws FileNotFoundException, IOException, ParseException { content.setBackground(Color.darkGray); /* - * initializing mainJPanel + * initializing mainJPanel & global stockData instance */ this.stockData = new StockData(); mainPage = new MainPage(content, this, this.stockData); @@ -67,7 +69,7 @@ public Frame() throws FileNotFoundException, IOException, ParseException { setVisible(true); /* - * listens if the window is resized + * window RESIZING event * * if run, then will delete and recreate open JPanel */ @@ -92,6 +94,7 @@ public void componentResized(ComponentEvent componentEvent) { * function to set the desktop getImage * * works for macOS, windows, and linux + * TODO: have it work for jar files */ private void setIcons(String path) { // windows & linux diff --git a/src/main/java/me/dhruvarora/UI/MainPage.java b/src/main/java/me/dhruvarora/UI/MainPage.java index 6fd7b69..24cedc6 100644 --- a/src/main/java/me/dhruvarora/UI/MainPage.java +++ b/src/main/java/me/dhruvarora/UI/MainPage.java @@ -22,6 +22,12 @@ import me.dhruvarora.Utility.MainPage.AddOrRemoveStock; import yahoofinance.Stock; +/* + * MainPage is the first page displayed when project is launched + * + * extention of JPanel and is converted into a JScrollPane + * format: scroll pane with graphs at top and buttons underneath + */ public class MainPage extends JPanel { // stores the frame content private JComponent content; @@ -35,6 +41,8 @@ public class MainPage extends JPanel { // stores refresh button instance for initializing and making default button private Refresh refresh; private StockData stockData; + // number of months that the app will predict + private final int predictionsCount = 2; /* * CONSTRUCTOR @@ -92,9 +100,10 @@ private void createContentPane() /* * interates through StockMarket.json * - * creates graphs for each stock in json file + * creates graphs and their titles for each stock in json file */ for (int i = 0; i < stockData.getWatchListLength(); i++) { + /* * using YahooFinanceAPI to get the stock current price * after getting current price, creates a title for the graph including the @@ -160,7 +169,9 @@ private void createContentPane() private Graph createGraph(StockData stockData, String ticker) throws IOException, ParseException { ArrayList dataSet = stockData.getGraphData(ticker); - Graph newGraphPanel = new Graph(dataSet); + // TODO: fully implement prediction data + // dataSet = stockData.addPredictionData(dataSet, predictionsCount, ticker); + Graph newGraphPanel = new Graph(dataSet, predictionsCount); return newGraphPanel; } diff --git a/src/main/java/me/dhruvarora/Utility/MainPage/AddOrRemoveStock.java b/src/main/java/me/dhruvarora/Utility/MainPage/AddOrRemoveStock.java index f7b99d3..d067fc2 100644 --- a/src/main/java/me/dhruvarora/Utility/MainPage/AddOrRemoveStock.java +++ b/src/main/java/me/dhruvarora/Utility/MainPage/AddOrRemoveStock.java @@ -17,6 +17,11 @@ import me.dhruvarora.UI.Frame; +/* + * AddOrRemoveStock class is a JButton which is displayed at the bottom of the MainPage + * + * overrides default paint functions for JButton and makes rounded corners + */ public class AddOrRemoveStock extends JButton { private final Color textColor = Color.white; private final Color backgroundColor = new Color(67, 129, 255); @@ -24,9 +29,15 @@ public class AddOrRemoveStock extends JButton { private final Frame frame; private Shape shape; + /* + * CONSTRUCTOR + * + * takes instance of frame + */ public AddOrRemoveStock(Frame frame) { - this.frame = frame; + this.frame = frame; // setting global frame variable + // setting defaults setVerticalTextPosition(AbstractButton.CENTER); setHorizontalTextPosition(AbstractButton.CENTER); setText("Add/Remove Stock"); @@ -36,14 +47,17 @@ public AddOrRemoveStock(Frame frame) { setPreferredSize(new Dimension(150, 75)); setFont(new Font("Arial", Font.PLAIN, 20)); setAlignmentX(CENTER_ALIGNMENT); + + // allowing button to have rounded corners setFocusPainted(false); setBorderPainted(false); + // listener for when the button is pressed addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { - AddOrRemoveStock.this.frame.swapScreens(); + AddOrRemoveStock.this.frame.swapScreens(); // will swap to change stocks page } catch (IOException | ParseException e1) { e1.printStackTrace(); } @@ -51,6 +65,12 @@ public void actionPerformed(ActionEvent e) { }); } + /* + * + * + * overriden function to round the corners of the button + */ + protected void paintComponent(Graphics g) { g.setColor(getBackground()); g.fillRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 30, 30); diff --git a/src/main/java/me/dhruvarora/Utility/MainPage/Graph.java b/src/main/java/me/dhruvarora/Utility/MainPage/Graph.java index 222bac8..4717643 100644 --- a/src/main/java/me/dhruvarora/Utility/MainPage/Graph.java +++ b/src/main/java/me/dhruvarora/Utility/MainPage/Graph.java @@ -26,8 +26,10 @@ public class Graph extends JPanel { private static final int PREF_W = 500; // graph width is 300 pixels private static final int PREF_H = 300; - // the gap between window border and - private static final int BORDER_GAP = 30; + // the gap between top window border and between other graphs + private static final int Y_BORDER_GAP = 30; + // the gap between the sides of the window + private static final int X_BORDER_GAP = 45; // color of graph lines are blue private static Color GRAPH_COLOR = new Color(67, 129, 255); // color of graph point is blue @@ -40,11 +42,17 @@ public class Graph extends JPanel { private static final int GRAPH_POINT_WIDTH = 6; // number of hash marks on the Y axis private static final int Y_HATCH_CNT = 10; + // number of months that the app will predict; imported from mainPage + private final int predictionsCount; // list of all the data points for graph private ArrayList dataSet; - public Graph(ArrayList dataSet) { + /* + * Initalizing global variables and setting background + */ + public Graph(ArrayList dataSet, int predictionsCount) { this.dataSet = dataSet; + this.predictionsCount = predictionsCount; setBackground(Color.darkGray); } @@ -63,68 +71,70 @@ public void paintComponent(Graphics g) { g2.setColor(GRAPHIC_COLOR); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - /* - * creating scale for the graph - * - * used for being referance when drawing lines - */ - double xScale = ((double) getWidth() - 2 * BORDER_GAP) / (dataSet.size() - 1); + // creating scale for the x axis for the graph; used for being referance when + // drawing lines + double xScale = ((double) getWidth() - 2 * X_BORDER_GAP) / (dataSet.size() - 1); + + // drawing the graph's data (points and line from point to point) + this.drawGraphData(g2, xScale); + + // drawing x and y axis lines + g2.drawLine(X_BORDER_GAP, getHeight() - Y_BORDER_GAP, X_BORDER_GAP, Y_BORDER_GAP); + g2.drawLine(X_BORDER_GAP, getHeight() - Y_BORDER_GAP, getWidth() - Y_BORDER_GAP, getHeight() - Y_BORDER_GAP); + + // drawing hash marks for both axis + drawHashes(g2); + + } // CONSTRUCTOR + + /* + * + * + * + * + * Function to draw the data for the graph + * + * 3 blocks + * - gets the data and the location of where the data should be + * - draws the lines from point to point + * - draws the points + * + * lines are drawn first so the points (if a different color) may be shown on + * top of the lines + */ + private void drawGraphData(Graphics2D g2, double xScale) { /* - * using dataSet and getting location of points + * block #1: + * + * using dataSet to get the points and then caculates their location based on + * the graph scaling + * uses getYLocation() to get the scaled position of the point */ List graphPoints = new ArrayList(); List graphPointsPrice = new ArrayList(); + // iterating through each price in the dataSet for (int i = 0; i < dataSet.size(); i++) { - int x1 = (int) (i * xScale + BORDER_GAP); - int y1 = (int) (Math.round(this.getYLocation(dataSet.get(i))) + BORDER_GAP); + int x1 = (int) (i * xScale + X_BORDER_GAP); + int y1 = (int) (Math.round(this.getYLocation(dataSet.get(i))) + Y_BORDER_GAP); // calculating position after + // scaling graphPoints.add(new Point(x1, y1)); graphPointsPrice.add(dataSet.get(i)); } /* - * drawing x and y axis lines + * setting color of the lines stroke and getting old color for points */ - g2.drawLine(BORDER_GAP, getHeight() - BORDER_GAP, BORDER_GAP, BORDER_GAP); - g2.drawLine(BORDER_GAP, getHeight() - BORDER_GAP, getWidth() - BORDER_GAP, getHeight() - BORDER_GAP); - - /* - * creating lines/hashes on top of the y axis for points - * - * uses Y_HATCH_CNT to get number of hash marks needed - */ - for (int i = 0; i < Y_HATCH_CNT; i++) { - int x0 = BORDER_GAP; - int x1 = GRAPH_POINT_WIDTH + BORDER_GAP; - int y0 = getHeight() - (((i + 1) * (getHeight() - BORDER_GAP * 2)) / Y_HATCH_CNT + BORDER_GAP); - int y1 = y0; - g2.drawLine(x0, y0, x1, y1); - g2.drawString("$" + String.valueOf(getHashLabel(i)), x0 + 10, y0 + 5); - } - - /* - * creating hashes for the x axis - * - * then creates labels for each - */ - for (int i = 0; i < dataSet.size() - 1; i++) { - int x0 = (i + 1) * (getWidth() - BORDER_GAP * 2) / (dataSet.size() - 1) + BORDER_GAP; - int x1 = x0; - int y0 = getHeight() - BORDER_GAP; - int y1 = y0 - GRAPH_POINT_WIDTH; - g2.drawLine(x0, y0, x1, y1); - g2.drawString(this.getMonth(i - 1), x0 - 10, y0 + 15); // drawing month label - } - - // setting colors Stroke oldStroke = g2.getStroke(); g2.setColor(GRAPH_COLOR); g2.setStroke(GRAPH_STROKE); + /* * drawing lines from point to point on graph * * uses graphPoints to get x and y cords of graph points */ + // iterating through each point in graphPoints for (int i = 0; i < graphPoints.size() - 1; i++) { // getting point dimensions @@ -133,17 +143,21 @@ public void paintComponent(Graphics g) { int x2 = graphPoints.get(i + 1).x; int y2 = graphPoints.get(i + 1).y; - g2.drawLine(x1, y1, x2, y2); + g2.drawLine(x1, y1, x2, y2); // drawing line } - // setting colors + /* + * changing colors to match the color of the points desired colors + */ g2.setStroke(oldStroke); g2.setColor(GRAPH_POINT_COLOR); + /* * drawing graph points specified in graphPoints * * uses GRAPH_POINT_WIDTH to get the size of the points */ + // iterating through graphPoints for (int i = 0; i < graphPoints.size(); i++) { /* getting dimensions of the point */ @@ -152,13 +166,62 @@ public void paintComponent(Graphics g) { int ovalW = GRAPH_POINT_WIDTH; int ovalH = GRAPH_POINT_WIDTH; - g2.fillOval(x, y, ovalW, ovalH); + g2.fillOval(x, y, ovalW, ovalH); // drawing point // drawing price above each point + if (i == 0) + x = x + 20; + // drawing label of each point g2.drawString(String.valueOf(Math.round(graphPointsPrice.get(i) * 100.0) / 100.0), x - 15, y - 5); } } /* + * + * + * + * + * function to draw the hash marks for the x and y axis + * + * after drawing hashes it will label each hash + */ + private void drawHashes(Graphics2D g2) { + + /* + * creating lines/hashes on top of the y axis for points + * + * uses Y_HATCH_CNT to get number of hash marks needed + * also draws labels next to hashmarks + */ + for (int i = 0; i < Y_HATCH_CNT; i++) { // iterating through number of hash marks needed + // getting dimensions of hash + int x0 = Y_BORDER_GAP + 8; + int x1 = GRAPH_POINT_WIDTH + Y_BORDER_GAP + 8; + int y0 = getHeight() - (((i + 1) * (getHeight() - Y_BORDER_GAP * 2)) / Y_HATCH_CNT + Y_BORDER_GAP); + int y1 = y0; + g2.drawLine(x0, y0, x1, y1); // drawing line + g2.drawString("$" + String.valueOf(getHashLabel(i)), x0 - 30, y0 + 5); // labeling the hash's price value + } + + /* + * creating hashes for the x axis + * + * then creates labels for each + * - uses getMonth() to find the short string version of month + */ + for (int i = 0; i < dataSet.size() - 1; i++) { + int x0 = (i + 1) * (getWidth() - Y_BORDER_GAP * 2) / (dataSet.size() - 1) + Y_BORDER_GAP; + int x1 = x0; + int y0 = getHeight() - Y_BORDER_GAP; + int y1 = y0 - GRAPH_POINT_WIDTH; + g2.drawLine(x0, y0, x1, y1); + g2.drawString(this.getMonth(i - 1), x0 - 10, y0 + 15); // drawing month label + } + } + + /* + * + * + * * sets preferred size of graph * * overriding default function @@ -169,6 +232,10 @@ public Dimension getPreferredSize() { } /* + * + * + * + * * function to find the biggest value and smallest value of dataSet * * iterates through entire data set to find lowest and largest numbers @@ -197,6 +264,10 @@ private int[] getMaxAndMin() { } /* + * + * + * + * * returns y Location of point * * - calculates size of graph @@ -206,7 +277,7 @@ private int[] getMaxAndMin() { * - y axis starts from top and ends at bottom */ private int getYLocation(Double price) { - int graphableHeight = this.getHeight() - (BORDER_GAP * 2); // calculates pixels of graph + int graphableHeight = this.getHeight() - (Y_BORDER_GAP * 2); // calculates pixels of graph int[] maxAndMin = getMaxAndMin(); int range = maxAndMin[1] - maxAndMin[0]; @@ -217,6 +288,10 @@ private int getYLocation(Double price) { } /* + * + * + * + * * returns label for y axis hash mark * * calculates scaling to find the top and bottom @@ -231,6 +306,10 @@ private int getHashLabel(int i) { } /* + * + * + * + * * uses built in java Date to find month name * calculates stock's month using enoch time * diff --git a/src/main/java/me/dhruvarora/Utility/MainPage/GraphTitle.java b/src/main/java/me/dhruvarora/Utility/MainPage/GraphTitle.java index 9352f5c..ec7541f 100644 --- a/src/main/java/me/dhruvarora/Utility/MainPage/GraphTitle.java +++ b/src/main/java/me/dhruvarora/Utility/MainPage/GraphTitle.java @@ -6,15 +6,29 @@ import javax.swing.JLabel; +/* + * class GraphTitle is a JLable for each graph + * + * used to label the company of each graph + */ public class GraphTitle extends JLabel { + private final Color backgroundColor = Color.darkGray; + private final Color textColor = Color.white; + private final int fontSize = 20; + /* + * CONSTRUCTOR + * + * take in the name of the company as title and sets defaults + */ public GraphTitle(String title) { setText(title); setAlignmentX(CENTER_ALIGNMENT); setPreferredSize(new Dimension(50, 25)); - setBackground(Color.darkGray); - setForeground(Color.white); - setFont(new Font("Arial", Font.PLAIN, 20)); + + setBackground(backgroundColor); + setForeground(textColor); + setFont(new Font("Arial", Font.PLAIN, fontSize)); } } diff --git a/src/main/java/me/dhruvarora/Utility/MainPage/Refresh.java b/src/main/java/me/dhruvarora/Utility/MainPage/Refresh.java index 89a27ca..10f2353 100644 --- a/src/main/java/me/dhruvarora/Utility/MainPage/Refresh.java +++ b/src/main/java/me/dhruvarora/Utility/MainPage/Refresh.java @@ -17,16 +17,22 @@ import me.dhruvarora.UI.Frame; +/* + * Refresh class is a JButton which is displayed at the bottom of the MainPage + * + * overrides default paint functions for JButton and makes rounded corners + */ public class Refresh extends JButton { private final Color textColor = Color.white; - private final Color backgroundColor = new Color(67, 129, 255); + private final Color backgroundColor = new Color(67, 129, 255); // background color is BLUE private final Color borderColor = Color.BLACK; - private final Frame frame; - private Shape shape; + private final Frame frame; // instance of the current frame + private Shape shape; // shape of the rounded bordered button public Refresh(Frame frame) { this.frame = frame; + // setting all the defaults setVerticalTextPosition(AbstractButton.CENTER); setHorizontalTextPosition(AbstractButton.CENTER); setText("Refresh"); @@ -36,14 +42,17 @@ public Refresh(Frame frame) { setPreferredSize(new Dimension(150, 75)); setFont(new Font("Arial", Font.PLAIN, 20)); setAlignmentX(CENTER_ALIGNMENT); + + // allows the button to have rounded corners setFocusPainted(false); setBorderPainted(false); + // button pressed listener addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { - Refresh.this.frame.refresh(); + Refresh.this.frame.refresh(); // calling the refresh method in Frame.java } catch (IOException | ParseException e1) { e1.printStackTrace(); } @@ -51,6 +60,12 @@ public void actionPerformed(ActionEvent e) { }); } + /* + * + * + * overriden functions used to make the corners round + */ + protected void paintComponent(Graphics g) { g.setColor(getBackground()); g.fillRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 30, 30); diff --git a/src/main/java/me/dhruvarora/Utility/StockData.java b/src/main/java/me/dhruvarora/Utility/StockData.java index 490bef8..cf72413 100644 --- a/src/main/java/me/dhruvarora/Utility/StockData.java +++ b/src/main/java/me/dhruvarora/Utility/StockData.java @@ -53,9 +53,6 @@ public StockData() throws FileNotFoundException, IOException, ParseException { JSONParser jsonParser = new JSONParser(); stockWatchList = (JSONArray) jsonParser.parse( new InputStreamReader(fis, "UTF-8")); - System.out.println(stockWatchList); - // stockWatchList = (JSONArray) new JSONParser() - // .parse(new FileReader("src/main/resources/me/dhruvarora/StockMarkets.json")); } /* @@ -312,25 +309,127 @@ public ArrayList getGraphData(String ticker) throws IOException, ParseEx * is put into this ArrayList * - all prices are arranged in order from oldest to current */ - int count = 0; ArrayList filteredData = new ArrayList<>(); - for (Long enochDate : timeStamps) { + for (Long enochDate : timeStamps) { // iterating through each time in timeStamps + // getting the date from timeStamps Date date2 = new Date(enochDate * 1000); String[] formattedDateString = format.format(date2).split(" "); int[] formatDate = { Integer.parseInt(formattedDateString[0]), Integer.parseInt(formattedDateString[1]) }; + // if the date matches to the target date if (formatDate[0] == targetDate[0] && formatDate[1] == targetDate[1]) { - count = count + 1; - filteredData.add(data.get(timeStamps.indexOf(enochDate))); + filteredData.add(data.get(timeStamps.indexOf(enochDate))); // add the price to filtered data - targetDate[1] = targetDate[1] + 1; - if (targetDate[1] == 13) { - targetDate[0] = targetDate[0] + 1; - targetDate[1] = 1; + targetDate[1] = targetDate[1] + 1; // change the target date to a month ahead + if (targetDate[1] == 13) { // if the months becomes 13 + targetDate[0] = targetDate[0] + 1; // add a year + targetDate[1] = 1; // and set the month to jan } } } - return filteredData; + return filteredData; // returned the collected data + } + + /* + * function to add predicted data to the dataSet + * + * returns the new dataSet + * + * TODO: work in progress (dead code) + */ + @SuppressWarnings("unchecked") + public ArrayList addPredictionData(ArrayList dataSet, int predictionCount, String ticker) + throws IOException, ParseException { + + // getting the data and timestamps from the JSON object + JSONObject rawData = (JSONObject) this.getHistoricalData(ticker); + JSONObject indicators = (JSONObject) rawData.get("indicators"); + JSONArray quote = (JSONArray) indicators.get("quote"); + JSONObject obj = (JSONObject) quote.get(0); + + ArrayList data = (ArrayList) obj.get("open"); + ArrayList timeStamps = (ArrayList) rawData.get("timestamp"); + + // if the graph is going downwards + if (isDownwardTrend(data, timeStamps)) { + addDownwardTrendData(data, timeStamps); // add another prediction of downwards + } + // TODO: create new checks for predictions + + return dataSet; // return the new dataset + + } + + /* + * function to check if the stock's price is on a decline + * + * returns true if it is on a decline + * return false if it is not on a decline + */ + private boolean isDownwardTrend(ArrayList data, ArrayList timeStamps) { + // setting format + DateFormat format = new SimpleDateFormat("yyyy MM"); + format.setTimeZone(TimeZone.getTimeZone("Etc/UTC")); + + // getting the date 6 months ago + Date targetDate = new Date(((System.currentTimeMillis() / 1000) - (2628288 * 2)) * 1000); + String[] targetDateString = format.format(targetDate).split(" "); + int[] targetDateList = { Integer.parseInt(targetDateString[0]), Integer.parseInt(targetDateString[1]) }; + System.out.println(targetDateString[0] + " " + targetDateList[1]); + + for (Long time : timeStamps) { // iterates through all the timeStamps + // getting the human format of the timeStamp + Date date = new Date(time * 1000); + String[] dateString = format.format(date).split(" "); + int[] dateList = { Integer.parseInt(dateString[0]), Integer.parseInt(dateString[1]) }; + + // if the date matches + if (dateList[0] == targetDateList[0] && dateList[1] == targetDateList[1]) { + // if the month previous price was higher than this months + if (data.get(timeStamps.indexOf(time)) > data.get(timeStamps.indexOf(time) + 1)) { + return true; // return that the trend is a decline + } else { + return false; // otherwise the trend is not a decline + } + } + } + return false; // if the timestamp was not in that list (shouldn't hit this at any point) + } + + /* + * function to return the data for a downwards trend + * - almost a REPEAT of the isDownwardTrend() function + * + * calculates how steep the trend is and what the price may look like for the + * next month + */ + private Double addDownwardTrendData(ArrayList data, ArrayList timeStamps) { + // setting human formatting + DateFormat format = new SimpleDateFormat("yyyy MM"); + format.setTimeZone(TimeZone.getTimeZone("Etc/UTC")); + + // setting the date the function is trying to find as 6 months previous + Date targetDate = new Date(((System.currentTimeMillis() / 1000) - (2628288 * 6)) * 1000); + String[] targetDateString = format.format(targetDate).split(" "); + int[] targetDateList = { Integer.parseInt(targetDateString[0]), Integer.parseInt(targetDateString[1]) }; + + // iterating through all the timeStamps + for (Long time : timeStamps) { + // getting the human formatting of the timeStamp + Date date = new Date(time * 1000); + String[] dateString = format.format(date).split(" "); + int[] dateList = { Integer.parseInt(dateString[0]), Integer.parseInt(dateString[1]) }; + + // TODO: finish all the checks + if (dateList[0] == targetDateList[0] && dateList[1] == targetDateList[1]) { + Double amount = 0.0; + if (data.get(timeStamps.indexOf(time) + 6) > data.get(timeStamps.indexOf(time) + 7)) { + amount = (data.get(timeStamps.indexOf(time) + 6) - data.get(timeStamps.indexOf(time) + 7)) / 2; + } + return amount; + } + } + return null; } } \ No newline at end of file