org.knowm.xchange.poloniex.PoloniexAdapters Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xchange-poloniex Show documentation
Show all versions of xchange-poloniex Show documentation
XChange implementation for the Poloniex Exchange
package org.knowm.xchange.poloniex;
import static org.knowm.xchange.dto.account.FundingRecord.Type.*;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.knowm.xchange.currency.Currency;
import org.knowm.xchange.currency.CurrencyPair;
import org.knowm.xchange.dto.LoanOrder;
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.FundingRecord.Type;
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.meta.WalletHealth;
import org.knowm.xchange.dto.trade.FixedRateLoanOrder;
import org.knowm.xchange.dto.trade.LimitOrder;
import org.knowm.xchange.dto.trade.OpenOrders;
import org.knowm.xchange.dto.trade.UserTrade;
import org.knowm.xchange.poloniex.dto.LoanInfo;
import org.knowm.xchange.poloniex.dto.account.PoloniexBalance;
import org.knowm.xchange.poloniex.dto.account.PoloniexLoan;
import org.knowm.xchange.poloniex.dto.marketdata.PoloniexCurrencyInfo;
import org.knowm.xchange.poloniex.dto.marketdata.PoloniexDepth;
import org.knowm.xchange.poloniex.dto.marketdata.PoloniexMarketData;
import org.knowm.xchange.poloniex.dto.marketdata.PoloniexPublicTrade;
import org.knowm.xchange.poloniex.dto.marketdata.PoloniexTicker;
import org.knowm.xchange.poloniex.dto.trade.PoloniexAdjustment;
import org.knowm.xchange.poloniex.dto.trade.PoloniexDeposit;
import org.knowm.xchange.poloniex.dto.trade.PoloniexDepositsWithdrawalsResponse;
import org.knowm.xchange.poloniex.dto.trade.PoloniexOpenOrder;
import org.knowm.xchange.poloniex.dto.trade.PoloniexUserTrade;
import org.knowm.xchange.poloniex.dto.trade.PoloniexWithdrawal;
/**
* @author Zach Holmes
* @author Dave Seyb
* @version 2.0 *
*/
public class PoloniexAdapters {
public static Ticker adaptPoloniexTicker(
PoloniexTicker poloniexTicker, CurrencyPair currencyPair) {
PoloniexMarketData marketData = poloniexTicker.getPoloniexMarketData();
return adaptPoloniexTicker(marketData, currencyPair);
}
public static Ticker adaptPoloniexTicker(
PoloniexMarketData marketData, CurrencyPair currencyPair) {
BigDecimal last = marketData.getLast();
BigDecimal bid = marketData.getHighestBid();
BigDecimal ask = marketData.getLowestAsk();
BigDecimal high = marketData.getHigh24hr();
BigDecimal low = marketData.getLow24hr();
BigDecimal volume = marketData.getQuoteVolume();
BigDecimal percentageChange = marketData.getPercentChange();
return new Ticker.Builder()
.currencyPair(currencyPair)
.last(last)
.bid(bid)
.ask(ask)
.high(high)
.low(low)
.volume(volume)
.percentageChange(percentageChange.multiply(new BigDecimal("100"), new MathContext(8)))
.build();
}
public static OrderBook adaptPoloniexDepth(PoloniexDepth depth, CurrencyPair currencyPair) {
List asks = adaptPoloniexPublicOrders(depth.getAsks(), OrderType.ASK, currencyPair);
List bids = adaptPoloniexPublicOrders(depth.getBids(), OrderType.BID, currencyPair);
return new OrderBook(null, asks, bids);
}
public static List adaptPoloniexPublicOrders(
List> rawLevels, OrderType orderType, CurrencyPair currencyPair) {
List orders = new ArrayList<>();
for (List rawlevel : rawLevels) {
LimitOrder limitOrder =
new LimitOrder.Builder(orderType, currencyPair)
.originalAmount(rawlevel.get(1))
.limitPrice(rawlevel.get(0))
.build();
orders.add(limitOrder);
}
return orders;
}
public static Trades adaptPoloniexPublicTrades(
PoloniexPublicTrade[] poloniexPublicTrades, CurrencyPair currencyPair) {
List trades = new ArrayList<>();
for (PoloniexPublicTrade poloniexTrade : poloniexPublicTrades) {
trades.add(adaptPoloniexPublicTrade(poloniexTrade, currencyPair));
}
return new Trades(trades, TradeSortType.SortByTimestamp);
}
public static Trade adaptPoloniexPublicTrade(
PoloniexPublicTrade poloniexTrade, CurrencyPair currencyPair) {
OrderType type =
poloniexTrade.getType().equalsIgnoreCase("buy") ? OrderType.BID : OrderType.ASK;
Date timestamp = PoloniexUtils.stringToDate(poloniexTrade.getDate());
return new Trade.Builder()
.type(type)
.originalAmount(poloniexTrade.getAmount())
.currencyPair(currencyPair)
.price(poloniexTrade.getRate())
.timestamp(timestamp)
.id(poloniexTrade.getTradeID())
.build();
}
public static List adaptPoloniexBalances(
HashMap poloniexBalances) {
List balances = new ArrayList<>();
for (Map.Entry item : poloniexBalances.entrySet()) {
Currency currency = Currency.getInstance(item.getKey());
balances.add(
new Balance(
currency, null, item.getValue().getAvailable(), item.getValue().getOnOrders()));
}
return balances;
}
public static LoanInfo adaptPoloniexLoans(HashMap poloniexLoans) {
Map> loans = new HashMap<>();
for (Map.Entry item : poloniexLoans.entrySet()) {
List loanOrders = new ArrayList<>();
for (PoloniexLoan poloniexLoan : item.getValue()) {
Date date = PoloniexUtils.stringToDate(poloniexLoan.getDate());
loanOrders.add(
new FixedRateLoanOrder(
OrderType.ASK,
poloniexLoan.getCurrency(),
poloniexLoan.getAmount(),
poloniexLoan.getRange(),
poloniexLoan.getId(),
date,
poloniexLoan.getRate())); // TODO
}
loans.put(item.getKey(), loanOrders);
}
return new LoanInfo(loans.get("provided"), loans.get("used"));
}
public static OpenOrders adaptPoloniexOpenOrders(
Map poloniexOpenOrders) {
List openOrders = new ArrayList<>();
for (String pairString : poloniexOpenOrders.keySet()) {
CurrencyPair currencyPair = PoloniexUtils.toCurrencyPair(pairString);
for (PoloniexOpenOrder openOrder : poloniexOpenOrders.get(pairString)) {
openOrders.add(adaptPoloniexOpenOrder(openOrder, currencyPair));
}
}
return new OpenOrders(openOrders);
}
public static LimitOrder adaptPoloniexOpenOrder(
PoloniexOpenOrder openOrder, CurrencyPair currencyPair) {
OrderType type = openOrder.getType().equals("buy") ? OrderType.BID : OrderType.ASK;
Date timestamp = PoloniexUtils.stringToDate(openOrder.getDate());
return new LimitOrder.Builder(type, currencyPair)
.limitPrice(openOrder.getRate())
.originalAmount(openOrder.getStartingAmount())
.cumulativeAmount(openOrder.getStartingAmount().subtract(openOrder.getAmount()))
.id(openOrder.getOrderNumber())
.timestamp(timestamp)
.build();
}
public static UserTrade adaptPoloniexUserTrade(
PoloniexUserTrade userTrade, CurrencyPair currencyPair) {
OrderType orderType =
userTrade.getType().equalsIgnoreCase("buy") ? OrderType.BID : OrderType.ASK;
BigDecimal amount = userTrade.getAmount();
BigDecimal price = userTrade.getRate();
Date date = PoloniexUtils.stringToDate(userTrade.getDate());
String tradeId = String.valueOf(userTrade.getTradeID());
String orderId = String.valueOf(userTrade.getOrderNumber());
// Poloniex returns fee as a multiplier, e.g. a 0.2% fee is 0.002
// fee currency/size depends on trade direction (buy/sell). It appears to be rounded down
final BigDecimal feeAmount;
final String feeCurrencyCode;
if (orderType == OrderType.ASK) {
feeAmount =
amount.multiply(price).multiply(userTrade.getFee()).setScale(8, RoundingMode.DOWN);
feeCurrencyCode = currencyPair.counter.getCurrencyCode();
} else {
feeAmount = amount.multiply(userTrade.getFee()).setScale(8, RoundingMode.DOWN);
feeCurrencyCode = currencyPair.base.getCurrencyCode();
}
return new UserTrade.Builder()
.type(orderType)
.originalAmount(amount)
.currencyPair(currencyPair)
.price(price)
.timestamp(date)
.id(tradeId)
.orderId(orderId)
.feeAmount(feeAmount)
.feeCurrency(Currency.getInstance(feeCurrencyCode))
.build();
}
public static ExchangeMetaData adaptToExchangeMetaData(
Map poloniexCurrencyInfo,
Map poloniexMarketData,
ExchangeMetaData exchangeMetaData) {
Map currencyMetaDataMap = exchangeMetaData.getCurrencies();
CurrencyMetaData currencyArchetype = currencyMetaDataMap.values().iterator().next();
for (Map.Entry entry : poloniexCurrencyInfo.entrySet()) {
Currency ccy = Currency.getInstance(entry.getKey());
if (!currencyMetaDataMap.containsKey(ccy)) {
currencyMetaDataMap.put(ccy, currencyArchetype);
}
CurrencyMetaData currencyMetaData = currencyMetaDataMap.get(ccy);
WalletHealth walletHealth = WalletHealth.ONLINE;
if (entry.getValue().isDelisted() || entry.getValue().isDisabled()) {
walletHealth = WalletHealth.OFFLINE;
}
CurrencyMetaData currencyMetaDataUpdated =
new CurrencyMetaData(
currencyMetaData.getScale(),
entry.getValue().getTxFee(),
currencyMetaData.getMinWithdrawalAmount(),
walletHealth);
currencyMetaDataMap.put(ccy, currencyMetaDataUpdated);
}
Map marketMetaDataMap = exchangeMetaData.getCurrencyPairs();
CurrencyPairMetaData marketArchetype = marketMetaDataMap.values().iterator().next();
for (String market : poloniexMarketData.keySet()) {
CurrencyPair currencyPair = PoloniexUtils.toCurrencyPair(market);
if (!marketMetaDataMap.containsKey(currencyPair))
marketMetaDataMap.put(currencyPair, marketArchetype);
}
return exchangeMetaData;
}
public static List adaptFundingRecords(
PoloniexDepositsWithdrawalsResponse poloFundings) {
final ArrayList fundingRecords = new ArrayList<>();
for (PoloniexAdjustment a : poloFundings.getAdjustments()) {
fundingRecords.add(adaptAdjustment(a));
}
for (PoloniexDeposit d : poloFundings.getDeposits()) {
fundingRecords.add(adaptDeposit(d));
}
for (PoloniexWithdrawal w : poloFundings.getWithdrawals()) {
fundingRecords.add(adaptWithdrawal(w));
}
return fundingRecords;
}
private static FundingRecord adaptAdjustment(PoloniexAdjustment a) {
FundingRecord.Type type = OTHER_INFLOW;
// There seems to be a spelling error in the returning reason. In case that ever gets
// corrected, this will still pick it up.
if (a.getReason().toLowerCase().contains("aidrop")
|| a.getReason().toLowerCase().contains("airdrop")) {
type = Type.AIRDROP;
}
// There could be other forms of adjustements, but it seems to be some kind of deposit.
return new FundingRecord(
null,
a.getTimestamp(),
Currency.getInstance(a.getCurrency()),
a.getAmount(),
null,
null,
type,
FundingRecord.Status.resolveStatus(a.getStatus()),
null,
null,
a.getCategory()
+ ":"
+ a.getReason()
+ "\n"
+ a.getAdjustmentTitle()
+ "\n"
+ a.getAdjustmentDesc()
+ "\n"
+ a.getAdjustmentHelp());
}
private static FundingRecord adaptDeposit(final PoloniexDeposit d) {
return new FundingRecord(
d.getAddress(),
d.getTimestamp(),
Currency.getInstance(d.getCurrency()),
d.getAmount(),
String.valueOf(d.getDepositNumber()),
d.getTxid(),
DEPOSIT,
FundingRecord.Status.resolveStatus(d.getStatus()),
null,
null,
d.getStatus());
}
private static FundingRecord adaptWithdrawal(final PoloniexWithdrawal w) {
final String[] statusParts = w.getStatus().split(": *");
final String statusStr = statusParts[0];
final FundingRecord.Status status = FundingRecord.Status.resolveStatus(statusStr);
final String externalId = statusParts.length == 1 ? null : statusParts[1];
// Poloniex returns the fee as an absolute value, that behaviour differs from UserTrades
final BigDecimal feeAmount = w.getFee();
return new FundingRecord(
w.getAddress(),
w.getTimestamp(),
Currency.getInstance(w.getCurrency()),
w.getAmount(),
String.valueOf(w.getWithdrawalNumber()),
externalId,
WITHDRAWAL,
status,
null,
feeAmount,
w.getStatus());
}
public static LimitOrder adaptUserTradesToOrderStatus(
String orderId, PoloniexUserTrade[] poloniexUserTrades) {
if (poloniexUserTrades.length == 0) return null;
OrderType orderType = null;
CurrencyPair currencyPair = null;
BigDecimal amount = new BigDecimal(0);
List weightedPrices = new ArrayList<>();
for (PoloniexUserTrade poloniexUserTrade : poloniexUserTrades) {
orderType =
poloniexUserTrade.getType().equals("buy")
? OrderType.BID
: OrderType.ASK; // what about others?
amount = amount.add(poloniexUserTrade.getAmount());
weightedPrices.add(poloniexUserTrade.getRate().multiply(poloniexUserTrade.getAmount()));
}
BigDecimal weightedAveragePrice =
weightedPrices.stream()
.reduce(new BigDecimal(0), BigDecimal::add)
.divide(amount, RoundingMode.HALF_UP);
return new LimitOrder(
orderType,
null,
currencyPair,
orderId,
null,
null,
weightedAveragePrice,
amount,
null,
Order.OrderStatus.UNKNOWN);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy