Skip to content

Commit

Permalink
Merge pull request #4981 from bigscoop/bitfinex-fixes
Browse files Browse the repository at this point in the history
[bitfinex] Minor fixes
  • Loading branch information
timmolter authored Dec 14, 2024
2 parents 41c1184 + e17c426 commit 494027c
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import com.fasterxml.jackson.databind.node.ArrayNode;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
Expand All @@ -20,6 +19,8 @@
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.knowm.xchange.bitfinex.v1.BitfinexOrderType;
import org.knowm.xchange.bitfinex.v1.BitfinexUtils;
import org.knowm.xchange.bitfinex.v1.dto.account.BitfinexAccountFeesResponse;
Expand Down Expand Up @@ -69,28 +70,25 @@
import org.knowm.xchange.instrument.Instrument;
import org.knowm.xchange.utils.DateUtils;
import org.knowm.xchange.utils.jackson.CurrencyPairDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class BitfinexAdapters {
@Slf4j
@UtilityClass
public class BitfinexAdapters {

public static final Logger log = LoggerFactory.getLogger(BitfinexAdapters.class);
private static final ObjectMapper mapper = new ObjectMapper();
private final ObjectMapper mapper = new ObjectMapper();

private static final AtomicBoolean warnedStopLimit = new AtomicBoolean();
private static final String USDT_SYMBOL_BITFINEX = "UST";
private static final String USDT_SYMBOL_XCHANGE = "USDT";
private static final int PLATFORM_STATUS_ONLINE = 1;
private static final int PLATFORM_STATUS_OFFLINE = 0;

private BitfinexAdapters() {}
private final AtomicBoolean warnedStopLimit = new AtomicBoolean();
private final String USDT_SYMBOL_BITFINEX = "UST";
private final String USDT_SYMBOL_XCHANGE = "USDT";
private final int PLATFORM_STATUS_ONLINE = 1;
private final int PLATFORM_STATUS_OFFLINE = 0;

/**
* Each element in the response array contains a set of currencies that are at a given fee tier.
* The API returns the fee per currency in each tier and does not make any promises that they are
* all the same, so this adapter will use the fee per currency instead of the fee per tier.
*/
public static Map<Instrument, Fee> adaptDynamicTradingFees(
public Map<Instrument, Fee> adaptDynamicTradingFees(
BitfinexTradingFeeResponse[] responses, List<Instrument> currencyPairs) {
Map<Instrument, Fee> result = new HashMap<>();
for (BitfinexTradingFeeResponse response : responses) {
Expand Down Expand Up @@ -118,15 +116,15 @@ public static Map<Instrument, Fee> adaptDynamicTradingFees(
return result;
}

public static String adaptBitfinexCurrency(String bitfinexSymbol) {
public String adaptBitfinexCurrency(String bitfinexSymbol) {
String result = bitfinexSymbol.toUpperCase();
if (USDT_SYMBOL_BITFINEX.equals(result)) {
result = USDT_SYMBOL_XCHANGE;
}
return result;
}

public static String adaptOrderType(OrderType type) {
public String adaptOrderType(OrderType type) {
switch (type) {
case BID:
case EXIT_BID:
Expand All @@ -139,7 +137,7 @@ public static String adaptOrderType(OrderType type) {
throw new IllegalArgumentException(String.format("Unexpected type of order: %s", type));
}

public static BitfinexOrderType adaptOrderFlagsToType(Set<Order.IOrderFlags> flags) {
public BitfinexOrderType adaptOrderFlagsToType(Set<Order.IOrderFlags> flags) {
if (flags.contains(BitfinexOrderFlags.MARGIN)) {
if (flags.contains(BitfinexOrderFlags.FILL_OR_KILL)) {
return BitfinexOrderType.MARGIN_FILL_OR_KILL;
Expand All @@ -163,7 +161,7 @@ public static BitfinexOrderType adaptOrderFlagsToType(Set<Order.IOrderFlags> fla
}
}

public static CurrencyPair adaptCurrencyPair(String bitfinexSymbol) {
public CurrencyPair adaptCurrencyPair(String bitfinexSymbol) {
String tradableIdentifier;
String transactionCurrency;
int startIndex =
Expand All @@ -182,7 +180,7 @@ public static CurrencyPair adaptCurrencyPair(String bitfinexSymbol) {
adaptBitfinexCurrency(tradableIdentifier), adaptBitfinexCurrency(transactionCurrency));
}

public static OrderStatus adaptOrderStatus(BitfinexOrderStatusResponse order) {
public OrderStatus adaptOrderStatus(BitfinexOrderStatusResponse order) {

if (order.isCancelled()) return OrderStatus.CANCELED;
else if (order.getExecutedAmount().compareTo(BigDecimal.ZERO) == 0) return OrderStatus.NEW;
Expand All @@ -193,25 +191,25 @@ else if (order.getExecutedAmount().compareTo(order.getOriginalAmount()) == 0)
else return null;
}

public static String adaptCurrencyPair(CurrencyPair pair) {
public String adaptCurrencyPair(CurrencyPair pair) {
return BitfinexUtils.toPairString(pair);
}

public static OrderBook adaptOrderBook(BitfinexDepth btceDepth, CurrencyPair currencyPair) {
public OrderBook adaptOrderBook(BitfinexDepth btceDepth, Instrument instrument) {

OrdersContainer asksOrdersContainer =
adaptOrders(btceDepth.getAsks(), currencyPair, OrderType.ASK);
adaptOrders(btceDepth.getAsks(), instrument, OrderType.ASK);
OrdersContainer bidsOrdersContainer =
adaptOrders(btceDepth.getBids(), currencyPair, OrderType.BID);
adaptOrders(btceDepth.getBids(), instrument, OrderType.BID);

return new OrderBook(
new Date(Math.max(asksOrdersContainer.getTimestamp(), bidsOrdersContainer.getTimestamp())),
asksOrdersContainer.getLimitOrders(),
bidsOrdersContainer.getLimitOrders());
}

public static OrdersContainer adaptOrders(
BitfinexLevel[] bitfinexLevels, CurrencyPair currencyPair, OrderType orderType) {
public OrdersContainer adaptOrders(
BitfinexLevel[] bitfinexLevels, Instrument instrument, OrderType orderType) {

BigDecimal maxTimestamp = new BigDecimal(Long.MIN_VALUE);
List<LimitOrder> limitOrders = new ArrayList<>(bitfinexLevels.length);
Expand All @@ -226,7 +224,7 @@ public static OrdersContainer adaptOrders(
adaptOrder(
bitfinexLevel.getAmount(),
bitfinexLevel.getPrice(),
currencyPair,
instrument,
orderType,
timestamp));
}
Expand All @@ -235,17 +233,17 @@ public static OrdersContainer adaptOrders(
return new OrdersContainer(maxTimestampInMillis, limitOrders);
}

public static LimitOrder adaptOrder(
public LimitOrder adaptOrder(
BigDecimal originalAmount,
BigDecimal price,
CurrencyPair currencyPair,
Instrument instrument,
OrderType orderType,
Date timestamp) {

return new LimitOrder(orderType, originalAmount, currencyPair, "", timestamp, price);
return new LimitOrder(orderType, originalAmount, instrument, "", timestamp, price);
}

public static List<FixedRateLoanOrder> adaptFixedRateLoanOrders(
public List<FixedRateLoanOrder> adaptFixedRateLoanOrders(
BitfinexLendLevel[] orders, String currency, String orderType, String id) {

List<FixedRateLoanOrder> loanOrders = new ArrayList<>(orders.length);
Expand All @@ -271,7 +269,7 @@ public static List<FixedRateLoanOrder> adaptFixedRateLoanOrders(
return loanOrders;
}

public static FixedRateLoanOrder adaptFixedRateLoanOrder(
public FixedRateLoanOrder adaptFixedRateLoanOrder(
String currency,
BigDecimal amount,
int dayPeriod,
Expand All @@ -284,7 +282,7 @@ public static FixedRateLoanOrder adaptFixedRateLoanOrder(
return new FixedRateLoanOrder(orderType, currency, amount, dayPeriod, id, null, rate);
}

public static List<FloatingRateLoanOrder> adaptFloatingRateLoanOrders(
public List<FloatingRateLoanOrder> adaptFloatingRateLoanOrders(
BitfinexLendLevel[] orders, String currency, String orderType, String id) {

List<FloatingRateLoanOrder> loanOrders = new ArrayList<>(orders.length);
Expand All @@ -310,7 +308,7 @@ public static List<FloatingRateLoanOrder> adaptFloatingRateLoanOrders(
return loanOrders;
}

public static FloatingRateLoanOrder adaptFloatingRateLoanOrder(
public FloatingRateLoanOrder adaptFloatingRateLoanOrder(
String currency,
BigDecimal amount,
int dayPeriod,
Expand All @@ -323,7 +321,7 @@ public static FloatingRateLoanOrder adaptFloatingRateLoanOrder(
return new FloatingRateLoanOrder(orderType, currency, amount, dayPeriod, id, null, rate);
}

public static Trade adaptTrade(BitfinexTrade trade, CurrencyPair currencyPair) {
public Trade adaptTrade(BitfinexTrade trade, CurrencyPair currencyPair) {

OrderType orderType = trade.getType().equals("buy") ? OrderType.BID : OrderType.ASK;
BigDecimal amount = trade.getAmount();
Expand All @@ -341,7 +339,7 @@ public static Trade adaptTrade(BitfinexTrade trade, CurrencyPair currencyPair) {
.build();
}

public static Trades adaptTrades(BitfinexTrade[] trades, CurrencyPair currencyPair) {
public Trades adaptTrades(BitfinexTrade[] trades, CurrencyPair currencyPair) {

List<Trade> tradesList = new ArrayList<>(trades.length);
long lastTradeId = 0;
Expand All @@ -355,7 +353,7 @@ public static Trades adaptTrades(BitfinexTrade[] trades, CurrencyPair currencyPa
return new Trades(tradesList, lastTradeId, TradeSortType.SortByID);
}

public static Ticker adaptTicker(BitfinexTicker bitfinexTicker, CurrencyPair currencyPair) {
public Ticker adaptTicker(BitfinexTicker bitfinexTicker, CurrencyPair currencyPair) {

BigDecimal last = bitfinexTicker.getLast_price();
BigDecimal bid = bitfinexTicker.getBid();
Expand All @@ -382,7 +380,7 @@ public static Ticker adaptTicker(BitfinexTicker bitfinexTicker, CurrencyPair cur
.build();
}

public static List<Wallet> adaptWallets(BitfinexBalancesResponse[] response) {
public List<Wallet> adaptWallets(BitfinexBalancesResponse[] response) {

Map<String, Map<String, BigDecimal[]>> walletsBalancesMap = new HashMap<>();

Expand Down Expand Up @@ -427,7 +425,7 @@ public static List<Wallet> adaptWallets(BitfinexBalancesResponse[] response) {
return wallets;
}

public static OpenOrders adaptOrders(BitfinexOrderStatusResponse[] activeOrders) {
public OpenOrders adaptOrders(BitfinexOrderStatusResponse[] activeOrders) {

List<LimitOrder> limitOrders = new ArrayList<>();
List<Order> hiddenOrders = new ArrayList<>();
Expand Down Expand Up @@ -563,7 +561,7 @@ public static OpenOrders adaptOrders(BitfinexOrderStatusResponse[] activeOrders)
return new OpenOrders(limitOrders, hiddenOrders);
}

private static void stopLimitWarning() {
private void stopLimitWarning() {
if (warnedStopLimit.compareAndSet(false, true)) {
log.warn(
"Found a stop-limit order. Bitfinex v1 API does not return limit prices for stop-limit "
Expand All @@ -572,7 +570,7 @@ private static void stopLimitWarning() {
}
}

public static UserTrades adaptTradeHistory(BitfinexTradeResponse[] trades, String symbol) {
public UserTrades adaptTradeHistory(BitfinexTradeResponse[] trades, String symbol) {

List<UserTrade> pastTrades = new ArrayList<>(trades.length);
CurrencyPair currencyPair = adaptCurrencyPair(symbol);
Expand All @@ -598,7 +596,7 @@ public static UserTrades adaptTradeHistory(BitfinexTradeResponse[] trades, Strin
return new UserTrades(pastTrades, TradeSortType.SortByTimestamp);
}

public static UserTrades adaptTradeHistoryV2(
public UserTrades adaptTradeHistoryV2(
List<org.knowm.xchange.bitfinex.v2.dto.trade.Trade> trades) {

List<UserTrade> pastTrades = new ArrayList<>(trades.size());
Expand Down Expand Up @@ -627,13 +625,13 @@ public static UserTrades adaptTradeHistoryV2(
return new UserTrades(pastTrades, TradeSortType.SortByTimestamp);
}

private static Date convertBigDecimalTimestampToDate(BigDecimal timestamp) {
private Date convertBigDecimalTimestampToDate(BigDecimal timestamp) {

BigDecimal timestampInMillis = timestamp.multiply(new BigDecimal("1000"));
return new Date(timestampInMillis.longValue());
}

public static ExchangeMetaData adaptMetaData(
public ExchangeMetaData adaptMetaData(
List<CurrencyPair> currencyPairs, ExchangeMetaData metaData) {

Map<Instrument, InstrumentMetaData> pairsMap = metaData.getInstruments();
Expand Down Expand Up @@ -679,7 +677,7 @@ public static ExchangeMetaData adaptMetaData(
* @param symbolDetails The symbol data fetced from Bitfinex.
* @return The combined result.
*/
public static ExchangeMetaData adaptMetaData(
public ExchangeMetaData adaptMetaData(
ExchangeMetaData exchangeMetaData,
List<BitfinexSymbolDetail> symbolDetails,
Map<CurrencyPair, BigDecimal> lastPrices) {
Expand Down Expand Up @@ -713,7 +711,7 @@ public static ExchangeMetaData adaptMetaData(
return exchangeMetaData;
}

public static ExchangeMetaData adaptMetaData(
public ExchangeMetaData adaptMetaData(
BitfinexAccountFeesResponse accountFeesResponse,
int platformStatus,
boolean platformStatusPresent,
Expand Down Expand Up @@ -749,7 +747,7 @@ public static ExchangeMetaData adaptMetaData(
return metaData;
}

public static ExchangeMetaData adaptMetaData(
public ExchangeMetaData adaptMetaData(
BitfinexAccountInfosResponse[] bitfinexAccountInfos, ExchangeMetaData exchangeMetaData) {
final Map<Instrument, InstrumentMetaData> currencyPairs = exchangeMetaData.getInstruments();

Expand Down Expand Up @@ -778,7 +776,7 @@ public static ExchangeMetaData adaptMetaData(
return exchangeMetaData;
}

public static List<FundingRecord> adaptFundingHistory(List<Movement> movementHistorys) {
public List<FundingRecord> adaptFundingHistory(List<Movement> movementHistorys) {
final List<FundingRecord> fundingRecords = new ArrayList<>();
for (Movement movement : movementHistorys) {
Currency currency = Currency.getInstance(movement.getCurency());
Expand Down Expand Up @@ -825,7 +823,7 @@ public static List<FundingRecord> adaptFundingHistory(List<Movement> movementHis
return fundingRecords;
}

public static List<FundingRecord> adaptFundingHistory(
public List<FundingRecord> adaptFundingHistory(
BitfinexDepositWithdrawalHistoryResponse[] bitfinexDepositWithdrawalHistoryResponses) {
final List<FundingRecord> fundingRecords = new ArrayList<>();
for (BitfinexDepositWithdrawalHistoryResponse responseEntry :
Expand Down Expand Up @@ -887,7 +885,7 @@ and sometimes like this (with the address in it as well as the txn hash):
return fundingRecords;
}

public static class OrdersContainer {
public class OrdersContainer {

private final long timestamp;
private final List<LimitOrder> limitOrders;
Expand Down Expand Up @@ -917,15 +915,15 @@ public List<LimitOrder> getLimitOrders() {

////// v2

public static String adaptCurrencyPairsToTickersParam(Collection<CurrencyPair> currencyPairs) {
public String adaptCurrencyPairsToTickersParam(Collection<CurrencyPair> currencyPairs) {
return currencyPairs == null || currencyPairs.isEmpty()
? "ALL"
: currencyPairs.stream()
.map(BitfinexAdapters::adaptCurrencyPair)
.collect(Collectors.joining(","));
}

public static Ticker adaptTicker(
public Ticker adaptTicker(
org.knowm.xchange.bitfinex.v2.dto.marketdata.BitfinexTicker bitfinexTicker) {

BigDecimal last = bitfinexTicker.getLastPrice();
Expand All @@ -936,8 +934,8 @@ public static Ticker adaptTicker(
BigDecimal high = bitfinexTicker.getHigh();
BigDecimal low = bitfinexTicker.getLow();
BigDecimal volume = bitfinexTicker.getVolume();
BigDecimal percentageChange =
bitfinexTicker.getDailyChangePerc().multiply(new BigDecimal("100"), new MathContext(8));
BigDecimal percentageChange = bitfinexTicker.getDailyChangePerc() != null ?
bitfinexTicker.getDailyChangePerc().scaleByPowerOfTen(2) : null;

CurrencyPair currencyPair =
CurrencyPairDeserializer.getCurrencyPairFromString(bitfinexTicker.getSymbol().substring(1));
Expand All @@ -956,7 +954,7 @@ public static Ticker adaptTicker(
.build();
}

public static Trade adaptPublicTrade(BitfinexPublicTrade trade, CurrencyPair currencyPair) {
public Trade adaptPublicTrade(BitfinexPublicTrade trade, CurrencyPair currencyPair) {

OrderType orderType = trade.getType();
BigDecimal amount = trade.getAmount();
Expand All @@ -973,7 +971,7 @@ public static Trade adaptPublicTrade(BitfinexPublicTrade trade, CurrencyPair cur
.build();
}

public static Trades adaptPublicTrades(BitfinexPublicTrade[] trades, CurrencyPair currencyPair) {
public Trades adaptPublicTrades(BitfinexPublicTrade[] trades, CurrencyPair currencyPair) {

List<Trade> tradesList = new ArrayList<>(trades.length);
long lastTradeId = 0;
Expand All @@ -987,7 +985,7 @@ public static Trades adaptPublicTrades(BitfinexPublicTrade[] trades, CurrencyPai
return new Trades(tradesList, lastTradeId, TradeSortType.SortByID);
}

public static org.knowm.xchange.bitfinex.v2.dto.marketdata.BitfinexTicker[] adoptBitfinexTickers(
public org.knowm.xchange.bitfinex.v2.dto.marketdata.BitfinexTicker[] adoptBitfinexTickers(
List<ArrayNode> tickers) throws IOException {

return tickers.stream()
Expand Down
Loading

0 comments on commit 494027c

Please sign in to comment.