Search in sources :

Example 1 with AccountDTO

use of tech.cassandre.trading.bot.dto.user.AccountDTO in project cassandre-trading-bot by cassandre-tech.

the class AccountDTOTest method checkEqualToForAccountIdAndName.

@Test
@DisplayName("Check equals() on account id & name")
public void checkEqualToForAccountIdAndName() {
    // Account 1 (null).
    AccountDTO account1 = AccountDTO.builder().accountId(null).name(null).build();
    // Account 2.
    AccountDTO account2 = AccountDTO.builder().accountId("01").name("01").build();
    assertNotEquals(account2, account1);
    assertNotEquals(account1, account2);
    // Account 3 - Same.
    AccountDTO account3 = AccountDTO.builder().accountId("01").name("01").build();
    assertEquals(account2, account3);
    assertEquals(account3, account2);
    // Account 4 - id changed.
    AccountDTO account4 = AccountDTO.builder().accountId("CHANGED").name("01").build();
    assertNotEquals(account2, account4);
    assertNotEquals(account4, account2);
    // Account 5 - Name changed.
    AccountDTO account5 = AccountDTO.builder().accountId("01").name("CHANGED").build();
    assertNotEquals(account2, account5);
    assertNotEquals(account5, account2);
}
Also used : AccountDTO(tech.cassandre.trading.bot.dto.user.AccountDTO) Test(org.junit.jupiter.api.Test) DisplayName(org.junit.jupiter.api.DisplayName)

Example 2 with AccountDTO

use of tech.cassandre.trading.bot.dto.user.AccountDTO in project cassandre-trading-bot by cassandre-tech.

the class UserServiceTest method checkGetUser.

@Test
@Tag("integration")
@DisplayName("Check get user, accounts and balances")
public void checkGetUser() {
    // Expected values.
    final int expectedAccounts = 1;
    final int expectedWalletsInTradingAccount = 2;
    // =============================================================================================================
    // Retrieve the account.
    Optional<UserDTO> user = userService.getUser();
    // =============================================================================================================
    // Testing Account.
    assertTrue(user.isPresent());
    assertNotNull(user.get().getTimestamp());
    assertTrue(user.get().getTimestamp().isAfter(ZonedDateTime.now().minusSeconds(1)));
    assertTrue(user.get().getTimestamp().isBefore(ZonedDateTime.now().plusSeconds(1)));
    // =============================================================================================================
    // Testing wallets.
    assertEquals(expectedAccounts, user.get().getAccounts().size());
    Map<String, AccountDTO> wallets = user.get().getAccounts();
    // AccountDTO mainWallet = wallets.get("main");
    // assertNotNull(mainWallet);
    // assertEquals("main", mainWallet.getAccountId());
    // assertEquals("main", mainWallet.getName());
    // assertEquals(2, mainWallet.getFeatures().size());
    // assertTrue(mainWallet.getFeatures().contains(TRADING));
    // assertTrue(mainWallet.getFeatures().contains(FUNDING));
    AccountDTO tradeWallet = wallets.get("trade");
    assertNotNull(tradeWallet);
    assertEquals("trade", tradeWallet.getAccountId());
    assertEquals("trade", tradeWallet.getName());
    assertEquals(2, tradeWallet.getFeatures().size());
    assertTrue(tradeWallet.getFeatures().contains(TRADING));
    assertTrue(tradeWallet.getFeatures().contains(FUNDING));
    // =============================================================================================================
    // Testing balances.
    assertEquals(expectedWalletsInTradingAccount, tradeWallet.getBalances().size());
    // Existing balances.
    assertTrue(tradeWallet.getBalance("BTC").isPresent());
    assertTrue(tradeWallet.getBalance(BTC).isPresent());
    assertTrue(tradeWallet.getBalance("USDT").isPresent());
    assertTrue(tradeWallet.getBalance(USDT).isPresent());
    // Non-existing balances.
    assertTrue(tradeWallet.getBalance("ANC").isEmpty());
    assertTrue(tradeWallet.getBalance(ANC).isEmpty());
    // Values.
    assertEquals(1, tradeWallet.getBalance("BTC").get().getTotal().compareTo(ZERO));
    assertEquals(1, tradeWallet.getBalance("USDT").get().getTotal().compareTo(ZERO));
}
Also used : UserDTO(tech.cassandre.trading.bot.dto.user.UserDTO) AccountDTO(tech.cassandre.trading.bot.dto.user.AccountDTO) Test(org.junit.jupiter.api.Test) SpringBootTest(org.springframework.boot.test.context.SpringBootTest) DisplayName(org.junit.jupiter.api.DisplayName) Tag(org.junit.jupiter.api.Tag)

Example 3 with AccountDTO

use of tech.cassandre.trading.bot.dto.user.AccountDTO in project cassandre-trading-bot by cassandre-tech.

the class UserServiceTest method checkBalancesUpdate.

