diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Exchange.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Exchange.java index 6276925..5115125 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Exchange.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Exchange.java @@ -1,81 +1,218 @@ package edu.ntnu.idi.idatt2003.g40.mappe; import java.math.BigDecimal; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; /** * Represents a stock exchange where stocks can be traded. - */ -public class Exchange { - - private final String name; - private int week; - private final Map stockMap; - private final Random random; - - public Exchange(String name, List stocks) { - this.name = name; - this.week = 1; - this.stockMap = new HashMap<>(); - this.random = new Random(); - - for (Stock stock : stocks) { - stockMap.put(stock.getSymbol(), stock); - } + * + *

Holds a map of stocks where stock symbol is key and stock is value.

+ * + *

Delegates buying and selling to player elements using calculators

+ * + *

Advances week.

+ * + * @see Player + * @see TransactionCalculator + * */ +public final class Exchange { + + /** + * Exchange name. + * */ + private final String name; + + /** + * Current week (set to 1 in constructor). + * */ + private int week; + + /** + * Map of {@link Stock} objects. Key is stock symbol. Value is stock. + * */ + private final Map stockMap; + + /** + * Random value determining week changes. + * */ + private final Random random; + + /** + * Constructor. + * + * @param name name of exchange. + * @param stocks list of {@link Stock} objects. + * */ + public Exchange(final String name, final List stocks) { + this.name = name; + this.week = 1; + this.stockMap = new HashMap<>(); + this.random = new Random(); + + for (Stock stock : stocks) { + stockMap.put(stock.getSymbol(), stock); } - - public String getName() { - return name; - } - - public int getWeek() { - return week; - } - - public boolean hasStock(String symbol) { - return stockMap.containsKey(symbol); - } - - public Stock getStock(String symbol) { - return stockMap.get(symbol); - } - - public List findStocks(String searchTerm) { - List result = new ArrayList<>(); - for (Stock stock : stockMap.values()) { - if (stock.getSymbol().toLowerCase().contains(searchTerm.toLowerCase()) - || stock.getCompany().toLowerCase().contains(searchTerm.toLowerCase())) { - result.add(stock); - } - } - return result; + } + + /** + * Getter method for name. + * + * @return name of exchange. + * */ + public String getName() { + return name; + } + + /** + * Getter method for current week. + * + * @return week. + * */ + public int getWeek() { + return week; + } + + /** + * Method for checking whether exchange has a stock. + * + * @param symbol the stock symbol. + * + * @return true or false. + * */ + public boolean hasStock(final String symbol) { + return stockMap.containsKey(symbol); + } + + /** + * Getter method for stock element. + * + * @param symbol the symbol of the stock to get. + * + * @return {@link Stock} element gotten. + * */ + public Stock getStock(final String symbol) { + return stockMap.get(symbol); + } + + /** + * Returns a list of stocks matching a given search term. + * + * @param searchTerm the term to search for. + * + * @return a list of {@link Stock} objects. + * */ + public List findStocks(final String searchTerm) { + List result = new ArrayList<>(); + for (Stock stock : stockMap.values()) { + if (stock.getSymbol().toLowerCase() + .contains(searchTerm.toLowerCase()) + || stock.getCompany().toLowerCase() + .contains(searchTerm.toLowerCase())) { + result.add(stock); + } } - - public Transaction buy(String symbol, BigDecimal quantity, Player player) { - Stock stock = stockMap.get(symbol); - Share share = new Share(stock, quantity, stock.getSalesPrice()); - TransactionCalculator calculator = new PurchaseCalculator(share); - player.withdrawMoney(calculator.calculateTotal()); - return new Purchase(share, week, calculator); - } - - public Transaction sell(Share share, Player player) { - TransactionCalculator calculator = new SaleCalculator(share); - player.addMoney(calculator.calculateTotal()); - return new Sale(share, week, calculator); - } - - public void advance() { - week++; - - for (Stock stock : stockMap.values()) { - BigDecimal currentPrice = stock.getSalesPrice(); - - double change = (random.nextDouble() * 0.10) - 0.05; - BigDecimal factor = BigDecimal.valueOf(1 + change); - - BigDecimal newPrice = currentPrice.multiply(factor); - stock.addNewSalesPrice(newPrice); - } + return result; + } + + /** + * Method called when a player buys a stock. + * + * @param symbol the stock this player buys. + * @param quantity the amount of stock to buy. + * @param player the player buying stock. + * + * @return Transaction representing the transaction. + * */ + public Transaction buy(final String symbol, + final BigDecimal quantity, + final Player player) { + Stock stock = stockMap.get(symbol); + Share share = new Share(stock, quantity, stock.getSalesPrice()); + TransactionCalculator calculator = new PurchaseCalculator(share); + player.withdrawMoney(calculator.calculateTotal()); + return new Purchase(share, week, calculator); + } + + /** + * Method called when a player sells share. + * + * @param share the share to sell. + * @param player the player buying stock. + * + * @return Transaction representing the transaction. + * */ + public Transaction sell(final Share share, final Player player) { + TransactionCalculator calculator = new SaleCalculator(share); + player.addMoney(calculator.calculateTotal()); + return new Sale(share, week, calculator); + } + + /** + * Method for advancing time, increasing the amount of weeks. + * */ + public void advance() { + week++; + + for (Stock stock : stockMap.values()) { + BigDecimal currentPrice = stock.getSalesPrice(); + + double change = (random.nextDouble() * 0.10) - 0.05; + BigDecimal factor = BigDecimal.valueOf(1 + change); + + BigDecimal newPrice = currentPrice.multiply(factor); + stock.addNewSalesPrice(newPrice); } -} \ No newline at end of file + } + + /** + * Method for getting the stocks with the most + * amount of increase since last week. + * + * @param limit the maximum amount of stocks returned + * + * @return list of {@link Stock} objects. + * */ + public List getGainers(final int limit) { + return stockMap.entrySet().stream() + // We only want the stocks with a positive price change. + .filter(e -> + e.getValue().getLatestPriceChange() + .compareTo(BigDecimal.ZERO) > 0) + // We sort the stocks based on the price change. + .sorted((e1, e2) -> + e2.getValue().getLatestPriceChange() + .compareTo(e1.getValue().getLatestPriceChange())) + // Sets a limit to the stream. + .limit(limit) + .map(Map.Entry::getValue) + // Converts to a list + .toList(); + } + + /** + * Method for getting the stocks with the highest + * loss of price since last week. + * + * @param limit the maximum amount of stocks returned + * + * @return list of {@link Stock} objects. + * */ + public List getLosers(final int limit) { + return stockMap.entrySet().stream() + // Only get entries with negative price change. + .filter(e -> + e.getValue().getLatestPriceChange() + .compareTo(BigDecimal.ZERO) < 0) + // Sort (lowest first) + .sorted((e1, e2) -> + e1.getValue().getLatestPriceChange() + .compareTo(e2.getValue().getLatestPriceChange())) + .limit(limit) + .map(Map.Entry::getValue) + .toList(); + } +}