Skip to content

Commit 6b23c4a

Browse files
Adds DustLog History to Binance and adds additional response to Kraken. (#4370)
* Adds the new response "EGeneral:Too many requests" from Kraken to the base service. See #4369 (comment) * Added new possibility to use the DustLog call (GET /sapi/v1/asset/dribblet) in Binance that gives you the history of your conversion results for small balances that are so small that they cannot be traded. See #4371. * Implemented suggestions from @walec51.
1 parent b93568b commit 6b23c4a

File tree

10 files changed

+455
-13
lines changed

10 files changed

+455
-13
lines changed

xchange-binance/src/main/java/org/knowm/xchange/binance/BinanceAuthenticated.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.knowm.xchange.binance.dto.BinanceException;
1919
import org.knowm.xchange.binance.dto.account.*;
2020
import org.knowm.xchange.binance.dto.trade.BinanceCancelledOrder;
21+
import org.knowm.xchange.binance.dto.trade.BinanceDustLog;
2122
import org.knowm.xchange.binance.dto.trade.BinanceListenKey;
2223
import org.knowm.xchange.binance.dto.trade.BinanceNewOrder;
2324
import org.knowm.xchange.binance.dto.trade.BinanceOrder;
@@ -287,6 +288,33 @@ List<BinanceTrade> myTrades(
287288
@QueryParam(SIGNATURE) ParamsDigest signature)
288289
throws IOException, BinanceException;
289290

291+
/**
292+
* Retrieves the dust log from Binance. If you have many currencies with low amount (=dust) that
293+
* cannot be traded, because their amount is less than the minimum amount required for trading
294+
* them, you can convert all these currencies at once into BNB with the button "Convert Small
295+
* Balance to BNB".
296+
*
297+
* @param startTime optional. If set, also the endTime must be set. If neither time is set, the
298+
* 100 most recent dust logs are returned.
299+
* @param endTime optional. If set, also the startTime must be set. If neither time is set, the
300+
* 100 most recent dust logs are returned.
301+
* @param recvWindow optional
302+
* @param timestamp mandatory
303+
* @return
304+
* @throws IOException
305+
* @throws BinanceException
306+
*/
307+
@GET
308+
@Path("/sapi/v1/asset/dribblet")
309+
BinanceDustLog getDustLog(
310+
@QueryParam("startTime") Long startTime,
311+
@QueryParam("endTime") Long endTime,
312+
@QueryParam("recvWindow") Long recvWindow,
313+
@QueryParam("timestamp") SynchronizedValueFactory<Long> timestamp,
314+
@HeaderParam(X_MBX_APIKEY) String apiKey,
315+
@QueryParam(SIGNATURE) ParamsDigest signature)
316+
throws IOException, BinanceException;
317+
290318
/**
291319
* Submit a withdraw request.
292320
*
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package org.knowm.xchange.binance.dto.trade;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import java.math.BigDecimal;
5+
6+
public final class BinanceDribbletDetails {
7+
private final String transId;
8+
private final BigDecimal serviceChargeAmount;
9+
private final BigDecimal amount;
10+
private final Long operateTime;
11+
private final BigDecimal transferedAmount;
12+
private final String fromAsset;
13+
14+
public BinanceDribbletDetails(
15+
@JsonProperty("transId") String transId,
16+
@JsonProperty("serviceChargeAmount") BigDecimal serviceChargeAmount,
17+
@JsonProperty("amount") BigDecimal amount,
18+
@JsonProperty("operateTime") Long operateTime,
19+
@JsonProperty("transferedAmount") BigDecimal transferedAmount,
20+
@JsonProperty("fromAsset") String fromAsset) {
21+
this.transId = transId;
22+
this.serviceChargeAmount = serviceChargeAmount;
23+
this.amount = amount;
24+
this.operateTime = operateTime;
25+
this.transferedAmount = transferedAmount;
26+
this.fromAsset = fromAsset;
27+
}
28+
29+
public String getTransId() {
30+
return transId;
31+
}
32+
33+
public BigDecimal getServiceChargeAmount() {
34+
return serviceChargeAmount;
35+
}
36+
37+
public BigDecimal getAmount() {
38+
return amount;
39+
}
40+
41+
public Long getOperateTime() {
42+
return operateTime;
43+
}
44+
45+
public BigDecimal getTransferedAmount() {
46+
return transferedAmount;
47+
}
48+
49+
public String getFromAsset() {
50+
return fromAsset;
51+
}
52+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package org.knowm.xchange.binance.dto.trade;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import java.math.BigDecimal;
5+
import java.util.List;
6+
7+
public final class BinanceDribblets {
8+
private final Long operateTime;
9+
private final BigDecimal totalTransferedAmount;
10+
private final BigDecimal totalServiceChargeAmount;
11+
private final String transId;
12+
private final List<BinanceDribbletDetails> binanceDribbletDetails;
13+
14+
public BinanceDribblets(
15+
@JsonProperty("operateTime") Long operateTime,
16+
@JsonProperty("totalTransferedAmount") BigDecimal totalTransferedAmount,
17+
@JsonProperty("totalServiceChargeAmount") BigDecimal totalServiceChargeAmount,
18+
@JsonProperty("transId") String transId,
19+
@JsonProperty("userAssetDribbletDetails")
20+
List<BinanceDribbletDetails> binanceDribbletDetails) {
21+
this.operateTime = operateTime;
22+
this.totalTransferedAmount = totalTransferedAmount;
23+
this.totalServiceChargeAmount = totalServiceChargeAmount;
24+
this.transId = transId;
25+
this.binanceDribbletDetails = binanceDribbletDetails;
26+
}
27+
28+
public Long getOperateTime() {
29+
return operateTime;
30+
}
31+
32+
public BigDecimal getTotalTransferedAmount() {
33+
return totalTransferedAmount;
34+
}
35+
36+
public BigDecimal getTotalServiceChargeAmount() {
37+
return totalServiceChargeAmount;
38+
}
39+
40+
public String getTransId() {
41+
return transId;
42+
}
43+
44+
public List<BinanceDribbletDetails> getBinanceDribbletDetails() {
45+
return binanceDribbletDetails;
46+
}
47+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package org.knowm.xchange.binance.dto.trade;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import java.util.List;
5+
6+
public final class BinanceDustLog {
7+
private final Integer total;
8+
private final List<BinanceDribblets> dribblets;
9+
10+
public BinanceDustLog(
11+
@JsonProperty("total") Integer total,
12+
@JsonProperty("userAssetDribblets") List<BinanceDribblets> dribblets) {
13+
this.total = total;
14+
this.dribblets = dribblets;
15+
}
16+
17+
public Integer getTotal() {
18+
return total;
19+
}
20+
21+
public List<BinanceDribblets> getDribblets() {
22+
return dribblets;
23+
}
24+
}

xchange-binance/src/main/java/org/knowm/xchange/binance/service/BinanceTradeService.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.knowm.xchange.binance.BinanceErrorAdapter;
1414
import org.knowm.xchange.binance.BinanceExchange;
1515
import org.knowm.xchange.binance.dto.BinanceException;
16+
import org.knowm.xchange.binance.dto.trade.BinanceDustLog;
1617
import org.knowm.xchange.binance.dto.trade.BinanceNewOrder;
1718
import org.knowm.xchange.binance.dto.trade.BinanceOrder;
1819
import org.knowm.xchange.binance.dto.trade.BinanceTrade;

xchange-binance/src/main/java/org/knowm/xchange/binance/service/BinanceTradeServiceRaw.java

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.knowm.xchange.binance.BinanceExchange;
1313
import org.knowm.xchange.binance.dto.BinanceException;
1414
import org.knowm.xchange.binance.dto.trade.BinanceCancelledOrder;
15+
import org.knowm.xchange.binance.dto.trade.BinanceDustLog;
1516
import org.knowm.xchange.binance.dto.trade.BinanceListenKey;
1617
import org.knowm.xchange.binance.dto.trade.BinanceNewOrder;
1718
import org.knowm.xchange.binance.dto.trade.BinanceOrder;
@@ -21,6 +22,7 @@
2122
import org.knowm.xchange.binance.dto.trade.TimeInForce;
2223
import org.knowm.xchange.client.ResilienceRegistries;
2324
import org.knowm.xchange.currency.CurrencyPair;
25+
import org.knowm.xchange.exceptions.ExchangeException;
2426

2527
public class BinanceTradeServiceRaw extends BinanceBaseService {
2628

@@ -189,23 +191,55 @@ public List<BinanceTrade> myTrades(
189191
CurrencyPair pair, Long orderId, Long startTime, Long endTime, Long fromId, Integer limit)
190192
throws BinanceException, IOException {
191193
return decorateApiCall(
192-
() ->
193-
binance.myTrades(
194-
BinanceAdapters.toSymbol(pair),
195-
orderId,
196-
startTime,
197-
endTime,
198-
fromId,
199-
limit,
200-
getRecvWindow(),
201-
getTimestampFactory(),
202-
apiKey,
203-
signatureCreator))
194+
() ->
195+
binance.myTrades(
196+
BinanceAdapters.toSymbol(pair),
197+
orderId,
198+
startTime,
199+
endTime,
200+
fromId,
201+
limit,
202+
getRecvWindow(),
203+
getTimestampFactory(),
204+
apiKey,
205+
signatureCreator))
204206
.withRetry(retry("myTrades"))
205207
.withRateLimiter(rateLimiter(REQUEST_WEIGHT_RATE_LIMITER), myTradesPermits(limit))
206208
.call();
207209
}
208210

211+
/**
212+
* Retrieves the dust log from Binance. If you have many currencies with low amount (=dust) that
213+
* cannot be traded, because their amount is less than the minimum amount required for trading
214+
* them, you can convert all these currencies at once into BNB with the button "Convert Small
215+
* Balance to BNB".
216+
*
217+
* @param startTime optional. If set, also the endTime must be set. If neither time is set, the
218+
* 100 most recent dust logs are returned.
219+
* @param endTime optional. If set, also the startTime must be set. If neither time is set, the
220+
* 100 most recent dust logs are returned.
221+
* @return
222+
* @throws IOException
223+
*/
224+
public BinanceDustLog getDustLog(Long startTime, Long endTime) throws IOException {
225+
226+
if (((startTime != null) && (endTime == null)) || (startTime == null) && (endTime != null))
227+
throw new ExchangeException("You need to specify both, the start and the end date, or none of them");
228+
229+
return decorateApiCall(
230+
() ->
231+
binance.getDustLog(
232+
startTime,
233+
endTime,
234+
getRecvWindow(),
235+
getTimestampFactory(),
236+
apiKey,
237+
signatureCreator))
238+
.withRetry(retry("myDustLog"))
239+
.withRateLimiter(rateLimiter(REQUEST_WEIGHT_RATE_LIMITER))
240+
.call();
241+
}
242+
209243
public BinanceListenKey startUserDataStream() throws IOException {
210244
return decorateApiCall(() -> binance.startUserDataStream(apiKey))
211245
.withRateLimiter(rateLimiter(REQUEST_WEIGHT_RATE_LIMITER))

xchange-binance/src/test/java/org/knowm/xchange/binance/BinanceExchangeIntegration.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
import static org.assertj.core.api.Assertions.assertThat;
44

5+
import com.github.tomakehurst.wiremock.junit.WireMockRule;
56
import java.io.IOException;
67
import org.junit.Assume;
78
import org.junit.BeforeClass;
9+
import org.junit.Rule;
810
import org.junit.Test;
911
import org.knowm.xchange.ExchangeFactory;
1012
import org.knowm.xchange.ExchangeSpecification;
@@ -13,7 +15,8 @@
1315

1416
public class BinanceExchangeIntegration {
1517
protected static BinanceExchange exchange;
16-
18+
@Rule
19+
public WireMockRule wireMockRule = new WireMockRule();
1720
@BeforeClass
1821
public static void beforeClass() throws Exception {
1922
createExchange();
@@ -42,4 +45,16 @@ protected static void createExchange() throws Exception {
4245
protected void assumeProduction() {
4346
Assume.assumeFalse("Using sandbox", exchange.usingSandbox());
4447
}
48+
49+
protected BinanceExchange createExchangeMocked() {
50+
BinanceExchange exchangeMocked =
51+
ExchangeFactory.INSTANCE.createExchangeWithoutSpecification(BinanceExchange.class);
52+
ExchangeSpecification specification = exchangeMocked.getDefaultExchangeSpecification();
53+
specification.setHost("localhost");
54+
specification.setSslUri("http://localhost:" + wireMockRule.port() + "/");
55+
specification.setPort(wireMockRule.port());
56+
specification.setShouldLoadRemoteMetaData(false);
57+
exchangeMocked.applySpecification(specification);
58+
return exchangeMocked;
59+
}
4560
}

xchange-binance/src/test/java/org/knowm/xchange/binance/service/trade/TradeServiceIntegration.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
package org.knowm.xchange.binance.service.trade;
22

3+
import static com.github.tomakehurst.wiremock.client.WireMock.get;
4+
import static com.github.tomakehurst.wiremock.client.WireMock.ok;
5+
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
6+
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
7+
8+
import static org.hamcrest.CoreMatchers.equalTo;
9+
import static org.hamcrest.CoreMatchers.is;
10+
import static org.hamcrest.MatcherAssert.assertThat;
11+
import static org.junit.Assert.assertEquals;
312
import static org.knowm.xchange.binance.dto.trade.OrderType.LIMIT;
413
import static org.knowm.xchange.binance.dto.trade.OrderType.MARKET;
514
import static org.knowm.xchange.binance.dto.trade.OrderType.STOP_LOSS_LIMIT;
@@ -9,17 +18,22 @@
918
import java.io.IOException;
1019
import java.math.BigDecimal;
1120
import java.math.RoundingMode;
21+
import java.util.Optional;
1222
import org.junit.Assume;
1323
import org.junit.Before;
1424
import org.junit.BeforeClass;
25+
1526
import org.junit.Test;
27+
import org.knowm.xchange.binance.BinanceExchange;
1628
import org.knowm.xchange.binance.BinanceExchangeIntegration;
29+
import org.knowm.xchange.binance.dto.trade.BinanceDustLog;
1730
import org.knowm.xchange.binance.dto.trade.TimeInForce;
1831
import org.knowm.xchange.binance.service.BinanceTradeService;
1932
import org.knowm.xchange.currency.CurrencyPair;
2033
import org.knowm.xchange.dto.trade.LimitOrder;
2134
import org.knowm.xchange.dto.trade.MarketOrder;
2235
import org.knowm.xchange.dto.trade.StopOrder;
36+
import org.knowm.xchange.utils.ObjectMapperHelper;
2337

2438
public class TradeServiceIntegration extends BinanceExchangeIntegration {
2539

@@ -128,4 +142,24 @@ private StopOrder sampleTakeProfitLimitOrder() throws IOException {
128142
.flag(TimeInForce.GTC)
129143
.build();
130144
}
145+
146+
@Test
147+
public void testDustLog() throws IOException {
148+
BinanceExchange exchangeMocked = createExchangeMocked();
149+
tradeService = (BinanceTradeService) exchangeMocked.getTradeService();
150+
stubFor(
151+
get(urlPathEqualTo("/sapi/v1/asset/dribblet"))
152+
.willReturn(
153+
ok()
154+
.withHeader("Content-Type", "application/json")
155+
.withBodyFile("dustlog.json")));
156+
157+
BinanceDustLog dustLog = tradeService.getDustLog(1639094400000L, 1639180800000L);
158+
assertEquals(1, dustLog.getDribblets().size());
159+
assertEquals(28, dustLog.getDribblets().get(0).getBinanceDribbletDetails().size());
160+
assertEquals((Long) 1639129045000L, dustLog.getDribblets().get(0).getOperateTime());
161+
assertEquals(
162+
"90698471826",
163+
dustLog.getDribblets().get(0).getBinanceDribbletDetails().get(0).getTransId());
164+
}
131165
}

0 commit comments

Comments
 (0)