From 2402ca839b33d4c16c59e43575a5791e1c6e7630 Mon Sep 17 00:00:00 2001 From: clarkohw Date: Wed, 31 Mar 2021 21:52:50 -0400 Subject: inital code for profit calculations --- data/mock_tradeClarks.sqlite3 | Bin 0 -> 45056 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 data/mock_tradeClarks.sqlite3 (limited to 'data') diff --git a/data/mock_tradeClarks.sqlite3 b/data/mock_tradeClarks.sqlite3 new file mode 100644 index 0000000..7b5f3d1 Binary files /dev/null and b/data/mock_tradeClarks.sqlite3 differ -- cgit v1.2.3-70-g09d2 From d2cb17744211b73080fa5ae476843e5acd52946b Mon Sep 17 00:00:00 2001 From: clarkohw Date: Sat, 3 Apr 2021 19:43:18 -0400 Subject: before restructuring --- data/mock_tradeTesting.sqlite3 | Bin 0 -> 45056 bytes src/main/java/edu/brown/cs/student/term/Main.java | 9 +- .../brown/cs/student/term/ProfitCalculation.java | 115 ++++++++++++++++----- 3 files changed, 95 insertions(+), 29 deletions(-) create mode 100644 data/mock_tradeTesting.sqlite3 (limited to 'data') diff --git a/data/mock_tradeTesting.sqlite3 b/data/mock_tradeTesting.sqlite3 new file mode 100644 index 0000000..9521fef Binary files /dev/null and b/data/mock_tradeTesting.sqlite3 differ 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 e6584f1..7838dd3 100644 --- a/src/main/java/edu/brown/cs/student/term/Main.java +++ b/src/main/java/edu/brown/cs/student/term/Main.java @@ -48,8 +48,13 @@ public final class Main { } - ProfitCalculation person = new ProfitCalculation(null, "Vincent", new Date(1615629591000L), new Date(1615507898000L)); - person.setConnection("./data/mock_tradeClarks.sqlite3"); + ProfitCalculation person = new ProfitCalculation(null, "Sophie", new Date(1615629591000L), new Date(1615507898000L)); + try { + person.setConnection("./data/mock_tradeClarks.sqlite3"); + } catch(Exception e) { + e.printStackTrace(); + } + person.calculateGains(); // HashMap commandHashMap = new HashMap<>(); 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 7c275d2..3975cef 100644 --- a/src/main/java/edu/brown/cs/student/term/ProfitCalculation.java +++ b/src/main/java/edu/brown/cs/student/term/ProfitCalculation.java @@ -10,12 +10,25 @@ import java.sql.Statement; import java.util.LinkedList; import java.util.List; import java.util.HashMap; +import java.util.Map; public class ProfitCalculation { private Connection conn; private String person; - Date startTime; - Date endTime; + private Date startTime; + private Date endTime; + + //map of stock to list of buy orders, first element in list is oldest + private Map> buyHistoryMap; + + //map of stock to list of buy orders, first element in list is oldest + private Map> sellHistoryMap; + + //map of stock to gains from sell orders + private Map realizedGainsMap; + + //map of stock to gains from increases in value of holdings + private Map unrealizedGainsMap; /** * constructor for ProfitCalculation. @@ -38,38 +51,66 @@ public class ProfitCalculation { * @return */ public double calculateGains() { - HashMap> buyHistory = new HashMap>(); + HashMap> buyHistory = new HashMap>(); HashMap perStockGain = new HashMap(); - double totalGain = 0; - //query for List per person + double realizedGain = 0; + double netWorthGain = 0; + //get a list of trades for a person to consider try { PreparedStatement prep; - prep = conn.prepareStatement("SELECT * FROM \'users\' WHERE user_id= ?;"); - //prep.setString(1, id); + // TODO: add start and end time + prep = + conn.prepareStatement("SELECT * FROM \'trades\' WHERE holder_name= ? " + + "order by trade_timestamp asc;"); + prep.setString(1, this.person); + //prep.setString(2, "NVDA"); ResultSet rs = prep.executeQuery(); + while (rs.next()) { - boolean buy = true; - String ticker = "STOCK"; + String ticker = rs.getString("stock_name"); + //for buy orders, build up buy history - if (buy) { - int sharesBought = 99; - double cost = 420.0; + 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 BuyTuple(sharesBought, cost)); + buyHistory.get(ticker).addLast(new OrderTuple(sharesBought, cost)); } else { - LinkedList tickerHistory = new LinkedList<>(); - tickerHistory.add(new BuyTuple(sharesBought, cost)); + LinkedList tickerHistory = new LinkedList<>(); + tickerHistory.add(new OrderTuple(sharesBought, cost)); buyHistory.put(ticker, tickerHistory); } //for sell orders, calculate realized gains } else { -// int sharesSold = 99; -// if (buyHistory.containsKey(ticker)) { -// LinkedList = -// } + int sharesSold = rs.getInt("number_of_shares"); + double shareSellPrice = rs.getDouble("trade_amount") / sharesSold; + if (buyHistory.containsKey(ticker)) { + LinkedList 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()); + + } + + } } @@ -80,19 +121,23 @@ public class ProfitCalculation { } - //FOR EACH RESULT in ResultsSet... - //if buy: add to hashmap tuple entry (shares, cost) to hashmap - // - get cost of stock at time of purchase - //if sell: check if we hold this stock. If so use FIFO to sell - - return totalGain; + //calculate change in value of holdings + for (String ticker : buyHistory.keySet()) { + double currentPrice = getCurrentPrice(ticker); + LinkedList stockHistory = buyHistory.get(ticker); + for (OrderTuple order : stockHistory) { + netWorthGain += order.getShares() * (currentPrice - order.getCost()); + } + } + System.out.println(realizedGain + netWorthGain); + return realizedGain + netWorthGain; } - private class BuyTuple { + private class OrderTuple { private int shares; private double cost; - private BuyTuple(int shares, double cost) { + private OrderTuple(int shares, double cost) { this.shares = shares; this.cost = cost; } @@ -106,6 +151,15 @@ public class ProfitCalculation { } } + public double getCurrentPrice(String ticker) { + return 100.0; + } + + public double getPriceAtTime(String ticker, Date sellTime) { + return 100.0; + //shuold be able ot use amount + } + public void setConnection(String filename) throws SQLException, ClassNotFoundException { // Initialize the database connection, turn foreign keys on @@ -118,4 +172,11 @@ public class ProfitCalculation { } + + //TODO: HELPER METHODS + //organizeOrders() + //getRealizedGains() + //getUnrealizedGains() + + } -- cgit v1.2.3-70-g09d2 From cc40a75c75de80383f931d5b853db52d90d3ff72 Mon Sep 17 00:00:00 2001 From: clarkohw Date: Sat, 3 Apr 2021 20:51:02 -0400 Subject: important methods are implemented --- data/mock_tradeTesting.sqlite3 | Bin 45056 -> 45056 bytes src/main/java/edu/brown/cs/student/term/Main.java | 4 +- .../brown/cs/student/term/ProfitCalculation.java | 153 +++++++++++++-------- 3 files changed, 99 insertions(+), 58 deletions(-) (limited to 'data') diff --git a/data/mock_tradeTesting.sqlite3 b/data/mock_tradeTesting.sqlite3 index 9521fef..d8515fe 100644 Binary files a/data/mock_tradeTesting.sqlite3 and b/data/mock_tradeTesting.sqlite3 differ 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 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 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> buyHistory = new HashMap>(); - HashMap perStockGain = new HashMap(); - 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 oneElement = new LinkedList(); + 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 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 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 sells = sellHistoryMap.get(ticker); + LinkedList 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 stockHistory = buyHistory.get(ticker); + LinkedList 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() -- cgit v1.2.3-70-g09d2