Search in sources :

Example 1 with CLOSED

use of tech.cassandre.trading.bot.dto.position.PositionStatusDTO.CLOSED in project cassandre-trading-bot by cassandre-tech.

the class PositionServiceCassandreImplementation method getGains.

@Override
public final Map<CurrencyDTO, GainDTO> getGains(final long strategyUid) {
    logger.debug("Retrieving gains for all positions");
    HashMap<CurrencyDTO, BigDecimal> totalBefore = new LinkedHashMap<>();
    HashMap<CurrencyDTO, BigDecimal> totalAfter = new LinkedHashMap<>();
    List<CurrencyAmountDTO> openingOrdersFees = new LinkedList<>();
    List<CurrencyAmountDTO> closingOrdersFees = new LinkedList<>();
    HashMap<CurrencyDTO, GainDTO> gains = new LinkedHashMap<>();
    // We calculate, by currency, the amount bought & sold.
    positionRepository.findByStatus(CLOSED).stream().filter(position -> strategyUid == 0 || position.getStrategy().getUid() == strategyUid).map(POSITION_MAPPER::mapToPositionDTO).forEach(positionDTO -> {
        // We retrieve the currency and initiate the maps if they are empty
        CurrencyDTO currency;
        if (positionDTO.getType() == LONG) {
            // LONG.
            currency = positionDTO.getCurrencyPair().getQuoteCurrency();
        } else {
            // SHORT.
            currency = positionDTO.getCurrencyPair().getBaseCurrency();
        }
        gains.putIfAbsent(currency, null);
        totalBefore.putIfAbsent(currency, ZERO);
        totalAfter.putIfAbsent(currency, ZERO);
        // We calculate the amounts bought and amount sold.
        if (positionDTO.getType() == LONG) {
            totalBefore.put(currency, positionDTO.getOpeningOrder().getTrades().stream().map(t -> t.getAmountValue().multiply(t.getPriceValue())).reduce(totalBefore.get(currency), BigDecimal::add));
            totalAfter.put(currency, positionDTO.getClosingOrder().getTrades().stream().map(t -> t.getAmountValue().multiply(t.getPriceValue())).reduce(totalAfter.get(currency), BigDecimal::add));
        } else {
            totalBefore.put(currency, positionDTO.getOpeningOrder().getTrades().stream().map(TradeDTO::getAmountValue).reduce(totalBefore.get(currency), BigDecimal::add));
            totalAfter.put(currency, positionDTO.getClosingOrder().getTrades().stream().map(TradeDTO::getAmountValue).reduce(totalAfter.get(currency), BigDecimal::add));
        }
        // And now the fees.
        positionDTO.getOpeningOrder().getTrades().stream().filter(tradeDTO -> tradeDTO.getFee() != null).forEach(tradeDTO -> openingOrdersFees.add(tradeDTO.getFee()));
        positionDTO.getClosingOrder().getTrades().stream().filter(tradeDTO -> tradeDTO.getFee() != null).forEach(tradeDTO -> closingOrdersFees.add(tradeDTO.getFee()));
    });
    gains.keySet().forEach(currency -> {
        // We make the calculation.
        BigDecimal before = totalBefore.get(currency);
        BigDecimal after = totalAfter.get(currency);
        BigDecimal gainAmount = after.subtract(before);
        BigDecimal gainPercentage = ((after.subtract(before)).divide(before, HALF_UP)).multiply(ONE_HUNDRED_BIG_DECIMAL);
        GainDTO g = GainDTO.builder().percentage(gainPercentage.setScale(2, HALF_UP).doubleValue()).amount(CurrencyAmountDTO.builder().value(gainAmount).currency(currency).build()).openingOrderFees(openingOrdersFees).closingOrderFees(closingOrdersFees).build();
        gains.put(currency, g);
    });
    return gains;
}
Also used : RequiredArgsConstructor(lombok.RequiredArgsConstructor) Position(tech.cassandre.trading.bot.domain.Position) CLOSED(tech.cassandre.trading.bot.dto.position.PositionStatusDTO.CLOSED) HashMap(java.util.HashMap) CurrencyAmountDTO(tech.cassandre.trading.bot.dto.util.CurrencyAmountDTO) LONG(tech.cassandre.trading.bot.dto.position.PositionTypeDTO.LONG) LinkedHashMap(java.util.LinkedHashMap) CassandreStrategyInterface(tech.cassandre.trading.bot.strategy.internal.CassandreStrategyInterface) BigDecimal(java.math.BigDecimal) OPENING(tech.cassandre.trading.bot.dto.position.PositionStatusDTO.OPENING) PositionFlux(tech.cassandre.trading.bot.batch.PositionFlux) Locale(java.util.Locale) Map(java.util.Map) CurrencyPairDTO(tech.cassandre.trading.bot.dto.util.CurrencyPairDTO) SHORT(tech.cassandre.trading.bot.dto.position.PositionTypeDTO.SHORT) LinkedList(java.util.LinkedList) FLOOR(java.math.RoundingMode.FLOOR) LinkedHashSet(java.util.LinkedHashSet) OPENED(tech.cassandre.trading.bot.dto.position.PositionStatusDTO.OPENED) PositionDTO(tech.cassandre.trading.bot.dto.position.PositionDTO) BIGINTEGER_SCALE(tech.cassandre.trading.bot.util.math.MathConstants.BIGINTEGER_SCALE) CurrencyDTO(tech.cassandre.trading.bot.dto.util.CurrencyDTO) CassandreStrategy(tech.cassandre.trading.bot.strategy.internal.CassandreStrategy) NonNull(lombok.NonNull) PositionRepository(tech.cassandre.trading.bot.repository.PositionRepository) HALF_UP(java.math.RoundingMode.HALF_UP) GainDTO(tech.cassandre.trading.bot.dto.util.GainDTO) Set(java.util.Set) ZERO(java.math.BigDecimal.ZERO) TradeDTO(tech.cassandre.trading.bot.dto.trade.TradeDTO) Collectors(java.util.stream.Collectors) PositionCreationResultDTO(tech.cassandre.trading.bot.dto.position.PositionCreationResultDTO) PositionTypeDTO(tech.cassandre.trading.bot.dto.position.PositionTypeDTO) List(java.util.List) PositionRulesDTO(tech.cassandre.trading.bot.dto.position.PositionRulesDTO) Stream(java.util.stream.Stream) BaseService(tech.cassandre.trading.bot.util.base.service.BaseService) ONE_HUNDRED_BIG_DECIMAL(tech.cassandre.trading.bot.util.math.MathConstants.ONE_HUNDRED_BIG_DECIMAL) OrderCreationResultDTO(tech.cassandre.trading.bot.dto.trade.OrderCreationResultDTO) Optional(java.util.Optional) TickerDTO(tech.cassandre.trading.bot.dto.market.TickerDTO) CurrencyAmountDTO(tech.cassandre.trading.bot.dto.util.CurrencyAmountDTO) TradeDTO(tech.cassandre.trading.bot.dto.trade.TradeDTO) GainDTO(tech.cassandre.trading.bot.dto.util.GainDTO) CurrencyDTO(tech.cassandre.trading.bot.dto.util.CurrencyDTO) BigDecimal(java.math.BigDecimal) LinkedList(java.util.LinkedList) LinkedHashMap(java.util.LinkedHashMap)

Example 2 with CLOSED

use of tech.cassandre.trading.bot.dto.position.PositionStatusDTO.CLOSED in project cassandre-trading-bot by cassandre-tech.

the class PositionTest method checkLoadPositionFromDatabase.

@Test
@DisplayName("Check load position from database")
public void checkLoadPositionFromDatabase() {
    // =============================================================================================================
    // Check position 1 - OPENING.
    PositionDTO position1 = strategy.getPositions().get(1L);
    assertNotNull(position1);
    assertEquals(1L, position1.getUid());
    assertEquals(1L, position1.getPositionId());
    assertEquals(LONG, position1.getType());
    assertNotNull(position1.getStrategy());
    assertEquals(1, position1.getStrategy().getUid());
    assertEquals("01", position1.getStrategy().getStrategyId());
    assertEquals(new CurrencyPairDTO("BTC/USDT"), position1.getCurrencyPair());
    assertEquals(0, new BigDecimal("10").compareTo(position1.getAmount().getValue()));
    assertEquals(BTC, position1.getAmount().getCurrency());
    assertFalse(position1.getRules().isStopGainPercentageSet());
    assertFalse(position1.getRules().isStopLossPercentageSet());
    assertEquals(OPENING, position1.getStatus());
    assertEquals("BACKUP_OPENING_ORDER_01", position1.getOpeningOrder().getOrderId());
    assertTrue(position1.getOpeningOrder().getTrades().isEmpty());
    assertNull(position1.getClosingOrder());
    assertNull(position1.getLowestGainPrice());
    assertNull(position1.getHighestGainPrice());
    assertNull(position1.getLatestGainPrice());
    // Test equals.
    Optional<PositionDTO> position1Bis = strategy.getPositionByPositionId(1L);
    assertTrue(position1Bis.isPresent());
    assertEquals(position1, position1Bis.get());
    // =============================================================================================================
    // Check position 2 - OPENED.
    PositionDTO position2 = strategy.getPositions().get(2L);
    assertNotNull(position2);
    assertEquals(2L, position2.getUid());
    assertEquals(2L, position2.getPositionId());
    assertEquals(LONG, position2.getType());
    assertNotNull(position2.getStrategy());
    assertEquals(1, position2.getStrategy().getUid());
    assertEquals("01", position2.getStrategy().getStrategyId());
    assertEquals(new CurrencyPairDTO("BTC/USDT"), position2.getCurrencyPair());
    assertEquals(0, new BigDecimal("20").compareTo(position2.getAmount().getValue()));
    assertEquals(BTC, position2.getAmount().getCurrency());
    assertTrue(position2.getRules().isStopGainPercentageSet());
    assertEquals(10, position2.getRules().getStopGainPercentage());
    assertFalse(position2.getRules().isStopLossPercentageSet());
    assertEquals(OPENED, position2.getStatus());
    assertEquals("BACKUP_OPENING_ORDER_02", position2.getOpeningOrder().getOrderId());
    assertEquals(1, position2.getOpeningOrder().getTrades().size());
    assertTrue(position2.getOpeningOrder().getTrade("BACKUP_TRADE_01").isPresent());
    assertNull(position2.getClosingOrder());
    assertEquals(0, new BigDecimal("1").compareTo(position2.getLowestGainPrice().getValue()));
    assertEquals(USDT, position2.getLowestGainPrice().getCurrency());
    assertEquals(0, new BigDecimal("2").compareTo(position2.getHighestGainPrice().getValue()));
    assertEquals(USDT, position2.getHighestGainPrice().getCurrency());
    assertEquals(0, new BigDecimal("3").compareTo(position2.getLatestGainPrice().getValue()));
    assertEquals(USDT, position2.getLatestGainPrice().getCurrency());
    // =============================================================================================================
    // Check position 3 - CLOSING.
    PositionDTO position3 = strategy.getPositions().get(3L);
    assertNotNull(position3);
    assertEquals(3L, position3.getUid());
    assertEquals(3L, position3.getPositionId());
    assertEquals(LONG, position3.getType());
    assertNotNull(position3.getStrategy());
    assertEquals(1, position3.getStrategy().getUid());
    assertEquals("01", position3.getStrategy().getStrategyId());
    assertEquals(new CurrencyPairDTO("BTC/USDT"), position3.getCurrencyPair());
    assertEquals(0, new BigDecimal("30").compareTo(position3.getAmount().getValue()));
    assertEquals(BTC, position3.getAmount().getCurrency());
    assertFalse(position3.getRules().isStopGainPercentageSet());
    assertTrue(position3.getRules().isStopLossPercentageSet());
    assertEquals(20, position3.getRules().getStopLossPercentage());
    assertEquals(CLOSING, position3.getStatus());
    assertEquals("BACKUP_OPENING_ORDER_03", position3.getOpeningOrder().getOrderId());
    assertEquals(1, position3.getOpeningOrder().getTrades().size());
    assertTrue(position3.getOpeningOrder().getTrade("BACKUP_TRADE_02").isPresent());
    assertEquals("BACKUP_CLOSING_ORDER_01", position3.getClosingOrder().getOrderId());
    assertEquals(1, position3.getClosingOrder().getTrades().size());
    assertTrue(position3.getClosingOrder().getTrade("BACKUP_TRADE_04").isPresent());
    assertEquals(0, new BigDecimal("17").compareTo(position3.getLowestGainPrice().getValue()));
    assertEquals(USDT, position3.getLowestGainPrice().getCurrency());
    assertEquals(0, new BigDecimal("68").compareTo(position3.getHighestGainPrice().getValue()));
    assertEquals(USDT, position3.getHighestGainPrice().getCurrency());
    assertEquals(0, new BigDecimal("92").compareTo(position3.getLatestGainPrice().getValue()));
    assertEquals(USDT, position3.getLatestGainPrice().getCurrency());
    // =============================================================================================================
    // Check position 4 - CLOSED.
    PositionDTO position4 = strategy.getPositions().get(4L);
    assertNotNull(position4);
    assertEquals(4L, position4.getUid());
    assertEquals(4L, position4.getPositionId());
    assertEquals(LONG, position4.getType());
    assertNotNull(position4.getStrategy());
    assertEquals(1, position4.getStrategy().getUid());
    assertEquals("01", position4.getStrategy().getStrategyId());
    assertEquals(new CurrencyPairDTO("BTC/USDT"), position4.getCurrencyPair());
    assertEquals(0, new BigDecimal("40").compareTo(position4.getAmount().getValue()));
    assertEquals(BTC, position4.getAmount().getCurrency());
    assertTrue(position4.getRules().isStopGainPercentageSet());
    assertEquals(30, position4.getRules().getStopGainPercentage());
    assertTrue(position4.getRules().isStopLossPercentageSet());
    assertEquals(40, position4.getRules().getStopLossPercentage());
    assertEquals(CLOSED, position4.getStatus());
    assertEquals("BACKUP_OPENING_ORDER_04", position4.getOpeningOrder().getOrderId());
    assertEquals(1, position4.getOpeningOrder().getTrades().size());
    assertTrue(position4.getOpeningOrder().getTrade("BACKUP_TRADE_03").isPresent());
    assertEquals("BACKUP_CLOSING_ORDER_02", position4.getClosingOrder().getOrderId());
    assertEquals(1, position4.getClosingOrder().getTrades().size());
    assertTrue(position4.getClosingOrder().getTrade("BACKUP_TRADE_05").isPresent());
    assertEquals(0, new BigDecimal("17").compareTo(position4.getLowestGainPrice().getValue()));
    assertEquals(USDT, position4.getLowestGainPrice().getCurrency());
    assertEquals(0, new BigDecimal("68").compareTo(position4.getHighestGainPrice().getValue()));
    assertEquals(USDT, position4.getHighestGainPrice().getCurrency());
    assertEquals(0, new BigDecimal("93").compareTo(position4.getLatestGainPrice().getValue()));
    assertEquals(USDT, position4.getLatestGainPrice().getCurrency());
    // =============================================================================================================
    // Check position 5 - CLOSED with several trades.
    PositionDTO position5 = strategy.getPositions().get(5L);
    assertNotNull(position5);
    assertEquals(5L, position5.getUid());
    assertEquals(5L, position5.getPositionId());
    assertEquals(LONG, position5.getType());
    assertNotNull(position5.getStrategy());
    assertEquals(1, position5.getStrategy().getUid());
    assertEquals("01", position5.getStrategy().getStrategyId());
    assertEquals(new CurrencyPairDTO("ETH/USD"), position5.getCurrencyPair());
    assertEquals(0, new BigDecimal("50").compareTo(position5.getAmount().getValue()));
    assertEquals(ETH, position5.getAmount().getCurrency());
    assertTrue(position5.getRules().isStopGainPercentageSet());
    assertEquals(30, position5.getRules().getStopGainPercentage());
    assertTrue(position5.getRules().isStopLossPercentageSet());
    assertEquals(40, position5.getRules().getStopLossPercentage());
    assertEquals(CLOSED, position5.getStatus());
    assertEquals("BACKUP_OPENING_ORDER_05", position5.getOpeningOrder().getOrderId());
    assertEquals("BACKUP_CLOSING_ORDER_03", position5.getClosingOrder().getOrderId());
    assertEquals(0, new BigDecimal("17").compareTo(position5.getLowestGainPrice().getValue()));
    assertEquals(USD, position5.getLowestGainPrice().getCurrency());
    assertEquals(0, new BigDecimal("68").compareTo(position5.getHighestGainPrice().getValue()));
    assertEquals(USD, position5.getHighestGainPrice().getCurrency());
    assertEquals(0, new BigDecimal("94").compareTo(position5.getLatestGainPrice().getValue()));
    assertEquals(USD, position5.getLatestGainPrice().getCurrency());
    // Open trades.
    assertEquals(2, position5.getOpeningOrder().getTrades().size());
    assertTrue(position5.getOpeningOrder().getTrade("BACKUP_TRADE_06").isPresent());
    assertEquals("BACKUP_TRADE_06", position5.getOpeningOrder().getTrade("BACKUP_TRADE_06").get().getTradeId());
    assertTrue(position5.getOpeningOrder().getTrades().stream().anyMatch(t -> "BACKUP_TRADE_06".equals(t.getTradeId())));
    assertTrue(position5.getOpeningOrder().getTrade("BACKUP_TRADE_07").isPresent());
    assertTrue(position5.getOpeningOrder().getTrades().stream().anyMatch(t -> "BACKUP_TRADE_07".equals(t.getTradeId())));
    assertEquals("BACKUP_TRADE_07", position5.getOpeningOrder().getTrade("BACKUP_TRADE_07").get().getTradeId());
    // Close trades.
    assertEquals(3, position5.getClosingOrder().getTrades().size());
    assertTrue(position5.getClosingOrder().getTrade("BACKUP_TRADE_08").isPresent());
    assertTrue(position5.getClosingOrder().getTrades().stream().anyMatch(t -> "BACKUP_TRADE_08".equals(t.getTradeId())));
    assertEquals("BACKUP_TRADE_08", position5.getClosingOrder().getTrade("BACKUP_TRADE_08").get().getTradeId());
    assertTrue(position5.getClosingOrder().getTrade("BACKUP_TRADE_09").isPresent());
    assertTrue(position5.getClosingOrder().getTrades().stream().anyMatch(t -> "BACKUP_TRADE_09".equals(t.getTradeId())));
    assertEquals("BACKUP_TRADE_09", position5.getClosingOrder().getTrade("BACKUP_TRADE_09").get().getTradeId());
    assertTrue(position5.getClosingOrder().getTrade("BACKUP_TRADE_10").isPresent());
    assertTrue(position5.getClosingOrder().getTrades().stream().anyMatch(t -> "BACKUP_TRADE_10".equals(t.getTradeId())));
    assertEquals("BACKUP_TRADE_10", position5.getClosingOrder().getTrade("BACKUP_TRADE_10").get().getTradeId());
    // Check trade orders.
    final Iterator<TradeDTO> openTradesIterator = position5.getOpeningOrder().getTrades().iterator();
    assertEquals("BACKUP_TRADE_06", openTradesIterator.next().getTradeId());
    assertEquals("BACKUP_TRADE_07", openTradesIterator.next().getTradeId());
    final Iterator<TradeDTO> closeTradesIterator = position5.getClosingOrder().getTrades().iterator();
    assertEquals("BACKUP_TRADE_08", closeTradesIterator.next().getTradeId());
    assertEquals("BACKUP_TRADE_09", closeTradesIterator.next().getTradeId());
    assertEquals("BACKUP_TRADE_10", closeTradesIterator.next().getTradeId());
}
Also used : DirtiesContext(org.springframework.test.annotation.DirtiesContext) ASK(tech.cassandre.trading.bot.dto.trade.OrderTypeDTO.ASK) ZonedDateTime(java.time.ZonedDateTime) BEFORE_EACH_TEST_METHOD(org.springframework.test.annotation.DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) Position(tech.cassandre.trading.bot.domain.Position) Autowired(org.springframework.beans.factory.annotation.Autowired) ActiveProfiles(org.springframework.test.context.ActiveProfiles) CurrencyAmountDTO(tech.cassandre.trading.bot.dto.util.CurrencyAmountDTO) BigDecimal(java.math.BigDecimal) TradeFlux(tech.cassandre.trading.bot.batch.TradeFlux) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) USDT(tech.cassandre.trading.bot.dto.util.CurrencyDTO.USDT) OrderFlux(tech.cassandre.trading.bot.batch.OrderFlux) NEW(tech.cassandre.trading.bot.dto.trade.OrderStatusDTO.NEW) OPENED(tech.cassandre.trading.bot.dto.position.PositionStatusDTO.OPENED) ETH(tech.cassandre.trading.bot.dto.util.CurrencyDTO.ETH) PositionDTO(tech.cassandre.trading.bot.dto.position.PositionDTO) Awaitility.await(org.awaitility.Awaitility.await) USD(tech.cassandre.trading.bot.dto.util.CurrencyDTO.USD) PositionRepository(tech.cassandre.trading.bot.repository.PositionRepository) PositionService(tech.cassandre.trading.bot.service.PositionService) TickerFlux(tech.cassandre.trading.bot.batch.TickerFlux) TradeDTO(tech.cassandre.trading.bot.dto.trade.TradeDTO) OrderDTO(tech.cassandre.trading.bot.dto.trade.OrderDTO) Test(org.junit.jupiter.api.Test) PositionCreationResultDTO(tech.cassandre.trading.bot.dto.position.PositionCreationResultDTO) OrderRepository(tech.cassandre.trading.bot.repository.OrderRepository) SpringBootTest(org.springframework.boot.test.context.SpringBootTest) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) Optional(java.util.Optional) TickerDTO(tech.cassandre.trading.bot.dto.market.TickerDTO) Property(tech.cassandre.trading.bot.test.util.junit.configuration.Property) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) CLOSED(tech.cassandre.trading.bot.dto.position.PositionStatusDTO.CLOSED) PositionException(tech.cassandre.trading.bot.util.exception.PositionException) LONG(tech.cassandre.trading.bot.dto.position.PositionTypeDTO.LONG) BaseTest(tech.cassandre.trading.bot.test.util.junit.BaseTest) TestableCassandreStrategy(tech.cassandre.trading.bot.test.util.strategies.TestableCassandreStrategy) OPENING(tech.cassandre.trading.bot.dto.position.PositionStatusDTO.OPENING) PositionFlux(tech.cassandre.trading.bot.batch.PositionFlux) BTC(tech.cassandre.trading.bot.dto.util.CurrencyDTO.BTC) CurrencyPairDTO(tech.cassandre.trading.bot.dto.util.CurrencyPairDTO) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Configuration(tech.cassandre.trading.bot.test.util.junit.configuration.Configuration) Iterator(java.util.Iterator) CLOSING(tech.cassandre.trading.bot.dto.position.PositionStatusDTO.CLOSING) DisplayName(org.junit.jupiter.api.DisplayName) PositionRulesDTO(tech.cassandre.trading.bot.dto.position.PositionRulesDTO) PARAMETER_EXCHANGE_DRY(tech.cassandre.trading.bot.test.util.junit.configuration.ConfigurationExtension.PARAMETER_EXCHANGE_DRY) TradeDTO(tech.cassandre.trading.bot.dto.trade.TradeDTO) CurrencyPairDTO(tech.cassandre.trading.bot.dto.util.CurrencyPairDTO) PositionDTO(tech.cassandre.trading.bot.dto.position.PositionDTO) BigDecimal(java.math.BigDecimal) Test(org.junit.jupiter.api.Test) SpringBootTest(org.springframework.boot.test.context.SpringBootTest) BaseTest(tech.cassandre.trading.bot.test.util.junit.BaseTest) DisplayName(org.junit.jupiter.api.DisplayName)

