Skip to content

Commit 143962d

Browse files
committed
[core] FundingRate.class changes - many exchanges funding rates can now vary from 1 to 8 hours
[binance] funding rate stream fixes [bybit] add funding rate stream [okx] funding rate stream fixes [kraken] funding rate rest fix
1 parent 29ff978 commit 143962d

File tree

18 files changed

+405
-49
lines changed

18 files changed

+405
-49
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ public static FundingRate adaptFundingRate(BinanceFundingRate binanceFundingRate
675675
BigDecimal.valueOf(8),
676676
binanceFundingRate.getLastFundingRate().scale(),
677677
RoundingMode.HALF_EVEN))
678-
.fundingRate8h(binanceFundingRate.getLastFundingRate())
678+
.fundingRate(binanceFundingRate.getLastFundingRate())
679679
.instrument(binanceFundingRate.getInstrument())
680680
.fundingRateDate(binanceFundingRate.getNextFundingTime())
681681
.fundingRateEffectiveInMinutes(

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.knowm.xchange.binance.dto.BinanceException;
1111
import org.knowm.xchange.binance.dto.marketdata.BinanceAggTrades;
1212
import org.knowm.xchange.binance.dto.marketdata.BinanceFundingRate;
13+
import org.knowm.xchange.binance.dto.marketdata.BinanceFundingRateInfo;
1314
import org.knowm.xchange.binance.dto.marketdata.BinanceOrderbook;
1415
import org.knowm.xchange.binance.dto.marketdata.BinanceTicker24h;
1516
import org.knowm.xchange.binance.dto.meta.BinanceSystemStatus;
@@ -122,6 +123,15 @@ List<BinanceAggTrades> aggTrades(
122123
BinanceFundingRate fundingRate(@QueryParam("symbol") String symbol)
123124
throws IOException, BinanceException;
124125

126+
/**
127+
* @return BinanceFundingRateInfo
128+
* @throws IOException
129+
* @throws BinanceException
130+
*/
131+
@GET
132+
@Path("fapi/v1/fundingInfo")
133+
List<BinanceFundingRateInfo> fundingRateInfo() throws IOException, BinanceException;
134+
125135
/**
126136
* Kline/candlestick bars for a symbol. Klines are uniquely identified by their open time.<br>
127137
* If startTime and endTime are not sent, the most recent klines are returned.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package org.knowm.xchange.binance.dto.marketdata;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import java.math.BigDecimal;
5+
import lombok.Getter;
6+
import lombok.ToString;
7+
import org.knowm.xchange.binance.BinanceAdapters;
8+
import org.knowm.xchange.instrument.Instrument;
9+
10+
@Getter
11+
@ToString
12+
public class BinanceFundingRateInfo {
13+
private final Instrument instrument;
14+
private final BigDecimal adjustedFundingRateCap;
15+
private final BigDecimal adjustedFundingRateFloor;
16+
private final int fundingIntervalHours;
17+
18+
public BinanceFundingRateInfo(
19+
@JsonProperty("symbol") String symbol,
20+
@JsonProperty("adjustedFundingRateCap") BigDecimal adjustedFundingRateCap,
21+
@JsonProperty("adjustedFundingRateFloor") BigDecimal adjustedFundingRateFloor,
22+
@JsonProperty("fundingIntervalHours") int fundingIntervalHours) {
23+
this.instrument = BinanceAdapters.adaptSymbol(symbol, true);
24+
this.adjustedFundingRateCap = adjustedFundingRateCap;
25+
this.adjustedFundingRateFloor = adjustedFundingRateFloor;
26+
this.fundingIntervalHours = fundingIntervalHours;
27+
}
28+
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.knowm.xchange.binance.BinanceExchange;
1010
import org.knowm.xchange.binance.dto.marketdata.BinanceAggTrades;
1111
import org.knowm.xchange.binance.dto.marketdata.BinanceFundingRate;
12+
import org.knowm.xchange.binance.dto.marketdata.BinanceFundingRateInfo;
1213
import org.knowm.xchange.binance.dto.marketdata.BinanceKline;
1314
import org.knowm.xchange.binance.dto.marketdata.BinanceOrderbook;
1415
import org.knowm.xchange.binance.dto.marketdata.BinancePrice;
@@ -168,6 +169,12 @@ public BinanceFundingRate getBinanceFundingRate(Instrument instrument) throws IO
168169
.call();
169170
}
170171

172+
public List<BinanceFundingRateInfo> getBinanceFundingRateInfo() throws IOException {
173+
return decorateApiCall(() -> binanceFutures.fundingRateInfo())
174+
.withRetry(retry("fundingRate"))
175+
.call();
176+
}
177+
171178
public BinancePrice tickerPrice(CurrencyPair pair) throws IOException {
172179
return tickerAllPrices().stream()
173180
.filter(p -> p.getCurrencyPair().equals(pair))

xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/tickers/BybitTicker.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
import com.fasterxml.jackson.annotation.JsonProperty;
44
import java.math.BigDecimal;
55
import lombok.Data;
6+
import lombok.NoArgsConstructor;
67
import lombok.experimental.SuperBuilder;
78

89
@SuperBuilder
910
@Data
11+
@NoArgsConstructor
1012
public abstract class BybitTicker {
1113

1214
@JsonProperty("symbol")

xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/tickers/linear/BybitLinearInverseTicker.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
package org.knowm.xchange.bybit.dto.marketdata.tickers.linear;
22

3+
import com.fasterxml.jackson.annotation.JsonInclude;
4+
import com.fasterxml.jackson.annotation.JsonInclude.Include;
35
import com.fasterxml.jackson.annotation.JsonProperty;
46
import java.math.BigDecimal;
57
import java.util.Date;
8+
import lombok.EqualsAndHashCode;
69
import lombok.Value;
710
import lombok.experimental.SuperBuilder;
811
import lombok.extern.jackson.Jacksonized;
912
import org.knowm.xchange.bybit.dto.marketdata.tickers.BybitTicker;
1013

14+
@EqualsAndHashCode(callSuper = true)
1115
@SuperBuilder
1216
@Jacksonized
1317
@Value
18+
@JsonInclude(Include.NON_NULL)
1419
public class BybitLinearInverseTicker extends BybitTicker {
1520

1621
@JsonProperty("indexPrice")
@@ -54,4 +59,10 @@ public class BybitLinearInverseTicker extends BybitTicker {
5459

5560
@JsonProperty("deliveryTime")
5661
Date deliveryTime;
62+
63+
@JsonProperty("fundingIntervalHour")
64+
Integer fundingIntervalHour;
65+
66+
@JsonProperty("fundingCap")
67+
String fundingCap;
5768
}

xchange-core/src/main/java/org/knowm/xchange/dto/marketdata/FundingRate.java

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,35 @@
66
import java.util.Date;
77
import java.util.concurrent.TimeUnit;
88
import lombok.Getter;
9+
import lombok.NoArgsConstructor;
10+
import lombok.Setter;
911
import lombok.ToString;
1012
import org.knowm.xchange.instrument.Instrument;
1113

1214
@Getter
1315
@ToString
16+
@Setter
17+
@NoArgsConstructor
1418
public class FundingRate {
1519

16-
private final Instrument instrument;
17-
private final BigDecimal fundingRate1h;
18-
private final BigDecimal fundingRate8h;
19-
private final Date fundingRateDate;
20-
private final long fundingRateEffectiveInMinutes;
20+
private Instrument instrument;
21+
private BigDecimal fundingRate1h;
22+
private BigDecimal fundingRate;
23+
private FundingRateInterval fundingRateInterval;
24+
private Date fundingRateDate;
25+
private long fundingRateEffectiveInMinutes;
2126

2227
public FundingRate(
2328
@JsonProperty("instrument") Instrument instrument,
2429
@JsonProperty("fundingRate1h") BigDecimal fundingRate1h,
25-
@JsonProperty("fundingRate8h") BigDecimal fundingRate8h,
30+
@JsonProperty("fundingRate") BigDecimal fundingRate,
31+
@JsonProperty("fundingRateInterval") FundingRateInterval fundingRateInterval,
2632
@JsonProperty("fundingRateDate") Date fundingRateDate,
2733
@JsonProperty("fundingRateEffectiveInMinutes") long fundingRateEffectiveInMinutes) {
2834
this.instrument = instrument;
2935
this.fundingRate1h = fundingRate1h;
30-
this.fundingRate8h = fundingRate8h;
36+
this.fundingRate = fundingRate;
37+
this.fundingRateInterval = fundingRateInterval;
3138
this.fundingRateDate = fundingRateDate;
3239
this.fundingRateEffectiveInMinutes =
3340
(fundingRateEffectiveInMinutes == 0 && fundingRateDate != null)
@@ -39,7 +46,8 @@ public static class Builder {
3946

4047
protected Instrument instrument;
4148
protected BigDecimal fundingRate1h;
42-
protected BigDecimal fundingRate8h;
49+
protected BigDecimal fundingRate;
50+
protected FundingRateInterval fundingRateInterval;
4351
protected Date fundingRateDate;
4452
protected long fundingRateEffectiveInMinutes;
4553

@@ -55,9 +63,9 @@ public FundingRate.Builder fundingRate1h(BigDecimal fundingRate1h) {
5563
return this;
5664
}
5765

58-
public FundingRate.Builder fundingRate8h(BigDecimal fundingRate8h) {
66+
public FundingRate.Builder fundingRate(BigDecimal fundingRate) {
5967

60-
this.fundingRate8h = fundingRate8h;
68+
this.fundingRate = fundingRate;
6169
return this;
6270
}
6371

@@ -72,12 +80,18 @@ public FundingRate.Builder fundingRateEffectiveInMinutes(long fundingRateEffecti
7280
return this;
7381
}
7482

83+
public FundingRate.Builder fundingRateInterval(FundingRateInterval fundingRateInterval) {
84+
this.fundingRateInterval = fundingRateInterval;
85+
return this;
86+
}
87+
7588
public FundingRate build() {
7689

7790
return new FundingRate(
7891
instrument,
7992
fundingRate1h,
80-
fundingRate8h,
93+
fundingRate,
94+
fundingRateInterval,
8195
fundingRateDate,
8296
(fundingRateEffectiveInMinutes == 0 && fundingRateDate != null)
8397
? calculateFundingRateEffectiveInMinutes(fundingRateDate)
@@ -89,4 +103,18 @@ private static long calculateFundingRateEffectiveInMinutes(Date fundingRateDate)
89103
return TimeUnit.MILLISECONDS.toMinutes(
90104
fundingRateDate.getTime() - Date.from(Instant.now()).getTime());
91105
}
106+
107+
@Getter
108+
public enum FundingRateInterval {
109+
H1(1),
110+
H2(2),
111+
H4(4),
112+
H6(6),
113+
H8(8);
114+
private final int hours;
115+
116+
FundingRateInterval(int hours) {
117+
this.hours = hours;
118+
}
119+
}
92120
}

xchange-krakenfutures/src/main/java/org/knowm/xchange/krakenfutures/KrakenFuturesAdapters.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.knowm.xchange.dto.account.OpenPositions;
2727
import org.knowm.xchange.dto.account.Wallet;
2828
import org.knowm.xchange.dto.marketdata.FundingRate;
29+
import org.knowm.xchange.dto.marketdata.FundingRate.FundingRateInterval;
2930
import org.knowm.xchange.dto.marketdata.FundingRates;
3031
import org.knowm.xchange.dto.marketdata.OrderBook;
3132
import org.knowm.xchange.dto.marketdata.Ticker;
@@ -329,13 +330,14 @@ public static FundingRate adaptFundingRate(KrakenFuturesTicker krakenFuturesTick
329330
.divide(krakenFuturesTicker.getMarkPrice(), 8, RoundingMode.HALF_EVEN);
330331
return new FundingRate.Builder()
331332
.fundingRate1h(relative1hFundingRate)
332-
.fundingRate8h(relative1hFundingRate.multiply(BigDecimal.valueOf(8)))
333+
.fundingRate(relative1hFundingRate.multiply(BigDecimal.valueOf(8)))
333334
.fundingRateDate(
334335
Date.from(
335336
now.plus(60 - now.get(ChronoField.MINUTE_OF_HOUR), ChronoUnit.MINUTES)
336337
.toInstant(ZoneOffset.UTC)))
337338
.fundingRateEffectiveInMinutes(60 - LocalTime.now().getMinute())
338339
.instrument(adaptInstrument(krakenFuturesTicker.getSymbol()))
340+
.fundingRateInterval(FundingRateInterval.H8)
339341
.build();
340342
}
341343

xchange-krakenfutures/src/test/java/org/knowm/xchange/krakenfutures/KrakenFuturesPublicDataIntegration.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public void checkFundingRates() throws IOException {
7070
fundingRate -> {
7171
assertThat(fundingRate.getFundingRateEffectiveInMinutes()).isLessThan(61);
7272
assertThat(fundingRate.getFundingRate1h()).isNotNull();
73-
assertThat(fundingRate.getFundingRate8h()).isNotNull();
73+
assertThat(fundingRate.getFundingRate()).isNotNull();
7474
assertThat(fundingRate.getFundingRateDate()).isNotNull();
7575
});
7676
}
@@ -82,7 +82,7 @@ public void checkFundingRate() throws IOException {
8282
assertThat(fundingRate.getInstrument().toString()).isEqualTo("PF_XBT/USD/PERP");
8383
assertThat(fundingRate.getFundingRateEffectiveInMinutes()).isLessThan(61);
8484
assertThat(fundingRate.getFundingRate1h()).isNotNull();
85-
assertThat(fundingRate.getFundingRate8h()).isNotNull();
85+
assertThat(fundingRate.getFundingRate()).isNotNull();
8686
assertThat(fundingRate.getFundingRateDate()).isNotNull();
8787
System.out.println(fundingRate);
8888
}

xchange-okex/src/main/java/org/knowm/xchange/okex/OkexAdapters.java

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.knowm.xchange.dto.marketdata.CandleStick;
3333
import org.knowm.xchange.dto.marketdata.CandleStickData;
3434
import org.knowm.xchange.dto.marketdata.FundingRate;
35+
import org.knowm.xchange.dto.marketdata.FundingRate.FundingRateInterval;
3536
import org.knowm.xchange.dto.marketdata.OrderBook;
3637
import org.knowm.xchange.dto.marketdata.OrderBookUpdate;
3738
import org.knowm.xchange.dto.marketdata.Ticker;
@@ -683,18 +684,59 @@ public static Type adaptOpenPositionType(OkexPosition okexPosition) {
683684
}
684685

685686
public static FundingRate adaptFundingRate(List<OkexFundingRate> okexFundingRate) {
687+
int interval =
688+
((int)
689+
(okexFundingRate.get(0).getNextFundingTime().getTime()
690+
- okexFundingRate.get(0).getFundingTime().getTime())
691+
/ 3600000);
692+
BigDecimal fundingRate = okexFundingRate.get(0).getFundingRate();
693+
FundingRateInterval rateInterval = FundingRateInterval.H8;
694+
BigDecimal fundingRate1h = BigDecimal.ZERO;
695+
switch (interval) {
696+
case 1:
697+
{
698+
rateInterval = FundingRateInterval.H1;
699+
fundingRate1h = fundingRate;
700+
break;
701+
}
702+
case 2:
703+
{
704+
rateInterval = FundingRateInterval.H2;
705+
fundingRate1h =
706+
fundingRate.divide(
707+
BigDecimal.valueOf(2), fundingRate.scale(), RoundingMode.HALF_EVEN);
708+
break;
709+
}
710+
case 4:
711+
{
712+
rateInterval = FundingRateInterval.H4;
713+
fundingRate1h =
714+
fundingRate.divide(
715+
BigDecimal.valueOf(4), fundingRate.scale(), RoundingMode.HALF_EVEN);
716+
break;
717+
}
718+
case 6:
719+
{
720+
rateInterval = FundingRateInterval.H6;
721+
fundingRate1h =
722+
fundingRate.divide(
723+
BigDecimal.valueOf(6), fundingRate.scale(), RoundingMode.HALF_EVEN);
724+
break;
725+
}
726+
case 8:
727+
{
728+
fundingRate1h =
729+
fundingRate.divide(
730+
BigDecimal.valueOf(8), fundingRate.scale(), RoundingMode.HALF_EVEN);
731+
break;
732+
}
733+
}
686734
return new FundingRate.Builder()
687735
.instrument(adaptOkexInstrumentId(okexFundingRate.get(0).getInstId()))
688-
.fundingRate8h(okexFundingRate.get(0).getFundingRate())
689-
.fundingRate1h(
690-
okexFundingRate
691-
.get(0)
692-
.getFundingRate()
693-
.divide(
694-
BigDecimal.valueOf(8),
695-
okexFundingRate.get(0).getFundingRate().scale(),
696-
RoundingMode.HALF_EVEN))
736+
.fundingRate(fundingRate)
737+
.fundingRate1h(fundingRate1h)
697738
.fundingRateDate(okexFundingRate.get(0).getFundingTime())
739+
.fundingRateInterval(rateInterval)
698740
.build();
699741
}
700742

0 commit comments

Comments
 (0)