@Test
@DisplayName("Check balances updates")
public void checkBalancesUpdate() {
    // We retrieve the account information in the strategy.
    assertTrue(strategy.getAccountsUpdatesReceived().isEmpty());
    accountFlux.update();
    await().untilAsserted(() -> assertEquals(3, strategy.getAccountsUpdatesReceived().size()));
    // =============================================================================================================
    // Received ticker for ETH/BTC - It means 1 ETH can be bought with 0.032661 BTC.
    // last = 0.032661 (Last trade field is the price set during the last trade)
    tickerFlux.emitValue(TickerDTO.builder().currencyPair(ETH_BTC).last(new BigDecimal("0.032666")).bid(new BigDecimal("0.032466")).ask(new BigDecimal("0.032657")).high(new BigDecimal("0.034441")).low(new BigDecimal("0.032355")).volume(new BigDecimal("33794.9795777")).quoteVolume(new BigDecimal("1146.8453384314658")).build());
    await().untilAsserted(() -> assertEquals(1, strategy.getLastTickers().size()));
    // =============================================================================================================
    // Account before buying.
    // Loaded from spring-boot-starter/autoconfigure/src/test/resources/user-trade.csv
    // BTC => 0.99962937
    // ETH => 10
    Optional<UserDTO> user = userService.getUser();
    assertTrue(user.isPresent());
    AccountDTO tradeAccount = user.get().getAccounts().get("trade");
    Optional<BalanceDTO> tradeBTC = tradeAccount.getBalance(BTC);
    assertTrue(tradeBTC.isPresent());
    assertEquals(0, new BigDecimal("0.99962937").compareTo(tradeBTC.get().getAvailable()));
    Optional<BalanceDTO> tradeETH = tradeAccount.getBalance(ETH);
    assertTrue(tradeETH.isPresent());
    assertEquals(0, new BigDecimal("10").compareTo(tradeETH.get().getAvailable()));
    // =============================================================================================================
    // Buying 0.02 ETH for 0.00065332 BTC.
    // Last price from ticker * amount ordered
    // 0.032666 * 0.02 = 0.00065332 BTC
    strategy.createBuyMarketOrder(ETH_BTC, new BigDecimal("0.02"));
    // =============================================================================================================
    // We expect one account update (with the new ETH and BTC balances).
    accountFlux.update();
    await().untilAsserted(() -> assertEquals(4, strategy.getAccountsUpdatesReceived().size()));
    // =============================================================================================================
    // Account after buying (from strategy).
    // BTC => 0.99897605 (previous amount - amount bought = 0.99962937 - 0.00065332)
    // ETH => 10.02 (we bought 0.02)
    tradeAccount = strategy.getAccounts().get("trade");
    assertNotNull(tradeAccount);
    tradeBTC = tradeAccount.getBalance(BTC);
    assertTrue(tradeBTC.isPresent());
    assertEquals(0, new BigDecimal("0.99897605").compareTo(tradeBTC.get().getAvailable()));
    tradeETH = tradeAccount.getBalance(ETH);
    assertTrue(tradeETH.isPresent());
    assertEquals(0, new BigDecimal("10.02").compareTo(tradeETH.get().getAvailable()));
    // =============================================================================================================
    // Account after buying (from user service).
    // BTC => 0.99897605 (previous amount - amount bought = 0.99962937 - 0.00065332)
    // ETH => 10.02
    user = userService.getUser();
    assertTrue(user.isPresent());
    tradeAccount = user.get().getAccounts().get("trade");
    tradeBTC = tradeAccount.getBalance(BTC);
    assertTrue(tradeBTC.isPresent());
    assertEquals(0, new BigDecimal("0.99897605").compareTo(tradeBTC.get().getAvailable()));
    tradeETH = tradeAccount.getBalance(ETH);
    assertTrue(tradeETH.isPresent());
    assertEquals(0, new BigDecimal("10.02").compareTo(tradeETH.get().getAvailable()));
    // =============================================================================================================
    // Testing the trade received.
    // Amount => 0.02
    // Price => 0.032666
    await().untilAsserted(() -> {
        orderFlux.update();
        tradeFlux.update();
        assertEquals(1, tradeRepository.count());
    });
    final Optional<TradeDTO> buyingTrade = tradeRepository.findByTradeId("DRY_TRADE_000000001").map(TRADE_MAPPER::mapToTradeDTO);
    assertTrue(buyingTrade.isPresent());
    assertEquals(BID, buyingTrade.get().getType());
    assertEquals(0, new BigDecimal("0.02").compareTo(buyingTrade.get().getAmount().getValue()));
    assertEquals(ETH, buyingTrade.get().getAmount().getCurrency());
    assertEquals(0, new BigDecimal("0.032666").compareTo(buyingTrade.get().getPrice().getValue()));
    assertEquals(BTC, buyingTrade.get().getPrice().getCurrency());
    // =============================================================================================================
    // Received ticker for ETH/BTC - It means 1 ETH can be bought with 0.032466 BTC.
    // last = 0.032466 (Last trade field is the price set during the last trade)
    tickerFlux.emitValue(TickerDTO.builder().currencyPair(ETH_BTC).last(new BigDecimal("0.032466")).bid(new BigDecimal("0.032466")).ask(new BigDecimal("0.032657")).high(new BigDecimal("0.034441")).low(new BigDecimal("0.032355")).volume(new BigDecimal("33794.9795777")).quoteVolume(new BigDecimal("1146.8453384314658")).build());
    await().untilAsserted(() -> assertEquals(2, strategy.getTickersUpdatesReceived().size()));
    // =============================================================================================================
    // Selling 0.02 ETH.
    // Amount * Last price from ticker
    // 0.02 * 0.032466 = 0.00064932 ETH
    strategy.createSellMarketOrder(ETH_BTC, new BigDecimal("0.02"));
    // =============================================================================================================
    // We expect one account update (with the new ETH and BTC balances).
    accountFlux.update();
    await().untilAsserted(() -> assertEquals(5, strategy.getAccountsUpdatesReceived().size()));
    // =============================================================================================================
    // Account values in strategy should be :
    // BTC => 0.99962537 (previous sold + amount sold = 0.99897605 + 0.00064932)
    // ETH => 10 (0.02 sold)
    tradeAccount = strategy.getAccounts().get("trade");
    assertNotNull(tradeAccount);
    tradeBTC = tradeAccount.getBalance(BTC);
    assertTrue(tradeBTC.isPresent());
    assertEquals(0, new BigDecimal("0.99962537").compareTo(tradeBTC.get().getAvailable()));
    tradeETH = tradeAccount.getBalance(ETH);
    assertTrue(tradeETH.isPresent());
    assertEquals(0, new BigDecimal("10").compareTo(tradeETH.get().getAvailable()));
    // =============================================================================================================
    // Testing the trade.
    // Amount => 0.02
    // Price => 0.032466
    await().untilAsserted(() -> {
        orderFlux.update();
        tradeFlux.update();
        assertEquals(2, tradeRepository.count());
    });
    final Optional<TradeDTO> sellingTrade = tradeRepository.findByTradeId("DRY_TRADE_000000002").map(TRADE_MAPPER::mapToTradeDTO);
    assertTrue(sellingTrade.isPresent());
    assertEquals(ASK, sellingTrade.get().getType());
    assertEquals(0, new BigDecimal("0.02").compareTo(sellingTrade.get().getAmount().getValue()));
    assertEquals(ETH, sellingTrade.get().getAmount().getCurrency());
    assertEquals(0, new BigDecimal("0.032466").compareTo(sellingTrade.get().getPrice().getValue()));
}
Also used : TradeDTO(tech.cassandre.trading.bot.dto.trade.TradeDTO) UserDTO(tech.cassandre.trading.bot.dto.user.UserDTO) BalanceDTO(tech.cassandre.trading.bot.dto.user.BalanceDTO) AccountDTO(tech.cassandre.trading.bot.dto.user.AccountDTO) BigDecimal(java.math.BigDecimal) BaseTest(tech.cassandre.trading.bot.test.util.junit.BaseTest) Test(org.junit.jupiter.api.Test) SpringBootTest(org.springframework.boot.test.context.SpringBootTest) DisplayName(org.junit.jupiter.api.DisplayName)

Example 4 with AccountDTO

use of tech.cassandre.trading.bot.dto.user.AccountDTO in project cassandre-trading-bot by cassandre-tech.

the class UserServiceTest method checkImportUserAccounts.

@Test
@DisplayName("Check imported user accounts")
public void checkImportUserAccounts() {
    assertTrue(strategy.getConfiguration().isDryMode());
    // Retrieve user.
    final Optional<UserDTO> user = userService.getUser();
    assertTrue(user.isPresent());
    assertEquals(3, user.get().getAccounts().size());
    // =============================================================================================================
    // In dry mode, Cassandre simulates your accounts by loading files starting with "user-" and ending with "*sv".
    // Main account.
    // Loaded from spring-boot-starter/autoconfigure/src/test/resources/user-main.tsv
    final AccountDTO mainAccount = user.get().getAccounts().get("main");
    assertEquals("main", mainAccount.getAccountId());
    assertEquals("main", mainAccount.getName());
    assertEquals(1, mainAccount.getBalances().size());
    Optional<BalanceDTO> mainBTC = mainAccount.getBalance(BTC);
    assertTrue(mainBTC.isPresent());
    assertEquals(0, new BigDecimal("99.0001").compareTo(mainBTC.get().getAvailable()));
    // Trade account.
    // Loaded from spring-boot-starter/autoconfigure/src/test/resources/user-trade.csv
    final AccountDTO tradeAccount = user.get().getAccounts().get("trade");
    assertEquals("trade", tradeAccount.getAccountId());
    assertEquals("trade", tradeAccount.getName());
    assertEquals(3, tradeAccount.getBalances().size());
    Optional<BalanceDTO> tradeBTC = tradeAccount.getBalance(BTC);
    assertTrue(tradeBTC.isPresent());
    assertEquals(0, new BigDecimal("0.99962937").compareTo(tradeBTC.get().getAvailable()));
    Optional<BalanceDTO> tradeUSDT = tradeAccount.getBalance(USDT);
    assertTrue(tradeUSDT.isPresent());
    assertEquals(0, new BigDecimal("1000").compareTo(tradeUSDT.get().getAvailable()));
    Optional<BalanceDTO> tradeETH = tradeAccount.getBalance(ETH);
    assertTrue(tradeETH.isPresent());
    assertEquals(0, new BigDecimal("10").compareTo(tradeETH.get().getAvailable()));
    // Savings account.
    // Loaded from: spring-boot-starter/autoconfigure/src/test/resources/user-savings.csv
    final AccountDTO savingsAccount = user.get().getAccounts().get("savings");
    assertEquals("savings", savingsAccount.getAccountId());
    assertEquals("savings", savingsAccount.getName());
    assertEquals(3, savingsAccount.getBalances().size());
    Optional<BalanceDTO> savingsBTC = savingsAccount.getBalance(BTC);
    assertTrue(savingsBTC.isPresent());
    assertEquals(0, new BigDecimal("1.1").compareTo(savingsBTC.get().getAvailable()));
    Optional<BalanceDTO> savingsUSDT = savingsAccount.getBalance(USDT);
    assertTrue(savingsUSDT.isPresent());
    assertEquals(0, new BigDecimal("2.2").compareTo(savingsUSDT.get().getAvailable()));
    Optional<BalanceDTO> savingsETH = savingsAccount.getBalance(ETH);
    assertTrue(savingsETH.isPresent());
    assertEquals(0, new BigDecimal("3.3").compareTo(savingsETH.get().getAvailable()));
}
Also used : UserDTO(tech.cassandre.trading.bot.dto.user.UserDTO) BalanceDTO(tech.cassandre.trading.bot.dto.user.BalanceDTO) AccountDTO(tech.cassandre.trading.bot.dto.user.AccountDTO) BigDecimal(java.math.BigDecimal) BaseTest(tech.cassandre.trading.bot.test.util.junit.BaseTest) Test(org.junit.jupiter.api.Test) SpringBootTest(org.springframework.boot.test.context.SpringBootTest) DisplayName(org.junit.jupiter.api.DisplayName)

Example 5 with AccountDTO

use of tech.cassandre.trading.bot.dto.user.AccountDTO in project cassandre-trading-bot by cassandre-tech.

the class MultipleStrategiesTest method checkMultipleStrategyBehavior.

@Test
@DisplayName("Check multiple strategies behavior with dry mode")
public void checkMultipleStrategyBehavior() {
    // ==============================================================================================================
    // Strategies tested.
    // Strategy 1 - Requesting BTC/USDT.
    // Strategy 2 - Requesting BTC/ETH.
    // Strategy 3 - Requesting BTC/USDT & ETH/USDT.
    // ==============================================================================================================
    // Checking the MarketService have all the currency pairs.
    final Set<CurrencyPairDTO> availableCurrencyPairs = exchangeService.getAvailableCurrencyPairs();
    assertEquals(3, availableCurrencyPairs.size());
    assertTrue(availableCurrencyPairs.contains(BTC_USDT));
    assertTrue(availableCurrencyPairs.contains(BTC_ETH));
    assertTrue(availableCurrencyPairs.contains(ETH_USDT));
    // ==============================================================================================================
    // Checking the three strategies is stored in the database.
    assertEquals(3, strategyRepository.count());
    final Optional<Strategy> s1 = strategyRepository.findByStrategyId("01");
    assertTrue(s1.isPresent());
    assertEquals(1, s1.get().getUid());
    assertEquals("01", s1.get().getStrategyId());
    assertEquals("Strategy 1", s1.get().getName());
    final Optional<Strategy> s2 = strategyRepository.findByStrategyId("02");
    assertTrue(s2.isPresent());
    assertEquals(2, s2.get().getUid());
    assertEquals("02", s2.get().getStrategyId());
    assertEquals("Strategy 2", s2.get().getName());
    final Optional<Strategy> s3 = strategyRepository.findByStrategyId("03");
    assertTrue(s3.isPresent());
    assertEquals(3, s3.get().getUid());
    assertEquals("03", s3.get().getStrategyId());
    assertEquals("Strategy 3", s3.get().getName());
    // ==============================================================================================================
    // Check balances on each strategy & onAccountUpdate(), we should have the same values in all strategies.
    // As we are in dry mode, balances are loaded from:
    // spring-boot-starter/autoconfigure/src/test/resources/user-main.csv
    // spring-boot-starter/autoconfigure/src/test/resources/user-trade.csv
    // spring-boot-starter/autoconfigure/src/test/resources/user-savings.csv
    accountFlux.update();
    await().untilAsserted(() -> assertEquals(3, strategy3.getAccountsUpdatesReceived().size()));
    // Strategy 1 accounts data test.
    Map<String, AccountDTO> strategy1Accounts = strategy1.getAccounts();
    Optional<AccountDTO> strategy1TradeAccount = strategy1.getTradeAccount();
    assertEquals(3, strategy1Accounts.size());
    assertTrue(strategy1Accounts.containsKey("main"));
    assertTrue(strategy1Accounts.containsKey("trade"));
    assertTrue(strategy1Accounts.containsKey("savings"));
    assertTrue(strategy1TradeAccount.isPresent());
    assertEquals("trade", strategy1TradeAccount.get().getName());
    assertEquals(3, strategy1TradeAccount.get().getBalances().size());
    assertEquals(3, strategy1TradeAccount.get().getBalances().size());
    assertTrue(strategy1TradeAccount.get().getBalance(BTC).isPresent());
    assertEquals(0, new BigDecimal("0.99962937").compareTo(strategy1TradeAccount.get().getBalance(BTC).get().getAvailable()));
    assertTrue(strategy1TradeAccount.get().getBalance(USDT).isPresent());
    assertEquals(0, new BigDecimal("1000").compareTo(strategy1TradeAccount.get().getBalance(USDT).get().getAvailable()));
    assertTrue(strategy1TradeAccount.get().getBalance(ETH).isPresent());
    assertEquals(0, new BigDecimal("10").compareTo(strategy1TradeAccount.get().getBalance(ETH).get().getAvailable()));
    // Strategy 2 accounts data test.
    Map<String, AccountDTO> strategy2Accounts = strategy2.getAccounts();
    Optional<AccountDTO> strategy2TradeAccount = strategy2.getTradeAccount();
    assertEquals(3, strategy2Accounts.size());
    assertTrue(strategy2Accounts.containsKey("main"));
    assertTrue(strategy2Accounts.containsKey("trade"));
    assertTrue(strategy2Accounts.containsKey("savings"));
    assertTrue(strategy2TradeAccount.isPresent());
    assertEquals("trade", strategy2TradeAccount.get().getName());
    assertEquals(3, strategy2TradeAccount.get().getBalances().size());
    assertTrue(strategy2TradeAccount.get().getBalance(BTC).isPresent());
    assertEquals(0, new BigDecimal("0.99962937").compareTo(strategy2TradeAccount.get().getBalance(BTC).get().getAvailable()));
    assertTrue(strategy2TradeAccount.get().getBalance(USDT).isPresent());
    assertEquals(0, new BigDecimal("1000").compareTo(strategy2TradeAccount.get().getBalance(USDT).get().getAvailable()));
    assertTrue(strategy2TradeAccount.get().getBalance(ETH).isPresent());
    assertEquals(0, new BigDecimal("10").compareTo(strategy2TradeAccount.get().getBalance(ETH).get().getAvailable()));
    // Strategy 3 accounts data test.
    Map<String, AccountDTO> strategy3Accounts = strategy3.getAccounts();
    Optional<AccountDTO> strategy3TradeAccount = strategy3.getTradeAccount();
    assertEquals(3, strategy3Accounts.size());
    assertTrue(strategy3Accounts.containsKey("main"));
    assertTrue(strategy3Accounts.containsKey("trade"));
    assertTrue(strategy3Accounts.containsKey("savings"));
    assertTrue(strategy3TradeAccount.isPresent());
    assertEquals("trade", strategy3TradeAccount.get().getName());
    assertEquals(3, strategy3TradeAccount.get().getBalances().size());
    assertTrue(strategy3TradeAccount.get().getBalance(BTC).isPresent());
    assertEquals(0, new BigDecimal("0.99962937").compareTo(strategy3TradeAccount.get().getBalance(BTC).get().getAvailable()));
    assertTrue(strategy3TradeAccount.get().getBalance(USDT).isPresent());
    assertEquals(0, new BigDecimal("1000").compareTo(strategy3TradeAccount.get().getBalance(USDT).get().getAvailable()));
    assertTrue(strategy3TradeAccount.get().getBalance(ETH).isPresent());
    assertEquals(0, new BigDecimal("10").compareTo(strategy3TradeAccount.get().getBalance(ETH).get().getAvailable()));
    // ==============================================================================================================
    // Emitting tickers and checking received tickers by strategies.
    // Sending BTC/USDT - BTC/ETH - ETH/USDT.
    // Strategy 1 - Requesting BTC/USDT should receive one ticker - 1 BTC costs 50 000 USDT.
    // Strategy 2 - Requesting BTC/ETH should receive one ticker - 1 BTC costs 25 ETH.
    // Strategy 3 - Requesting BTC/USDT & ETH/USDT should receive two tickers - 1 ETH costs 2000 USDT.
    tickerFlux.emitValue(TickerDTO.builder().currencyPair(BTC_USDT).last(new BigDecimal("50000")).build());
    tickerFlux.emitValue(TickerDTO.builder().currencyPair(BTC_ETH).last(new BigDecimal("25")).build());
    tickerFlux.emitValue(TickerDTO.builder().currencyPair(ETH_USDT).last(new BigDecimal("2000")).build());
    await().untilAsserted(() -> assertEquals(2, strategy3.getTickersUpdatesReceived().size()));
    // Strategy 1.
    assertEquals(1, strategy1.getTickersUpdatesReceived().size());
    final TickerDTO strategy1Ticker1 = strategy1.getTickersUpdatesReceived().get(0);
    assertNotNull(strategy1Ticker1);
    assertEquals(BTC_USDT, strategy1Ticker1.getCurrencyPair());
    assertEquals(0, new BigDecimal("50000").compareTo(strategy1Ticker1.getLast()));
    // Strategy 2.
    assertEquals(1, strategy2.getTickersUpdatesReceived().size());
    final TickerDTO strategy2Ticker1 = strategy2.getTickersUpdatesReceived().get(0);
    assertNotNull(strategy2Ticker1);
    assertEquals(BTC_ETH, strategy2Ticker1.getCurrencyPair());
    assertEquals(0, new BigDecimal("25").compareTo(strategy2Ticker1.getLast()));
    // Strategy 3.
    assertEquals(2, strategy3.getTickersUpdatesReceived().size());
    final TickerDTO strategy3Ticker1 = strategy3.getTickersUpdatesReceived().get(0);
    assertNotNull(strategy3Ticker1);
    assertEquals(BTC_USDT, strategy3Ticker1.getCurrencyPair());
    assertEquals(0, new BigDecimal("50000").compareTo(strategy3Ticker1.getLast()));
    final TickerDTO strategy3Ticker2 = strategy3.getTickersUpdatesReceived().get(1);
    assertNotNull(strategy3Ticker2);
    assertEquals(ETH_USDT, strategy3Ticker2.getCurrencyPair());
    assertEquals(0, new BigDecimal("2000").compareTo(strategy3Ticker2.getLast()));
    // ==============================================================================================================
    // Strategy 1 - Creating 1 position on BTC/USDT (0.001 BTC for 50 USDT).
    // The price of 1 BTC is 50 000 USDT, and we buy 0.001 BTC for 50 USDT.
    // We stop at 100% gain.
    final PositionCreationResultDTO position1Result = strategy1.createLongPosition(BTC_USDT, new BigDecimal("0.001"), PositionRulesDTO.builder().stopGainPercentage(100f).build());
    assertTrue(position1Result.isSuccessful());
    final long position1Uid = position1Result.getPosition().getUid();
    final long position1PositionId = position1Result.getPosition().getPositionId();
    await().untilAsserted(() -> {
        orderFlux.update();
        tradeFlux.update();
        assertEquals(OPENED, getPositionDTO(position1Uid).getStatus());
    });
    // Check position uid & position id.
    assertEquals(1, position1Uid);
    assertEquals(1, position1PositionId);
    // Check onPositionUpdate() & onPositionStatusUpdate().
    // For strategy 1:
    // 4 positions updates:
    // - Position OPENING with opening order with PENDING_NEW status.
    // - Position OPENING with opening order with NEW status.
    // - Position OPENING with opening order with FILLED status.
    // - Position OPENED with opening order with FILLED status and the corresponding trade.
    // Positions status updates 2: OPENING and then OPENED.
    await().untilAsserted(() -> assertEquals(4, strategy1.getPositionsUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(2, strategy1.getPositionsStatusUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(0, strategy2.getPositionsUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(0, strategy2.getPositionsStatusUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(0, strategy3.getPositionsStatusUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(0, strategy3.getPositionsUpdatesReceived().size()));
    // Check onOrderUpdate().
    // - Order with NEW status.
    // - Order with FILLED status.
    // (PENDING_NEW orders are not in events).
    await().untilAsserted(() -> assertEquals(2, strategy1.getOrdersUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(0, strategy2.getOrdersUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(0, strategy3.getOrdersUpdatesReceived().size()));
    // Check onTradeUpdate().
    // - Trade arrives for the opening order.
    await().untilAsserted(() -> assertEquals(1, strategy1.getTradesUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(0, strategy2.getTradesUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(0, strategy3.getTradesUpdatesReceived().size()));
    // Check getOrders() & getOrderByOrderId().
    // Only strategy 1 should have received an order.
    assertEquals(1, strategy1.getOrders().size());
    assertTrue(strategy1.getOrderByOrderId("DRY_ORDER_000000001").isPresent());
    assertEquals(0, strategy2.getOrders().size());
    assertTrue(strategy2.getOrderByOrderId("DRY_ORDER_000000001").isEmpty());
    assertEquals(0, strategy3.getOrders().size());
    assertTrue(strategy3.getOrderByOrderId("DRY_ORDER_000000001").isEmpty());
    // Check getTrades() & getTradeByTradeId().
    // Only strategy 1 should have received a trade.
    assertEquals(1, strategy1.getTrades().size());
    assertTrue(strategy1.getTradeByTradeId("DRY_TRADE_000000001").isPresent());
    assertEquals(0, strategy2.getTrades().size());
    assertTrue(strategy2.getTradeByTradeId("DRY_TRADE_000000001").isEmpty());
    assertEquals(0, strategy3.getTrades().size());
    assertTrue(strategy3.getTradeByTradeId("DRY_TRADE_000000001").isEmpty());
    // Check getAmountsLockedByPosition().
    BigDecimal amountLockedForBTC = strategy1.getAmountsLockedByCurrency(BTC);
    assertEquals(0, new BigDecimal("0.001").compareTo(amountLockedForBTC));
    amountLockedForBTC = strategy2.getAmountsLockedByCurrency(BTC);
    assertEquals(0, new BigDecimal("0.001").compareTo(amountLockedForBTC));
    amountLockedForBTC = strategy3.getAmountsLockedByCurrency(BTC);
    assertEquals(0, new BigDecimal("0.001").compareTo(amountLockedForBTC));
    // ==============================================================================================================
    // Strategy 2 - Creating 1 position on BTC/ETH (0.2 BTC for 0.5 ETH).
    // The price of 1 BTC is 25 ETH, and we buy 0.02 BTC for 0.5 ETH.
    // We stop at 100% gain.
    final PositionCreationResultDTO position2Result = strategy2.createLongPosition(BTC_ETH, new BigDecimal("0.02"), PositionRulesDTO.builder().stopGainPercentage(100f).build());
    assertTrue(position2Result.isSuccessful());
    final long position2Uid = position2Result.getPosition().getUid();
    final long position2PositionId = position2Result.getPosition().getPositionId();
    await().untilAsserted(() -> {
        orderFlux.update();
        tradeFlux.update();
        assertEquals(OPENED, getPositionDTO(position2Uid).getStatus());
    });
    // Check position uid & position id.
    assertEquals(2, position2Uid);
    assertEquals(1, position2PositionId);
    // Check onPositionUpdate() & onPositionStatusUpdate().
    // For strategy 2:
    // 4 positions updates:
    // - Position OPENING with opening order with PENDING_NEW status.
    // - Position OPENING with opening order with NEW status.
    // - Position OPENING with opening order with FILLED status.
    // - Position OPENED with opening order with FILLED status and the corresponding trade.
    // Positions status updates 2: OPENING and then OPENED.
    await().untilAsserted(() -> assertEquals(4, strategy1.getPositionsUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(2, strategy1.getPositionsStatusUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(4, strategy2.getPositionsUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(2, strategy2.getPositionsStatusUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(0, strategy3.getPositionsStatusUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(0, strategy3.getPositionsUpdatesReceived().size()));
    // Check onOrderUpdate().
    // - Order with NEW status.
    // - Order with FILLED status.
    // (PENDING_NEW orders are not in events).
    await().untilAsserted(() -> assertEquals(2, strategy1.getOrdersUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(2, strategy2.getOrdersUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(0, strategy3.getOrdersUpdatesReceived().size()));
    // Check onTradeUpdate().
    // - Trade arrives for the opening order.
    await().untilAsserted(() -> assertEquals(1, strategy1.getTradesUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(1, strategy2.getTradesUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(0, strategy3.getTradesUpdatesReceived().size()));
    // Check getOrders() & getOrderByOrderId().
    assertEquals(1, strategy1.getOrders().size());
    assertTrue(strategy1.getOrderByOrderId("DRY_ORDER_000000001").isPresent());
    assertEquals(1, strategy2.getOrders().size());
    assertTrue(strategy2.getOrderByOrderId("DRY_ORDER_000000002").isPresent());
    assertEquals(0, strategy3.getOrders().size());
    assertTrue(strategy3.getOrderByOrderId("DRY_ORDER_000000001").isEmpty());
    // Check getTrades() & getTradeByTradeId().
    assertEquals(1, strategy1.getTrades().size());
    assertTrue(strategy1.getTradeByTradeId("DRY_TRADE_000000001").isPresent());
    assertEquals(1, strategy2.getTrades().size());
    assertTrue(strategy2.getTradeByTradeId("DRY_TRADE_000000002").isPresent());
    assertEquals(0, strategy3.getTrades().size());
    assertTrue(strategy3.getTradeByTradeId("DRY_TRADE_000000001").isEmpty());
    // Check getAmountsLockedByPosition().
    amountLockedForBTC = strategy1.getAmountsLockedByCurrency(BTC);
    assertEquals(0, new BigDecimal("0.021").compareTo(amountLockedForBTC));
    amountLockedForBTC = strategy2.getAmountsLockedByCurrency(BTC);
    assertEquals(0, new BigDecimal("0.021").compareTo(amountLockedForBTC));
    amountLockedForBTC = strategy3.getAmountsLockedByCurrency(BTC);
    assertEquals(0, new BigDecimal("0.021").compareTo(amountLockedForBTC));
    // =============================================================================================================
    // Changing the price for BTC/USDT.
    // A bitcoin now costs 10000 USDT and the price of position should have change.
    tickerFlux.emitValue(TickerDTO.builder().currencyPair(BTC_USDT).last(new BigDecimal("10000")).build());
    await().untilAsserted(() -> assertEquals(3, strategy3.getTickersUpdatesReceived().size()));
    assertEquals(2, strategy1.getTickersUpdatesReceived().size());
    assertEquals(1, strategy2.getTickersUpdatesReceived().size());
    assertEquals(3, strategy3.getTickersUpdatesReceived().size());
    // =============================================================================================================
    // Strategy 3
    // - Creating one position on BTC/USDT (0.01 BTC for 100 USDT).
    final PositionCreationResultDTO position3Result = strategy3.createLongPosition(BTC_USDT, new BigDecimal("0.01"), PositionRulesDTO.builder().stopGainPercentage(100f).build());
    assertTrue(position3Result.isSuccessful());
    final long position3Uid = position3Result.getPosition().getUid();
    final long position3PositionId = position3Result.getPosition().getPositionId();
    await().untilAsserted(() -> {
        orderFlux.update();
        tradeFlux.update();
        assertEquals(OPENED, getPositionDTO(position3Uid).getStatus());
    });
    // - Creating one position on ETH/USDT (0.1 ETH for 200 USDT).
    final PositionCreationResultDTO position4Result = strategy3.createLongPosition(ETH_USDT, new BigDecimal("0.1"), PositionRulesDTO.builder().stopGainPercentage(100f).build());
    assertTrue(position4Result.isSuccessful());
    final long position4Uid = position4Result.getPosition().getUid();
    final long position4PositionId = position4Result.getPosition().getPositionId();
    await().untilAsserted(() -> {
        orderFlux.update();
        tradeFlux.update();
        assertEquals(OPENED, getPositionDTO(position4Uid).getStatus());
    });
    // Check position uid & position id.
    assertEquals(3, position3Uid);
    assertEquals(1, position3PositionId);
    assertEquals(4, position4Uid);
    assertEquals(2, position4PositionId);
    // Check onPositionUpdate() & onPositionStatusUpdate().
    // 8 positions updates:
    // - 2 positions OPENING with opening order with PENDING_NEW status.
    // - 2 positions OPENING with opening order with NEW status.
    // - 2 positions OPENING with opening order with FILLED status.
    // - 2 positions OPENED with opening order with FILLED status and the corresponding trade.
    // Positions status updates 4: 2 orders OPENING and then OPENED.
    await().untilAsserted(() -> assertEquals(5, strategy1.getPositionsUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(2, strategy1.getPositionsStatusUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(4, strategy2.getPositionsUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(2, strategy2.getPositionsStatusUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(8, strategy3.getPositionsUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(4, strategy3.getPositionsStatusUpdatesReceived().size()));
    // Check onOrderUpdate().
    await().untilAsserted(() -> assertEquals(2, strategy1.getOrdersUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(2, strategy2.getOrdersUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(4, strategy3.getOrdersUpdatesReceived().size()));
    // Check onTradeUpdate().
    await().untilAsserted(() -> assertEquals(1, strategy1.getTradesUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(1, strategy2.getTradesUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(2, strategy3.getTradesUpdatesReceived().size()));
    // Check getOrders() & getOrderByOrderId().
    // - 2 orders with NEW status.
    // - 2 orders with FILLED status.
    // (PENDING_NEW orders are not in events).
    assertEquals(1, strategy1.getOrders().size());
    assertTrue(strategy1.getOrderByOrderId("DRY_ORDER_000000001").isPresent());
    assertEquals(1, strategy2.getOrders().size());
    assertTrue(strategy2.getOrderByOrderId("DRY_ORDER_000000002").isPresent());
    assertEquals(2, strategy3.getOrders().size());
    assertTrue(strategy3.getOrderByOrderId("DRY_ORDER_000000003").isPresent());
    assertTrue(strategy3.getOrderByOrderId("DRY_ORDER_000000004").isPresent());
    // Check getTrades() & getTradeByTradeId().
    // - 2 trades arrives for the 2 opening orders.
    assertEquals(1, strategy1.getTrades().size());
    assertTrue(strategy1.getTradeByTradeId("DRY_TRADE_000000001").isPresent());
    assertEquals(1, strategy2.getTrades().size());
    assertTrue(strategy2.getTradeByTradeId("DRY_TRADE_000000002").isPresent());
    assertEquals(2, strategy3.getTrades().size());
    assertTrue(strategy3.getTradeByTradeId("DRY_TRADE_000000003").isPresent());
    assertTrue(strategy3.getTradeByTradeId("DRY_TRADE_000000004").isPresent());
    // Check getAmountsLockedByPosition().
    amountLockedForBTC = strategy1.getAmountsLockedByCurrency(BTC);
    assertEquals(0, new BigDecimal("0.031").compareTo(amountLockedForBTC));
    amountLockedForBTC = strategy2.getAmountsLockedByCurrency(BTC);
    assertEquals(0, new BigDecimal("0.031").compareTo(amountLockedForBTC));
    amountLockedForBTC = strategy3.getAmountsLockedByCurrency(BTC);
    assertEquals(0, new BigDecimal("0.031").compareTo(amountLockedForBTC));
    BigDecimal amountLockedForETH = strategy1.getAmountsLockedByCurrency(ETH);
    assertEquals(0, new BigDecimal("0.1").compareTo(amountLockedForETH));
    amountLockedForETH = strategy2.getAmountsLockedByCurrency(ETH);
    assertEquals(0, new BigDecimal("0.1").compareTo(amountLockedForETH));
    amountLockedForETH = strategy3.getAmountsLockedByCurrency(ETH);
    assertEquals(0, new BigDecimal("0.1").compareTo(amountLockedForETH));
    // ==============================================================================================================
    // Check balances, canBuy() & canSell().
    // At the beginning my balances was:
    // - 0.99962937 BTC.
    // - 1 000 USDT.
    // - 10 ETH.
    // ---
    // Position 1 - Bought 0.001 BTC for 50 USDT - BTC/USDT : 50000.
    // Position 2 - Bought 0.2 BTC for 0.5 ETH - BTC/ETH : 25.
    // Position 3 - Bought 0.01 BTC for 100 USDT - BTC/USDT : 10000
    // Position 4 - Bought 0.1 ETH for 200 USDT - ETH/USDT : 2000.
    // --
    // BTC : 0.99962937 + 0.001 (P1) + 0.02 (P2) + 0.01 (P2) = 1.03062937 BTC
    // USDT : 1000 - 50 (P1) - 100 (P3) - 200 (P4) = 650 USDT
    // ETH : 10 - 0.5 (P2) + 0.1 (P4) = 5.1 ETH
    accountFlux.update();
    await().untilAsserted(() -> assertEquals(4, strategy3.getAccountsUpdatesReceived().size()));
    // Strategy 1 balances.
    assertEquals(0, new BigDecimal("1.03062937").compareTo(strategy1.getTradeAccountBalances().get(BTC).getAvailable()));
    assertEquals(0, new BigDecimal("650").compareTo(strategy1.getTradeAccountBalances().get(USDT).getAvailable()));
    assertEquals(0, new BigDecimal("9.6").compareTo(strategy1.getTradeAccountBalances().get(ETH).getAvailable()));
    // Strategy 2 balances.
    assertEquals(0, new BigDecimal("1.03062937").compareTo(strategy2.getTradeAccountBalances().get(BTC).getAvailable()));
    assertEquals(0, new BigDecimal("650").compareTo(strategy2.getTradeAccountBalances().get(USDT).getAvailable()));
    assertEquals(0, new BigDecimal("9.6").compareTo(strategy2.getTradeAccountBalances().get(ETH).getAvailable()));
    // Strategy 3 balances.
    assertEquals(0, new BigDecimal("1.03062937").compareTo(strategy3.getTradeAccountBalances().get(BTC).getAvailable()));
    assertEquals(0, new BigDecimal("650").compareTo(strategy3.getTradeAccountBalances().get(USDT).getAvailable()));
    assertEquals(0, new BigDecimal("9.6").compareTo(strategy3.getTradeAccountBalances().get(ETH).getAvailable()));
    // ==============================================================================================================
    // New ticker on BTC USDT to close a position.
    // Before : BTC/USDT - 10 000
    // New : BTC/USDT - 20 000 => Should trigger closing Position 3 (Position 1 of strategy 3).
    // Position 1 - Bought 0.001 BTC for 50 USDT - BTC/USDT : 50000.
    // Position 2 - Bought 0.2 BTC for 0.5 ETH - BTC/ETH : 25.
    // Position 3 - Bought 0.01 BTC for 100 USDT - BTC/USDT : 20000 => Now close, sold 0.01 BTC for 200 USDT.
    // Position 4 - Bought 0.1 ETH for 200 USDT - ETH/USDT : 2000.
    tickerFlux.emitValue(TickerDTO.builder().currencyPair(BTC_USDT).last(new BigDecimal("20000")).build());
    await().untilAsserted(() -> assertEquals(CLOSING, getPositionDTO(position3Uid).getStatus()));
    await().untilAsserted(() -> {
        orderFlux.update();
        tradeFlux.update();
        assertEquals(CLOSED, getPositionDTO(position3Uid).getStatus());
    });
    // Check position status.
    assertEquals(OPENED, getPositionDTO(position1Uid).getStatus());
    assertEquals(OPENED, getPositionDTO(position2Uid).getStatus());
    assertEquals(CLOSED, getPositionDTO(position3Uid).getStatus());
    assertEquals(OPENED, getPositionDTO(position4Uid).getStatus());
    // Check onPositionUpdate() & onPositionStatusUpdate().
    // strategy1: 1 position update because of prices updates.
    // strategy3, 5 position updates:
    // - Position prices updates.
    // - Position CLOSING with opening order with PENDING_NEW status.
    // - Position CLOSING with opening order with NEW status.
    // - Position CLOSING with opening order with FILLED status.
    // - Position CLOSED with opening order with FILLED status and the corresponding trade.
    // Positions status updates : CLOSING and then CLOSED.
    await().untilAsserted(() -> assertEquals(6, strategy1.getPositionsUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(2, strategy1.getPositionsStatusUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(4, strategy2.getPositionsUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(2, strategy2.getPositionsStatusUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(13, strategy3.getPositionsUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(6, strategy3.getPositionsStatusUpdatesReceived().size()));
    // Check onOrderUpdate().
    // - Order with NEW status.
    // - Order with FILLED status.
    // (PENDING_NEW orders are not in events).
    await().untilAsserted(() -> assertEquals(2, strategy1.getOrdersUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(2, strategy2.getOrdersUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(6, strategy3.getOrdersUpdatesReceived().size()));
    // Check onTradeUpdate().
    // - Trade arrives for the closing order.
    await().untilAsserted(() -> assertEquals(1, strategy1.getTradesUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(1, strategy2.getTradesUpdatesReceived().size()));
    await().untilAsserted(() -> assertEquals(3, strategy3.getTradesUpdatesReceived().size()));
    // Check getOrders() & getOrderByOrderId().
    assertEquals(1, strategy1.getOrders().size());
    assertTrue(strategy1.getOrderByOrderId("DRY_ORDER_000000001").isPresent());
    assertEquals(1, strategy2.getOrders().size());
    assertTrue(strategy2.getOrderByOrderId("DRY_ORDER_000000002").isPresent());
    assertEquals(3, strategy3.getOrders().size());
    assertTrue(strategy3.getOrderByOrderId("DRY_ORDER_000000003").isPresent());
    assertTrue(strategy3.getOrderByOrderId("DRY_ORDER_000000004").isPresent());
    assertTrue(strategy3.getOrderByOrderId("DRY_ORDER_000000005").isPresent());
    // Check getTrades() & getTradeByTradeId().
    assertEquals(1, strategy1.getTrades().size());
    assertTrue(strategy1.getTradeByTradeId("DRY_TRADE_000000001").isPresent());
    assertEquals(1, strategy2.getTrades().size());
    assertTrue(strategy2.getTradeByTradeId("DRY_TRADE_000000002").isPresent());
    assertEquals(3, strategy3.getTrades().size());
    assertTrue(strategy3.getTradeByTradeId("DRY_TRADE_000000003").isPresent());
    assertTrue(strategy3.getTradeByTradeId("DRY_TRADE_000000004").isPresent());
    assertTrue(strategy3.getTradeByTradeId("DRY_TRADE_000000005").isPresent());
    // Check getAmountsLockedByPosition().
    // Position 3 - Bought 0.01 BTC for 100 USDT - BTC/USDT : 20000 => Now close, sold 0.01 BTC for 200 USDT.
    amountLockedForBTC = strategy1.getAmountsLockedByCurrency(BTC);
    assertEquals(0, new BigDecimal("0.021").compareTo(amountLockedForBTC));
    amountLockedForBTC = strategy2.getAmountsLockedByCurrency(BTC);
    assertEquals(0, new BigDecimal("0.021").compareTo(amountLockedForBTC));
    amountLockedForBTC = strategy3.getAmountsLockedByCurrency(BTC);
    assertEquals(0, new BigDecimal("0.021").compareTo(amountLockedForBTC));
    amountLockedForETH = strategy1.getAmountsLockedByCurrency(ETH);
    assertEquals(0, new BigDecimal("0.1").compareTo(amountLockedForETH));
    amountLockedForETH = strategy2.getAmountsLockedByCurrency(ETH);
    assertEquals(0, new BigDecimal("0.1").compareTo(amountLockedForETH));
    amountLockedForETH = strategy3.getAmountsLockedByCurrency(ETH);
    assertEquals(0, new BigDecimal("0.1").compareTo(amountLockedForETH));
    // ==============================================================================================================
    // Check balances, canBuy() & canSell().
    // At the beginning my balances was:
    // - 0.99962937 BTC.
    // - 1 000 USDT.
    // - 10 ETH.
    // ---
    // Position 1 - Bought 0.001 BTC for 50 USDT - BTC/USDT : 50000.
    // Position 2 - Bought 0.2 BTC for 0.5 ETH - BTC/ETH : 25.
    // Position 3 - Bought 0.01 BTC for 100 USDT - BTC/USDT : 10000
    // Position 4 - Bought 0.1 ETH for 200 USDT - ETH/USDT : 2000.
    // New event.
    // Position 3 - Bought 0.01 BTC for 100 USDT - BTC/USDT : 20000 => Now close, sold 0.01 BTC for 200 USDT.
    // --
    // BTC : 0.99962937 + 0.001 (P1) + 0.02 (P2) + 0.01 (P2) - 0.01 (P3 close) = 1.02062937 BTC
    // USDT : 1000 - 50 (P1) - 100 (P3) - 200 (P4) + 200 (P3) = 850 USDT
    // ETH : 10 - 0.5 (P2) + 0.1 (P4) = 5.1 ETH
    accountFlux.update();
    await().untilAsserted(() -> assertEquals(5, strategy3.getAccountsUpdatesReceived().size()));
    // Strategy 1.
    assertEquals(0, new BigDecimal("1.02062937").compareTo(strategy1.getTradeAccountBalances().get(BTC).getAvailable()));
    assertEquals(0, new BigDecimal("850").compareTo(strategy1.getTradeAccountBalances().get(USDT).getAvailable()));
    assertEquals(0, new BigDecimal("9.6").compareTo(strategy1.getTradeAccountBalances().get(ETH).getAvailable()));
    // Strategy 2.
    assertEquals(0, new BigDecimal("1.02062937").compareTo(strategy2.getTradeAccountBalances().get(BTC).getAvailable()));
    assertEquals(0, new BigDecimal("850").compareTo(strategy2.getTradeAccountBalances().get(USDT).getAvailable()));
    assertEquals(0, new BigDecimal("9.6").compareTo(strategy2.getTradeAccountBalances().get(ETH).getAvailable()));
    // Strategy 3.
    assertEquals(0, new BigDecimal("1.02062937").compareTo(strategy3.getTradeAccountBalances().get(BTC).getAvailable()));
    assertEquals(0, new BigDecimal("850").compareTo(strategy3.getTradeAccountBalances().get(USDT).getAvailable()));
    assertEquals(0, new BigDecimal("9.6").compareTo(strategy3.getTradeAccountBalances().get(ETH).getAvailable()));
}
Also used : PositionCreationResultDTO(tech.cassandre.trading.bot.dto.position.PositionCreationResultDTO) CurrencyPairDTO(tech.cassandre.trading.bot.dto.util.CurrencyPairDTO) TickerDTO(tech.cassandre.trading.bot.dto.market.TickerDTO) Strategy(tech.cassandre.trading.bot.domain.Strategy) AccountDTO(tech.cassandre.trading.bot.dto.user.AccountDTO) BigDecimal(java.math.BigDecimal) BaseTest(tech.cassandre.trading.bot.test.util.junit.BaseTest) Test(org.junit.jupiter.api.Test) SpringBootTest(org.springframework.boot.test.context.SpringBootTest) DisplayName(org.junit.jupiter.api.DisplayName)

Aggregations

AccountDTO (tech.cassandre.trading.bot.dto.user.AccountDTO)23 BigDecimal (java.math.BigDecimal)18 DisplayName (org.junit.jupiter.api.DisplayName)14 Test (org.junit.jupiter.api.Test)14 BalanceDTO (tech.cassandre.trading.bot.dto.user.BalanceDTO)12 UserDTO (tech.cassandre.trading.bot.dto.user.UserDTO)11 SpringBootTest (org.springframework.boot.test.context.SpringBootTest)10 BaseTest (tech.cassandre.trading.bot.test.util.junit.BaseTest)7 LinkedHashSet (java.util.LinkedHashSet)6 Around (org.aspectj.lang.annotation.Around)6 TickerDTO (tech.cassandre.trading.bot.dto.market.TickerDTO)5 LinkedHashMap (java.util.LinkedHashMap)4 OrderCreationResultDTO (tech.cassandre.trading.bot.dto.trade.OrderCreationResultDTO)4 IOException (java.io.IOException)3 Collections (java.util.Collections)3 Optional (java.util.Optional)3 Tag (org.junit.jupiter.api.Tag)3 Strategy (tech.cassandre.trading.bot.domain.Strategy)3 DryModeException (tech.cassandre.trading.bot.util.exception.DryModeException)3 FileNotFoundException (java.io.FileNotFoundException)2