Example 3 with CLOSED

use of tech.cassandre.trading.bot.dto.position.PositionStatusDTO.CLOSED in project cassandre-trading-bot by cassandre-tech.

the class PositionTest method checkSavedDataDuringPositionLifecycle.

@Test
@DisplayName("Check saved data during position lifecycle")
public void checkSavedDataDuringPositionLifecycle() {
    // First ticker emitted for dry mode - MANDATORY.
    tickerFlux.emitValue(TickerDTO.builder().currencyPair(ETH_BTC).timestamp(createZonedDateTime(1)).last(new BigDecimal("0.01")).build());
    await().untilAsserted(() -> assertEquals(1, strategy.getTickersUpdatesReceived().size()));
    // =============================================================================================================
    // A position is created on ETH/BTC - ID 6.
    // We buy 1 ETH for 0.01 BTC.
    // Waiting for order DRY_ORDER_000000001.
    final PositionCreationResultDTO positionResult = strategy.createLongPosition(ETH_BTC, new BigDecimal("1"), PositionRulesDTO.builder().stopGainPercentage(// 1 000% max gain.
    1000f).stopLossPercentage(// 100% max lost.
    100f).build());
    assertTrue(positionResult.isSuccessful());
    final long positionId = positionResult.getPosition().getUid();
    // =============================================================================================================
    // Still "OPENING".
    // Two tickers arrived - min and max gain should not be set as the position is still in OPENING status.
    // Check that the position was correctly created.
    // The corresponding order and trade will arrive in few seconds.
    // In the meantime, the position should be in OPENING status.
    await().untilAsserted(() -> assertEquals(OPENING, getPosition(positionId).getStatus()));
    Position p = getPosition(positionId);
    assertEquals(positionId, p.getUid());
    assertEquals(positionId, p.getPositionId());
    assertEquals(LONG, p.getType());
    assertEquals(1, p.getStrategy().getUid());
    assertEquals("01", p.getStrategy().getStrategyId());
    assertEquals(ETH_BTC.toString(), p.getCurrencyPair());
    assertEquals(0, new BigDecimal("1").compareTo(p.getAmount().getValue()));
    assertEquals(ETH_BTC.getBaseCurrency().toString(), p.getAmount().getCurrency());
    assertEquals(1000, p.getStopGainPercentageRule());
    assertEquals(100, p.getStopLossPercentageRule());
    assertEquals(OPENING, p.getStatus());
    assertEquals("DRY_ORDER_000000001", p.getOpeningOrder().getOrderId());
    assertNull(p.getClosingOrder());
    assertNull(p.getClosingOrder());
    assertNull(p.getLowestGainPrice());
    assertNull(p.getHighestGainPrice());
    ZonedDateTime createdOn = p.getCreatedOn();
    ZonedDateTime updatedON = p.getUpdatedOn();
    assertNotNull(createdOn);
    assertNotNull(updatedON);
    // We should have one more position and one more trade in database.
    await().untilAsserted(() -> assertEquals(6, positionRepository.count()));
    // =============================================================================================================
    // The position should now be OPENED.
    // We are in dry mode, we wait for order and trade to arrive, position will now be opened.
    await().untilAsserted(() -> {
        orderFlux.update();
        tradeFlux.update();
        assertEquals(OPENED, getPosition(positionId).getStatus());
    });
    // Check the position data in database.
    p = getPosition(positionId);
    assertEquals(positionId, p.getUid());
    assertEquals(positionId, p.getPositionId());
    assertEquals(LONG, p.getType());
    assertEquals(1, p.getStrategy().getUid());
    assertEquals("01", p.getStrategy().getStrategyId());
    assertEquals(ETH_BTC.toString(), p.getCurrencyPair());
    assertEquals(0, new BigDecimal("1").compareTo(p.getAmount().getValue()));
    assertEquals(ETH_BTC.getBaseCurrency().toString(), p.getAmount().getCurrency());
    assertEquals(1000, p.getStopGainPercentageRule());
    assertEquals(100, p.getStopLossPercentageRule());
    assertEquals(OPENED, p.getStatus());
    assertEquals("DRY_ORDER_000000001", p.getOpeningOrder().getOrderId());
    assertFalse(p.getOpeningOrder().getTrades().isEmpty());
    assertTrue(p.getOpeningOrder().getTrades().stream().anyMatch(t -> "DRY_TRADE_000000001".equals(t.getTradeId())));
    assertNull(p.getClosingOrder());
    // =============================================================================================================
    // Now that the position is OPENED, we are sending tickers to see if lowest, highest and latest price change.
    // First ticker arrives (500% gain) - min and max gain should be set to that value.
    tickerFlux.emitValue(TickerDTO.builder().currencyPair(ETH_BTC).last(new BigDecimal("0.06")).build());
    await().untilAsserted(() -> assertNotNull(getPosition(positionId).getLatestGainPrice()));
    await().untilAsserted(() -> assertEquals(0, new BigDecimal("0.06").compareTo(getPosition(positionId).getLatestGainPrice().getValue())));
    // Second ticker arrives (100% gain) - min gain should be set to that value.
    tickerFlux.emitValue(TickerDTO.builder().currencyPair(ETH_BTC).last(new BigDecimal("0.02")).build());
    await().untilAsserted(() -> assertEquals(0, new BigDecimal("0.02").compareTo(getPosition(positionId).getLatestGainPrice().getValue())));
    // Third ticker arrives (200% gain) - nothing should change.
    tickerFlux.emitValue(TickerDTO.builder().currencyPair(ETH_BTC).last(new BigDecimal("0.03")).build());
    await().untilAsserted(() -> assertEquals(0, new BigDecimal("0.03").compareTo(getPosition(positionId).getLatestGainPrice().getValue())));
    // Fourth ticker arrives (50% loss) - min gain should be set to that value.
    tickerFlux.emitValue(TickerDTO.builder().currencyPair(ETH_BTC).last(new BigDecimal("0.005")).build());
    await().untilAsserted(() -> assertEquals(0, new BigDecimal("0.005").compareTo(getPosition(positionId).getLatestGainPrice().getValue())));
    // Fifth ticker arrives (600% gain) - max gain should be set to that value.
    tickerFlux.emitValue(TickerDTO.builder().currencyPair(ETH_BTC).last(new BigDecimal("0.07")).build());
    await().untilAsserted(() -> assertEquals(0, new BigDecimal("0.07").compareTo(getPosition(positionId).getLatestGainPrice().getValue())));
    // Check lowest & highest in database.
    await().untilAsserted(() -> assertEquals(6, strategy.getTickersUpdatesReceived().size()));
    assertTrue(getPositionDTO(positionId).getLowestCalculatedGain().isPresent());
    assertTrue(getPositionDTO(positionId).getHighestCalculatedGain().isPresent());
    assertEquals(0, new BigDecimal("0.005").compareTo(getPositionDTO(positionId).getLowestGainPrice().getValue()));
    assertEquals(ETH_BTC.getQuoteCurrency(), getPositionDTO(positionId).getLowestGainPrice().getCurrency());
    assertEquals(0, new BigDecimal("0.07").compareTo(getPositionDTO(positionId).getHighestGainPrice().getValue()));
    assertEquals(ETH_BTC.getQuoteCurrency(), getPositionDTO(positionId).getHighestGainPrice().getCurrency());
    assertEquals(-50, getPositionDTO(positionId).getLowestCalculatedGain().get().getPercentage());
    assertEquals(600, getPositionDTO(positionId).getHighestCalculatedGain().get().getPercentage());
    // Check that the new data was inserted in database.
    await().untilAsserted(() -> assertEquals(6, positionRepository.count()));
    assertEquals(createdOn, getPosition(positionId).getCreatedOn());
    assertTrue(updatedON.isBefore(getPosition(positionId).getUpdatedOn()));
    // =============================================================================================================
    // The status should now be CLOSING. We are going to receive two trades to close.
    // Closing the trade - min and max should not change.
    PositionDTO pDTO = getPositionDTO(positionId);
    final OrderDTO order2 = OrderDTO.builder().orderId("DRY_ORDER_000000002").type(ASK).strategy(strategyDTO).currencyPair(ETH_BTC).amount(new CurrencyAmountDTO("1", ETH_BTC.getBaseCurrency())).averagePrice(new CurrencyAmountDTO("1.00003", ETH_BTC.getQuoteCurrency())).limitPrice(new CurrencyAmountDTO("1.00005", ETH_BTC.getQuoteCurrency())).leverage("leverage3").status(NEW).cumulativeAmount(new CurrencyAmountDTO("1.00002", ETH_BTC.getBaseCurrency())).userReference("MY_REF_3").timestamp(createZonedDateTime("01-01-2020")).build();
    pDTO.closePositionWithOrder(order2);
    positionFlux.emitValue(pDTO);
    orderFlux.emitValue(order2);
    await().untilAsserted(() -> assertTrue(() -> orderRepository.findByOrderId("DRY_ORDER_000000002").isPresent()));
    positionFlux.emitValue(pDTO);
    // The first close trade arrives, status should not change as it's not the total amount.
    tradeFlux.emitValue(TradeDTO.builder().tradeId("000002").type(ASK).orderId("DRY_ORDER_000000002").currencyPair(ETH_BTC).amount(new CurrencyAmountDTO("0.5", ETH_BTC.getBaseCurrency())).price(new CurrencyAmountDTO("1", ETH_BTC.getQuoteCurrency())).build());
    await().untilAsserted(() -> assertEquals(1, getPositionDTO(positionId).getClosingOrder().getTrades().size()));
    assertEquals(CLOSING, getPositionDTO(positionId).getStatus());
    // The second close trade arrives, status should change as the total of trades quantities equals order quantity.
    tradeFlux.emitValue(TradeDTO.builder().tradeId("000003").type(ASK).orderId("DRY_ORDER_000000002").currencyPair(ETH_BTC).amount(new CurrencyAmountDTO("0.5", ETH_BTC.getBaseCurrency())).price(new CurrencyAmountDTO("1", ETH_BTC.getQuoteCurrency())).build());
    await().untilAsserted(() -> assertEquals(2, getPositionDTO(positionId).getClosingOrder().getTrades().size()));
    await().untilAsserted(() -> assertEquals(CLOSED, getPositionDTO(positionId).getStatus()));
    // =============================================================================================================
    // We should now be CLOSED as we received the two trades.
    // Check saved position.
    await().until(() -> getPosition(positionId).getStatus().equals(CLOSED));
    p = getPosition(positionId);
    assertEquals(positionId, p.getUid());
    assertEquals(positionId, p.getPositionId());
    assertEquals(LONG, p.getType());
    assertEquals(1, p.getStrategy().getUid());
    assertEquals("01", p.getStrategy().getStrategyId());
    assertEquals(ETH_BTC.toString(), p.getCurrencyPair());
    assertEquals(0, new BigDecimal("1").compareTo(p.getAmount().getValue()));
    assertEquals(ETH_BTC.getBaseCurrency().toString(), p.getAmount().getCurrency());
    assertEquals(1000, p.getStopGainPercentageRule());
    assertEquals(100, p.getStopLossPercentageRule());
    assertEquals(CLOSED, p.getStatus());
    assertEquals("DRY_ORDER_000000001", p.getOpeningOrder().getOrderId());
    assertEquals("DRY_ORDER_000000002", p.getClosingOrder().getOrderId());
    assertEquals(1, p.getOpeningOrder().getTrades().size());
    assertEquals(2, p.getClosingOrder().getTrades().size());
    assertTrue(p.getOpeningOrder().getTrades().stream().anyMatch(t -> "DRY_TRADE_000000001".equals(t.getTradeId())));
    assertTrue(p.getClosingOrder().getTrades().stream().anyMatch(t -> "000002".equals(t.getTradeId())));
    assertTrue(p.getClosingOrder().getTrades().stream().anyMatch(t -> "000003".equals(t.getTradeId())));
    assertEquals(0, new BigDecimal("0.005").compareTo(p.getLowestGainPrice().getValue()));
    assertEquals(0, new BigDecimal("0.07").compareTo(p.getHighestGainPrice().getValue()));
    assertEquals(0, new BigDecimal("0.07").compareTo(p.getLatestGainPrice().getValue()));
}
Also used : DirtiesContext(org.springframework.test.annotation.DirtiesContext) ASK(tech.cassandre.trading.bot.dto.trade.OrderTypeDTO.ASK) ZonedDateTime(java.time.ZonedDateTime) BEFORE_EACH_TEST_METHOD(org.springframework.test.annotation.DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) Position(tech.cassandre.trading.bot.domain.Position) Autowired(org.springframework.beans.factory.annotation.Autowired) ActiveProfiles(org.springframework.test.context.ActiveProfiles) CurrencyAmountDTO(tech.cassandre.trading.bot.dto.util.CurrencyAmountDTO) BigDecimal(java.math.BigDecimal) TradeFlux(tech.cassandre.trading.bot.batch.TradeFlux) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) USDT(tech.cassandre.trading.bot.dto.util.CurrencyDTO.USDT) OrderFlux(tech.cassandre.trading.bot.batch.OrderFlux) NEW(tech.cassandre.trading.bot.dto.trade.OrderStatusDTO.NEW) OPENED(tech.cassandre.trading.bot.dto.position.PositionStatusDTO.OPENED) ETH(tech.cassandre.trading.bot.dto.util.CurrencyDTO.ETH) PositionDTO(tech.cassandre.trading.bot.dto.position.PositionDTO) Awaitility.await(org.awaitility.Awaitility.await) USD(tech.cassandre.trading.bot.dto.util.CurrencyDTO.USD) PositionRepository(tech.cassandre.trading.bot.repository.PositionRepository) PositionService(tech.cassandre.trading.bot.service.PositionService) TickerFlux(tech.cassandre.trading.bot.batch.TickerFlux) TradeDTO(tech.cassandre.trading.bot.dto.trade.TradeDTO) OrderDTO(tech.cassandre.trading.bot.dto.trade.OrderDTO) Test(org.junit.jupiter.api.Test) PositionCreationResultDTO(tech.cassandre.trading.bot.dto.position.PositionCreationResultDTO) OrderRepository(tech.cassandre.trading.bot.repository.OrderRepository) SpringBootTest(org.springframework.boot.test.context.SpringBootTest) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) Optional(java.util.Optional) TickerDTO(tech.cassandre.trading.bot.dto.market.TickerDTO) Property(tech.cassandre.trading.bot.test.util.junit.configuration.Property) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) CLOSED(tech.cassandre.trading.bot.dto.position.PositionStatusDTO.CLOSED) PositionException(tech.cassandre.trading.bot.util.exception.PositionException) LONG(tech.cassandre.trading.bot.dto.position.PositionTypeDTO.LONG) BaseTest(tech.cassandre.trading.bot.test.util.junit.BaseTest) TestableCassandreStrategy(tech.cassandre.trading.bot.test.util.strategies.TestableCassandreStrategy) OPENING(tech.cassandre.trading.bot.dto.position.PositionStatusDTO.OPENING) PositionFlux(tech.cassandre.trading.bot.batch.PositionFlux) BTC(tech.cassandre.trading.bot.dto.util.CurrencyDTO.BTC) CurrencyPairDTO(tech.cassandre.trading.bot.dto.util.CurrencyPairDTO) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Configuration(tech.cassandre.trading.bot.test.util.junit.configuration.Configuration) Iterator(java.util.Iterator) CLOSING(tech.cassandre.trading.bot.dto.position.PositionStatusDTO.CLOSING) DisplayName(org.junit.jupiter.api.DisplayName) PositionRulesDTO(tech.cassandre.trading.bot.dto.position.PositionRulesDTO) PARAMETER_EXCHANGE_DRY(tech.cassandre.trading.bot.test.util.junit.configuration.ConfigurationExtension.PARAMETER_EXCHANGE_DRY) PositionCreationResultDTO(tech.cassandre.trading.bot.dto.position.PositionCreationResultDTO) CurrencyAmountDTO(tech.cassandre.trading.bot.dto.util.CurrencyAmountDTO) Position(tech.cassandre.trading.bot.domain.Position) ZonedDateTime(java.time.ZonedDateTime) OrderDTO(tech.cassandre.trading.bot.dto.trade.OrderDTO) BigDecimal(java.math.BigDecimal) PositionDTO(tech.cassandre.trading.bot.dto.position.PositionDTO) Test(org.junit.jupiter.api.Test) SpringBootTest(org.springframework.boot.test.context.SpringBootTest) BaseTest(tech.cassandre.trading.bot.test.util.junit.BaseTest) DisplayName(org.junit.jupiter.api.DisplayName)

