diff options
| author | Julia McCauley <skurvyj@gmail.com> | 2021-04-16 13:14:36 -0400 |
|---|---|---|
| committer | Julia McCauley <skurvyj@gmail.com> | 2021-04-16 13:14:36 -0400 |
| commit | b8279f5498ac7189690b4b85d1d68edb63df3185 (patch) | |
| tree | 14d57eccf7fa09d3cb88e1720cda4c7710252605 /src/main | |
| parent | 033eba394d9df4fb0ac6d76f2660dc8f2251b2b8 (diff) | |
| parent | 12ebe0f16988daf87391f99f681a3e89b985d8c2 (diff) | |
Merge branch 'master' of github.com:cs0320-2021/term-project-cohwille-jmccaul3-mfoiani-rhunt2 into fronend-dev
# Conflicts:
# src/main/java/edu/brown/cs/student/term/Main.java
Diffstat (limited to 'src/main')
6 files changed, 154 insertions, 56 deletions
diff --git a/src/main/java/edu/brown/cs/student/term/DatabaseQuerier.java b/src/main/java/edu/brown/cs/student/term/DatabaseQuerier.java index 688270f..6900a19 100644 --- a/src/main/java/edu/brown/cs/student/term/DatabaseQuerier.java +++ b/src/main/java/edu/brown/cs/student/term/DatabaseQuerier.java @@ -1,24 +1,29 @@ package edu.brown.cs.student.term; + import edu.brown.cs.student.term.hub.Holder; +import edu.brown.cs.student.term.profit.ProfitCalculation; import edu.brown.cs.student.term.trade.Trade; import java.sql.*; import java.time.Instant; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; public class DatabaseQuerier { private static Connection conn = null; //TODO: Be prepared to overhaul this to account for IDs + /** * Makes a database querier for a particular sqlite database + * * @param filename - String representing filepath of database * @throws SQLException * @throws ClassNotFoundException */ public DatabaseQuerier(String filename) throws SQLException, - ClassNotFoundException { + ClassNotFoundException { Class.forName("org.sqlite.JDBC"); String urlToDB = "jdbc:sqlite:" + filename; // AutoClosable TRY-WITH-RESOURCES ensures database connection will be closed when it is done @@ -31,8 +36,9 @@ public class DatabaseQuerier { /** * Gets the names of all stocks traded between start and end ddate + * * @param startDate - the start date - * @param endDate - the end date + * @param endDate - the end date * @return a list of stock names * @throws SQLException */ @@ -40,13 +46,13 @@ public class DatabaseQuerier { List<String> stocks = new ArrayList<>(); PreparedStatement prep = conn.prepareStatement( - "SELECT DISTINCT stock_name FROM trades WHERE trade_timestamp <= ? AND trade_timestamp >= ?"); + "SELECT DISTINCT stock_name FROM trades WHERE trade_timestamp <= ? AND trade_timestamp >= ?"); prep.setLong(1, endDate.toEpochMilli()); prep.setLong(2, startDate.toEpochMilli()); ResultSet rs = prep.executeQuery(); - while(rs.next()){ + while (rs.next()) { stocks.add(rs.getString(1)); } @@ -57,16 +63,18 @@ public class DatabaseQuerier { /** * Gets all the trades in by stock and buy type, ordered by time + * * @param startDate - the start date of these trades - * @param endDate - the end date of these trades + * @param endDate - the end date of these trades * @return a list of list of trades as specified above * @throws SQLException - if something goes wrong with connection */ - public List<List<Trade>> getAllTradesByStock(Instant startDate, Instant endDate) throws SQLException { + public List<List<Trade>> getAllTradesByStock(Instant startDate, Instant endDate) + throws SQLException { List<List<Trade>> allTrades = new ArrayList<>(); List<String> stocks = getRecentStocks(startDate, endDate); //get the buys and sells for each stock - for(String stock: stocks){ + for (String stock : stocks) { allTrades.add(getTradeByStock(stock, 1, startDate, endDate)); allTrades.add(getTradeByStock(stock, 0, startDate, endDate)); } @@ -75,19 +83,21 @@ public class DatabaseQuerier { /** * Gets a single stock's list of trades for that time period (either buy or sell) - * @param stock - string name of the stock to get the trades for - * @param isBuy - integer whether it's a buy or sell + * + * @param stock - string name of the stock to get the trades for + * @param isBuy - integer whether it's a buy or sell * @param startDate - an Instant representing the start of the time period - * @param endDate - an Instant representing the end of the time period + * @param endDate - an Instant representing the end of the time period * @return - a list of trades for that stock * @throws SQLException - if issue getting connection */ - public List<Trade> getTradeByStock(String stock, int isBuy, Instant startDate, Instant endDate) throws SQLException{ + public List<Trade> getTradeByStock(String stock, int isBuy, Instant startDate, Instant endDate) + throws SQLException { List<Trade> trades = new ArrayList<>(); PreparedStatement prep = conn.prepareStatement( - "SELECT * FROM trades WHERE (stock_name = ? AND is_buy = ?) " - + "AND (trade_timestamp <= ? AND trade_timestamp >= ?) ORDER BY trade_timestamp"); + "SELECT * FROM trades WHERE (stock_name = ? AND is_buy = ?) " + + "AND (trade_timestamp <= ? AND trade_timestamp >= ?) ORDER BY trade_timestamp"); prep.setString(1, stock); prep.setInt(2, isBuy); @@ -95,7 +105,7 @@ public class DatabaseQuerier { prep.setLong(4, startDate.toEpochMilli()); ResultSet rs = prep.executeQuery(); - while(rs.next()){ + while (rs.next()) { trades.add(new Trade(rs.getInt(1), rs.getString(2), rs.getLong(4), rs.getInt(5), rs.getInt(6), new Holder(rs.getInt(7), rs.getString(3)), @@ -107,4 +117,34 @@ public class DatabaseQuerier { return trades; } + + public List<Trade> getAllTradesByHolder(String person, Date startDate, Date endDate) { + LinkedList<Trade> trades = new LinkedList<>(); + + try { + PreparedStatement prep; + prep = + conn.prepareStatement("SELECT * FROM \'trades\' WHERE holder_name= ? " + + " AND trade_timestamp BETWEEN ? AND ?" + + "order by trade_timestamp asc;"); + prep.setString(1, person); + prep.setDate(2, startDate); + prep.setDate(3, endDate); + ResultSet rs = prep.executeQuery(); + + while (rs.next()) { + trades.addFirst(new Trade(rs.getInt("trade_id"), + rs.getString("stock_name"), + rs.getDouble("trade_timestamp"), + rs.getInt("is_buy"), + rs.getInt("number_of_shares"), + new Holder(rs.getInt("holder_id"), rs.getString("holder_name")), + rs.getDouble("share_price"))); + } + prep.close(); + } catch (SQLException e) { + System.out.println("ERROR: sql error getting trades"); + } + return trades; + } } diff --git a/src/main/java/edu/brown/cs/student/term/Main.java b/src/main/java/edu/brown/cs/student/term/Main.java index 8fa3993..4b910f7 100644 --- a/src/main/java/edu/brown/cs/student/term/Main.java +++ b/src/main/java/edu/brown/cs/student/term/Main.java @@ -9,6 +9,7 @@ import edu.brown.cs.student.term.repl.Command; import edu.brown.cs.student.term.repl.REPL; import edu.brown.cs.student.term.repl.commands.LoadCommand; import edu.brown.cs.student.term.repl.commands.SetupCommand; +import edu.brown.cs.student.term.trade.Trade; import joptsimple.OptionParser; import joptsimple.OptionSet; @@ -73,7 +74,7 @@ public final class Main { runSparkServer((int) options.valueOf("port")); //will auto connect to correct db when running gui! SetupCommand setConnection = new SetupCommand(); - setConnection.run(new String[]{"data/trades.sqlite3"}); + setConnection.run(new String[] {"data/trades.sqlite3"}); } if (!options.has("debug")) { @@ -130,8 +131,9 @@ public final class Main { return "OK"; }); Spark.before((request, response) -> response.header("Access-Control-Allow-Origin", "*")); - Spark.post("/susrank", new SuspicionRankHandler()); + Spark.post("/data", new SuspicionRankHandler()); Spark.post("/profit", new ProfitQueryHandler()); + Spark.post("/trade-lookup", new TradeQueryHandler()); } /** @@ -146,24 +148,23 @@ public final class Main { public Object handle(Request request, Response response) throws Exception { //String str = request.body(); //xmlLinks = new JSONObject(str); //this is all the filedAt times and xml files - System.out.println("gets here!"); - DatabaseQuerier db = SetupCommand.getDq(); - SuspicionRanker ranker = new SuspicionRanker(db); - JSONObject data = new JSONObject(request.body()); - xmlLinks = data; - - long startMilli = data.getLong("start"); - long endMilli = data.getLong("end"); - System.out.println(startMilli); - System.out.println(endMilli); - Instant start = Instant.ofEpochMilli(startMilli); - Instant end = Instant.ofEpochMilli(endMilli); - System.out.println(start.toString()); - System.out.println(end.toString()); - List<Holder> suspiciousHolders = ranker.getSuspicionScoreList(start, end); - Map<String, Object> variables = ImmutableMap.of("holders", suspiciousHolders); - return GSON.toJson(variables); - + try { + DatabaseQuerier db = SetupCommand.getDq(); + SuspicionRanker ranker = new SuspicionRanker(db); + + JSONObject data = new JSONObject(request.body()); + + long startMilli = data.getLong("start"); + long endMilli = data.getLong("end"); + Instant start = Instant.ofEpochMilli(startMilli); + Instant end = Instant.ofEpochMilli(endMilli); + List<Holder> suspiciousHolders = ranker.getSuspicionScoreList(start, end); + Map<String, Object> variables = ImmutableMap.of("holders", suspiciousHolders); + return GSON.toJson(variables); + } catch (Exception e) { + System.out.println("DBQuerier Test, couldn't connect to db???"); + return "Error"; + } } } @@ -175,22 +176,11 @@ public final class Main { Date startPeriod = new Date(req.getLong("startTime")); Date endPeriod = new Date(req.getLong("endTime")); - List<StockHolding> holdings = new LinkedList<>(); - ProfitCalculation profit; - double gains = 0.0; - double sp500PercentGain = 0.0; - double sp500Gain = 0.0; - try { - profit = - new ProfitCalculation(DatabaseQuerier.getConn(), person, startPeriod, endPeriod); - holdings = profit.getHoldingsList(); - gains = profit.calculateGains(); - sp500PercentGain = profit.compareToSP500(); - } catch (Exception e) { - e.printStackTrace(); - System.out.println("DBQuerier Test, couldn't connect to db???"); - return "Error"; - } + ProfitCalculation profit = + new ProfitCalculation(DatabaseQuerier.getConn(), person, startPeriod, endPeriod); + List<StockHolding> holdings = profit.getHoldingsList(); + double gains = profit.calculateGains(); + double sp500PercentGain = profit.compareToSP500(); Map<String, Object> res = new HashMap<>(); res.put("person", person); @@ -206,6 +196,22 @@ public final class Main { } + private static class TradeQueryHandler implements Route { + @Override + public Object handle(Request request, Response response) throws Exception { + JSONObject req = new JSONObject(request.body()); + String person = req.getString("person"); + Date startPeriod = new Date(req.getLong("startTime")); + Date endPeriod = new Date(req.getLong("endTime")); + + DatabaseQuerier db = SetupCommand.getDq(); + List<Trade> trades = db.getAllTradesByHolder(person, startPeriod, endPeriod); + + return GSON.toJson(trades); + + } + } + /** * Display an error page when an exception occurs in the server. */ diff --git a/src/main/java/edu/brown/cs/student/term/hub/Holder.java b/src/main/java/edu/brown/cs/student/term/hub/Holder.java index 1151e74..2d11079 100644 --- a/src/main/java/edu/brown/cs/student/term/hub/Holder.java +++ b/src/main/java/edu/brown/cs/student/term/hub/Holder.java @@ -1,15 +1,17 @@ package edu.brown.cs.student.term.hub; -import java.util.Objects; +import java.util.*; public class Holder { private int id; private String name; private double suspicionScore; + private Set<Holder> followers; public Holder(int id, String name) { this.id = id; this.name = name; + followers = new HashSet<>(); } public int getId() { @@ -26,11 +28,29 @@ public class Holder { return name; } + public Set<Holder> getFollowers() { + return followers; + } + + public void addFollower(Holder follower){ + followers.add(follower); + } + @Override - public String toString() { + public String toString() { return name; } + + public String toTestString() { + return "Holder{" + + "id=" + id + + ", name='" + name + '\'' + + ", suspicionScore=" + suspicionScore + + ", followers=" + followers + + '}'; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/edu/brown/cs/student/term/hub/HubSearch.java b/src/main/java/edu/brown/cs/student/term/hub/HubSearch.java index ccefeef..86b883f 100644 --- a/src/main/java/edu/brown/cs/student/term/hub/HubSearch.java +++ b/src/main/java/edu/brown/cs/student/term/hub/HubSearch.java @@ -60,9 +60,12 @@ public class HubSearch { who followed leader or the number of people who follower followed --- probably the second option ;( */ Set<Holder> peopleFollowed = followerToLeaderMap.get(follower); + int numberFollowed = peopleFollowed.size(); if(peopleFollowed.contains(leader)){ + //constructs the leader to follower links as we go for use later on + leader.addFollower(follower); return ((damp / numHolders) + (1 - damp) * (1.0 / numberFollowed)); } else if(numberFollowed == 0){ return ((damp / numHolders) + (1 - damp) * (1.0 / numHolders)); diff --git a/src/main/java/edu/brown/cs/student/term/hub/SuspicionRanker.java b/src/main/java/edu/brown/cs/student/term/hub/SuspicionRanker.java index 4f82cde..564ba28 100644 --- a/src/main/java/edu/brown/cs/student/term/hub/SuspicionRanker.java +++ b/src/main/java/edu/brown/cs/student/term/hub/SuspicionRanker.java @@ -17,8 +17,11 @@ public class SuspicionRanker { public <K, V extends Comparable<V>> V getMaxOfMap(Map<K, V> map) { Map.Entry<K, V> maxEntry = Collections.max(map.entrySet(), Map.Entry.comparingByValue()); - System.out.println(maxEntry); - System.out.println(maxEntry.getValue()); + return maxEntry.getValue(); + } + + public <K, V extends Comparable<V>> V getMinOfMap(Map<K, V> map) { + Map.Entry<K, V> maxEntry = Collections.min(map.entrySet(), Map.Entry.comparingByValue()); return maxEntry.getValue(); } @@ -36,11 +39,25 @@ public class SuspicionRanker { Map<Integer, Double> profitMap = pc.getProfitMap(); double profitMax = getMaxOfMap(profitMap); + /*if all of our values are negative, we need to flip sides so that the + * biggest loser doesn't end up being the most suspicious person*/ + if(profitMax <= 0) { + profitMax = Math.abs(getMinOfMap(profitMap)); + } + + /*if both the min we found and max we found are 0, then we have + the special case where all the values are 0, in which case we + need to avoid dividing by 0*/ + if(profitMax == 0){ + profitMax = 1; + } + double hubMax = getMaxOfMap(holderToHubScore); for (Holder guy : holderToHubScore.keySet()) { double normalizedProfitScore = profitMap.get(guy.getId()) / profitMax; + double normalizedHubScore = holderToHubScore.get(guy) / hubMax; double suspicionScore = normalizedHubScore * 0.6 + normalizedProfitScore * 0.4; guy.setSuspicionScore(suspicionScore); diff --git a/src/main/java/edu/brown/cs/student/term/profit/ProfitCalculation.java b/src/main/java/edu/brown/cs/student/term/profit/ProfitCalculation.java index 85b2a9a..4b59aae 100644 --- a/src/main/java/edu/brown/cs/student/term/profit/ProfitCalculation.java +++ b/src/main/java/edu/brown/cs/student/term/profit/ProfitCalculation.java @@ -361,17 +361,18 @@ public class ProfitCalculation { while (rs.next()) { int id = rs.getInt("holder_id"); this.person = rs.getString("holder_name"); + resetClass(); + double gain = this.calculateGains(); if (moneyInput == 0) { profitMap.put(id, 0.0); } else { - profitMap.put(id, this.calculateGains() / moneyInput); + profitMap.put(id, gain / moneyInput); } } } catch (SQLException throwables) { System.out.println("ERROR: SQl error in profit calculation"); } - System.out.println(profitMap.toString()); return profitMap; } @@ -379,6 +380,17 @@ public class ProfitCalculation { return this.moneyInput; } + private void resetClass() { + tablesFilled = false; + moneyInput = 0; + buyHistoryMap = new HashMap<>(); + sellHistoryMap = new HashMap<>(); + realizedGainsMap = new HashMap<>(); + unrealizedGainsMap = new HashMap<>(); + currentStockPrices = new HashMap<>(); + tablesFilled = false; + } + public void setConnection(String filename) throws SQLException, ClassNotFoundException { // Initialize the database connection, turn foreign keys on |
