Skip to content

Commit

Permalink
[binance] Merge develop branch
Browse files Browse the repository at this point in the history
  • Loading branch information
bigscoop committed May 13, 2024
2 parents 8606a12 + 52641e0 commit e0b3da0
Show file tree
Hide file tree
Showing 10 changed files with 328 additions and 89 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package org.knowm.xchange.binance;

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;
Expand All @@ -18,16 +21,16 @@
import si.mazi.rescu.SynchronizedValueFactory;

public class BinanceExchange extends BaseExchange implements Exchange {
public static final String SPECIFIC_PARAM_USE_SANDBOX = "Use_Sandbox";
public static final String SPECIFIC_PARAM_USE_FUTURES_SANDBOX = "Use_Sandbox_Futures";
public static final String SPECIFIC_PARAM_FUTURES_ENABLED = "Futures_Enabled";
public static final String SPECIFIC_PARAM_PORTFOLIO_MARGIN_ENABLED = "Portfolio_Margin_Enabled";
public static String EXCHANGE_TYPE = "Exchange_Type";
private static final String SPOT_URL = "https://api.binance.com";
public static final String FUTURES_URL = "https://dapi.binance.com";
public static final String FUTURES_URL = "https://fapi.binance.com";
public static final String INVERSE_FUTURES_URL = "https://dapi.binance.com";
public static final String PORTFOLIO_MARGIN_URL = "https://papi.binance.com";

public static final String SANDBOX_SPOT_URL = "https://testnet.binance.vision";
public static final String SANDBOX_FUTURES_URL = "https://testnet.binancefuture.com";
public static final String SANDBOX_INVERSE_FUTURES_URL = "https://testnet.binancefuture.com";

protected static ResilienceRegistries RESILIENCE_REGISTRIES;
protected SynchronizedValueFactory<Long> timestampFactory;

Expand Down Expand Up @@ -65,13 +68,14 @@ public ResilienceRegistries getResilienceRegistries() {

@Override
public ExchangeSpecification getDefaultExchangeSpecification() {

ExchangeSpecification spec = new ExchangeSpecification(this.getClass());
spec.setSslUri(SPOT_URL);
spec.setHost("www.binance.com");
spec.setPort(80);
spec.setExchangeName("Binance");
spec.setExchangeDescription("Binance Exchange.");
spec.setExchangeSpecificParametersItem(EXCHANGE_TYPE, SPOT);
spec.setExchangeSpecificParametersItem(USE_SANDBOX, false);
AuthUtils.setApiAndSecretKey(spec, "binance");
return spec;
}
Expand All @@ -82,21 +86,14 @@ public void applySpecification(ExchangeSpecification exchangeSpecification) {
super.applySpecification(exchangeSpecification);
}

public boolean isFuturesSandbox() {
return Boolean.TRUE.equals(
exchangeSpecification.getExchangeSpecificParametersItem(
SPECIFIC_PARAM_USE_FUTURES_SANDBOX));
}

public boolean isFuturesEnabled() {
return Boolean.TRUE.equals(
exchangeSpecification.getExchangeSpecificParametersItem(SPECIFIC_PARAM_FUTURES_ENABLED));
return ExchangeType.FUTURES.equals(exchangeSpecification.
getExchangeSpecificParametersItem(EXCHANGE_TYPE));
}

public boolean isPortfolioMarginEnabled() {
return Boolean.TRUE.equals(
exchangeSpecification.getExchangeSpecificParametersItem(
SPECIFIC_PARAM_PORTFOLIO_MARGIN_ENABLED));
return ExchangeType.PORTFOLIO_MARGIN.equals(exchangeSpecification
.getExchangeSpecificParametersItem(EXCHANGE_TYPE));
}

public boolean usingSandbox() {
Expand All @@ -105,32 +102,26 @@ public boolean usingSandbox() {

@Override
public void remoteInit() {

try {
BinanceMarketDataServiceRaw marketDataServiceRaw = (BinanceMarketDataServiceRaw) marketDataService;

BinanceAccountService accountService = (BinanceAccountService) getAccountService();
Map<String, AssetDetail> assetDetailMap = null;
if (!usingSandbox() && isAuthenticated()) {
assetDetailMap = accountService.getAssetDetails(); // not available in sndbox
}

BinanceExchangeInfo exchangeInfo;
if (usingSandbox()) {
if (isFuturesSandbox()) {
// 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);
} else {
break;
default:
exchangeInfo = marketDataServiceRaw.getExchangeInfo();
exchangeMetaData = BinanceAdapters.adaptExchangeMetaData(exchangeInfo, assetDetailMap);
}
} else {
exchangeInfo = marketDataServiceRaw.getExchangeInfo();
exchangeMetaData = BinanceAdapters.adaptExchangeMetaData(exchangeInfo, assetDetailMap);
if (isFuturesEnabled()) {
exchangeInfo = marketDataServiceRaw.getFutureExchangeInfo();
BinanceAdapters.adaptFutureExchangeMetaData(exchangeMetaData, exchangeInfo);
}
}

// init symbol mappings
Expand All @@ -149,21 +140,38 @@ protected boolean isAuthenticated() {
&& exchangeSpecification.getSecretKey() != null;
}

/** Adjust host parameters depending on exchange specific parameters */
/**
* Adjust host parameters depending on exchange specific parameters
*/
private static void concludeHostParams(ExchangeSpecification exchangeSpecification) {
if (exchangeSpecification.getExchangeSpecificParameters() != null) {
if (enabledSandbox(exchangeSpecification)) {
exchangeSpecification.setSslUri("https://testnet.binance.vision");
exchangeSpecification.setHost("testnet.binance.vision");
if(exchangeSpecification.getExchangeSpecificParametersItem(EXCHANGE_TYPE) != null) {
switch ((ExchangeType)exchangeSpecification.getExchangeSpecificParametersItem(EXCHANGE_TYPE)) {
case SPOT: {
if (enabledSandbox(exchangeSpecification))
exchangeSpecification.setSslUri(SANDBOX_SPOT_URL);
break;
}
case FUTURES: {
if (!enabledSandbox(exchangeSpecification))
exchangeSpecification.setSslUri(FUTURES_URL);
else
exchangeSpecification.setSslUri(SANDBOX_FUTURES_URL);
break;
}
case INVERSE: {
if (!enabledSandbox(exchangeSpecification))
exchangeSpecification.setSslUri(INVERSE_FUTURES_URL);
else
exchangeSpecification.setSslUri(SANDBOX_INVERSE_FUTURES_URL);
break;
}
}
}
}


private static boolean enabledSandbox(ExchangeSpecification exchangeSpecification) {
return Boolean.TRUE.equals(
exchangeSpecification.getExchangeSpecificParametersItem(SPECIFIC_PARAM_USE_SANDBOX))
|| Boolean.TRUE.equals(
exchangeSpecification.getExchangeSpecificParametersItem(
SPECIFIC_PARAM_USE_FUTURES_SANDBOX));
return Boolean.TRUE.equals(exchangeSpecification.getExchangeSpecificParametersItem(USE_SANDBOX));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.knowm.xchange.binance.dto;

import lombok.Getter;

@Getter
public enum ExchangeType {
SPOT,
FUTURES,
INVERSE,
PORTFOLIO_MARGIN;
}

Original file line number Diff line number Diff line change
@@ -1,23 +1,39 @@
package org.knowm.xchange.binance.service;

import static org.knowm.xchange.binance.BinanceExchange.EXCHANGE_TYPE;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Instant;
import java.util.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.knowm.xchange.binance.BinanceAdapters;
import org.knowm.xchange.binance.BinanceErrorAdapter;
import org.knowm.xchange.binance.BinanceExchange;
import org.knowm.xchange.binance.dto.BinanceException;
import org.knowm.xchange.binance.dto.account.*;
import org.knowm.xchange.binance.dto.ExchangeType;
import org.knowm.xchange.binance.dto.account.AssetDetail;
import org.knowm.xchange.binance.dto.account.BinanceAccountInformation;
import org.knowm.xchange.binance.dto.account.BinanceFundingHistoryParams;
import org.knowm.xchange.binance.dto.account.BinanceMasterAccountTransferHistoryParams;
import org.knowm.xchange.binance.dto.account.BinanceSubAccountTransferHistoryParams;
import org.knowm.xchange.binance.dto.account.DepositAddress;
import org.knowm.xchange.binance.dto.account.WithdrawResponse;
import org.knowm.xchange.binance.dto.account.futures.BinanceFutureAccountInformation;
import org.knowm.xchange.client.ResilienceRegistries;
import org.knowm.xchange.currency.Currency;
import org.knowm.xchange.dto.account.*;
import org.knowm.xchange.dto.account.AccountInfo;
import org.knowm.xchange.dto.account.AddressWithTag;
import org.knowm.xchange.dto.account.Fee;
import org.knowm.xchange.dto.account.FundingRecord;
import org.knowm.xchange.dto.account.FundingRecord.Status;
import org.knowm.xchange.dto.account.FundingRecord.Type;
import org.knowm.xchange.dto.account.OpenPosition;
import org.knowm.xchange.dto.account.Wallet;
import org.knowm.xchange.instrument.Instrument;
import org.knowm.xchange.service.account.AccountService;
import org.knowm.xchange.service.trade.params.DefaultWithdrawFundsParams;
Expand Down Expand Up @@ -91,25 +107,19 @@ public AccountInfo getAccountInfo() throws IOException {
try {
List<Wallet> wallets = new ArrayList<>();
List<OpenPosition> openPositions = new ArrayList<>();

if (exchange.usingSandbox()) {
if (exchange.isFuturesSandbox()) {
BinanceFutureAccountInformation futureAccountInformation = futuresAccount();
wallets.add(BinanceAdapters.adaptBinanceFutureWallet(futureAccountInformation));
openPositions.addAll(
BinanceAdapters.adaptOpenPositions(futureAccountInformation.getPositions()));

} else {
switch ((ExchangeType)exchange.getExchangeSpecification().getExchangeSpecificParametersItem(
EXCHANGE_TYPE)) {
case SPOT: {
wallets.add(BinanceAdapters.adaptBinanceSpotWallet(account()));
break;
}
} else {
if (exchange.isFuturesEnabled()) {
case FUTURES: {
BinanceFutureAccountInformation futureAccountInformation = futuresAccount();
wallets.add(BinanceAdapters.adaptBinanceFutureWallet(futureAccountInformation));
openPositions.addAll(
BinanceAdapters.adaptOpenPositions(futureAccountInformation.getPositions()));
break;
}
wallets.add(BinanceAdapters.adaptBinanceSpotWallet(account()));
}
return new AccountInfo(
exchange.getExchangeSpecification().getUserName(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package org.knowm.xchange.binance.service;

import static org.knowm.xchange.binance.BinanceExchange.EXCHANGE_TYPE;

import java.io.IOException;
import org.knowm.xchange.ExchangeSpecification;
import org.knowm.xchange.binance.BinanceAuthenticated;
import org.knowm.xchange.binance.BinanceExchange;
import org.knowm.xchange.binance.BinanceFuturesAuthenticated;
import org.knowm.xchange.binance.dto.ExchangeType;
import org.knowm.xchange.binance.dto.meta.BinanceSystemStatus;
import org.knowm.xchange.client.ExchangeRestProxyBuilder;
import org.knowm.xchange.client.ResilienceRegistries;
Expand All @@ -20,8 +23,8 @@ public class BinanceBaseService extends BaseResilientExchangeService<BinanceExch

protected final String apiKey;
protected final BinanceAuthenticated binance;
protected final BinanceFuturesAuthenticated binanceFutures;
protected final BinanceFuturesAuthenticated inverseBinanceFutures;
protected BinanceFuturesAuthenticated binanceFutures;
protected BinanceFuturesAuthenticated inverseBinanceFutures;
protected final ParamsDigest signatureCreator;

protected BinanceBaseService(
Expand All @@ -32,30 +35,34 @@ protected BinanceBaseService(
ExchangeRestProxyBuilder.forInterface(
BinanceAuthenticated.class, exchange.getExchangeSpecification())
.build();
ExchangeSpecification futuresSpec = exchange.getDefaultExchangeSpecification();
ExchangeSpecification inverseFuturesSpec = futuresSpec;
futuresSpec.setSslUri(
(exchange.usingSandbox())
? BinanceExchange.SANDBOX_FUTURES_URL
: (exchange.isPortfolioMarginEnabled())
? BinanceExchange.PORTFOLIO_MARGIN_URL
: BinanceExchange.FUTURES_URL);
if (!exchange.isPortfolioMarginEnabled()) {
inverseFuturesSpec.setSslUri(
(exchange.usingSandbox())
? BinanceExchange.SANDBOX_FUTURES_URL
: BinanceExchange.INVERSE_FUTURES_URL);
this.inverseBinanceFutures =
ExchangeRestProxyBuilder.forInterface(
BinanceFuturesAuthenticated.class, inverseFuturesSpec)
.build();
} else {
this.inverseBinanceFutures = null;
ExchangeSpecification futuresSpec;
ExchangeSpecification inverseFuturesSpec;
if(exchange.getExchangeSpecification().getExchangeSpecificParametersItem(EXCHANGE_TYPE) != null)
{
switch ((ExchangeType) exchange.getExchangeSpecification()
.getExchangeSpecificParametersItem(EXCHANGE_TYPE)) {
case SPOT: {
break;
}
case FUTURES: {
futuresSpec = exchange.getExchangeSpecification();
binanceFutures =
ExchangeRestProxyBuilder.forInterface(BinanceFuturesAuthenticated.class, futuresSpec)
.build();
inverseBinanceFutures = null;
break;
}
case INVERSE: {
inverseFuturesSpec = exchange.getExchangeSpecification();
inverseBinanceFutures =
ExchangeRestProxyBuilder.forInterface(BinanceFuturesAuthenticated.class,
inverseFuturesSpec)
.build();
binanceFutures = null;
break;
}
}
}
this.binanceFutures =
ExchangeRestProxyBuilder.forInterface(BinanceFuturesAuthenticated.class, futuresSpec)
.build();

this.apiKey = exchange.getExchangeSpecification().getApiKey();
this.signatureCreator =
BinanceHmacDigest.createInstance(exchange.getExchangeSpecification().getSecretKey());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public Ticker getTicker(CurrencyPair currencyPair, Object... args) throws IOExce
@Override
public List<Ticker> getTickers(Params params) throws IOException {
try {
boolean isFutures = exchange.isFuturesEnabled() || exchange.isFuturesSandbox();
boolean isFutures = exchange.isFuturesEnabled();

return ticker24hAllProducts(isFutures).stream()
.filter(BinanceTicker24h::isValid)
Expand Down
Loading

0 comments on commit e0b3da0

Please sign in to comment.