aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/edu
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/edu')
-rw-r--r--src/main/java/edu/brown/cs/student/term/DatabaseQuerier.java68
-rw-r--r--src/main/java/edu/brown/cs/student/term/Main.java78
-rw-r--r--src/main/java/edu/brown/cs/student/term/hub/Holder.java24
-rw-r--r--src/main/java/edu/brown/cs/student/term/hub/HubSearch.java3
-rw-r--r--src/main/java/edu/brown/cs/student/term/hub/SuspicionRanker.java21
-rw-r--r--src/main/java/edu/brown/cs/student/term/profit/ProfitCalculation.java16
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