Example 4 with CLOSED

use of tech.cassandre.trading.bot.dto.position.PositionStatusDTO.CLOSED in project cassandre-trading-bot by cassandre-tech.

the class PositionRepositoryTest method checkImportedPositions.

@Test
@DisplayName("Check imported data")
public void checkImportedPositions() {
    // Positions.
    final Iterator<Position> positions = positionRepository.findByOrderByUid().iterator();
    assertEquals(5, positionRepository.count());
    // Position 1.
    Position position1 = positions.next();
    assertEquals(1, position1.getUid());
    assertEquals(1, position1.getPositionId());
    assertEquals(LONG, position1.getType());
    assertNotNull(position1.getStrategy());
    assertEquals(1, position1.getStrategy().getUid());
    assertEquals("01", position1.getStrategy().getStrategyId());
    assertEquals("BTC/USDT", position1.getCurrencyPair());
    assertEquals(0, new BigDecimal("10").compareTo(position1.getAmount().getValue()));
    assertEquals("BTC", position1.getAmount().getCurrency());
    assertNull(position1.getStopGainPercentageRule());
    assertNull(position1.getStopLossPercentageRule());
    assertEquals(OPENING, position1.getStatus());
    assertFalse(position1.isForceClosing());
    assertEquals("BACKUP_OPENING_ORDER_01", position1.getOpeningOrder().getOrderId());
    assertTrue(position1.getOpeningOrder().getTrades().isEmpty());
    assertNull(position1.getClosingOrder());
    assertNull(position1.getLowestGainPrice());
    assertNull(position1.getHighestGainPrice());
    assertNull(position1.getLatestGainPrice());
    // Retrieving position 1 with findByPositionId().
    Optional<Position> position1Bis = positionRepository.findByPositionId(1L);
    assertTrue(position1Bis.isPresent());
    assertEquals(position1, position1Bis.get());
    // Position 2.
    Position position2 = positions.next();
    assertEquals(2, position2.getUid());
    assertEquals(2, position2.getPositionId());
    assertEquals(LONG, position2.getType());
    assertNotNull(position2.getStrategy());
    assertEquals(1, position2.getStrategy().getUid());
    assertEquals("01", position2.getStrategy().getStrategyId());
    assertEquals("BTC/USDT", position2.getCurrencyPair());
    assertEquals(0, new BigDecimal("20").compareTo(position2.getAmount().getValue()));
    assertEquals("BTC", position2.getAmount().getCurrency());
    assertEquals(10, position2.getStopGainPercentageRule());
    assertNull(position2.getStopLossPercentageRule());
    assertEquals(OPENED, position2.getStatus());
    assertFalse(position2.isForceClosing());
    assertEquals("BACKUP_OPENING_ORDER_02", position2.getOpeningOrder().getOrderId());
    assertTrue(position2.getOpeningOrder().getTrades().stream().anyMatch(trade -> "BACKUP_TRADE_01".equals(trade.getTradeId())));
    assertNull(position2.getClosingOrder());
    assertEquals(0, new BigDecimal("1").compareTo(position2.getLowestGainPrice().getValue()));
    assertEquals("USDT", position2.getLowestGainPrice().getCurrency());
    assertEquals(0, new BigDecimal("2").compareTo(position2.getHighestGainPrice().getValue()));
    assertEquals("USDT", position2.getHighestGainPrice().getCurrency());
    assertEquals(0, new BigDecimal("3").compareTo(position2.getLatestGainPrice().getValue()));
    assertEquals("USDT", position2.getLatestGainPrice().getCurrency());
    // Retrieving position 2 with findByPositionId().
    Optional<Position> position2Bis = positionRepository.findByPositionId(2L);
    assertTrue(position2Bis.isPresent());
    assertEquals(position2, position2Bis.get());
    // Position 3.
    Position position3 = positions.next();
    assertEquals(3, position3.getUid());
    assertEquals(3, position3.getPositionId());
    assertEquals(LONG, position3.getType());
    assertNotNull(position3.getStrategy());
    assertEquals(1, position3.getStrategy().getUid());
    assertEquals("01", position3.getStrategy().getStrategyId());
    assertEquals("BTC/USDT", position3.getCurrencyPair());
    assertEquals(0, new BigDecimal("30").compareTo(position3.getAmount().getValue()));
    assertEquals("BTC", position3.getAmount().getCurrency());
    assertNull(position3.getStopGainPercentageRule());
    assertEquals(20, position3.getStopLossPercentageRule());
    assertEquals(CLOSING, position3.getStatus());
    assertFalse(position3.isForceClosing());
    assertEquals("BACKUP_OPENING_ORDER_03", position3.getOpeningOrder().getOrderId());
    assertEquals(1, position3.getOpeningOrder().getTrades().size());
    assertTrue(position3.getOpeningOrder().getTrades().stream().anyMatch(trade -> "BACKUP_TRADE_02".equals(trade.getTradeId())));
    assertEquals("BACKUP_CLOSING_ORDER_01", position3.getClosingOrder().getOrderId());
    assertEquals(1, position3.getClosingOrder().getTrades().size());
    assertTrue(position3.getClosingOrder().getTrades().stream().anyMatch(trade -> "BACKUP_TRADE_04".equals(trade.getTradeId())));
    assertEquals(0, new BigDecimal("17").compareTo(position3.getLowestGainPrice().getValue()));
    assertEquals("USDT", position3.getLowestGainPrice().getCurrency());
    assertEquals(0, new BigDecimal("68").compareTo(position3.getHighestGainPrice().getValue()));
    assertEquals("USDT", position3.getHighestGainPrice().getCurrency());
    assertEquals(0, new BigDecimal("92").compareTo(position3.getLatestGainPrice().getValue()));
    assertEquals("USDT", position3.getLatestGainPrice().getCurrency());
    // Retrieving position 3 with findByPositionId().
    Optional<Position> position3Bis = positionRepository.findByPositionId(3L);
    assertTrue(position3Bis.isPresent());
    assertEquals(position3, position3Bis.get());
    // Position 4.
    Position position4 = positions.next();
    assertEquals(4, position4.getUid());
    assertEquals(4, position4.getPositionId());
    assertEquals(LONG, position4.getType());
    assertNotNull(position4.getStrategy());
    assertEquals(1, position4.getStrategy().getUid());
    assertEquals("01", position4.getStrategy().getStrategyId());
    assertEquals("BTC/USDT", position4.getCurrencyPair());
    assertEquals(0, new BigDecimal("40").compareTo(position4.getAmount().getValue()));
    assertEquals("BTC", position4.getAmount().getCurrency());
    assertEquals(30, position4.getStopGainPercentageRule());
    assertEquals(40, position4.getStopLossPercentageRule());
    assertEquals(CLOSED, position4.getStatus());
    assertFalse(position4.isForceClosing());
    assertEquals("BACKUP_OPENING_ORDER_04", position4.getOpeningOrder().getOrderId());
    assertEquals(1, position4.getOpeningOrder().getTrades().size());
    assertTrue(position4.getOpeningOrder().getTrades().stream().anyMatch(trade -> "BACKUP_TRADE_03".equals(trade.getTradeId())));
    assertEquals("BACKUP_CLOSING_ORDER_02", position4.getClosingOrder().getOrderId());
    assertEquals(1, position4.getClosingOrder().getTrades().size());
    assertTrue(position4.getClosingOrder().getTrades().stream().anyMatch(trade -> "BACKUP_TRADE_05".equals(trade.getTradeId())));
    assertEquals(0, new BigDecimal("17").compareTo(position4.getLowestGainPrice().getValue()));
    assertEquals("USDT", position4.getLowestGainPrice().getCurrency());
    assertEquals(0, new BigDecimal("68").compareTo(position4.getHighestGainPrice().getValue()));
    assertEquals("USDT", position4.getLowestGainPrice().getCurrency());
    assertEquals(0, new BigDecimal("93").compareTo(position4.getLatestGainPrice().getValue()));
    assertEquals("USDT", position4.getLowestGainPrice().getCurrency());
    // Retrieving position 4 with findByPositionId().
    Optional<Position> position4Bis = positionRepository.findByPositionId(4L);
    assertTrue(position4Bis.isPresent());
    assertEquals(position4, position4Bis.get());
    // Test last position id retrieval.
    assertEquals(5, positionRepository.getLastPositionIdUsedByStrategy(1L));
    assertEquals(0, positionRepository.getLastPositionIdUsedByStrategy(9L));
}
Also used : DirtiesContext(org.springframework.test.annotation.DirtiesContext) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) BEFORE_EACH_TEST_METHOD(org.springframework.test.annotation.DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) Position(tech.cassandre.trading.bot.domain.Position) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) CLOSED(tech.cassandre.trading.bot.dto.position.PositionStatusDTO.CLOSED) Autowired(org.springframework.beans.factory.annotation.Autowired) ActiveProfiles(org.springframework.test.context.ActiveProfiles) LONG(tech.cassandre.trading.bot.dto.position.PositionTypeDTO.LONG) BigDecimal(java.math.BigDecimal) OPENING(tech.cassandre.trading.bot.dto.position.PositionStatusDTO.OPENING) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) OPENED(tech.cassandre.trading.bot.dto.position.PositionStatusDTO.OPENED) Configuration(tech.cassandre.trading.bot.test.util.junit.configuration.Configuration) Iterator(java.util.Iterator) PositionRepository(tech.cassandre.trading.bot.repository.PositionRepository) CLOSING(tech.cassandre.trading.bot.dto.position.PositionStatusDTO.CLOSING) DisplayName(org.junit.jupiter.api.DisplayName) Test(org.junit.jupiter.api.Test) List(java.util.List) Stream(java.util.stream.Stream) SpringBootTest(org.springframework.boot.test.context.SpringBootTest) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) Optional(java.util.Optional) Property(tech.cassandre.trading.bot.test.util.junit.configuration.Property) Position(tech.cassandre.trading.bot.domain.Position) BigDecimal(java.math.BigDecimal) Test(org.junit.jupiter.api.Test) SpringBootTest(org.springframework.boot.test.context.SpringBootTest) DisplayName(org.junit.jupiter.api.DisplayName)

