All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.knowm.xchange.livecoin.LivecoinAdapters Maven / Gradle / Ivy

There is a newer version: 5.2.0
Show newest version
package org.knowm.xchange.livecoin;

import static org.knowm.xchange.currency.Currency.getInstance;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
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.Balance;
import org.knowm.xchange.dto.account.FundingRecord;
import org.knowm.xchange.dto.account.Wallet;
import org.knowm.xchange.dto.marketdata.OrderBook;
import org.knowm.xchange.dto.marketdata.Ticker;
import org.knowm.xchange.dto.marketdata.Trade;
import org.knowm.xchange.dto.marketdata.Trades;
import org.knowm.xchange.dto.marketdata.Trades.TradeSortType;
import org.knowm.xchange.dto.meta.CurrencyMetaData;
import org.knowm.xchange.dto.meta.CurrencyPairMetaData;
import org.knowm.xchange.dto.meta.ExchangeMetaData;
import org.knowm.xchange.dto.trade.LimitOrder;
import org.knowm.xchange.dto.trade.MarketOrder;
import org.knowm.xchange.dto.trade.UserTrade;
import org.knowm.xchange.exceptions.ExchangeException;
import org.knowm.xchange.livecoin.dto.account.LivecoinBalance;
import org.knowm.xchange.livecoin.dto.marketdata.LivecoinAllOrderBooks;
import org.knowm.xchange.livecoin.dto.marketdata.LivecoinOrder;
import org.knowm.xchange.livecoin.dto.marketdata.LivecoinOrderBook;
import org.knowm.xchange.livecoin.dto.marketdata.LivecoinRestriction;
import org.knowm.xchange.livecoin.dto.marketdata.LivecoinTicker;
import org.knowm.xchange.livecoin.dto.marketdata.LivecoinTrade;
import org.knowm.xchange.livecoin.dto.marketdata.LivecoinUserOrder;
import org.knowm.xchange.utils.DateUtils;

public class LivecoinAdapters {

  private static final int FALLBACK_PRICE_SCALE = 8;

  // user for all their pairs
  private static final int LIVECOIN_BASE_SCALE = 8;

  public static CurrencyPair adaptCurrencyPair(LivecoinRestriction product) {
    String[] data = product.getCurrencyPair().split("\\/");
    return new CurrencyPair(data[0], data[1]);
  }

  public static OrderBook adaptOrderBook(LivecoinOrderBook book, CurrencyPair currencyPair) {

    List asks = toLimitOrderList(book.getAsks(), OrderType.ASK, currencyPair);
    List bids = toLimitOrderList(book.getBids(), OrderType.BID, currencyPair);

    return new OrderBook(null, asks, bids);
  }

  private static List toLimitOrderList(
      List levels, OrderType orderType, CurrencyPair currencyPair) {

    if (levels == null || levels.isEmpty()) {
      return Collections.emptyList();
    }
    List allLevels = new ArrayList<>(levels.size());
    for (LivecoinOrder ask : levels) {
      if (ask != null) {
        allLevels.add(
            new LimitOrder(orderType, ask.getQuantity(), currencyPair, "0", null, ask.getRate()));
      }
    }

    return allLevels;
  }

  public static Map adaptToCurrencyPairKeysMap(
      LivecoinAllOrderBooks orderBooksRaw) {

    Set> entries =
        orderBooksRaw.getOrderBooksByPair().entrySet();
    Map converted = new HashMap<>(entries.size());
    for (Map.Entry entry : entries) {
      String[] currencyPairSplit = entry.getKey().split("/");
      CurrencyPair currencyPair = new CurrencyPair(currencyPairSplit[0], currencyPairSplit[1]);
      converted.put(currencyPair, entry.getValue());
    }
    return converted;
  }

