Exchange.java
package edu.ntnu.idi.idatt.model;
import java.math.BigDecimal;
import java.util.*;
import edu.ntnu.idi.idatt.model.market.Stock;
import edu.ntnu.idi.idatt.model.player.Player;
import edu.ntnu.idi.idatt.model.portfolio.Share;
import edu.ntnu.idi.idatt.model.transaction.Purchase;
import edu.ntnu.idi.idatt.model.transaction.Sale;
import edu.ntnu.idi.idatt.model.transaction.Transaction;
/**
* Exchange class
*
* <p>
* Class that keeps the 'stock game' gameloop.
* Contains methods for managing game states aswell as performing
* all functionality.
* </p>
*
*/
public class Exchange {
private final String name;
private int week;
private HashMap<String, Stock> stockMap = new HashMap<>();
/**
* Constructor for Exchange class
*
* @param name - Name of the current stock Exchange
* @param stocks - List of stocks for this exchange
*/
public Exchange(String name, List<Stock> stocks) {
this.name = name;
this.week = 1;
stocks.forEach(stock -> stockMap.put(stock.getSymbol(), stock));
}
/**
* Getter for name.
*
* @return String;
*/
public String getName() {
return name;
}
/**
* Getter for week.
*
* @return int;
*/
public int getWeek() {
return week;
}
/**
* Getter for all stocks.
*
* @return List of Stocks.
*/
public List<Stock> getStocks() {
return stockMap.values().stream().toList();
}
/**
* Method for checking if a specific stock exists in the exchange.
*
* @param symbol - String symbol of a specific stock.
* @return - true/false if the exchange has the specific stock.
*/
public boolean hasStock(String symbol) {
return stockMap.containsKey(symbol);
}
/**
* Getter for a specific stock.
*
* @param symbol - String symbol of a specific stock.
* @return - The found stock if existant.
* @throws IllegalArgumentException if invalid symbol given.
*/
public Stock getStock(String symbol) {
if (this.hasStock(symbol)) {
return stockMap.get(symbol);
}
throw new IllegalArgumentException("This stock doesn't exist in [" + name + "] exchange.");
}
/**
* Method for searching after stocks.
*
* @param searchTerm - String or character sequence of corporation name /
* corresponding symbol.
* @return - List of found stocks.
*/
public List<Stock> findStocks(String searchTerm) {
ArrayList<Stock> stocksFound = new ArrayList<>();
for (Stock stock : stockMap.values()) {
if (stock.getCompany().contains(searchTerm) || stock.getSymbol().contains(searchTerm)) {
stocksFound.add(stock);
}
}
return stocksFound;
}
/**
* Method for obtaining gainers
*
* <p>
* Returns the stocks that have done it the best
* (percent change) in the latest week.
* </p>
*
* @param limit - Amount of stocks to be returned.
* @return A list of stocks sorted in declining order.
*/
public List<Stock> getGainers(int limit) {
return stockMap.values().stream()
.filter(stock -> stock.getLatestPriceChangePercent().compareTo(BigDecimal.ZERO) > 0)
.sorted(Comparator.comparing(Stock::getLatestPriceChangePercent).reversed())
.limit(limit)
.toList();
}
/**
* Method for obtaining losers
*
* <p>
* Returns the stocks that have done it the worst
* in percent change in the latest week.
* </p>
*
* @param limit - Amount of stocks to be returned.
* @return A list of stocks sorted in ascending order.
*/
public List<Stock> getLosers(int limit) {
return stockMap.values().stream()
.filter(stock -> stock.getLatestPriceChangePercent().compareTo(BigDecimal.ZERO) < 0)
.sorted(Comparator.comparing(Stock::getLatestPriceChangePercent))
.limit(limit)
.toList();
}
/**
* Method to allow a player to buy a stock.
*
* <p>
* Executes a purchase for a player which executes all logic
* and management of money, portfolio and archive.
* </p>
*
* @see Purchase
*
* @param symbol - The symbol of the bought stock.
* @param quantity - The amount of a bought stock.
* @param player - which player did this event.
* @return The given transaction details. (Transaction).
* @see Transaction
*/
public Transaction buy(String symbol, BigDecimal quantity, Player player) {
Stock stock = getStock(symbol);
Share share = new Share(stock, quantity, stock.getSalesPrice());
Purchase purchase = new Purchase(share, this.week);
purchase.commit(player);
return player.getTransactionArchive().getPurchases(this.week).getLast();
}
/**
* Method to allow a player to sell a stock.
*
* <p>
* Executes a sale for a player which executes all logic
* and management of money, portfolio and archive.
* </p>
*
* @see Sale
*
* @param share - The instance of the sold share.
* @param player - which player did this event.
* @return The given transaction details. (Transaction).
* @see Transaction
*/
public Transaction sell(Share share, Player player) {
Sale sale = new Sale(share, this.week);
sale.commit(player);
return player.getTransactionArchive().getSales(this.week).getLast();
}
/**
* Method to advance the gameloop.
*
* <p>
* Adds a new price to each of the stock array.
* Progresses week counter.
* </p>
*
* @see Stock
*/
public void advance() {
stockMap.values()
.forEach(stock -> stock.advancePrice());
this.week += 1;
}
}