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);
}
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));
}
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()));
}
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()));
}
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()));
}
Aggregations