  public static ExchangeMetaData adaptToExchangeMetaData(
      ExchangeMetaData exchangeMetaData, List products) {

    Map currencyPairs = exchangeMetaData.getCurrencyPairs();
    Map currencies = exchangeMetaData.getCurrencies();
    for (LivecoinRestriction product : products) {
      CurrencyPair pair = adaptCurrencyPair(product);
      CurrencyPairMetaData staticMetaData = exchangeMetaData.getCurrencyPairs().get(pair);
      CurrencyPairMetaData.Builder builder;
      if (staticMetaData == null) {
        builder = new CurrencyPairMetaData.Builder();
      } else {
        builder = CurrencyPairMetaData.Builder.from(staticMetaData);
      }
      if (product.getPriceScale() != null) {
        builder.priceScale(product.getPriceScale());
      } else if (staticMetaData != null && staticMetaData.getPriceScale() == null) {
        builder.priceScale(FALLBACK_PRICE_SCALE);
      }
      if (!(staticMetaData != null && staticMetaData.getBaseScale() != null)) {
        builder.baseScale(LIVECOIN_BASE_SCALE);
      }
      if (product.getMinLimitQuantity() != null) {
        builder.minimumAmount(product.getMinLimitQuantity());
      }
      currencyPairs.put(pair, builder.build());

      if (!currencies.containsKey(pair.base)) currencies.put(pair.base, null);
      if (!currencies.containsKey(pair.counter)) currencies.put(pair.counter, null);
    }
    return new ExchangeMetaData(currencyPairs, currencies, null, null, true);
  }

  public static Trades adaptTrades(List tradesRaw, CurrencyPair currencyPair) {

    if (tradesRaw.isEmpty()) {
      return new Trades(Collections.emptyList());
    }
    List trades = new ArrayList<>(tradesRaw.size());

    for (LivecoinTrade trade : tradesRaw) {
      OrderType type = trade.getType().equals("SELL") ? OrderType.BID : OrderType.ASK;
      Trade t =
          new Trade(
              type,
              trade.getQuantity(),
              currencyPair,
              trade.getPrice(),
              parseDate(trade.getTime()),
              String.valueOf(trade.getId()));
      trades.add(t);
    }

    return new Trades(trades, tradesRaw.get(0).getId(), TradeSortType.SortByID);
  }

  private static Date parseDate(Long rawDateLong) {
    return new Date(rawDateLong * 1000);
  }

  public static Ticker adaptTicker(LivecoinTicker ticker, CurrencyPair currencyPair) {
    BigDecimal last = ticker.getLast();
    BigDecimal bid = ticker.getBestBid();
    BigDecimal ask = ticker.getBestAsk();
    BigDecimal high = ticker.getHigh();
    BigDecimal low = ticker.getLow();
    BigDecimal volume = ticker.getVolume();

    return new Ticker.Builder()
        .currencyPair(currencyPair)
        .last(last)
        .bid(bid)
        .ask(ask)
        .high(high)
        .low(low)
        .volume(volume)
        .build();
  }

  public static Collection adaptUserOrders(Collection orders) {
    return orders.stream().map(LivecoinAdapters::adaptUserOrder).collect(Collectors.toList());
  }

  public static Order adaptUserOrder(LivecoinUserOrder order) {
    OrderType type;
    boolean limit;
    switch (order.getType()) {
      case "MARKET_SELL":
        type = OrderType.ASK;
        limit = false;
        break;
      case "LIMIT_SELL":
        type = OrderType.ASK;
        limit = true;
        break;
      case "LIMIT_BUY":
        type = OrderType.BID;
        limit = true;
        break;
      case "MARKET_BUY":
        type = OrderType.BID;
        limit = false;
        break;
      default:
        throw new ExchangeException(
            "Order id=" + order.getId() + " has unknown type " + order.getType());
    }
    CurrencyPair pair = new CurrencyPair(order.getCurrencyPair());
    Order.OrderStatus status;
    if (order.getRemainingQuantity().compareTo(BigDecimal.ZERO) == 0) {
      status = Order.OrderStatus.FILLED;
    } else {
      status =
          order.getRemainingQuantity().compareTo(order.getQuantity()) < 0
              ? Order.OrderStatus.PARTIALLY_FILLED
              : Order.OrderStatus.PENDING_NEW;
    }

    Order.Builder builder;
    if (limit) {
      builder =
          new LimitOrder.Builder(type, pair)
              .limitPrice(order.getPrice())
              .remainingAmount(order.getRemainingQuantity());
    } else {
      builder = new MarketOrder.Builder(type, pair).averagePrice(order.getPrice());
    }
    return builder
        .originalAmount(order.getQuantity())
        .id(order.getId().toString())
        .timestamp(DateUtils.fromUnixTime(order.getIssueTime()))
        .orderStatus(status)
        .build();
  }

