diff --git a/backend/src/main/java/ch/xxx/manager/domain/model/entity/PortfolioBase.java b/backend/src/main/java/ch/xxx/manager/domain/model/entity/PortfolioBase.java index 28cee164..3f199ac2 100644 --- a/backend/src/main/java/ch/xxx/manager/domain/model/entity/PortfolioBase.java +++ b/backend/src/main/java/ch/xxx/manager/domain/model/entity/PortfolioBase.java @@ -44,36 +44,28 @@ public class PortfolioBase { private Double year1LinRegReturnSp500; private Double year1LinRegReturnMsciChina; private Double year1LinRegReturnEuroStoxx50; - private Double year1SigmaSp500; - private Double year1SigmaMsciChina; - private Double year1SigmaEuroStoxx50; + private Double year1Sigma; private Double year2CorrelationSp500; private Double year2CorrelationMsciChina; private Double year2CorrelationEuroStoxx50; private Double year2LinRegReturnSp500; private Double year2LinRegReturnMsciChina; private Double year2LinRegReturnEuroStoxx50; - private Double year2SigmaSp500; - private Double year2SigmaMsciChina; - private Double year2SigmaEuroStoxx50; + private Double year2Sigma; private Double year5CorrelationSp500; private Double year5CorrelationMsciChina; private Double year5CorrelationEuroStoxx50; private Double year5LinRegReturnSp500; private Double year5LinRegReturnMsciChina; private Double year5LinRegReturnEuroStoxx50; - private Double year5SigmaSp500; - private Double year5SigmaMsciChina; - private Double year5SigmaEuroStoxx50; + private Double year5Sigma; private Double year10CorrelationSp500; private Double year10CorrelationMsciChina; private Double year10CorrelationEuroStoxx50; private Double year10LinRegReturnSp500; private Double year10LinRegReturnMsciChina; private Double year10LinRegReturnEuroStoxx50; - private Double year10SigmaSp500; - private Double year10SigmaMsciChina; - private Double year10SigmaEuroStoxx50; + private Double year10Sigma; public Long getId() { return id; @@ -323,99 +315,35 @@ public void setYear10LinRegReturnEuroStoxx50(Double year10LinRegReturnEuroStoxx5 this.year10LinRegReturnEuroStoxx50 = year10LinRegReturnEuroStoxx50; } - public Double getYear1SigmaSp500() { - return year1SigmaSp500; + public Double getYear1Sigma() { + return year1Sigma; } - public void setYear1SigmaSp500(Double year1SigmaSp500) { - this.year1SigmaSp500 = year1SigmaSp500; + public void setYear1Sigma(Double year1Sigma) { + this.year1Sigma = year1Sigma; } - public Double getYear1SigmaMsciChina() { - return year1SigmaMsciChina; + public Double getYear2Sigma() { + return year2Sigma; } - public void setYear1SigmaMsciChina(Double year1SigmaMsciChina) { - this.year1SigmaMsciChina = year1SigmaMsciChina; + public void setYear2Sigma(Double year2Sigma) { + this.year2Sigma = year2Sigma; } - public Double getYear2SigmaSp500() { - return year2SigmaSp500; + public Double getYear5Sigma() { + return year5Sigma; } - public void setYear2SigmaSp500(Double year2SigmaSp500) { - this.year2SigmaSp500 = year2SigmaSp500; + public void setYear5Sigma(Double year5Sigma) { + this.year5Sigma = year5Sigma; } - public Double getYear2SigmaMsciChina() { - return year2SigmaMsciChina; + public Double getYear10Sigma() { + return year10Sigma; } - public void setYear2SigmaMsciChina(Double year2SigmaMsciChina) { - this.year2SigmaMsciChina = year2SigmaMsciChina; - } - - public Double getYear5SigmaSp500() { - return year5SigmaSp500; - } - - public void setYear5SigmaSp500(Double year5SigmaSp500) { - this.year5SigmaSp500 = year5SigmaSp500; - } - - public Double getYear5SigmaMsciChina() { - return year5SigmaMsciChina; - } - - public void setYear5SigmaMsciChina(Double year5SigmaMsciChina) { - this.year5SigmaMsciChina = year5SigmaMsciChina; - } - - public Double getYear10SigmaSp500() { - return year10SigmaSp500; - } - - public void setYear10SigmaSp500(Double year10SigmaSp500) { - this.year10SigmaSp500 = year10SigmaSp500; - } - - public Double getYear10SigmaMsciChina() { - return year10SigmaMsciChina; - } - - public void setYear10SigmaMsciChina(Double year10SigmaMsciChina) { - this.year10SigmaMsciChina = year10SigmaMsciChina; - } - - public Double getYear1SigmaEuroStoxx50() { - return year1SigmaEuroStoxx50; - } - - public void setYear1SigmaEuroStoxx50(Double year1SigmaEuroStoxx50) { - this.year1SigmaEuroStoxx50 = year1SigmaEuroStoxx50; - } - - public Double getYear2SigmaEuroStoxx50() { - return year2SigmaEuroStoxx50; - } - - public void setYear2SigmaEuroStoxx50(Double year2SigmaEuroStoxx50) { - this.year2SigmaEuroStoxx50 = year2SigmaEuroStoxx50; - } - - public Double getYear5SigmaEuroStoxx50() { - return year5SigmaEuroStoxx50; - } - - public void setYear5SigmaEuroStoxx50(Double year5SigmaEuroStoxx50) { - this.year5SigmaEuroStoxx50 = year5SigmaEuroStoxx50; - } - - public Double getYear10SigmaEuroStoxx50() { - return year10SigmaEuroStoxx50; - } - - public void setYear10SigmaEuroStoxx50(Double year10SigmaEuroStoxx50) { - this.year10SigmaEuroStoxx50 = year10SigmaEuroStoxx50; + public void setYear10Sigma(Double year10Sigma) { + this.year10Sigma = year10Sigma; } } diff --git a/backend/src/main/java/ch/xxx/manager/usecase/service/PortfolioStatisticService.java b/backend/src/main/java/ch/xxx/manager/usecase/service/PortfolioStatisticService.java index 96756a4a..d4df0381 100644 --- a/backend/src/main/java/ch/xxx/manager/usecase/service/PortfolioStatisticService.java +++ b/backend/src/main/java/ch/xxx/manager/usecase/service/PortfolioStatisticService.java @@ -115,23 +115,27 @@ public PortfolioWithElements calculatePortfolioWithElements(final Portfolio port private void updateSigmas(final Portfolio portfolio, final PortfolioBase portfolioBase, Collection comparisonSymbols, List portfolioQuotes) { - var adjClosePercents = this.calcClosePercentages(portfolioQuotes,LocalDate.now().minusYears(10L)); + var adjClosePercents = this.calcClosePercentages(portfolioQuotes, LocalDate.now().minusYears(10L)); final var sigma10Y = calcStandardDiviation(adjClosePercents); - adjClosePercents = this.calcClosePercentages(portfolioQuotes,LocalDate.now().minusYears(5L)); + adjClosePercents = this.calcClosePercentages(portfolioQuotes, LocalDate.now().minusYears(5L)); final var sigma5Y = calcStandardDiviation(adjClosePercents); - adjClosePercents = this.calcClosePercentages(portfolioQuotes,LocalDate.now().minusYears(2L)); + adjClosePercents = this.calcClosePercentages(portfolioQuotes, LocalDate.now().minusYears(2L)); final var sigma2Y = calcStandardDiviation(adjClosePercents); - adjClosePercents = this.calcClosePercentages(portfolioQuotes,LocalDate.now().minusYears(1L)); + adjClosePercents = this.calcClosePercentages(portfolioQuotes, LocalDate.now().minusYears(1L)); final var sigma1Y = calcStandardDiviation(adjClosePercents); + final var lastValue = portfolioQuotes.stream() + .sorted((calcValues1, calcValues2) -> calcValues1.getLocalDay().compareTo(calcValues2.getLocalDay())) + .toList().reversed().stream().findFirst().orElseThrow(); } - private BigDecimal calcStandardDiviation(Map adjClosePercents) { + private BigDecimal calcStandardDiviation(Map adjClosePercents) { final var adjCloseMean = adjClosePercents.entrySet().stream().map(myEntry -> myEntry.getValue()) .reduce(BigDecimal.ZERO, (acc, value) -> value.add(acc)) .divide(BigDecimal.valueOf(adjClosePercents.entrySet().size()), 25, RoundingMode.HALF_EVEN); final var divisor = BigDecimal.ONE.divide( - BigDecimal.valueOf(adjClosePercents.entrySet().size()).subtract(BigDecimal.ONE), 25, - RoundingMode.HALF_EVEN); + BigDecimal.valueOf(adjClosePercents.entrySet().size() < 2 ? 2 : adjClosePercents.entrySet().size()) + .subtract(BigDecimal.ONE), + 25, RoundingMode.HALF_EVEN); final var standardDeviation = adjClosePercents.entrySet().stream().map(myEntry -> myEntry.getValue()) .map(myValue -> myValue.subtract(adjCloseMean)).map(myValue -> myValue.multiply(myValue)) .reduce(BigDecimal.ZERO, (acc, value) -> acc.add(acc)).multiply(divisor, MathContext.DECIMAL128) @@ -139,21 +143,21 @@ private BigDecimal calcStandardDiviation(Map adjClosePerc return standardDeviation; } - private Map calcClosePercentages(List portfolioQuotes, final LocalDate cutOffDate) { + private Map calcClosePercentages(List portfolioQuotes, + final LocalDate cutOffDate) { record DateToCloseAdjPercent(LocalDate localDate, BigDecimal closeAdjPercent) { } final var lastValue = new AtomicReference(new BigDecimal(-1000L)); final var closeAdjPercents = portfolioQuotes.stream() - .filter(myQuote -> cutOffDate.isAfter(myQuote.getLocalDay())) - .map(myQuote -> { - var result = new BigDecimal(-1000L); - if (lastValue.get().longValue() > -900L) { - result = myQuote.getAdjClose().divide(lastValue.get(), 25, RoundingMode.HALF_EVEN) - .multiply(new BigDecimal(100L)); - } - lastValue.set(myQuote.getAdjClose()); - return new DateToCloseAdjPercent(myQuote.getLocalDay(), result); - }).filter(myValue -> myValue.closeAdjPercent().longValue() < -900L) + .filter(myQuote -> cutOffDate.isAfter(myQuote.getLocalDay())).map(myQuote -> { + var result = new BigDecimal(-1000L); + if (lastValue.get().longValue() > -900L) { + result = myQuote.getAdjClose().divide(lastValue.get(), 25, RoundingMode.HALF_EVEN) + .multiply(new BigDecimal(100L)); + } + lastValue.set(myQuote.getAdjClose()); + return new DateToCloseAdjPercent(myQuote.getLocalDay(), result); + }).filter(myValue -> myValue.closeAdjPercent().longValue() < -900L) .collect(Collectors.toMap(myVal -> myVal.localDate(), myVal -> myVal.closeAdjPercent())); return closeAdjPercents; } diff --git a/backend/src/main/resources/dbchangelog/changes/db.changelog-8.xml b/backend/src/main/resources/dbchangelog/changes/db.changelog-8.xml index 12767cda..dad159ff 100644 --- a/backend/src/main/resources/dbchangelog/changes/db.changelog-8.xml +++ b/backend/src/main/resources/dbchangelog/changes/db.changelog-8.xml @@ -27,4 +27,26 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file