Example 5 with CLOSED

use of tech.cassandre.trading.bot.dto.position.PositionStatusDTO.CLOSED in project cassandre-trading-bot by cassandre-tech.

the class PositionServiceCassandreImplementation method getGains.

@Override
public final HashMap<CurrencyDTO, GainDTO> getGains() {
    HashMap<CurrencyDTO, BigDecimal> totalBefore = new LinkedHashMap<>();
    HashMap<CurrencyDTO, BigDecimal> totalAfter = new LinkedHashMap<>();
    List<CurrencyAmountDTO> totalFees = new LinkedList<>();
    List<CurrencyAmountDTO> openingOrdersFees = new LinkedList<>();
    List<CurrencyAmountDTO> closingOrdersFees = new LinkedList<>();
    HashMap<CurrencyDTO, GainDTO> gains = new LinkedHashMap<>();
    // We calculate, by currency, the amount bought & sold.
    positionRepository.findByStatus(CLOSED).stream().map(POSITION_MAPPER::mapToPositionDTO).forEach(p -> {
        // We retrieve the currency and initiate the maps if they are empty
        CurrencyDTO currency;
        if (p.getType() == LONG) {
            // LONG.
            currency = p.getCurrencyPair().getQuoteCurrency();
        } else {
            // SHORT.
            currency = p.getCurrencyPair().getBaseCurrency();
        }
        gains.putIfAbsent(currency, null);
        totalBefore.putIfAbsent(currency, ZERO);
        totalAfter.putIfAbsent(currency, ZERO);
        // We calculate the amounts bought and amount sold.
        if (p.getType() == LONG) {
            totalBefore.put(currency, p.getOpeningOrder().getTrades().stream().map(t -> t.getAmountValue().multiply(t.getPriceValue())).reduce(totalBefore.get(currency), BigDecimal::add));
            totalAfter.put(currency, p.getClosingOrder().getTrades().stream().map(t -> t.getAmountValue().multiply(t.getPriceValue())).reduce(totalAfter.get(currency), BigDecimal::add));
        } else {
            totalBefore.put(currency, p.getOpeningOrder().getTrades().stream().map(TradeDTO::getAmountValue).reduce(totalBefore.get(currency), BigDecimal::add));
            totalAfter.put(currency, p.getClosingOrder().getTrades().stream().map(TradeDTO::getAmountValue).reduce(totalAfter.get(currency), BigDecimal::add));
        }
        // And now the fees.
        Stream.concat(p.getOpeningOrder().getTrades().stream(), p.getClosingOrder().getTrades().stream()).filter(tradeDTO -> tradeDTO.getFee() != null).forEach(tradeDTO -> totalFees.add(tradeDTO.getFee()));
        p.getOpeningOrder().getTrades().stream().filter(tradeDTO -> tradeDTO.getFee() != null).forEach(tradeDTO -> openingOrdersFees.add(tradeDTO.getFee()));
        p.getClosingOrder().getTrades().stream().filter(tradeDTO -> tradeDTO.getFee() != null).forEach(tradeDTO -> closingOrdersFees.add(tradeDTO.getFee()));
    });
    gains.keySet().forEach(currency -> {
        // We make the calculation.
        BigDecimal before = totalBefore.get(currency);
        BigDecimal after = totalAfter.get(currency);
        BigDecimal gainAmount = after.subtract(before);
        BigDecimal gainPercentage = ((after.subtract(before)).divide(before, HALF_UP)).multiply(new BigDecimal("100"));
        // We calculate the fees for the currency.
        final BigDecimal fees = totalFees.stream().filter(Objects::nonNull).filter(amount -> amount.getCurrency().equals(currency)).map(CurrencyAmountDTO::getValue).reduce(ZERO, BigDecimal::add);
        GainDTO g = GainDTO.builder().percentage(gainPercentage.setScale(2, HALF_UP).doubleValue()).amount(CurrencyAmountDTO.builder().value(gainAmount).currency(currency).build()).fees(CurrencyAmountDTO.builder().value(fees).currency(currency).build()).openingOrderFees(openingOrdersFees).closingOrderFees(closingOrdersFees).build();
        gains.put(currency, g);
    });
    return gains;
}
Also used : Arrays(java.util.Arrays) RequiredArgsConstructor(lombok.RequiredArgsConstructor) Position(tech.cassandre.trading.bot.domain.Position) CLOSED(tech.cassandre.trading.bot.dto.position.PositionStatusDTO.CLOSED) HashMap(java.util.HashMap) CurrencyAmountDTO(tech.cassandre.trading.bot.dto.util.CurrencyAmountDTO) LONG(tech.cassandre.trading.bot.dto.position.PositionTypeDTO.LONG) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) BigDecimal(java.math.BigDecimal) OPENING(tech.cassandre.trading.bot.dto.position.PositionStatusDTO.OPENING) PositionFlux(tech.cassandre.trading.bot.batch.PositionFlux) Locale(java.util.Locale) Map(java.util.Map) CurrencyPairDTO(tech.cassandre.trading.bot.dto.util.CurrencyPairDTO) SHORT(tech.cassandre.trading.bot.dto.position.PositionTypeDTO.SHORT) LinkedList(java.util.LinkedList) FLOOR(java.math.RoundingMode.FLOOR) LinkedHashSet(java.util.LinkedHashSet) OPENED(tech.cassandre.trading.bot.dto.position.PositionStatusDTO.OPENED) PositionDTO(tech.cassandre.trading.bot.dto.position.PositionDTO) CurrencyDTO(tech.cassandre.trading.bot.dto.util.CurrencyDTO) PositionRepository(tech.cassandre.trading.bot.repository.PositionRepository) HALF_UP(java.math.RoundingMode.HALF_UP) GainDTO(tech.cassandre.trading.bot.dto.util.GainDTO) Set(java.util.Set) ZERO(java.math.BigDecimal.ZERO) TradeDTO(tech.cassandre.trading.bot.dto.trade.TradeDTO) Collectors(java.util.stream.Collectors) PositionCreationResultDTO(tech.cassandre.trading.bot.dto.position.PositionCreationResultDTO) Objects(java.util.Objects) PositionTypeDTO(tech.cassandre.trading.bot.dto.position.PositionTypeDTO) List(java.util.List) PositionRulesDTO(tech.cassandre.trading.bot.dto.position.PositionRulesDTO) GenericCassandreStrategy(tech.cassandre.trading.bot.strategy.GenericCassandreStrategy) Stream(java.util.stream.Stream) BaseService(tech.cassandre.trading.bot.util.base.service.BaseService) OrderCreationResultDTO(tech.cassandre.trading.bot.dto.trade.OrderCreationResultDTO) Optional(java.util.Optional) TickerDTO(tech.cassandre.trading.bot.dto.market.TickerDTO) CurrencyAmountDTO(tech.cassandre.trading.bot.dto.util.CurrencyAmountDTO) TradeDTO(tech.cassandre.trading.bot.dto.trade.TradeDTO) GainDTO(tech.cassandre.trading.bot.dto.util.GainDTO) CurrencyDTO(tech.cassandre.trading.bot.dto.util.CurrencyDTO) BigDecimal(java.math.BigDecimal) LinkedList(java.util.LinkedList) LinkedHashMap(java.util.LinkedHashMap)

