From 69f7abe23e5ba7a53944c0efdd33d305a5cbf8a0 Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 25 May 2026 10:34:08 +0200 Subject: [PATCH] Merging changes, defined price functions --- .../fileIO/CSV/CSVStockFileParser.java | 4 +- src/main/java/millions/model/Exchange.java | 29 +++++----- src/main/java/millions/model/Stock.java | 2 +- .../calculators/PriceChangeCalculator.java | 54 +++++++++++-------- src/main/java/millions/view/GameView.java | 14 +---- 5 files changed, 50 insertions(+), 53 deletions(-) diff --git a/src/main/java/millions/controller/fileIO/CSV/CSVStockFileParser.java b/src/main/java/millions/controller/fileIO/CSV/CSVStockFileParser.java index 04e80db..caf1097 100644 --- a/src/main/java/millions/controller/fileIO/CSV/CSVStockFileParser.java +++ b/src/main/java/millions/controller/fileIO/CSV/CSVStockFileParser.java @@ -21,14 +21,14 @@ public CSVStockFileParser() {} public boolean verifyCSV(List lines) { return lines.stream() .filter(l -> !(l.startsWith("#") || l.isBlank())) - .noneMatch(l -> l.split(",").length != 4); + .noneMatch(l -> l.split(",").length != 4 || l.split(",")[3].split(";").length != 6); } /** * Parses the supplied lines if they satisfy the correct format expectations * * @param lines

lines to be parsed.
- * Each line must contain three data fields: String,String,BigDecimal
+ * Each line must contain four data fields: String,String,BigDecimal,String
* (Fields cannot be blank)
* blank lines or lines beginning with '#' are ignored *

diff --git a/src/main/java/millions/model/Exchange.java b/src/main/java/millions/model/Exchange.java index f96d2bb..fbbec8d 100644 --- a/src/main/java/millions/model/Exchange.java +++ b/src/main/java/millions/model/Exchange.java @@ -10,14 +10,14 @@ import java.util.Map; import java.util.Random; import java.util.stream.Collectors; - import millions.model.calculators.PriceChangeCalculator; import millions.model.factories.PurchaseFactory; import millions.model.factories.SaleFactory; import millions.model.factories.TransactionFactory; /** - * The stock exchange where players buy and sell shares. Manages stocks and simulates weekly price changes. + * The stock exchange where players buy and sell shares. Manages stocks and simulates weekly price + * changes. */ public class Exchange { private String name; @@ -141,23 +141,22 @@ public List getLosers(int limit) { .collect(Collectors.toList()); } - /** - * Advances the current game week by performing new price calculations for all stocks. - */ + /** Advances the current game week by performing new price calculations for all stocks. */ public void advance() { - PriceChangeCalculator priceChangeCalculator = new PriceChangeCalculator(); + PriceChangeCalculator priceChangeCalculator = new PriceChangeCalculator(); this.weekNumber++; for (Stock stock : this.stocks.values()) { BigDecimal change = priceChangeCalculator.calculateChange(stock); - stock.addNewSalesPrice(stock.getSalesPrice().add(change)); - - // double change = 0.9 + random.nextDouble() * 0.2; - // stock.addNewSalesPrice( - // stock - // .getSalesPrice() - // .multiply(BigDecimal.valueOf(change)) - // .setScale(2, RoundingMode.HALF_UP)); - // // RoundingMode from AI suggestion + stock.addNewSalesPrice(stock.getSalesPrice().add(change).setScale(2, RoundingMode.HALF_UP)); + // Round to stop crazy values + + // double change = 0.9 + random.nextDouble() * 0.2; + // stock.addNewSalesPrice( + // stock + // .getSalesPrice() + // .multiply(BigDecimal.valueOf(change)) + // .setScale(2, RoundingMode.HALF_UP)); + // // RoundingMode from AI suggestion } notifyWeekAdvanced(); } diff --git a/src/main/java/millions/model/Stock.java b/src/main/java/millions/model/Stock.java index 95954e1..07dad71 100644 --- a/src/main/java/millions/model/Stock.java +++ b/src/main/java/millions/model/Stock.java @@ -25,7 +25,7 @@ public Stock(String symbol, String company, List prices, List values = stock.getVolatilityParameters(); + int week = stock.getHistoricalPrices().size(); BigDecimal change = BigDecimal.ZERO; - List volatilityParameters = stock.getVolatilityParameters(); - change = change.add(upChange(volatilityParameters.get(0))); - change = change.add(downChange(volatilityParameters.get(1))); - change = change.add(randomChange(volatilityParameters.get(2))); - change = change.add(sinChange(volatilityParameters.get(3))); - change = change.add(cosChange(volatilityParameters.get(4))); - return change; + change = change.add(drift(values.get(0))); + change = change.add(volatility(values.get(1))); + change = change.add(cycle(values.get(2), values.get(3), week)); + change = change.add(explosion(values.get(4), values.get(5))); + return stock.getSalesPrice().multiply(change); } - private BigDecimal upChange(BigDecimal input) { + /* + * Flat slope change, eg upwards/downwards slope + */ + private BigDecimal drift(BigDecimal input) { if (input.equals(BigDecimal.ZERO)) { return BigDecimal.ZERO; } return input; - } - private BigDecimal downChange(BigDecimal input) { + + /* + * Random noise of size x + */ + private BigDecimal volatility(BigDecimal input) { if (input.equals(BigDecimal.ZERO)) { return BigDecimal.ZERO; } - return input.negate(); + return input.multiply(BigDecimal.valueOf(Math.random() * 2 - 1)); } - private BigDecimal randomChange(BigDecimal input) { - if (input.equals(BigDecimal.ZERO)) { + /* + * Sinus curve based on week, times size of the curve + */ + private BigDecimal cycle(BigDecimal speed, BigDecimal size, int week) { + if (speed.equals(BigDecimal.ZERO) || size.equals(BigDecimal.ZERO)) { return BigDecimal.ZERO; } - return new BigDecimal(Math.random()*10).multiply(input); + return size.multiply(BigDecimal.valueOf(Math.sin(week * speed.doubleValue()))); } - private BigDecimal sinChange(BigDecimal input) { - if (input.equals(BigDecimal.ZERO)) { + /* + * probability% change of an explosion of size% positive or negative + */ + private BigDecimal explosion(BigDecimal probability, BigDecimal size) { + if (probability.equals(BigDecimal.ZERO) || size.equals(BigDecimal.ZERO)) { return BigDecimal.ZERO; } - return new BigDecimal(Math.sin(input.doubleValue())); - } - private BigDecimal cosChange(BigDecimal input) { - if (input.equals(BigDecimal.ZERO)) { + if (Math.random() >= probability.doubleValue()) { return BigDecimal.ZERO; } - return new BigDecimal(Math.cos(input.doubleValue())); + return Math.random() < 0.5 ? size : size.negate(); } } diff --git a/src/main/java/millions/view/GameView.java b/src/main/java/millions/view/GameView.java index 32b03ce..ad63e4e 100644 --- a/src/main/java/millions/view/GameView.java +++ b/src/main/java/millions/view/GameView.java @@ -338,12 +338,7 @@ private void refreshQuantityControls(Stock stock) { private void refreshPortfolio() { Player player = controller.getPlayer(); - portfolioList - .getItems() - .setAll( - player.getPortfolio().getShares().stream() - .map(ViewUtils::formatPortfolioShare) - .toList()); + portfolioTable.getItems().setAll(player.getPortfolio().getShares()); } private void refreshTransactions() { @@ -352,12 +347,7 @@ private void refreshTransactions() { return; } - transactionsList - .getItems() - .setAll( - player.getTransactionArchive().getTransactions().stream() - .map(ViewUtils::formatTransaction) - .toList()); + transactionsTable.getItems().setAll(player.getTransactionArchive().getTransactions()); } private void buySelectedStock() {