package edu.brown.cs.student.term.hub; import edu.brown.cs.student.term.DatabaseQuerier; import edu.brown.cs.student.term.trade.Trade; import java.sql.SQLException; import java.time.Instant; import java.util.*; public class LinkMapper { //TODO: Review what we actually need in here //not strictly necessary but may be nice to maintain //private List> allTrades = new ArrayList<>(); private Map> followerToLeaders = new HashMap<>(); private static Map> holderIDToTrades = new HashMap<>(); private DatabaseQuerier databaseQuerier; public LinkMapper(DatabaseQuerier db){ this.databaseQuerier = db; } /** * Returns the follower to leaders map as is, does not update it * @return person to follower map */ public Map> getFollowerToLeaders() { return followerToLeaders; } /** * This links a person and the set of people whose trades they followed * in the same time period * @param start - instant representing start of time period to look at * @param end - instant representing end of time period to look at * @return - the newly updated link map */ public Map> makeFollowerLinks(Instant start, Instant end){ if(databaseQuerier != null){ try{ List> allTrades = databaseQuerier.getAllTradesByStock(start, end); //reset the map to be blank followerToLeaders = new HashMap<>(); for(List tradeList : allTrades){ convertTradeListToFollowerMap(tradeList); } } catch(SQLException e) { System.out.println("ERROR: SQL Error while retrieving trade list"); } } else { System.out.println("ERROR: No database loaded in yet"); } return followerToLeaders; } public static List getCommonTrades(int leaderID, int followerID){ Set leaderTrades = new HashSet<>(holderIDToTrades.get(leaderID)); Set followerTrades = new HashSet<>(holderIDToTrades.get(followerID)); leaderTrades.retainAll(followerTrades); //TODO: Could retain WAY more info in here! List commonTrades = new ArrayList<>(); for(Trade leaderTrade: leaderTrades){ String buyType = ""; if(leaderTrade.isBuy()){ buyType = "Buy"; } else{ buyType = "Sell"; } commonTrades.add(buyType + ": " + leaderTrade.getStock()); } return commonTrades; } /** * Converts a single trade list into entries in the follower to leader map * @param tradeList - a list of trades for a single stock (either buy or sell) */ private void convertTradeListToFollowerMap(List tradeList){ List holderList = new ArrayList<>(); //gets in order list of people for (Trade trade : tradeList) { Holder currentHolder = trade.getHolder(); holderList.add(currentHolder); if(!holderIDToTrades.containsKey(currentHolder.getId())){ Set tradeSet = new HashSet<>(); tradeSet.add(trade); holderIDToTrades.put(currentHolder.getId(), tradeSet); } else { holderIDToTrades.get(currentHolder.getId()).add(trade); } } //Set followers = new HashSet<>(holderList); Set encountered = new HashSet<>(); //[bob, george, jane, bob, mary] for(Holder current: holderList){ //only want to use first instance of a holder to dictate who they followed //for instance, if the person whose at the front buys again, they probably //didn't follow the people in between, just wanted to buy again if(!encountered.contains(current)){ if(followerToLeaders.containsKey(current)){ //TODO: this probably makes it O(n^2), might want to optimize later followerToLeaders.get(current).addAll(encountered); } else { Set currentLeaders = new HashSet<>(encountered); followerToLeaders.put(current, currentLeaders); } encountered.add(current); } } } //This code creates a leader => follower map! /*private void convertTradeListToFollowerMap(List tradeList){ List holderList = new ArrayList<>(); //gets in order list of people for (Trade trade : tradeList) { holderList.add(trade.getHolder()); } Set followers = new HashSet<>(holderList); Set encountered = new HashSet<>(); for(Holder current: holderList){ //want to check if we've already gotten followers for this trade for this holder if(!encountered.contains(current)){ encountered.add(current); followers.remove(current); if(personToFollowers.containsKey(current)){ //TODO: this probably makes it O(n^2), might want to optimize later personToFollowers.get(current).addAll(followers); } else { Set currentFollowers = new HashSet<>(followers); personToFollowers.put(current, currentFollowers); } } } }*/ //Old version using lists of followers, allowing for duplicates /*private void convertTradeListToFollowerMap(List tradeList){ List holderList = new ArrayList<>(); //gets in order list of people for (Trade trade : tradeList) { holderList.add(trade.getHolder()); } Set followers = new HashSet<>(holderList); Set encountered = new HashSet<>(); for(Holder current: holderList){ //want to check if we've already gotten followers for this trade for this holder if(!encountered.contains(current)){ encountered.add(current); followers.remove(current); if(personToFollowers.containsKey(current)){ //TODO: this probably makes it O(n^2), might want to optimize later personToFollowers.get(current).addAll(followers); } else { List currentFollowers = new ArrayList<>(followers); personToFollowers.put(current, currentFollowers); } } } }*/ }