package org.knowm.xchange.gemini.v1; import static org.junit.Assert.assertEquals; import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; import org.junit.Test; import org.knowm.xchange.currency.Currency; import org.knowm.xchange.currency.CurrencyPair; import org.knowm.xchange.dto.Order; import org.knowm.xchange.dto.Order.OrderType; import org.knowm.xchange.dto.account.Wallet; import org.knowm.xchange.dto.marketdata.Trade; import org.knowm.xchange.dto.marketdata.Trades; import org.knowm.xchange.dto.trade.LimitOrder; import org.knowm.xchange.dto.trade.OpenOrders; import org.knowm.xchange.gemini.v1.dto.account.GeminiBalancesResponse; import org.knowm.xchange.gemini.v1.dto.account.GeminiWalletJSONTest; import org.knowm.xchange.gemini.v1.dto.marketdata.GeminiLevel; import org.knowm.xchange.gemini.v1.dto.trade.GeminiOrderStatusResponse; import org.knowm.xchange.gemini.v1.dto.trade.GeminiTradeResponse; import com.fasterxml.jackson.databind.ObjectMapper; public class GeminiAdaptersTest { private final static String MARKET = "Gemini"; private final static String EXCHANGE = "exchange"; private final static String SYMBOL = "BTCUSD"; @Test public void shouldAdaptBalances() throws IOException { // Read in the JSON from the example resources InputStream is = GeminiWalletJSONTest.class.getResourceAsStream("/v1/account/example-account-info-balance.json"); // Use Jackson to parse it ObjectMapper mapper = new ObjectMapper(); GeminiBalancesResponse[] response = mapper.readValue(is, GeminiBalancesResponse[].class); Wallet wallet = GeminiAdapters.adaptWallet(response); assertEquals(2, wallet.getBalances().size()); assertEquals(new BigDecimal("105.5"), wallet.getBalance(Currency.USD).getTotal()); assertEquals(new BigDecimal("55.5"), wallet.getBalance(Currency.USD).getAvailable()); assertEquals(new BigDecimal("50"), wallet.getBalance(Currency.BTC).getTotal()); assertEquals(new BigDecimal("30"), wallet.getBalance(Currency.BTC).getAvailable()); } @Test public void testAdaptOrdersToOrdersContainer() { GeminiLevel[] levels = initLevels(); GeminiAdapters.OrdersContainer container = GeminiAdapters.adaptOrders(levels, CurrencyPair.BTC_USD, OrderType.BID); GeminiLevel lastLevel = levels[levels.length - 1]; assertEquals(lastLevel.getTimestamp().multiply(new BigDecimal(1000l)).longValue(), container.getTimestamp()); assertEquals(container.getLimitOrders().size(), levels.length); for (int i = 0; i < levels.length; i++) { LimitOrder order = container.getLimitOrders().get(i); long expectedTimestampMillis = levels[i].getTimestamp().multiply(new BigDecimal(1000l)).longValue(); assertEquals(levels[i].getAmount(), order.getTradableAmount()); assertEquals(expectedTimestampMillis, order.getTimestamp().getTime()); assertEquals(levels[i].getPrice(), order.getLimitPrice()); } } /** * Create 60 {@link GeminiLevel}s. The values increase as the array index does. The timestamps increase by 1 second + 1 minute + 1 hour + 1 day in * order to test the correct handling of the given timestamp. * * @return The generated responses. */ private GeminiLevel[] initLevels() { GeminiLevel[] responses = new GeminiLevel[60]; for (int i = 0; i < responses.length; i++) { BigDecimal price = new BigDecimal(350l + i); BigDecimal timestamp = new BigDecimal("1414669893.823615468").add(new BigDecimal(i * (1 + 60 + 60 * 60 + 60 * 60 * 24))); BigDecimal amount = new BigDecimal(1l + i); responses[i] = new GeminiLevel(price, amount, timestamp); } return responses; } @Test public void testAdaptOrdersToOpenOrders() { GeminiOrderStatusResponse[] responses = initOrderStatusResponses(); OpenOrders orders = GeminiAdapters.adaptOrders(responses); assertEquals(orders.getOpenOrders().size(), responses.length); for (int i = 0; i < responses.length; i++) { LimitOrder order = orders.getOpenOrders().get(i); long expectedTimestampMillis = responses[i].getTimestamp().multiply(new BigDecimal(1000l)).longValue(); Order.OrderType expectedOrderType = responses[i].getSide().equalsIgnoreCase("buy") ? Order.OrderType.BID : Order.OrderType.ASK; assertEquals(String.valueOf(responses[i].getId()), order.getId()); assertEquals(responses[i].getRemainingAmount(), order.getTradableAmount()); assertEquals(GeminiAdapters.adaptCurrencyPair(SYMBOL), order.getCurrencyPair()); assertEquals(expectedOrderType, order.getType()); assertEquals(expectedTimestampMillis, order.getTimestamp().getTime()); assertEquals(responses[i].getPrice(), order.getLimitPrice()); } } /** * Create 60 {@link GeminiOrderStatusResponse}s. The values increase as array index does. The timestamps increase by 1 second + 1 minute + 1 hour + * 1 day in order to test the correct handling of the given timestamp. * * @return The generated responses. */ private GeminiOrderStatusResponse[] initOrderStatusResponses() { GeminiOrderStatusResponse[] responses = new GeminiOrderStatusResponse[60]; for (int i = 0; i < responses.length; i++) { BigDecimal price = new BigDecimal(350l + i); BigDecimal avgExecutionPrice = price.add(new BigDecimal(0.25 * i)); String side = i % 2 == 0 ? "buy" : "sell"; String type = "limit"; BigDecimal timestamp = new BigDecimal("1414658239.41373654").add(new BigDecimal(i * (1 + 60 + 60 * 60 + 60 * 60 * 24))); boolean isLive = false; boolean isCancelled = false; boolean wasForced = false; BigDecimal originalAmount = new BigDecimal("70"); BigDecimal remainingAmount = originalAmount.subtract(new BigDecimal(i * 1)); BigDecimal executedAmount = originalAmount.subtract(remainingAmount); responses[i] = new GeminiOrderStatusResponse(i, SYMBOL, EXCHANGE, price, avgExecutionPrice, side, type, timestamp, isLive, isCancelled, wasForced, originalAmount, remainingAmount, executedAmount); } return responses; } @Test public void testAdaptTradeHistory() { GeminiTradeResponse[] responses = initTradeResponses(); Trades trades = GeminiAdapters.adaptTradeHistory(responses, SYMBOL); assertEquals(trades.getTrades().size(), responses.length); for (int i = 0; i < responses.length; i++) { Trade trade = trades.getTrades().get(i); long expectedTimestampMillis = responses[i].getTimestamp().multiply(new BigDecimal(1000l)).longValue(); Order.OrderType expectedOrderType = responses[i].getType().equalsIgnoreCase("buy") ? OrderType.BID : OrderType.ASK; assertEquals(responses[i].getPrice(), trade.getPrice()); assertEquals(responses[i].getAmount(), trade.getTradableAmount()); assertEquals(GeminiAdapters.adaptCurrencyPair(SYMBOL), trade.getCurrencyPair()); assertEquals(expectedTimestampMillis, trade.getTimestamp().getTime()); assertEquals(expectedOrderType, trade.getType()); assertEquals(responses[i].getTradeId(), trade.getId()); } } /** * Create 60 {@link GeminiTradeResponse}s. The values increase as array index does. The timestamps increase by 1 second + 1 minute + 1 hour + 1 day * in order to test the correct handling of the given timestamp. * * @return The generated responses. */ private GeminiTradeResponse[] initTradeResponses() { GeminiTradeResponse[] responses = new GeminiTradeResponse[60]; int tradeId = 2000; int orderId = 1000; for (int i = 0; i < responses.length; i++) { BigDecimal price = new BigDecimal(350l + i); BigDecimal amount = new BigDecimal(1l + i); BigDecimal timestamp = new BigDecimal("1414658239.41373654").add(new BigDecimal(i * (1 + 60 + 60 * 60 + 60 * 60 * 24))); String type = i % 2 == 0 ? "buy" : "sell"; String tradeIdString = String.valueOf(tradeId++); String orderIdString = String.valueOf(orderId++); BigDecimal feeAmount = new BigDecimal(0l); String feeCurrency = "USD"; responses[i] = new GeminiTradeResponse(price, amount, timestamp, MARKET, type, tradeIdString, orderIdString, feeAmount, feeCurrency); } return responses; } }