Aggregations

BigDecimal (java.math.BigDecimal)7 Optional (java.util.Optional)7 CLOSED (tech.cassandre.trading.bot.dto.position.PositionStatusDTO.CLOSED)7 OPENED (tech.cassandre.trading.bot.dto.position.PositionStatusDTO.OPENED)7 OPENING (tech.cassandre.trading.bot.dto.position.PositionStatusDTO.OPENING)7 LONG (tech.cassandre.trading.bot.dto.position.PositionTypeDTO.LONG)7 TickerDTO (tech.cassandre.trading.bot.dto.market.TickerDTO)6 TradeDTO (tech.cassandre.trading.bot.dto.trade.TradeDTO)6 CurrencyAmountDTO (tech.cassandre.trading.bot.dto.util.CurrencyAmountDTO)6 CurrencyPairDTO (tech.cassandre.trading.bot.dto.util.CurrencyPairDTO)6 List (java.util.List)5 Stream (java.util.stream.Stream)5 Position (tech.cassandre.trading.bot.domain.Position)5 CLOSING (tech.cassandre.trading.bot.dto.position.PositionStatusDTO.CLOSING)5 PositionRepository (tech.cassandre.trading.bot.repository.PositionRepository)5 ZERO (java.math.BigDecimal.ZERO)4 FLOOR (java.math.RoundingMode.FLOOR)4 HALF_UP (java.math.RoundingMode.HALF_UP)4 Locale (java.util.Locale)4 Collectors (java.util.stream.Collectors)4