Skip to content

Commit

Permalink
Merge branch 'knowm-develop' into code-cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
bigscoop committed May 21, 2024
2 parents 736d36e + ae208df commit 2cab9c9
Show file tree
Hide file tree
Showing 33 changed files with 496 additions and 369 deletions.
6 changes: 6 additions & 0 deletions xchange-binance/http-client.env.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"default": {
"api_host": "https://api.binance.com",
"data_api_host": "https://data-api.binance.vision"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.knowm.xchange.binance.dto.account.AssetDetail;
Expand All @@ -18,7 +23,7 @@
import org.knowm.xchange.binance.dto.marketdata.BinanceAggTrades;
import org.knowm.xchange.binance.dto.marketdata.BinanceFundingRate;
import org.knowm.xchange.binance.dto.marketdata.BinanceKline;
import org.knowm.xchange.binance.dto.marketdata.BinancePriceQuantity;
import org.knowm.xchange.binance.dto.marketdata.BinanceTicker24h;
import org.knowm.xchange.binance.dto.meta.exchangeinfo.BinanceExchangeInfo;
import org.knowm.xchange.binance.dto.meta.exchangeinfo.Filter;
import org.knowm.xchange.binance.dto.meta.exchangeinfo.Symbol;
Expand All @@ -36,18 +41,32 @@
import org.knowm.xchange.dto.account.Balance;
import org.knowm.xchange.dto.account.OpenPosition;
import org.knowm.xchange.dto.account.Wallet;
import org.knowm.xchange.dto.marketdata.*;
import org.knowm.xchange.dto.marketdata.CandleStick;
import org.knowm.xchange.dto.marketdata.CandleStickData;
import org.knowm.xchange.dto.marketdata.FundingRate;
import org.knowm.xchange.dto.marketdata.FundingRates;
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.meta.CurrencyMetaData;
import org.knowm.xchange.dto.meta.ExchangeMetaData;
import org.knowm.xchange.dto.meta.InstrumentMetaData;
import org.knowm.xchange.dto.meta.WalletHealth;
import org.knowm.xchange.dto.trade.*;
import org.knowm.xchange.dto.trade.LimitOrder;
import org.knowm.xchange.dto.trade.MarketOrder;
import org.knowm.xchange.dto.trade.OpenOrders;
import org.knowm.xchange.dto.trade.StopOrder;
import org.knowm.xchange.dto.trade.UserTrade;
import org.knowm.xchange.dto.trade.UserTrades;
import org.knowm.xchange.instrument.Instrument;

public class BinanceAdapters {
private static final DateTimeFormatter DATE_TIME_FMT =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

private static final Map<String, CurrencyPair> SYMBOL_TO_CURRENCY_PAIR = new HashMap<>();


private BinanceAdapters() {}

/**
Expand Down Expand Up @@ -134,17 +153,6 @@ public static OrderSide convert(OrderType type) {
}
}

public static CurrencyPair convert(String symbol) {
// Iterate by base currency priority at binance.
for (Currency base : Arrays.asList(Currency.BTC, Currency.ETH, Currency.BNB, Currency.USDT)) {
if (symbol.contains(base.toString())) {
String counter = symbol.replace(base.toString(), "");
return new CurrencyPair(base, new Currency(counter));
}
}
throw new IllegalArgumentException("Could not parse currency pair from '" + symbol + "'");
}

public static long id(String id) {
try {
return Long.parseLong(id);
Expand Down Expand Up @@ -178,23 +186,19 @@ public static OrderType convertType(boolean isBuyer) {
return isBuyer ? OrderType.BID : OrderType.ASK;
}


public static void putSymbolMapping(String symbol, CurrencyPair currencyPair) {
SYMBOL_TO_CURRENCY_PAIR.put(symbol, currencyPair);
}


public static CurrencyPair toCurrencyPair(String symbol) {
return SYMBOL_TO_CURRENCY_PAIR.get(symbol);
}


public static Instrument adaptSymbol(String symbol, boolean isFuture) {
int pairLength = symbol.length();
CurrencyPair currencyPair;
if (symbol.endsWith("USDT")) {
currencyPair = new CurrencyPair(symbol.substring(0, pairLength - 4), "USDT");
} else if (symbol.endsWith("USDC")) {
currencyPair = new CurrencyPair(symbol.substring(0, pairLength - 4), "USDC");
} else if (symbol.endsWith("TUSD")) {
currencyPair = new CurrencyPair(symbol.substring(0, pairLength - 4), "TUSD");
} else if (symbol.endsWith("USDS")) {
currencyPair = new CurrencyPair(symbol.substring(0, pairLength - 4), "USDS");
} else if (symbol.endsWith("BUSD")) {
currencyPair = new CurrencyPair(symbol.substring(0, pairLength - 4), "BUSD");
} else {
currencyPair =
new CurrencyPair(symbol.substring(0, pairLength - 3), symbol.substring(pairLength - 3));
}
CurrencyPair currencyPair = toCurrencyPair(symbol);

return (isFuture) ? new FuturesContract(currencyPair, "PERP") : currencyPair;
}
Expand Down Expand Up @@ -243,22 +247,28 @@ public static Order adaptOrder(BinanceOrder order, boolean isFuture) {
return builder.build();
}

private static Ticker adaptPriceQuantity(BinancePriceQuantity priceQuantity, boolean isFuture) {

public static Ticker toTicker(BinanceTicker24h binanceTicker24h, boolean isFuture) {
Instrument instrument = (isFuture) ? new FuturesContract(binanceTicker24h.getCurrencyPair(), "PERP"): binanceTicker24h.getCurrencyPair();
return new Ticker.Builder()
.instrument(adaptSymbol(priceQuantity.symbol, isFuture))
.ask(priceQuantity.askPrice)
.askSize(priceQuantity.askQty)
.bid(priceQuantity.bidPrice)
.bidSize(priceQuantity.bidQty)
.instrument(instrument)
.open(binanceTicker24h.getOpenPrice())
.ask(binanceTicker24h.getAskPrice())
.bid(binanceTicker24h.getBidPrice())
.last(binanceTicker24h.getLastPrice())
.high(binanceTicker24h.getHighPrice())
.low(binanceTicker24h.getLowPrice())
.volume(binanceTicker24h.getVolume())
.vwap(binanceTicker24h.getWeightedAvgPrice())
.askSize(binanceTicker24h.getAskQty())
.bidSize(binanceTicker24h.getBidQty())
.quoteVolume(binanceTicker24h.getQuoteVolume())
.timestamp(
binanceTicker24h.getCloseTime() > 0 ? new Date(binanceTicker24h.getCloseTime()) : null)
.percentageChange(binanceTicker24h.getPriceChangePercent())
.build();
}

public static List<Ticker> adaptPriceQuantities(
List<BinancePriceQuantity> priceQuantities, boolean isFuture) {
return priceQuantities.stream()
.map(binancePriceQuantity -> adaptPriceQuantity(binancePriceQuantity, isFuture))
.collect(Collectors.toList());
}

static CurrencyMetaData adaptCurrencyMetaData(
Map<Currency, CurrencyMetaData> currencies,
Expand Down Expand Up @@ -462,7 +472,7 @@ public static CandleStickData adaptBinanceCandleStickData(

public static void adaptFutureExchangeMetaData(
ExchangeMetaData exchangeMetaData, BinanceExchangeInfo binanceExchangeInfo) {
Symbol[] futureSymbols = binanceExchangeInfo.getSymbols();
List<Symbol> futureSymbols = binanceExchangeInfo.getSymbols();

for (Symbol futureSymbol : futureSymbols) {
if (futureSymbol.getStatus().equals("TRADING")) { // Symbols which are trading
Expand Down Expand Up @@ -527,7 +537,7 @@ public static ExchangeMetaData adaptExchangeMetaData(
Map<Instrument, InstrumentMetaData> instruments = new HashMap<>();
Map<Currency, CurrencyMetaData> currencies = new HashMap<>();

Symbol[] symbols = binanceExchangeInfo.getSymbols();
List<Symbol> symbols = binanceExchangeInfo.getSymbols();

for (Symbol symbol : symbols) {
if (symbol.getStatus().equals("TRADING")) { // Symbols which are trading
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@
import static org.knowm.xchange.binance.dto.ExchangeType.SPOT;

import java.util.Map;
import org.apache.commons.lang3.ObjectUtils;
import org.knowm.xchange.BaseExchange;
import org.knowm.xchange.Exchange;
import org.knowm.xchange.ExchangeSpecification;
import org.knowm.xchange.binance.dto.ExchangeType;
import org.knowm.xchange.binance.dto.account.AssetDetail;
import org.knowm.xchange.binance.dto.meta.exchangeinfo.BinanceExchangeInfo;
import org.knowm.xchange.binance.service.BinanceAccountService;
import org.knowm.xchange.binance.service.BinanceMarketDataService;
import org.knowm.xchange.binance.service.BinanceMarketDataServiceRaw;
import org.knowm.xchange.binance.service.BinanceTradeService;
import org.knowm.xchange.client.ExchangeRestProxyBuilder;
import org.knowm.xchange.client.ResilienceRegistries;
import org.knowm.xchange.currency.CurrencyPair;
import org.knowm.xchange.exceptions.ExchangeException;
import org.knowm.xchange.utils.AuthUtils;
import si.mazi.rescu.SynchronizedValueFactory;
Expand Down Expand Up @@ -100,34 +103,32 @@ public boolean usingSandbox() {
@Override
public void remoteInit() {
try {
BinanceMarketDataService marketDataService =
(BinanceMarketDataService) this.marketDataService;
BinanceMarketDataServiceRaw marketDataServiceRaw = (BinanceMarketDataServiceRaw) marketDataService;
BinanceAccountService accountService = (BinanceAccountService) getAccountService();
Map<String, AssetDetail> assetDetailMap = null;
if (!usingSandbox() && isAuthenticated()) {
assetDetailMap = accountService.getAssetDetails(); // not available in sndbox
}
//hook for Binance US
if(exchangeSpecification.getExchangeSpecificParametersItem(EXCHANGE_TYPE) ==null) {
exchangeMetaData =
BinanceAdapters.adaptExchangeMetaData(
marketDataService.getExchangeInfo(), assetDetailMap);
} else {
switch ((ExchangeType) exchangeSpecification.getExchangeSpecificParametersItem(
EXCHANGE_TYPE)) {
case SPOT: {
exchangeMetaData =
BinanceAdapters.adaptExchangeMetaData(
marketDataService.getExchangeInfo(), assetDetailMap);
break;
}
case FUTURES: {
BinanceAdapters.adaptFutureExchangeMetaData(
exchangeMetaData, marketDataService.getFutureExchangeInfo());
break;
}
}

BinanceExchangeInfo exchangeInfo;
// get exchange type or SPOT as default
ExchangeType exchangeType = (ExchangeType) ObjectUtils.defaultIfNull(exchangeSpecification.getExchangeSpecificParametersItem(EXCHANGE_TYPE), SPOT);

switch (exchangeType) {
case FUTURES:
exchangeInfo = marketDataServiceRaw.getFutureExchangeInfo();
BinanceAdapters.adaptFutureExchangeMetaData(exchangeMetaData, exchangeInfo);
break;
default:
exchangeInfo = marketDataServiceRaw.getExchangeInfo();
exchangeMetaData = BinanceAdapters.adaptExchangeMetaData(exchangeInfo, assetDetailMap);
}

// init symbol mappings
exchangeInfo.getSymbols().stream()
.filter(symbol -> ObjectUtils.allNotNull(symbol.getBaseAsset(), symbol.getQuoteAsset(), symbol.getSymbol()))
.forEach(symbol -> BinanceAdapters.putSymbolMapping(symbol.getSymbol(), new CurrencyPair(symbol.getBaseAsset(), symbol.getQuoteAsset())));

} catch (Exception e) {
throw new ExchangeException("Failed to initialize: " + e.getMessage(), e);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package org.knowm.xchange.binance;

import static org.knowm.xchange.binance.dto.ExchangeType.SPOT;

import java.io.IOException;
import org.knowm.xchange.ExchangeSpecification;
import org.knowm.xchange.binance.service.BinanceMarketDataService;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.knowm.xchange.binance.config.converter;

import com.fasterxml.jackson.databind.util.StdConverter;
import org.knowm.xchange.binance.BinanceAdapters;
import org.knowm.xchange.currency.CurrencyPair;

/** Converts string to {@code CurrencyPair} */
public class StringToCurrencyPairConverter extends StdConverter<String, CurrencyPair> {

@Override
public CurrencyPair convert(String value) {
return BinanceAdapters.toCurrencyPair(value);
}
}
Original file line number Diff line number Diff line change
@@ -1,59 +1,28 @@
package org.knowm.xchange.binance.dto.marketdata;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.math.BigDecimal;
import lombok.Builder;
import lombok.Data;
import lombok.extern.jackson.Jacksonized;
import org.knowm.xchange.binance.config.converter.StringToCurrencyPairConverter;
import org.knowm.xchange.currency.CurrencyPair;
import org.knowm.xchange.utils.Assert;
import org.knowm.xchange.utils.jackson.CurrencyPairDeserializer;

public final class BinancePrice implements Comparable<BinancePrice> {
@Data
@Builder
@Jacksonized
public class BinancePrice {

private final CurrencyPair pair;
private final BigDecimal price;
@JsonProperty("symbol")
@JsonDeserialize(converter = StringToCurrencyPairConverter.class)
CurrencyPair currencyPair;

public BinancePrice(
@JsonProperty("symbol") String symbol, @JsonProperty("price") BigDecimal price) {
this(CurrencyPairDeserializer.getCurrencyPairFromString(symbol), price);
}

public BinancePrice(CurrencyPair pair, BigDecimal price) {
Assert.notNull(price, "Null price");
Assert.notNull(pair, "Null pair");
this.pair = pair;
this.price = price;
}

public CurrencyPair getCurrencyPair() {
return pair;
}

public BigDecimal getPrice() {
return price;
}

@Override
public int compareTo(BinancePrice o) {
if (pair.compareTo(o.pair) == 0) return price.compareTo(o.price);
return pair.compareTo(o.pair);
}
@JsonProperty("price")
BigDecimal price;

@Override
public int hashCode() {
int result = 1;
result = 31 * result + ((pair == null) ? 0 : pair.hashCode());
result = 31 * result + ((price == null) ? 0 : price.hashCode());
return result;
public boolean isValid() {
return currencyPair != null && price != null;
}

@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof BinancePrice)) return false;
BinancePrice other = (BinancePrice) obj;
return pair.equals(other.pair) && price.equals(other.price);
}

public String toString() {
return "[" + pair + "] => " + price;
}
}
Loading

0 comments on commit 2cab9c9

Please sign in to comment.