@Test public void calculateHasLoss() { Trade master = common().openingPrice(LESS).isSell(false).build(); Trade slave = common().dependsOn(master).openingAmount(BigDecimal.ONE).openingPrice(MORE).isSell(true).build(); master.setStatus(TradeStatus.CLOSED); slave.setStatus(TradeStatus.CANCELLED); TradePerformanceCalculator.Performance performance = calculator.calculateOnGroupedByPair( ImmutableList.of(master, slave), Trade::getId ); assertErrorGain(performance, "1", "0.1"); }
@Transactional(readOnly = true) public <T> Performance calculateOnGroupedByPair(List<Trade> scopedTrades, Function<Trade, T> key) { Map<TradingCurrency, CryptoPricing> priceList = pricingRepository.priceList(); BigDecimal expectedProfitBtc = BigDecimal.ZERO; BigDecimal claimedProfitBtc = BigDecimal.ZERO; BigDecimal claimedLossBtc = BigDecimal.ZERO; BigDecimal total = BigDecimal.ZERO; BigDecimal inOrders = BigDecimal.ZERO; BigDecimal inErrors = BigDecimal.ZERO; Map<T, List<Trade>> grouped = scopedTrades.stream().collect(Collectors.groupingBy(key)); Function<TradeStatus, Boolean> onlyDone = DONE::contains; for (List<Trade> trades : grouped.values()) { expectedProfitBtc = expectedProfitBtc.add(computeExpectedBalanceChange(trades, priceList, status -> true)); if (ChainStatus.DONE == status(trades)) { claimedProfitBtc = claimedProfitBtc.add(computeExpectedBalanceChange(trades, priceList, onlyDone)); } if (ChainStatus.LOSS == status(trades)) { claimedLossBtc = claimedLossBtc.add(computeExpectedBalanceChange(trades, priceList, onlyDone).abs()); } inOrders = inOrders.add( computeAmount( trades.stream().filter(it -> OPEN.contains(it.getStatus())).collect(Collectors.toList()), priceList) ); inErrors = inErrors.add( computeAmount( trades.stream().filter(it -> ERRORS.contains(it.getStatus())).collect(Collectors.toList()), priceList) ); total = total.add(computeAmount(trades, priceList)); } return new Performance(expectedProfitBtc, claimedProfitBtc, claimedLossBtc, total, inOrders, inErrors, computeLatestTimeToClose(scopedTrades)); }
TradePerformanceCalculator { @Transactional(readOnly = true) public <T> Performance calculateOnGroupedByPair(List<Trade> scopedTrades, Function<Trade, T> key) { Map<TradingCurrency, CryptoPricing> priceList = pricingRepository.priceList(); BigDecimal expectedProfitBtc = BigDecimal.ZERO; BigDecimal claimedProfitBtc = BigDecimal.ZERO; BigDecimal claimedLossBtc = BigDecimal.ZERO; BigDecimal total = BigDecimal.ZERO; BigDecimal inOrders = BigDecimal.ZERO; BigDecimal inErrors = BigDecimal.ZERO; Map<T, List<Trade>> grouped = scopedTrades.stream().collect(Collectors.groupingBy(key)); Function<TradeStatus, Boolean> onlyDone = DONE::contains; for (List<Trade> trades : grouped.values()) { expectedProfitBtc = expectedProfitBtc.add(computeExpectedBalanceChange(trades, priceList, status -> true)); if (ChainStatus.DONE == status(trades)) { claimedProfitBtc = claimedProfitBtc.add(computeExpectedBalanceChange(trades, priceList, onlyDone)); } if (ChainStatus.LOSS == status(trades)) { claimedLossBtc = claimedLossBtc.add(computeExpectedBalanceChange(trades, priceList, onlyDone).abs()); } inOrders = inOrders.add( computeAmount( trades.stream().filter(it -> OPEN.contains(it.getStatus())).collect(Collectors.toList()), priceList) ); inErrors = inErrors.add( computeAmount( trades.stream().filter(it -> ERRORS.contains(it.getStatus())).collect(Collectors.toList()), priceList) ); total = total.add(computeAmount(trades, priceList)); } return new Performance(expectedProfitBtc, claimedProfitBtc, claimedLossBtc, total, inOrders, inErrors, computeLatestTimeToClose(scopedTrades)); } }
TradePerformanceCalculator { @Transactional(readOnly = true) public <T> Performance calculateOnGroupedByPair(List<Trade> scopedTrades, Function<Trade, T> key) { Map<TradingCurrency, CryptoPricing> priceList = pricingRepository.priceList(); BigDecimal expectedProfitBtc = BigDecimal.ZERO; BigDecimal claimedProfitBtc = BigDecimal.ZERO; BigDecimal claimedLossBtc = BigDecimal.ZERO; BigDecimal total = BigDecimal.ZERO; BigDecimal inOrders = BigDecimal.ZERO; BigDecimal inErrors = BigDecimal.ZERO; Map<T, List<Trade>> grouped = scopedTrades.stream().collect(Collectors.groupingBy(key)); Function<TradeStatus, Boolean> onlyDone = DONE::contains; for (List<Trade> trades : grouped.values()) { expectedProfitBtc = expectedProfitBtc.add(computeExpectedBalanceChange(trades, priceList, status -> true)); if (ChainStatus.DONE == status(trades)) { claimedProfitBtc = claimedProfitBtc.add(computeExpectedBalanceChange(trades, priceList, onlyDone)); } if (ChainStatus.LOSS == status(trades)) { claimedLossBtc = claimedLossBtc.add(computeExpectedBalanceChange(trades, priceList, onlyDone).abs()); } inOrders = inOrders.add( computeAmount( trades.stream().filter(it -> OPEN.contains(it.getStatus())).collect(Collectors.toList()), priceList) ); inErrors = inErrors.add( computeAmount( trades.stream().filter(it -> ERRORS.contains(it.getStatus())).collect(Collectors.toList()), priceList) ); total = total.add(computeAmount(trades, priceList)); } return new Performance(expectedProfitBtc, claimedProfitBtc, claimedLossBtc, total, inOrders, inErrors, computeLatestTimeToClose(scopedTrades)); }  }
TradePerformanceCalculator { @Transactional(readOnly = true) public <T> Performance calculateOnGroupedByPair(List<Trade> scopedTrades, Function<Trade, T> key) { Map<TradingCurrency, CryptoPricing> priceList = pricingRepository.priceList(); BigDecimal expectedProfitBtc = BigDecimal.ZERO; BigDecimal claimedProfitBtc = BigDecimal.ZERO; BigDecimal claimedLossBtc = BigDecimal.ZERO; BigDecimal total = BigDecimal.ZERO; BigDecimal inOrders = BigDecimal.ZERO; BigDecimal inErrors = BigDecimal.ZERO; Map<T, List<Trade>> grouped = scopedTrades.stream().collect(Collectors.groupingBy(key)); Function<TradeStatus, Boolean> onlyDone = DONE::contains; for (List<Trade> trades : grouped.values()) { expectedProfitBtc = expectedProfitBtc.add(computeExpectedBalanceChange(trades, priceList, status -> true)); if (ChainStatus.DONE == status(trades)) { claimedProfitBtc = claimedProfitBtc.add(computeExpectedBalanceChange(trades, priceList, onlyDone)); } if (ChainStatus.LOSS == status(trades)) { claimedLossBtc = claimedLossBtc.add(computeExpectedBalanceChange(trades, priceList, onlyDone).abs()); } inOrders = inOrders.add( computeAmount( trades.stream().filter(it -> OPEN.contains(it.getStatus())).collect(Collectors.toList()), priceList) ); inErrors = inErrors.add( computeAmount( trades.stream().filter(it -> ERRORS.contains(it.getStatus())).collect(Collectors.toList()), priceList) ); total = total.add(computeAmount(trades, priceList)); } return new Performance(expectedProfitBtc, claimedProfitBtc, claimedLossBtc, total, inOrders, inErrors, computeLatestTimeToClose(scopedTrades)); }  @Transactional(readOnly = true) Performance calculateOnGroupedByPair(List<Trade> scopedTrades, Function<Trade, T> key); void reportPerformance(String pathPrefix, Performance performance); }
TradePerformanceCalculator { @Transactional(readOnly = true) public <T> Performance calculateOnGroupedByPair(List<Trade> scopedTrades, Function<Trade, T> key) { Map<TradingCurrency, CryptoPricing> priceList = pricingRepository.priceList(); BigDecimal expectedProfitBtc = BigDecimal.ZERO; BigDecimal claimedProfitBtc = BigDecimal.ZERO; BigDecimal claimedLossBtc = BigDecimal.ZERO; BigDecimal total = BigDecimal.ZERO; BigDecimal inOrders = BigDecimal.ZERO; BigDecimal inErrors = BigDecimal.ZERO; Map<T, List<Trade>> grouped = scopedTrades.stream().collect(Collectors.groupingBy(key)); Function<TradeStatus, Boolean> onlyDone = DONE::contains; for (List<Trade> trades : grouped.values()) { expectedProfitBtc = expectedProfitBtc.add(computeExpectedBalanceChange(trades, priceList, status -> true)); if (ChainStatus.DONE == status(trades)) { claimedProfitBtc = claimedProfitBtc.add(computeExpectedBalanceChange(trades, priceList, onlyDone)); } if (ChainStatus.LOSS == status(trades)) { claimedLossBtc = claimedLossBtc.add(computeExpectedBalanceChange(trades, priceList, onlyDone).abs()); } inOrders = inOrders.add( computeAmount( trades.stream().filter(it -> OPEN.contains(it.getStatus())).collect(Collectors.toList()), priceList) ); inErrors = inErrors.add( computeAmount( trades.stream().filter(it -> ERRORS.contains(it.getStatus())).collect(Collectors.toList()), priceList) ); total = total.add(computeAmount(trades, priceList)); } return new Performance(expectedProfitBtc, claimedProfitBtc, claimedLossBtc, total, inOrders, inErrors, computeLatestTimeToClose(scopedTrades)); }  @Transactional(readOnly = true) Performance calculateOnGroupedByPair(List<Trade> scopedTrades, Function<Trade, T> key); void reportPerformance(String pathPrefix, Performance performance);  }