diff options
-rw-r--r-- | data/mock_tradeTesting.sqlite3 | bin | 45056 -> 45056 bytes | |||
-rw-r--r-- | src/main/java/edu/brown/cs/student/term/Main.java | 4 | ||||
-rw-r--r-- | src/main/java/edu/brown/cs/student/term/ProfitCalculation.java | 153 |
3 files changed, 99 insertions, 58 deletions
diff --git a/data/mock_tradeTesting.sqlite3 b/data/mock_tradeTesting.sqlite3 Binary files differindex 9521fef..d8515fe 100644 --- a/data/mock_tradeTesting.sqlite3 +++ b/data/mock_tradeTesting.sqlite3 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 7838dd3..3800837 100644 --- a/src/main/java/edu/brown/cs/student/term/Main.java +++ b/src/main/java/edu/brown/cs/student/term/Main.java @@ -55,7 +55,9 @@ public final class Main { e.printStackTrace(); } - person.calculateGains(); + person.organizeOrders(); + + System.out.println("hello"); // HashMap<String, Command> commandHashMap = new HashMap<>(); // /** add commands to map here! */ diff --git a/src/main/java/edu/brown/cs/student/term/ProfitCalculation.java b/src/main/java/edu/brown/cs/student/term/ProfitCalculation.java index 3975cef..66891ce 100644 --- a/src/main/java/edu/brown/cs/student/term/ProfitCalculation.java +++ b/src/main/java/edu/brown/cs/student/term/ProfitCalculation.java @@ -30,6 +30,8 @@ public class ProfitCalculation { //map of stock to gains from increases in value of holdings private Map<String, Double> unrealizedGainsMap; + private double moneyInput; + /** * constructor for ProfitCalculation. * @@ -43,19 +45,16 @@ public class ProfitCalculation { this.person = person; this.startTime = startTime; this.endTime = endTime; + buyHistoryMap = new HashMap<>(); + sellHistoryMap = new HashMap<>(); + realizedGainsMap = new HashMap<>(); + unrealizedGainsMap = new HashMap<>(); } /** - * calculate the gains for a given person in a specified time. - * - * @return + * This method fills the maps of sell and buy orders with lists of oldest - new trades */ - public double calculateGains() { - HashMap<String, LinkedList<OrderTuple>> buyHistory = new HashMap<String, LinkedList<OrderTuple>>(); - HashMap<String, Double> perStockGain = new HashMap<String, Double>(); - double realizedGain = 0; - double netWorthGain = 0; - + public void organizeOrders() { //get a list of trades for a person to consider try { PreparedStatement prep; @@ -69,49 +68,33 @@ public class ProfitCalculation { while (rs.next()) { String ticker = rs.getString("stock_name"); + int shares = rs.getInt("number_of_shares"); + double price = rs.getDouble("trade_amount") / shares; + OrderTuple order = new OrderTuple(shares, price, rs.getDate("trade_timestamp")); + + //one element list for first time ticker is seen. + LinkedList<OrderTuple> oneElement = new LinkedList<OrderTuple>(); + oneElement.addLast(order); //for buy orders, build up buy history if (rs.getInt("is_buy") != 0) { - int sharesBought = rs.getInt("number_of_shares"); - double cost = rs.getDouble("trade_amount") / sharesBought; - - //add a buy to the end of a history for a given stock - if (buyHistory.containsKey(ticker)) { - buyHistory.get(ticker).addLast(new OrderTuple(sharesBought, cost)); + moneyInput += shares * price; + if (buyHistoryMap.containsKey(ticker)) { + buyHistoryMap.get(ticker).addLast(order); } else { - LinkedList<OrderTuple> tickerHistory = new LinkedList<>(); - tickerHistory.add(new OrderTuple(sharesBought, cost)); - buyHistory.put(ticker, tickerHistory); + buyHistoryMap.put(ticker, oneElement); } - //for sell orders, calculate realized gains - } else { - int sharesSold = rs.getInt("number_of_shares"); - double shareSellPrice = rs.getDouble("trade_amount") / sharesSold; - if (buyHistory.containsKey(ticker)) { - LinkedList<OrderTuple> stockHistory = buyHistory.get(ticker); - - //use FIFO sell off to realize gains - while (sharesSold > 0 && !stockHistory.isEmpty()) { - OrderTuple buyBundle = stockHistory.removeFirst(); - int sharesAtBundlePrice; - if (buyBundle.getShares() > sharesSold) { - sharesAtBundlePrice = sharesSold; - sharesSold = 0; - //add back the holdings that were not sold - stockHistory - .addFirst( - new OrderTuple(buyBundle.getShares() - sharesAtBundlePrice, - buyBundle.getCost())); - } else { - sharesSold -= buyBundle.getShares(); - sharesAtBundlePrice = buyBundle.getShares(); - } - realizedGain += sharesAtBundlePrice * (shareSellPrice - buyBundle.getCost()); - + } + //for sell orders build up sell history + else { + //ignore sell orders for which we do not have buys for + if (buyHistoryMap.containsKey(ticker)) { + if (sellHistoryMap.containsKey(ticker)) { + sellHistoryMap.get(ticker).addLast(order); + } else { + sellHistoryMap.put(ticker, oneElement); } - } - } } @@ -119,27 +102,81 @@ public class ProfitCalculation { } catch (SQLException e) { System.out.println("ERROR: sql error getting trades"); } + } + + /** + * This method processes the sell orders in the sellHistoryMap to get realized gains + */ + public void getRealizedGains() { + for (String ticker : sellHistoryMap.keySet()) { + //use FIFO selling + LinkedList<OrderTuple> sells = sellHistoryMap.get(ticker); + LinkedList<OrderTuple> buys = buyHistoryMap.get(ticker); + double realizedGain = 0; + + //process each sell order (unless all buy orders are "drained" + for (OrderTuple sell : sells) { + //stop if buys are empty, stop if buy happened after sell + if (buys.isEmpty()) { + break; + } + + int sharesToSell = sell.getShares(); + + //sell off through list of buys + while (sharesToSell > 0 && !buys.isEmpty() && + !sell.getDate().after(buys.getFirst().getDate())) { + OrderTuple buyBundle = buys.removeFirst(); + int sharesAtBundlePrice; + + //the buy has more shares than we want to sell + if (buyBundle.getShares() > sharesToSell) { + sharesAtBundlePrice = sharesToSell; + sharesToSell = 0; + //add back the holdings that were not sold + buyBundle.setShares(buyBundle.getShares() - sharesAtBundlePrice); + buys.addFirst(buyBundle); + } else { + sharesToSell -= buyBundle.getShares(); + sharesAtBundlePrice = buyBundle.getShares(); + } + realizedGain += sharesAtBundlePrice * (sell.getCost() - buyBundle.getCost()); + } + } + + realizedGainsMap.put(ticker, realizedGain); + } + } + /** + * get the change in value of stocks which are still held + */ + public void getUnrealizedGains() { //calculate change in value of holdings - for (String ticker : buyHistory.keySet()) { + for (String ticker : buyHistoryMap.keySet()) { + double unrealizedGains = 0; + double currentPrice = getCurrentPrice(ticker); - LinkedList<OrderTuple> stockHistory = buyHistory.get(ticker); + LinkedList<OrderTuple> stockHistory = buyHistoryMap.get(ticker); for (OrderTuple order : stockHistory) { - netWorthGain += order.getShares() * (currentPrice - order.getCost()); + unrealizedGains += order.getShares() * (currentPrice - order.getCost()); } + + unrealizedGainsMap.put(ticker, unrealizedGains); } - System.out.println(realizedGain + netWorthGain); - return realizedGain + netWorthGain; } + private class OrderTuple { private int shares; private double cost; + private Date date; - private OrderTuple(int shares, double cost) { + private OrderTuple(int shares, double cost, Date date) { this.shares = shares; this.cost = cost; + this.date = date; } public double getCost() { @@ -149,15 +186,18 @@ public class ProfitCalculation { public int getShares() { return shares; } - } - public double getCurrentPrice(String ticker) { - return 100.0; + public Date getDate() { + return date; + } + + public void setShares(int shares) { + this.shares = shares; + } } - public double getPriceAtTime(String ticker, Date sellTime) { + public double getCurrentPrice(String ticker) { return 100.0; - //shuold be able ot use amount } public void setConnection(String filename) throws SQLException, ClassNotFoundException { @@ -172,7 +212,6 @@ public class ProfitCalculation { } - //TODO: HELPER METHODS //organizeOrders() //getRealizedGains() |