  public static UserTrade adaptUserTrade(Map map) {
    OrderType type = OrderType.BID;
    if (map.get("type").toString().equals("SELL")) type = OrderType.ASK;

    Currency ccyA = Currency.getInstance(map.get("fixedCurrency").toString());
    Currency ccyB = Currency.getInstance(map.get("variableCurrency").toString());

    BigDecimal amountA = new BigDecimal(map.get("amount").toString());
    BigDecimal amountB = new BigDecimal(map.get("variableAmount").toString());
    int scale = Math.max(amountA.scale(), amountB.scale());
    BigDecimal price = amountB.divide(amountA, scale, RoundingMode.HALF_UP);

    String id = map.get("id").toString();

    return new UserTrade(
        type,
        amountA,
        new CurrencyPair(ccyA, ccyB),
        price,
        DateUtils.fromMillisUtc(Long.valueOf(map.get("date").toString())),
        id,
        Optional.ofNullable(map.get("externalKey")).map(Object::toString).orElse(null),
        new BigDecimal(map.get("fee").toString()),
        getInstance(map.get("taxCurrency").toString()));
  }

  public static FundingRecord adaptFundingRecord(Map map) {
    FundingRecord.Type type = FundingRecord.Type.WITHDRAWAL;
    if (map.get("type").toString().equals("DEPOSIT")) type = FundingRecord.Type.DEPOSIT;

    return new FundingRecord(
        Optional.ofNullable(map.get("externalKey")).map(Object::toString).orElse(null),
        DateUtils.fromMillisUtc(Long.valueOf(map.get("date").toString())),
        getInstance(map.get("fixedCurrency").toString()),
        new BigDecimal(map.get("amount").toString()),
        map.get("id").toString(),
        null,
        type,
        FundingRecord.Status.COMPLETE,
        null,
        new BigDecimal(map.get("fee").toString()),
        null);
  }

  public static Wallet adaptWallet(List livecoinBalances) {
    Map balanceBuildersByCurrency = new HashMap<>();
    for (LivecoinBalance livecoinBalance : livecoinBalances) {

      // Livecoin has a currency Bricktox (XBT) which is different from XChange Bitcoin (XBT). See
      // Currency.XBT.
      // The "get all currencies" call to Livecoin returns all currencies including those with 0
      // balance.
      // As a result, XBT overrides BTC, so BTC becomes 0 (in most cases).
      // Excluding XBT.
      if (livecoinBalance.getCurrency().equals("XBT")) {
        continue;
      }

      Currency currency = getInstance(livecoinBalance.getCurrency());

      Balance.Builder builder = balanceBuildersByCurrency.get(currency);
      if (builder == null) {
        builder = new Balance.Builder().currency(currency);
        balanceBuildersByCurrency.put(currency, builder);
      }
      BigDecimal value = livecoinBalance.getValue();
      switch (livecoinBalance.getType()) {
        case "total":
          builder.total(value);
          break;
        case "available":
          builder.available(value);
          break;
        case "trade":
          builder.frozen(value);
          break;
      }
    }
    return Wallet.Builder.from(
            balanceBuildersByCurrency.values().stream()
                .map(Balance.Builder::build)
                .collect(Collectors.toList()))
        .build();
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy