diff --git a/pom.xml b/pom.xml
index 9e3af921e02..e55c6d48b09 100644
--- a/pom.xml
+++ b/pom.xml
@@ -211,6 +211,7 @@
xchange-stream-service-pubnub
xchange-stream-coincheck
xchange-stream-krakenfutures
+ xchange-stream-bybit
diff --git a/xchange-bibox/src/main/java/org/knowm/xchange/bibox/dto/BiboxAdapters.java b/xchange-bibox/src/main/java/org/knowm/xchange/bibox/dto/BiboxAdapters.java
index 6d5642fde96..c250e2813c1 100644
--- a/xchange-bibox/src/main/java/org/knowm/xchange/bibox/dto/BiboxAdapters.java
+++ b/xchange-bibox/src/main/java/org/knowm/xchange/bibox/dto/BiboxAdapters.java
@@ -172,33 +172,25 @@ public static Date convert(String s) {
}
public static FundingRecord adaptDeposit(BiboxDeposit d) {
- return new FundingRecord(
- d.to,
- d.getCreatedAt(),
- Currency.getInstance(d.coinSymbol),
- d.amount,
- null,
- null,
- Type.DEPOSIT,
- convertStatus(d.status),
- null,
- null,
- null);
+ return FundingRecord.builder()
+ .address(d.to)
+ .date(d.getCreatedAt())
+ .currency(Currency.getInstance(d.coinSymbol))
+ .amount(d.amount)
+ .type(Type.DEPOSIT)
+ .status(convertStatus(d.status))
+ .build();
}
public static FundingRecord adaptDeposit(BiboxWithdrawal w) {
- return new FundingRecord(
- w.toAddress,
- w.getCreatedAt(),
- Currency.getInstance(w.coinSymbol),
- w.amountReal,
- null,
- null,
- Type.WITHDRAWAL,
- convertStatus(w.status),
- null,
- null,
- null);
+ return FundingRecord.builder()
+ .address(w.toAddress)
+ .date(w.getCreatedAt())
+ .currency(Currency.getInstance(w.coinSymbol))
+ .amount(w.amountReal)
+ .type(Type.WITHDRAWAL)
+ .status(convertStatus(w.status))
+ .build();
}
public static Status convertStatus(int status) {
diff --git a/xchange-binance/src/main/java/org/knowm/xchange/binance/service/BinanceAccountService.java b/xchange-binance/src/main/java/org/knowm/xchange/binance/service/BinanceAccountService.java
index 6aab63f855e..a3cd9d962b3 100644
--- a/xchange-binance/src/main/java/org/knowm/xchange/binance/service/BinanceAccountService.java
+++ b/xchange-binance/src/main/java/org/knowm/xchange/binance/service/BinanceAccountService.java
@@ -288,57 +288,49 @@ public List getFundingHistory(TradeHistoryParams params) throws I
super.withdrawHistory(asset, startTime, endTime)
.forEach(
w -> result.add(
- new FundingRecord(
- w.getAddress(),
- w.getAddressTag(),
- BinanceAdapters.toDate(w.getApplyTime()),
- Currency.getInstance(w.getCoin()),
- w.getAmount(),
- w.getId(),
- w.getTxId(),
- Type.WITHDRAWAL,
- withdrawStatus(w.getStatus()),
- null,
- w.getTransactionFee(),
- null)));
+ FundingRecord.builder()
+ .address(w.getAddress())
+ .addressTag(w.getAddressTag())
+ .date(BinanceAdapters.toDate(w.getApplyTime()))
+ .currency(Currency.getInstance(w.getCoin()))
+ .amount(w.getAmount())
+ .internalId(w.getId())
+ .blockchainTransactionHash(w.getTxId())
+ .type(Type.WITHDRAWAL)
+ .status(withdrawStatus(w.getStatus()))
+ .fee(w.getTransactionFee())
+ .build()));
}
if (deposits) {
super.depositHistory(asset, startTime, endTime)
.forEach(
d -> result.add(
- new FundingRecord(
- d.getAddress(),
- d.getAddressTag(),
- new Date(d.getInsertTime()),
- Currency.getInstance(d.getCoin()),
- d.getAmount(),
- null,
- d.getTxId(),
- Type.DEPOSIT,
- depositStatus(d.getStatus()),
- null,
- null,
- null)));
+ FundingRecord.builder()
+ .address(d.getAddress())
+ .addressTag(d.getAddressTag())
+ .date(new Date(d.getInsertTime()))
+ .currency(Currency.getInstance(d.getCoin()))
+ .amount(d.getAmount())
+ .blockchainTransactionHash(d.getTxId())
+ .type(Type.DEPOSIT)
+ .status(depositStatus(d.getStatus()))
+ .build()));
}
if (otherInflow) {
super.getAssetDividend(asset, startTime, endTime)
.forEach(
a -> result.add(
- new FundingRecord(
- null,
- null,
- new Date(a.getDivTime()),
- Currency.getInstance(a.getAsset()),
- a.getAmount(),
- null,
- String.valueOf(a.getTranId()),
- Type.OTHER_INFLOW,
- Status.COMPLETE,
- null,
- null,
- a.getEnInfo())));
+ FundingRecord.builder()
+ .date(new Date(a.getDivTime()))
+ .currency(Currency.getInstance(a.getAsset()))
+ .amount(a.getAmount())
+ .blockchainTransactionHash(String.valueOf(a.getTranId()))
+ .type(Type.OTHER_INFLOW)
+ .status(Status.COMPLETE)
+ .description(a.getEnInfo())
+ .build()));
}
final String finalEmail = email;
@@ -347,13 +339,13 @@ public List getFundingHistory(TradeHistoryParams params) throws I
super.getTransferHistory(email, startTime, endTime, page, limit)
.forEach(
a -> result.add(
- new FundingRecord.Builder()
- .setAddress(finalEmail)
- .setDate(new Date(a.getTime()))
- .setCurrency(Currency.getInstance(a.getAsset()))
- .setAmount(a.getQty())
- .setType(Type.INTERNAL_WITHDRAWAL)
- .setStatus(transferHistoryStatus(a.getStatus()))
+ FundingRecord.builder()
+ .address(finalEmail)
+ .date(new Date(a.getTime()))
+ .currency(Currency.getInstance(a.getAsset()))
+ .amount(a.getQty())
+ .type(Type.INTERNAL_WITHDRAWAL)
+ .status(transferHistoryStatus(a.getStatus()))
.build()));
}
@@ -363,16 +355,16 @@ public List getFundingHistory(TradeHistoryParams params) throws I
super.getSubUserHistory(asset, type, startTime, endTime, limit)
.forEach(
a -> result.add(
- new FundingRecord.Builder()
- .setAddress(a.getEmail())
- .setDate(new Date(a.getTime()))
- .setCurrency(Currency.getInstance(a.getAsset()))
- .setAmount(a.getQty())
- .setType(
+ FundingRecord.builder()
+ .address(a.getEmail())
+ .date(new Date(a.getTime()))
+ .currency(Currency.getInstance(a.getAsset()))
+ .amount(a.getQty())
+ .type(
a.getType().equals(1)
? Type.INTERNAL_DEPOSIT
: Type.INTERNAL_WITHDRAWAL)
- .setStatus(Status.COMPLETE)
+ .status(Status.COMPLETE)
.build()));
}
diff --git a/xchange-bitbay/src/main/java/org/knowm/xchange/bitbay/service/BitbayAccountServiceRaw.java b/xchange-bitbay/src/main/java/org/knowm/xchange/bitbay/service/BitbayAccountServiceRaw.java
index 12df1e6daa6..9e917a5ab4e 100644
--- a/xchange-bitbay/src/main/java/org/knowm/xchange/bitbay/service/BitbayAccountServiceRaw.java
+++ b/xchange-bitbay/src/main/java/org/knowm/xchange/bitbay/service/BitbayAccountServiceRaw.java
@@ -5,6 +5,7 @@
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
@@ -13,6 +14,7 @@
import org.knowm.xchange.bitbay.dto.acount.BitbayAccountInfoResponse;
import org.knowm.xchange.currency.Currency;
import org.knowm.xchange.dto.account.FundingRecord;
+import org.knowm.xchange.dto.account.FundingRecord.Status;
import org.knowm.xchange.exceptions.ExchangeException;
/** @author Z. Dolezal */
@@ -103,18 +105,15 @@ else if (map.get("operation_type").toString().equals("-transfer"))
else continue;
res.add(
- new FundingRecord(
- null,
- dateFormat.parse(map.get("time").toString()),
- Currency.getInstance(map.get("currency").toString()),
- new BigDecimal(map.get("amount").toString()),
- map.get("id").toString(),
- null,
- type,
- FundingRecord.Status.COMPLETE,
- null,
- null,
- map.get("comment").toString()));
+ FundingRecord.builder()
+ .date(dateFormat.parse(map.get("time").toString()))
+ .currency(Currency.getInstance(map.get("currency").toString()))
+ .amount(new BigDecimal(map.get("amount").toString()))
+ .internalId(map.get("id").toString())
+ .type(type)
+ .status(Status.COMPLETE)
+ .description(map.get("comment").toString())
+ .build());
} catch (ParseException e) {
throw new IllegalStateException("Should not happen", e);
}
diff --git a/xchange-bitbay/src/main/java/org/knowm/xchange/bitbay/v3/service/BitbayAccountService.java b/xchange-bitbay/src/main/java/org/knowm/xchange/bitbay/v3/service/BitbayAccountService.java
index 35003687aaa..04dad9af454 100644
--- a/xchange-bitbay/src/main/java/org/knowm/xchange/bitbay/v3/service/BitbayAccountService.java
+++ b/xchange-bitbay/src/main/java/org/knowm/xchange/bitbay/v3/service/BitbayAccountService.java
@@ -86,17 +86,17 @@ private static FundingRecord adaptFundingRecord(BitbayBalanceHistoryEntry item)
? FundingRecord.Type.WITHDRAWAL
: FundingRecord.Type.DEPOSIT;
- return new FundingRecord.Builder()
- .setType(type)
- .setBlockchainTransactionHash(null) // not available in the API yet
- .setAddress(null) // not available in the API yet
- .setAmount(item.getValue().abs())
- .setCurrency(Currency.getInstance(item.getBalance().getCurrency()))
- .setDate(DateUtils.fromMillisUtc(item.getTime()))
- .setInternalId(item.getHistoryId().toString())
- .setFee(null) // not available in the API yet
- .setStatus(FundingRecord.Status.COMPLETE)
- .setBalance(item.getFundsAfter().getTotal())
+ return FundingRecord.builder()
+ .type(type)
+ .blockchainTransactionHash(null) // not available in the API yet
+ .address(null) // not available in the API yet
+ .amount(item.getValue().abs())
+ .currency(Currency.getInstance(item.getBalance().getCurrency()))
+ .date(DateUtils.fromMillisUtc(item.getTime()))
+ .internalId(item.getHistoryId().toString())
+ .fee(null) // not available in the API yet
+ .status(FundingRecord.Status.COMPLETE)
+ .balance(item.getFundsAfter().getTotal())
.build();
}
}
diff --git a/xchange-bitcoinde/src/main/java/org/knowm/xchange/bitcoinde/v4/BitcoindeAdapters.java b/xchange-bitcoinde/src/main/java/org/knowm/xchange/bitcoinde/v4/BitcoindeAdapters.java
index c5999c2a92b..dd84b1a6314 100644
--- a/xchange-bitcoinde/src/main/java/org/knowm/xchange/bitcoinde/v4/BitcoindeAdapters.java
+++ b/xchange-bitcoinde/src/main/java/org/knowm/xchange/bitcoinde/v4/BitcoindeAdapters.java
@@ -284,20 +284,20 @@ public static List adaptFundingHistory(
ledger -> {
FundingRecord.Type type = adaptFundingRecordType(ledger.getType());
- FundingRecord.Builder builder =
- new FundingRecord.Builder()
- .setType(type)
- .setDate(ledger.getDate())
- .setCurrency(currency)
- .setAmount(ledger.getCashflow().abs())
- .setBalance(ledger.getBalance())
- .setStatus(FundingRecord.Status.COMPLETE)
- .setDescription(ledger.getType().getValue());
+ FundingRecord.FundingRecordBuilder builder =
+ FundingRecord.builder()
+ .type(type)
+ .date(ledger.getDate())
+ .currency(currency)
+ .amount(ledger.getCashflow().abs())
+ .balance(ledger.getBalance())
+ .status(FundingRecord.Status.COMPLETE)
+ .description(ledger.getType().getValue());
if (INPAYMENT == ledger.getType() || PAYOUT == ledger.getType()) {
- builder.setBlockchainTransactionHash(ledger.getReference());
+ builder.blockchainTransactionHash(ledger.getReference());
} else {
- builder.setInternalId(ledger.getReference());
+ builder.internalId(ledger.getReference());
}
if (!leaveFeesSeperate && PAYOUT == ledger.getType()) {
@@ -305,8 +305,8 @@ public static List adaptFundingHistory(
findFeeLedger(ledger.getReference(), feeLedgers);
if (feeLedger.isPresent()) {
BigDecimal fee = feeLedger.get().getCashflow().abs();
- builder.setAmount(ledger.getCashflow().abs().add(fee));
- builder.setFee(fee);
+ builder.amount(ledger.getCashflow().abs().add(fee));
+ builder.fee(fee);
/*
* There can be multiple {@code PAYOUTS}s with the same reference/ blockchain
diff --git a/xchange-bitfinex/src/main/java/org/knowm/xchange/bitfinex/service/BitfinexAdapters.java b/xchange-bitfinex/src/main/java/org/knowm/xchange/bitfinex/service/BitfinexAdapters.java
index 6690dd6e279..f209b9cac90 100644
--- a/xchange-bitfinex/src/main/java/org/knowm/xchange/bitfinex/service/BitfinexAdapters.java
+++ b/xchange-bitfinex/src/main/java/org/knowm/xchange/bitfinex/service/BitfinexAdapters.java
@@ -48,6 +48,8 @@
import org.knowm.xchange.dto.account.Balance;
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.Wallet;
import org.knowm.xchange.dto.marketdata.OrderBook;
import org.knowm.xchange.dto.marketdata.Ticker;
@@ -805,19 +807,17 @@ public static List adaptFundingHistory(List movementHis
}
FundingRecord fundingRecordEntry =
- new FundingRecord(
- movement.getDestinationAddress(),
- null,
- movement.getMtsUpdated(),
- currency,
- amount,
- movement.getId(),
- movement.getTransactionId(),
- type,
- status,
- null,
- fee,
- null);
+ FundingRecord.builder()
+ .address(movement.getDestinationAddress())
+ .date(movement.getMtsStarted())
+ .currency(currency)
+ .amount(amount)
+ .internalId(movement.getId())
+ .blockchainTransactionHash(movement.getTransactionId())
+ .type(type)
+ .status(status)
+ .fee(fee)
+ .build();
fundingRecords.add(fundingRecordEntry);
}
@@ -868,18 +868,17 @@ and sometimes like this (with the address in it as well as the txn hash):
}
FundingRecord fundingRecordEntry =
- new FundingRecord(
- address,
- responseEntry.getTimestamp(),
- currency,
- responseEntry.getAmount(),
- String.valueOf(responseEntry.getId()),
- txnId,
- responseEntry.getType(),
- status,
- null,
- null,
- description);
+ FundingRecord.builder()
+ .address(address)
+ .date(responseEntry.getTimestamp())
+ .currency(currency)
+ .amount(responseEntry.getAmount())
+ .internalId(String.valueOf(responseEntry.getId()))
+ .blockchainTransactionHash(txnId)
+ .type(responseEntry.getType())
+ .status(status)
+ .description(description)
+ .build();
fundingRecords.add(fundingRecordEntry);
}
diff --git a/xchange-bitflyer/src/main/java/org/knowm/xchange/bitflyer/BitflyerAdapters.java b/xchange-bitflyer/src/main/java/org/knowm/xchange/bitflyer/BitflyerAdapters.java
index 6d87c982e6b..8f7d4ea3590 100755
--- a/xchange-bitflyer/src/main/java/org/knowm/xchange/bitflyer/BitflyerAdapters.java
+++ b/xchange-bitflyer/src/main/java/org/knowm/xchange/bitflyer/BitflyerAdapters.java
@@ -121,29 +121,29 @@ public static List adaptFundingRecordsFromDepositHistory(
public static FundingRecord adaptFundingRecord(
BitflyerCoinHistory history, FundingRecord.Type type) {
- return new FundingRecord.Builder()
- .setDate(BitflyerUtils.parseDate(history.getEventDate()))
- .setCurrency(new Currency(history.getCurrencyCode()))
- .setAmount(history.getAmount())
- .setAddress(history.getAddress())
- .setInternalId(history.getID())
- .setType(type)
- .setStatus(adaptStatus(history.getStatus()))
- .setBalance(history.getAmount())
- .setFee(add(history.getFee(), history.getAdditionalFee()))
+ return FundingRecord.builder()
+ .date(BitflyerUtils.parseDate(history.getEventDate()))
+ .currency(new Currency(history.getCurrencyCode()))
+ .amount(history.getAmount())
+ .address(history.getAddress())
+ .internalId(history.getID())
+ .type(type)
+ .status(adaptStatus(history.getStatus()))
+ .balance(history.getAmount())
+ .fee(add(history.getFee(), history.getAdditionalFee()))
.build();
}
public static FundingRecord adaptFundingRecord(
BitflyerDepositOrWithdrawal history, FundingRecord.Type type) {
- return new FundingRecord.Builder()
- .setDate(BitflyerUtils.parseDate(history.getEventDate()))
- .setCurrency(new Currency(history.getCurrencyCode()))
- .setAmount(history.getAmount())
- .setInternalId(history.getID())
- .setType(type)
- .setStatus(adaptStatus(history.getStatus()))
- .setBalance(history.getAmount())
+ return FundingRecord.builder()
+ .date(BitflyerUtils.parseDate(history.getEventDate()))
+ .currency(new Currency(history.getCurrencyCode()))
+ .amount(history.getAmount())
+ .internalId(history.getID())
+ .type(type)
+ .status(adaptStatus(history.getStatus()))
+ .balance(history.getAmount())
.build();
}
diff --git a/xchange-bitmex/src/main/java/org/knowm/xchange/bitmex/BitmexAdapters.java b/xchange-bitmex/src/main/java/org/knowm/xchange/bitmex/BitmexAdapters.java
index ede595c8ddb..764f6542105 100644
--- a/xchange-bitmex/src/main/java/org/knowm/xchange/bitmex/BitmexAdapters.java
+++ b/xchange-bitmex/src/main/java/org/knowm/xchange/bitmex/BitmexAdapters.java
@@ -380,18 +380,19 @@ private static OrderType convertType(String side) {
}
public static FundingRecord adaptFundingRecord(BitmexWalletTransaction walletTransaction) {
- return new FundingRecord(
- walletTransaction.getAddress(),
- walletTransaction.getTransactTime(),
- adaptCurrency(walletTransaction.getCurrency()),
- walletTransaction.getAmount().abs(),
- walletTransaction.getTransactID(),
- walletTransaction.getTx(),
- adaptFundingRecordtype(walletTransaction),
- adaptFundingRecordStatus(walletTransaction.getTransactStatus()),
- walletTransaction.getWalletBalance(),
- walletTransaction.getFee(),
- walletTransaction.getText());
+ return FundingRecord.builder()
+ .address(walletTransaction.getAddress())
+ .date(walletTransaction.getTransactTime())
+ .currency(adaptCurrency(walletTransaction.getCurrency()))
+ .amount(walletTransaction.getAmount().abs())
+ .internalId(walletTransaction.getTransactID())
+ .blockchainTransactionHash(walletTransaction.getTx())
+ .type(adaptFundingRecordtype(walletTransaction))
+ .status(adaptFundingRecordStatus(walletTransaction.getTransactStatus()))
+ .balance(walletTransaction.getWalletBalance())
+ .fee(walletTransaction.getFee())
+ .description(walletTransaction.getText())
+ .build();
}
private static FundingRecord.Type adaptFundingRecordtype(
diff --git a/xchange-bitstamp/src/main/java/org/knowm/xchange/bitstamp/BitstampAdapters.java b/xchange-bitstamp/src/main/java/org/knowm/xchange/bitstamp/BitstampAdapters.java
index 48bb0455c03..6b846f5241f 100644
--- a/xchange-bitstamp/src/main/java/org/knowm/xchange/bitstamp/BitstampAdapters.java
+++ b/xchange-bitstamp/src/main/java/org/knowm/xchange/bitstamp/BitstampAdapters.java
@@ -28,6 +28,7 @@
import org.knowm.xchange.dto.account.AccountInfo;
import org.knowm.xchange.dto.account.Balance;
import org.knowm.xchange.dto.account.FundingRecord;
+import org.knowm.xchange.dto.account.FundingRecord.Status;
import org.knowm.xchange.dto.account.Wallet;
import org.knowm.xchange.dto.marketdata.OrderBook;
import org.knowm.xchange.dto.marketdata.Ticker;
@@ -284,18 +285,15 @@ public static List adaptFundingHistory(
}
FundingRecord record =
- new FundingRecord(
- null,
- trans.getDatetime(),
- Currency.getInstance(amount.getKey()),
- amount.getValue().abs(),
- String.valueOf(trans.getId()),
- null,
- type,
- FundingRecord.Status.COMPLETE,
- null,
- trans.getFee(),
- null);
+ FundingRecord.builder()
+ .date(trans.getDatetime())
+ .currency(Currency.getInstance(amount.getKey()))
+ .amount(amount.getValue().abs())
+ .internalId(String.valueOf(trans.getId()))
+ .type(type)
+ .status(Status.COMPLETE)
+ .fee(trans.getFee())
+ .build();
fundingRecords.add(record);
}
}
diff --git a/xchange-bl3p/src/main/java/org/knowm/xchange/bl3p/Bl3pAdapters.java b/xchange-bl3p/src/main/java/org/knowm/xchange/bl3p/Bl3pAdapters.java
index a98064816bc..6cc55e0667e 100644
--- a/xchange-bl3p/src/main/java/org/knowm/xchange/bl3p/Bl3pAdapters.java
+++ b/xchange-bl3p/src/main/java/org/knowm/xchange/bl3p/Bl3pAdapters.java
@@ -110,13 +110,13 @@ public static List adaptUserTransactionsToFundingRecords(
for (Bl3pUserTransactions.Bl3pUserTransaction tx : transactions) {
list.add(
- new FundingRecord.Builder()
- .setAmount(tx.amount.value)
- .setBalance(tx.balance.value)
- .setCurrency(Currency.getInstance(tx.amount.currency))
- .setDate(tx.date)
- .setFee(tx.fee == null ? null : tx.fee.value)
- .setType(
+ FundingRecord.builder()
+ .amount(tx.amount.value)
+ .balance(tx.balance.value)
+ .currency(Currency.getInstance(tx.amount.currency))
+ .date(tx.date)
+ .fee(tx.fee == null ? null : tx.fee.value)
+ .type(
tx.type == "deposit" ? FundingRecord.Type.DEPOSIT : FundingRecord.Type.WITHDRAWAL)
.build());
}
diff --git a/xchange-bleutrade/src/main/java/org/knowm/xchange/bleutrade/service/BleutradeAccountService.java b/xchange-bleutrade/src/main/java/org/knowm/xchange/bleutrade/service/BleutradeAccountService.java
index e821b39c93a..cc8b7ea7822 100644
--- a/xchange-bleutrade/src/main/java/org/knowm/xchange/bleutrade/service/BleutradeAccountService.java
+++ b/xchange-bleutrade/src/main/java/org/knowm/xchange/bleutrade/service/BleutradeAccountService.java
@@ -5,6 +5,7 @@
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import org.knowm.xchange.Exchange;
@@ -13,6 +14,8 @@
import org.knowm.xchange.currency.Currency;
import org.knowm.xchange.dto.account.AccountInfo;
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.exceptions.NotAvailableFromExchangeException;
import org.knowm.xchange.service.account.AccountService;
import org.knowm.xchange.service.trade.params.DefaultWithdrawFundsParams;
@@ -88,34 +91,31 @@ public List getFundingHistory(TradeHistoryParams params) throws I
}
fundingRecords.add(
- new FundingRecord(
- address,
- dateFormat.parse(record.timestamp),
- Currency.getInstance(record.coin),
- amount,
- record.id,
- record.transactionId,
- FundingRecord.Type.WITHDRAWAL,
- FundingRecord.Status.COMPLETE,
- null,
- fee,
- label));
+ FundingRecord.builder()
+ .address(address)
+ .date(dateFormat.parse(record.timestamp))
+ .currency(Currency.getInstance(record.coin))
+ .amount(amount)
+ .internalId(record.id)
+ .blockchainTransactionHash(record.transactionId)
+ .type(Type.WITHDRAWAL)
+ .status(Status.COMPLETE)
+ .fee(fee)
+ .description(label)
+ .build());
}
for (DepositRecord record : depositHistory()) {
fundingRecords.add(
- new FundingRecord(
- null,
- dateFormat.parse(record.timestamp),
- Currency.getInstance(record.coin),
- record.amount,
- record.id,
- null,
- FundingRecord.Type.DEPOSIT,
- FundingRecord.Status.COMPLETE,
- null,
- null,
- record.label));
+ FundingRecord.builder()
+ .date(dateFormat.parse(record.timestamp))
+ .currency(Currency.getInstance(record.coin))
+ .amount(record.amount)
+ .internalId(record.id)
+ .type(Type.DEPOSIT)
+ .status(Status.COMPLETE)
+ .description(record.label)
+ .build());
}
} catch (ParseException e) {
throw new IllegalStateException("Should not happen", e);
diff --git a/xchange-blockchain/src/main/java/org/knowm/xchange/blockchain/BlockchainAdapters.java b/xchange-blockchain/src/main/java/org/knowm/xchange/blockchain/BlockchainAdapters.java
index ce415765960..d4f3d6e72eb 100644
--- a/xchange-blockchain/src/main/java/org/knowm/xchange/blockchain/BlockchainAdapters.java
+++ b/xchange-blockchain/src/main/java/org/knowm/xchange/blockchain/BlockchainAdapters.java
@@ -13,6 +13,8 @@
import org.knowm.xchange.dto.Order;
import org.knowm.xchange.dto.account.AddressWithTag;
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.marketdata.OrderBook;
import org.knowm.xchange.dto.marketdata.Trades;
import org.knowm.xchange.dto.meta.CurrencyMetaData;
@@ -75,35 +77,29 @@ public static FundingRecord.Status toDepositStatus(String status) {
}
public static FundingRecord toFundingWithdrawal(BlockchainWithdrawal w){
- return new FundingRecord(
- w.getBeneficiary(),
- null,
- w.getTimestamp(),
- w.getCurrency(),
- w.getAmount(),
- w.getWithdrawalId(),
- null,
- FundingRecord.Type.WITHDRAWAL,
- BlockchainAdapters.toWithdrawStatus(w.getState()),
- null,
- w.getFee(),
- null);
+ return FundingRecord.builder()
+ .address(w.getBeneficiary())
+ .date(w.getTimestamp())
+ .currency(w.getCurrency())
+ .amount(w.getAmount())
+ .internalId(w.getWithdrawalId())
+ .type(Type.WITHDRAWAL)
+ .status(BlockchainAdapters.toWithdrawStatus(w.getState()))
+ .fee(w.getFee())
+ .build();
}
public static FundingRecord toFundingDeposit(BlockchainDeposits d){
- return new FundingRecord(
- d.getAddress(),
- null,
- d.getTimestamp(),
- d.getCurrency(),
- d.getAmount(),
- d.getDepositId(),
- d.getTxHash(),
- FundingRecord.Type.DEPOSIT,
- BlockchainAdapters.toDepositStatus(d.getState()),
- null,
- null,
- null);
+ return FundingRecord.builder()
+ .address(d.getAddress())
+ .date(d.getTimestamp())
+ .currency(d.getCurrency())
+ .amount(d.getAmount())
+ .internalId(d.getDepositId())
+ .blockchainTransactionHash(d.getTxHash())
+ .type(Type.DEPOSIT)
+ .status(BlockchainAdapters.toDepositStatus(d.getState()))
+ .build();
}
public static CurrencyPair toCurrencyPairBySymbol(BlockchainSymbol blockchainSymbol) {
diff --git a/xchange-btcmarkets/src/main/java/org/knowm/xchange/btcmarkets/BTCMarketsAdapters.java b/xchange-btcmarkets/src/main/java/org/knowm/xchange/btcmarkets/BTCMarketsAdapters.java
index 2ceec8877a6..4e4878dd611 100644
--- a/xchange-btcmarkets/src/main/java/org/knowm/xchange/btcmarkets/BTCMarketsAdapters.java
+++ b/xchange-btcmarkets/src/main/java/org/knowm/xchange/btcmarkets/BTCMarketsAdapters.java
@@ -5,6 +5,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -244,18 +245,18 @@ public static List adaptFundingHistory(
}
result.add(
- new FundingRecord(
- address,
- transfer.getCreationTime(),
- Currency.getInstance(transfer.getCurrency()),
- transfer.getAmount(),
- Long.toString(transfer.getFundTransferId()),
- blockchainTransactionHash,
- fundingrecordType,
- fundingRecordStatus,
- null,
- transfer.getFee(),
- transfer.getDescription()));
+ FundingRecord.builder()
+ .address(address)
+ .date(transfer.getCreationTime())
+ .currency(Currency.getInstance(transfer.getCurrency()))
+ .amount(transfer.getAmount())
+ .internalId(Long.toString(transfer.getFundTransferId()))
+ .blockchainTransactionHash(blockchainTransactionHash)
+ .type(fundingrecordType)
+ .status(fundingRecordStatus)
+ .fee(transfer.getFee())
+ .description(transfer.getDescription())
+ .build());
}
return result;
}
diff --git a/xchange-btcturk/src/main/java/org/knowm/xchange/btcturk/BTCTurkAdapters.java b/xchange-btcturk/src/main/java/org/knowm/xchange/btcturk/BTCTurkAdapters.java
index 606a75c23e9..822ec40ef18 100644
--- a/xchange-btcturk/src/main/java/org/knowm/xchange/btcturk/BTCTurkAdapters.java
+++ b/xchange-btcturk/src/main/java/org/knowm/xchange/btcturk/BTCTurkAdapters.java
@@ -208,15 +208,15 @@ public static FundingRecord adaptTransaction(BTCTurkUserTransactions transaction
description += ", index: " + transaction.getId();
}
- return new FundingRecord.Builder()
- .setInternalId(transaction.getId().toString())
- .setDate(transaction.getDate())
- .setType(transaction.getOperation().getType())
- .setCurrency(transaction.getCurrency())
- .setAmount(transaction.getAmount())
- .setFee(transaction.getFee())
- .setBalance(transaction.getFunds())
- .setDescription(description)
+ return FundingRecord.builder()
+ .internalId(transaction.getId().toString())
+ .date(transaction.getDate())
+ .type(transaction.getOperation().getType())
+ .currency(transaction.getCurrency())
+ .amount(transaction.getAmount())
+ .fee(transaction.getFee())
+ .balance(transaction.getFunds())
+ .description(description)
.build();
}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/Bybit.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/Bybit.java
index cfcb9778c52..458d68fb193 100644
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/Bybit.java
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/Bybit.java
@@ -1,33 +1,46 @@
package org.knowm.xchange.bybit;
-import java.io.IOException;
-import java.util.List;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;
+import java.io.IOException;
import org.knowm.xchange.bybit.dto.BybitResult;
-import org.knowm.xchange.bybit.dto.marketdata.BybitSymbol;
-import org.knowm.xchange.bybit.dto.marketdata.BybitTicker;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.BybitInstrumentInfo;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.BybitInstrumentsInfo;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.BybitTicker;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.BybitTickers;
import org.knowm.xchange.bybit.service.BybitException;
-@Path("")
+@Path("/v5/market")
@Produces(MediaType.APPLICATION_JSON)
public interface Bybit {
- /**
- * @apiSpec API
- */
+ /** @apiSpec API */
@GET
- @Path("/v2/public/tickers")
- BybitResult> getTicker24h(@QueryParam("symbol") String symbol) throws IOException, BybitException;
+ @Path("/tickers")
+ BybitResult> getTicker24h(
+ @QueryParam("category") String category, @QueryParam("symbol") String symbol)
+ throws IOException, BybitException;
- /**
- * @apiSpec API
- */
+ /** @apiSpec API */
@GET
- @Path("/v2/public/symbols")
- BybitResult> getSymbols() throws IOException, BybitException;
+ @Path("/instruments-info")
+ BybitResult> getInstrumentsInfo(
+ @QueryParam("category") String category,
+ @QueryParam("symbol") String symbol,
+ @QueryParam("status") String status,
+ @QueryParam("baseCoin") String baseCoin,
+ @QueryParam("limit") Integer limit,
+ @QueryParam("cursor") String cursor
-}
\ No newline at end of file
+ ) throws IOException, BybitException;
+
+ @GET
+ @Path("/asset/transfer/query-asset-info")
+ BybitResult getAssetsInfo(
+ @QueryParam("accountType") String accountType,
+ @QueryParam("coin") String coin
+ ) throws IOException, BybitException;
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/BybitAdapters.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/BybitAdapters.java
index 9178a3b8929..c2ff18af7ea 100644
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/BybitAdapters.java
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/BybitAdapters.java
@@ -1,50 +1,107 @@
package org.knowm.xchange.bybit;
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import lombok.SneakyThrows;
+import org.apache.commons.lang3.StringUtils;
+import org.knowm.xchange.bybit.dto.BybitCategory;
import org.knowm.xchange.bybit.dto.BybitResult;
-import org.knowm.xchange.bybit.dto.account.BybitBalance;
-import org.knowm.xchange.bybit.dto.trade.BybitOrderDetails;
+import org.knowm.xchange.bybit.dto.account.BybitDepositRecordsResponse.BybitDepositRecord;
+import org.knowm.xchange.bybit.dto.account.BybitInternalDepositRecordsResponse.BybitInternalDepositRecord;
+import org.knowm.xchange.bybit.dto.account.BybitTransactionLogResponse.BybitTransactionLog;
+import org.knowm.xchange.bybit.dto.account.BybitTransactionLogResponse.BybitTransactionLog.BybitTransactionLogType;
+import org.knowm.xchange.bybit.dto.account.BybitTransfersResponse.BybitTransfer;
+import org.knowm.xchange.bybit.dto.account.BybitTransfersResponse.BybitTransferStatus;
+import org.knowm.xchange.bybit.dto.account.BybitAllCoinsBalance;
+import org.knowm.xchange.bybit.dto.account.BybitAllCoinsBalance.BybitCoinBalance;
+import org.knowm.xchange.bybit.dto.account.BybitWithdrawRecordsResponse.BybitWithdrawRecord;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.BybitInstrumentInfo;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.BybitInstrumentInfo.InstrumentStatus;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.linear.BybitLinearInverseInstrumentInfo;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.option.BybitOptionInstrumentInfo;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.spot.BybitSpotInstrumentInfo;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.BybitTicker;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.linear.BybitLinearInverseTicker;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.option.BybitOptionTicker;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.spot.BybitSpotTicker;
+import org.knowm.xchange.bybit.dto.trade.BybitOrderStatus;
+import org.knowm.xchange.bybit.dto.trade.BybitSide;
+import org.knowm.xchange.bybit.dto.trade.BybitTradeHistoryResponse;
+import org.knowm.xchange.bybit.dto.trade.BybitUserTradeDto;
+import org.knowm.xchange.bybit.dto.trade.details.BybitOrderDetail;
import org.knowm.xchange.bybit.service.BybitException;
import org.knowm.xchange.currency.Currency;
import org.knowm.xchange.currency.CurrencyPair;
+import org.knowm.xchange.derivative.FuturesContract;
+import org.knowm.xchange.derivative.OptionsContract;
+import org.knowm.xchange.derivative.OptionsContract.OptionType;
import org.knowm.xchange.dto.Order;
+import org.knowm.xchange.dto.Order.OrderStatus;
+import org.knowm.xchange.dto.Order.OrderType;
import org.knowm.xchange.dto.account.Balance;
+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.Wallet;
+import org.knowm.xchange.dto.account.Wallet.WalletFeature;
+import org.knowm.xchange.dto.marketdata.Ticker;
+import org.knowm.xchange.dto.marketdata.Ticker.Builder;
+import org.knowm.xchange.dto.meta.CurrencyMetaData;
+import org.knowm.xchange.dto.meta.InstrumentMetaData;
import org.knowm.xchange.dto.trade.LimitOrder;
-
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
+import org.knowm.xchange.dto.trade.UserTrade;
+import org.knowm.xchange.instrument.Instrument;
public class BybitAdapters {
- public static final List QUOTE_CURRENCIES = Arrays.asList("USDT", "USDC", "BTC", "DAI");
+ protected static final List QUOTE_CURRENCIES =
+ Arrays.asList("USDT", "USDC", "BTC", "DAI", "EUR", "ETH");
+
+ public static final String FUTURES_CONTRACT_QUOTE_CURRENCY = "USD";
+
+ private static final String BYBIT_PERPETUAL = "PERP";
- public static Wallet adaptBybitBalances(List bybitBalances) {
- List balances = new ArrayList<>(bybitBalances.size());
- for (BybitBalance bybitBalance : bybitBalances) {
- balances.add(new Balance(new Currency(bybitBalance.getCoin()),
- new BigDecimal(bybitBalance.getTotal()),
- new BigDecimal(bybitBalance.getFree())
- ));
+ public static final SimpleDateFormat OPTIONS_EXPIRED_DATE_PARSER = new SimpleDateFormat("ddMMMyy", Locale.ENGLISH);
+
+ public static Wallet adaptBybitBalances(BybitAllCoinsBalance allCoinsBalance, Set features) {
+ List balances = new ArrayList<>(allCoinsBalance.getBalance().size());
+ for (BybitCoinBalance coinBalance : allCoinsBalance.getBalance()) {
+ balances.add(
+ new Balance(
+ new Currency(coinBalance.getCoin()),
+ coinBalance.getWalletBalance(),
+ coinBalance.getTransferBalance()));
}
- return Wallet.Builder.from(balances).build();
+
+ return Wallet.Builder.from(balances)
+ .id(allCoinsBalance.getAccountType().name())
+ .features(features)
+ .build();
}
- public static String getSideString(Order.OrderType type) {
- if (type == Order.OrderType.ASK)
- return "Sell";
- if (type == Order.OrderType.BID)
- return "Buy";
+ public static BybitSide getSideString(Order.OrderType type) {
+ if (type == Order.OrderType.ASK) {
+ return BybitSide.SELL;
+ }
+ if (type == Order.OrderType.BID) {
+ return BybitSide.BUY;
+ }
throw new IllegalArgumentException("invalid order type");
}
- public static Order.OrderType getOrderType(String side) {
- if ("sell".equalsIgnoreCase(side)) {
+ public static Order.OrderType getOrderType(BybitSide side) {
+ if ("sell".equalsIgnoreCase(side.name())) {
return Order.OrderType.ASK;
}
- if ("buy".equalsIgnoreCase(side)) {
+ if ("buy".equalsIgnoreCase(side.name())) {
return Order.OrderType.BID;
}
throw new IllegalArgumentException("invalid order type");
@@ -63,31 +120,478 @@ public static CurrencyPair guessSymbol(String symbol) {
}
int splitIndex = symbol.length() - 3;
return new CurrencyPair(symbol.substring(0, splitIndex), symbol.substring(splitIndex));
-
}
- public static LimitOrder adaptBybitOrderDetails(BybitOrderDetails bybitOrderResult) {
- LimitOrder limitOrder = new LimitOrder(
+ public static LimitOrder adaptBybitOrderDetails(BybitOrderDetail bybitOrderResult) {
+ LimitOrder limitOrder =
+ new LimitOrder(
getOrderType(bybitOrderResult.getSide()),
- new BigDecimal(bybitOrderResult.getOrigQty()),
- new BigDecimal(bybitOrderResult.getExecutedQty()),
+ bybitOrderResult.getQty(),
+ bybitOrderResult.getCumExecQty(),
guessSymbol(bybitOrderResult.getSymbol()),
bybitOrderResult.getOrderId(),
- new Date(Long.parseLong(bybitOrderResult.getTime())),
- new BigDecimal(bybitOrderResult.getPrice())) {
- };
- BigDecimal averagePrice = new BigDecimal(bybitOrderResult.getAvgPrice());
- limitOrder.setAveragePrice(averagePrice);
- limitOrder.setOrderStatus(Order.OrderStatus.valueOf(bybitOrderResult.getStatus()));
+ bybitOrderResult.getCreatedTime(),
+ bybitOrderResult.getPrice()) {};
+ limitOrder.setAveragePrice(bybitOrderResult.getAvgPrice());
+ limitOrder.setOrderStatus(adaptBybitOrderStatus(bybitOrderResult.getOrderStatus()));
return limitOrder;
}
+ private static OrderStatus adaptBybitOrderStatus(BybitOrderStatus orderStatus) {
+ switch (orderStatus) {
+ case CREATED:
+ return OrderStatus.OPEN;
+ case NEW:
+ return OrderStatus.NEW;
+ case REJECTED:
+ return OrderStatus.REJECTED;
+ case PARTIALLY_FILLED:
+ case ACTIVE:
+ return OrderStatus.PARTIALLY_FILLED;
+ case PARTIALLY_FILLED_CANCELED:
+ return OrderStatus.PARTIALLY_CANCELED;
+ case FILLED:
+ return OrderStatus.FILLED;
+ case CANCELLED:
+ return OrderStatus.CANCELED;
+ case UNTRIGGERED:
+ case TRIGGERED:
+ return OrderStatus.UNKNOWN;
+ case DEACTIVATED:
+ return OrderStatus.STOPPED;
+ default:
+ throw new IllegalStateException("Unexpected value: " + orderStatus);
+ }
+ }
+
public static BybitException createBybitExceptionFromResult(BybitResult walletBalances) {
return new BybitException(
- walletBalances.getRetCode(),
- walletBalances.getRetMsg(),
- walletBalances.getExtCode(),
- walletBalances.getExtCode()
- );
+ walletBalances.getRetCode(), walletBalances.getRetMsg(), walletBalances.getRetExtInfo());
+ }
+
+ public static Ticker adaptBybitLinearInverseTicker(
+ Instrument instrument, Date time, BybitLinearInverseTicker bybitTicker) {
+ return adaptBybitTickerBuilder(instrument, time, bybitTicker)
+ .open(bybitTicker.getPrevPrice24h())
+ .percentageChange(bybitTicker.getPrice24hPcnt())
+ .build();
+ }
+
+ public static Ticker adaptBybitSpotTicker(
+ Instrument instrument, Date time, BybitSpotTicker bybitTicker) {
+ return adaptBybitTickerBuilder(instrument, time, bybitTicker)
+ .open(bybitTicker.getPrevPrice24h())
+ .percentageChange(bybitTicker.getPrice24hPcnt())
+ .build();
+ }
+
+ public static Ticker adaptBybitOptionTicker(
+ Instrument instrument, Date time, BybitOptionTicker bybitTicker) {
+ return adaptBybitTickerBuilder(instrument, time, bybitTicker).build();
+ }
+
+ private static Builder adaptBybitTickerBuilder(
+ Instrument instrument, Date time, BybitTicker bybitTicker) {
+ return new Ticker.Builder()
+ .timestamp(time)
+ .instrument(instrument)
+ .last(bybitTicker.getLastPrice())
+ .bid(bybitTicker.getBid1Price())
+ .bidSize(bybitTicker.getBid1Size())
+ .ask(bybitTicker.getAsk1Price())
+ .askSize(bybitTicker.getAsk1Size())
+ .high(bybitTicker.getHighPrice24h())
+ .low(bybitTicker.getLowPrice24h())
+ .quoteVolume(bybitTicker.getTurnover24h())
+ .volume(bybitTicker.getVolume24h());
+ }
+
+ public static Map adaptBybitInstruments(
+ List instrumentList) {
+ Map map = new HashMap<>();
+
+ instrumentList.forEach(
+ info -> {
+ if (info instanceof BybitSpotInstrumentInfo) {
+ BybitSpotInstrumentInfo spotInstrumentInfo = (BybitSpotInstrumentInfo) info;
+ map.put(
+ adaptInstrument(spotInstrumentInfo.getSymbol(), BybitCategory.SPOT),
+ new InstrumentMetaData.Builder()
+ .minimumAmount(spotInstrumentInfo.getLotSizeFilter().getMinOrderQty())
+ .maximumAmount(spotInstrumentInfo.getLotSizeFilter().getMaxOrderQty())
+ .counterMinimumAmount(spotInstrumentInfo.getLotSizeFilter().getMinOrderAmt())
+ .counterMaximumAmount(spotInstrumentInfo.getLotSizeFilter().getMaxOrderAmt())
+ .priceScale(spotInstrumentInfo.getPriceFilter().getTickSize().scale())
+ .volumeScale(spotInstrumentInfo.getLotSizeFilter().getBasePrecision().scale())
+ .amountStepSize(spotInstrumentInfo.getLotSizeFilter().getBasePrecision())
+ .priceStepSize(spotInstrumentInfo.getPriceFilter().getTickSize())
+ .marketOrderEnabled(
+ spotInstrumentInfo.getStatus().equals(InstrumentStatus.TRADING))
+ .build());
+ } else if (info instanceof BybitLinearInverseInstrumentInfo) {
+ BybitLinearInverseInstrumentInfo perpetualInstrumentInfo =
+ (BybitLinearInverseInstrumentInfo) info;
+ map.put(
+ adaptInstrument(perpetualInstrumentInfo.getSymbol(), BybitCategory.LINEAR),
+ new InstrumentMetaData.Builder()
+ .minimumAmount(perpetualInstrumentInfo.getLotSizeFilter().getMinOrderQty())
+ .maximumAmount(perpetualInstrumentInfo.getLotSizeFilter().getMaxOrderQty())
+ .counterMinimumAmount(
+ perpetualInstrumentInfo.getLotSizeFilter().getMinOrderQty())
+ .counterMaximumAmount(
+ perpetualInstrumentInfo.getLotSizeFilter().getMaxOrderQty())
+ .priceScale(perpetualInstrumentInfo.getPriceScale())
+ .volumeScale(perpetualInstrumentInfo.getLotSizeFilter().getQtyStep().scale())
+ .amountStepSize(perpetualInstrumentInfo.getLotSizeFilter().getQtyStep())
+ .priceStepSize(perpetualInstrumentInfo.getPriceFilter().getTickSize())
+ .marketOrderEnabled(
+ perpetualInstrumentInfo.getStatus().equals(InstrumentStatus.TRADING))
+ .build());
+ } else if (info instanceof BybitOptionInstrumentInfo) {
+ BybitOptionInstrumentInfo optionsInstrumentInfo = (BybitOptionInstrumentInfo) info;
+ map.put(
+ adaptInstrument(optionsInstrumentInfo.getSymbol(), BybitCategory.OPTION),
+ new InstrumentMetaData.Builder()
+ .minimumAmount(optionsInstrumentInfo.getLotSizeFilter().getMinOrderQty())
+ .maximumAmount(optionsInstrumentInfo.getLotSizeFilter().getMaxOrderQty())
+ .counterMinimumAmount(optionsInstrumentInfo.getLotSizeFilter().getMinOrderQty())
+ .counterMaximumAmount(optionsInstrumentInfo.getLotSizeFilter().getMaxOrderQty())
+ .priceScale(optionsInstrumentInfo.getPriceFilter().getTickSize().scale())
+ .volumeScale(optionsInstrumentInfo.getLotSizeFilter().getQtyStep().scale())
+ .amountStepSize(optionsInstrumentInfo.getLotSizeFilter().getQtyStep())
+ .priceStepSize(optionsInstrumentInfo.getPriceFilter().getTickSize())
+ .marketOrderEnabled(optionsInstrumentInfo.getStatus().equals(InstrumentStatus.TRADING))
+ .build());
+ }
+ });
+ return map;
+ }
+
+ public static OrderType adaptSide(BybitSide side) {
+ return (side.equals(BybitSide.BUY)) ? OrderType.BID : OrderType.ASK;
+ }
+
+ public static String getBybitQuoteCurrency(String symbol) {
+ String quoteCurrency = FUTURES_CONTRACT_QUOTE_CURRENCY;
+
+ for (String quote : QUOTE_CURRENCIES) {
+ if (symbol.endsWith(quote)) {
+ quoteCurrency = quote;
+ break;
+ }
+ }
+
+ return quoteCurrency;
+ }
+
+ public static Currency getFeeCurrency(
+ boolean isMaker, BigDecimal feeRate, Instrument instrument, BybitSide side) {
+ if (instrument instanceof CurrencyPair) {
+ if (isMaker && feeRate.compareTo(BigDecimal.ZERO) > 0) {
+ return (side.equals(BybitSide.BUY)
+ ? ((CurrencyPair) instrument).base
+ : ((CurrencyPair) instrument).counter);
+ } else {
+ if (isMaker) {
+ return (side.equals(BybitSide.BUY)
+ ? ((CurrencyPair) instrument).counter
+ : ((CurrencyPair) instrument).base);
+ } else {
+ return (side.equals(BybitSide.BUY)
+ ? ((CurrencyPair) instrument).base
+ : ((CurrencyPair) instrument).counter);
+ }
+ }
+ } else {
+ return instrument.getCounter();
+ }
+ }
+
+ @SneakyThrows
+ public static Instrument adaptInstrument(String symbol, BybitCategory category) {
+ Instrument instrument = null;
+
+ String quoteCurrency = getBybitQuoteCurrency(symbol);
+
+ if (category.equals(BybitCategory.SPOT)) {
+ String baseCurrency = symbol.substring(0, symbol.length() - quoteCurrency.length());
+
+ instrument = new CurrencyPair(baseCurrency, quoteCurrency);
+ } else if (category.equals(BybitCategory.LINEAR) || category.equals(BybitCategory.INVERSE)) {
+ instrument =
+ (symbol.contains("-"))
+ ? new FuturesContract(new CurrencyPair(symbol.substring(0, symbol.indexOf("-")), quoteCurrency), symbol.substring(symbol.indexOf("-") + 1))
+ : new FuturesContract(new CurrencyPair(symbol.substring(0, symbol.length() - quoteCurrency.length()), quoteCurrency), BYBIT_PERPETUAL);
+ } else if (category.equals(BybitCategory.OPTION)) {
+ int secondIndex = symbol.indexOf("-", symbol.indexOf("-") + 1); // second index of "-" after the first one
+ instrument =
+ new OptionsContract.Builder()
+ .currencyPair(new CurrencyPair(symbol.substring(0, symbol.indexOf("-")), quoteCurrency))
+ .expireDate(OPTIONS_EXPIRED_DATE_PARSER.parse(symbol.substring(symbol.indexOf("-") + 1, secondIndex)))
+ .strike(new BigDecimal(symbol.substring(secondIndex + 1, symbol.lastIndexOf("-"))))
+ .type(symbol.contains("C") ? OptionType.CALL : OptionType.PUT)
+ .build();
+ }
+
+ return instrument;
+ }
+
+ public static BybitCategory getBybitCategoryFromInstrument(Instrument instrument) {
+ int count = StringUtils.countMatches(instrument.toString(), "/");
+ if(count == 1){
+ return BybitCategory.SPOT;
+ } else if(count == 4){
+ return BybitCategory.OPTION;
+ } else if(instrument.getCounter().equals(Currency.USDC) || instrument.getCounter().equals(Currency.USDT)){
+ return BybitCategory.LINEAR;
+ } else {
+ return BybitCategory.INVERSE;
+ }
+ }
+
+ public static List adaptUserTrades(BybitTradeHistoryResponse result) {
+ List userTrades = new ArrayList<>();
+
+ result.getTradeHistoryList().forEach(bybitUserTradeDto -> userTrades.add(adaptUserTrade(bybitUserTradeDto, result.getCategory())));
+
+ return userTrades;
+ }
+
+ public static UserTrade adaptUserTrade(BybitUserTradeDto bybitUserTradeDto, BybitCategory bybitCategory) {
+ Instrument instrument = BybitAdapters.adaptInstrument(bybitUserTradeDto.getSymbol(), bybitCategory);
+ return new UserTrade.Builder()
+ .instrument(instrument)
+ .feeAmount(bybitUserTradeDto.getExecFee())
+ .type(BybitAdapters.adaptSide(bybitUserTradeDto.getSide()))
+ .orderUserReference(bybitUserTradeDto.getOrderLinkId())
+ .id(bybitUserTradeDto.getExecId())
+ .orderId(bybitUserTradeDto.getOrderId())
+ .originalAmount(bybitUserTradeDto.getExecQty())
+ .price(bybitUserTradeDto.getExecPrice())
+ .timestamp(bybitUserTradeDto.getExecTime())
+ .feeCurrency((instrument == null) ? null : BybitAdapters.getFeeCurrency(bybitUserTradeDto.getIsMaker(), bybitUserTradeDto.getFeeRate(), instrument , bybitUserTradeDto.getSide()))
+ .build();
+ }
+
+ public static String adaptBybitSymbol(Instrument instrument) {
+ if(instrument instanceof CurrencyPair){
+ return instrument.toString().replace("/","");
+ } else if(instrument instanceof OptionsContract){
+ return instrument.toString().replace("/","-");
+ } else if(instrument.toString().contains(BYBIT_PERPETUAL)){
+ return instrument.toString().replace("/","").replace(BYBIT_PERPETUAL,"");
+ } else {
+ return instrument.toString().replace("/","-");
+ }
+ }
+
+ public static Map adaptBybitCurrencies(List list) {
+ Map currencyCurrencyMetaDataMap = new HashMap<>();
+
+ list.forEach(bybitInstrumentInfo -> {
+ BybitSpotInstrumentInfo spotInfo = (BybitSpotInstrumentInfo) bybitInstrumentInfo;
+
+ if(!currencyCurrencyMetaDataMap.containsKey(new Currency(spotInfo.getBaseCoin()))){
+ currencyCurrencyMetaDataMap.put(
+ new Currency(spotInfo.getBaseCoin()),
+ CurrencyMetaData.builder()
+ .scale(spotInfo.getLotSizeFilter().getBasePrecision().scale())
+ .build());
+ }
+ if(!currencyCurrencyMetaDataMap.containsKey(new Currency(spotInfo.getQuoteCoin()))) {
+ currencyCurrencyMetaDataMap.put(
+ new Currency(spotInfo.getQuoteCoin()),
+ CurrencyMetaData.builder()
+ .scale(spotInfo.getLotSizeFilter().getQuotePrecision().scale())
+ .build());
+ }
+ });
+
+ return currencyCurrencyMetaDataMap;
+ }
+
+ public static List adaptBybitInternalTransfers(List internalTransfers) {
+ List fundingRecords = new ArrayList<>();
+
+ internalTransfers.forEach(internalTransfer -> fundingRecords.add(FundingRecord.builder()
+ .internalId(internalTransfer.getTransferId())
+ .currency(new Currency(internalTransfer.getCoin()))
+ .amount(internalTransfer.getAmount())
+ .date(internalTransfer.getTimestamp())
+ .type(Type.INTERNAL_WALLET_TRANSFER)
+ .status(Status.resolveStatus(internalTransfer.getStatus().name()))
+ .fromWallet(internalTransfer.getFromAccountType().name())
+ .toWallet(internalTransfer.getToAccountType().name())
+ .description(internalTransfer.getFromAccountType().name()+"->"+internalTransfer.getToAccountType().name())
+ .build()));
+ return fundingRecords;
+ }
+
+ public static List adaptBybitWithdrawRecords(List withdrawRecords) {
+ List fundingRecords = new ArrayList<>();
+
+ withdrawRecords.forEach(withdrawRecord -> fundingRecords.add(FundingRecord.builder()
+ .internalId(withdrawRecord.getWithdrawId())
+ .blockchainTransactionHash(withdrawRecord.getTxID())
+ .addressTag(withdrawRecord.getTag())
+ .address(withdrawRecord.getToAddress())
+ .currency(new Currency(withdrawRecord.getCoin()))
+ .type(withdrawRecord.getWithdrawType() == 0 ? Type.WITHDRAWAL: Type.INTERNAL_WITHDRAWAL)
+ .amount(withdrawRecord.getAmount())
+ .date(withdrawRecord.getCreateTime())
+ .status(Status.resolveStatus(withdrawRecord.getStatus().name()))
+ .fee(withdrawRecord.getWithdrawFee())
+ .description(withdrawRecord.getChain())
+ .build()));
+ return fundingRecords;
+ }
+
+ public static List adaptBybitUniversalTransfers(List universalTransfers) {
+ List fundingRecords = new ArrayList<>();
+
+ universalTransfers.forEach(universalTransfer -> fundingRecords.add(FundingRecord.builder()
+ .internalId(universalTransfer.getTransferId())
+ .currency(Currency.getInstance(universalTransfer.getCoin()))
+ .amount(universalTransfer.getAmount())
+ .date(universalTransfer.getTimestamp())
+ .type(Type.INTERNAL_SUB_ACCOUNT_TRANSFER)
+ .status(Status.resolveStatus(universalTransfer.getStatus().name()))
+ .toSubAccount(universalTransfer.getToMember())
+ .fromSubAccount(universalTransfer.getFromMember())
+ .toWallet(universalTransfer.getToAccountType().name())
+ .fromWallet(universalTransfer.getFromAccountType().name())
+ .description(universalTransfer.getFromMember()+"."+universalTransfer.getFromAccountType().name()+"->"+universalTransfer.getToMember()+"."+universalTransfer.getToAccountType().name())
+ .build()));
+
+ return fundingRecords;
+ }
+
+
+ public static List adaptBybitDepositRecords(List bybitDepositRecords) {
+ List fundingRecords = new ArrayList<>();
+
+ bybitDepositRecords.forEach(depositRecord -> fundingRecords.add(FundingRecord.builder()
+ .internalId(depositRecord.getTxID())
+ .addressTag(depositRecord.getTag())
+ .address((depositRecord.getToAddress() == null) ? "" : depositRecord.getToAddress())
+ .type(Type.DEPOSIT)
+ .fee((depositRecord.getDepositFee() == null) ? BigDecimal.ZERO : depositRecord.getDepositFee())
+ .blockchainTransactionHash(depositRecord.getBlockHash())
+ .currency(Currency.getInstance(depositRecord.getCoin()))
+ .amount(depositRecord.getAmount())
+ .date(depositRecord.getSuccessAt())
+ .status(Status.resolveStatus(depositRecord.getStatus().name()))
+ .description(depositRecord.getDepositType().name())
+ .build()));
+
+ return fundingRecords;
+ }
+
+ public static List adaptBybitInternalDepositRecords(List bybitInternalDepositRecords) {
+ List fundingRecords = new ArrayList<>();
+
+ bybitInternalDepositRecords.forEach(internalRecord -> fundingRecords.add(FundingRecord.builder()
+ .internalId(internalRecord.getId())
+ .address(internalRecord.getAddress())
+ .type(Type.INTERNAL_DEPOSIT)
+ .currency(Currency.getInstance(internalRecord.getCoin()))
+ .amount(internalRecord.getAmount())
+ .date(internalRecord.getCreatedTime())
+ .status(Status.resolveStatus(internalRecord.getStatus().name()))
+ .build()));
+
+ return fundingRecords;
+ }
+
+ public static BybitTransferStatus convertToBybitStatus(FundingRecord.Status status) {
+ BybitTransferStatus bybitStatus = null;
+
+ if(status != null){
+ switch (status){
+ case CANCELLED:
+ case FAILED:
+ bybitStatus = BybitTransferStatus.FAILED;
+ break;
+ case COMPLETE:
+ bybitStatus = BybitTransferStatus.SUCCESS;
+ break;
+ case PROCESSING:
+ bybitStatus = BybitTransferStatus.PENDING;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return bybitStatus;
+ }
+
+ public static List adaptBybitLedger(List list) {
+ List fundingRecords = new ArrayList<>();
+
+ list.forEach(
+ bybitTransactionLog -> fundingRecords.add(
+ FundingRecord.builder()
+ .currency(Currency.getInstance(bybitTransactionLog.getCurrency()))
+ .balance(bybitTransactionLog.getCashBalance())
+ .internalId(bybitTransactionLog.getId())
+ .fee(bybitTransactionLog.getFee())
+ .amount(bybitTransactionLog.getChange())
+ .type(convertToFundingRecordType(bybitTransactionLog.getType()))
+ .status(Status.COMPLETE)
+ .date(bybitTransactionLog.getTransactionTime())
+ .build()));
+
+ return fundingRecords;
+ }
+
+ private static Type convertToFundingRecordType(BybitTransactionLogType type) {
+ Type fundingRecordType = null;
+
+ if(type != null){
+ switch (type) {
+ case TRANSFER_IN:
+ case TRANSFER_IN_INS_LOAN:
+ fundingRecordType = Type.DEPOSIT;
+ break;
+ case TRANSFER_OUT:
+ case TRANSFER_OUT_INS_LOAN:
+ fundingRecordType = Type.WITHDRAWAL;
+ break;
+ case TRADE:
+ case CURRENCY_BUY:
+ case CURRENCY_SELL:
+ case SPOT_REPAYMENT_BUY:
+ case SPOT_REPAYMENT_SELL:
+ case AUTO_BUY_LIABILITY_INS_LOAN:
+ case LIQUIDATION:
+ case AUTO_SOLD_COLLATERAL_INS_LOAN:
+ fundingRecordType = Type.TRADE;
+ break;
+ case DELIVERY:
+ fundingRecordType = Type.DELIVERY;
+ break;
+ case INTEREST:
+ fundingRecordType = Type.INTEREST;
+ break;
+ case SETTLEMENT:
+ fundingRecordType = Type.SETTLEMENT;
+ break;
+ case BONUS:
+ case FEE_REFUND:
+ case BORROWED_AMOUNT_INS_LOAN:
+ fundingRecordType = Type.OTHER_INFLOW;
+ break;
+ case AUTO_PRINCIPLE_REPAYMENT_INS_LOAN:
+ case PRINCIPLE_REPAYMENT_INS_LOAN:
+ case INTEREST_REPAYMENT_INS_LOAN:
+ case AUTO_INTEREST_REPAYMENT_INS_LOAN:
+ fundingRecordType = Type.OTHER_OUTFLOW;
+ break;
+ default:
+ break;
+ }
+ }
+ return fundingRecordType;
}
}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/BybitAuthenticated.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/BybitAuthenticated.java
index ffadff217ca..e202fc2447c 100644
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/BybitAuthenticated.java
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/BybitAuthenticated.java
@@ -1,49 +1,238 @@
package org.knowm.xchange.bybit;
+import static org.knowm.xchange.bybit.service.BybitDigest.X_BAPI_API_KEY;
+import static org.knowm.xchange.bybit.service.BybitDigest.X_BAPI_SIGN;
+import static org.knowm.xchange.bybit.service.BybitDigest.X_BAPI_TIMESTAMP;
+
+import jakarta.ws.rs.FormParam;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.HeaderParam;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.core.MediaType;
+import java.io.IOException;
+import java.math.BigDecimal;
import org.knowm.xchange.bybit.dto.BybitResult;
-import org.knowm.xchange.bybit.dto.account.BybitBalances;
-import org.knowm.xchange.bybit.dto.trade.BybitOrderDetails;
-import org.knowm.xchange.bybit.dto.trade.BybitOrderRequest;
+import org.knowm.xchange.bybit.dto.account.BybitDepositRecordsResponse;
+import org.knowm.xchange.bybit.dto.account.BybitInternalDepositRecordsResponse;
+import org.knowm.xchange.bybit.dto.account.BybitTransactionLogResponse;
+import org.knowm.xchange.bybit.dto.account.BybitTransfersResponse;
+import org.knowm.xchange.bybit.dto.account.BybitAllCoinsBalance;
+import org.knowm.xchange.bybit.dto.account.BybitFeeRates;
+import org.knowm.xchange.bybit.dto.account.BybitWithdrawRecordsResponse;
+import org.knowm.xchange.bybit.dto.account.walletbalance.BybitWalletBalance;
+import org.knowm.xchange.bybit.dto.trade.BybitTradeHistoryResponse;
+import org.knowm.xchange.bybit.dto.trade.BybitOrderResponse;
+import org.knowm.xchange.bybit.dto.trade.details.BybitOrderDetail;
+import org.knowm.xchange.bybit.dto.trade.details.BybitOrderDetails;
import org.knowm.xchange.bybit.service.BybitException;
import si.mazi.rescu.ParamsDigest;
import si.mazi.rescu.SynchronizedValueFactory;
-import jakarta.ws.rs.*;
-import jakarta.ws.rs.core.MediaType;
-import java.io.IOException;
-
-@Path("/spot/v1")
+@Path("/v5")
@Produces(MediaType.APPLICATION_JSON)
public interface BybitAuthenticated {
- @GET
- @Path("/account")
- BybitResult getWalletBalances(
- @QueryParam("api_key") String apiKey,
- @QueryParam("timestamp") SynchronizedValueFactory timestamp,
- @QueryParam("sign") ParamsDigest signature
- ) throws IOException, BybitException;
-
- @GET
- @Path("/order")
- BybitResult getOrder(
- @QueryParam("api_key") String apiKey,
- @QueryParam("orderId") String orderId,
- @QueryParam("timestamp") SynchronizedValueFactory timestamp,
- @QueryParam("sign") ParamsDigest signature
- ) throws IOException, BybitException;
-
- @POST
- @Path("/order")
- BybitResult placeOrder(
- @FormParam("api_key") String apiKey,
- @FormParam("symbol") String symbol,
- @FormParam("qty") long qty,
- @FormParam("side") String side,
- @FormParam("type") String type,
- @FormParam("timestamp") SynchronizedValueFactory timestamp,
- @FormParam("sign") ParamsDigest signature
- ) throws IOException, BybitException;
-
-
-}
\ No newline at end of file
+ /** @apiSpec API */
+ @GET
+ @Path("/account/wallet-balance")
+ BybitResult getWalletBalance(
+ @HeaderParam(X_BAPI_API_KEY) String apiKey,
+ @HeaderParam(X_BAPI_SIGN) ParamsDigest signature,
+ @HeaderParam(X_BAPI_TIMESTAMP) SynchronizedValueFactory timestamp,
+ @QueryParam("accountType") String accountType)
+ throws IOException, BybitException;
+
+ /** @apiSpec API */
+ @GET
+ @Path("/asset/transfer/query-account-coins-balance")
+ BybitResult getAllCoinsBalance(
+ @HeaderParam(X_BAPI_API_KEY) String apiKey,
+ @HeaderParam(X_BAPI_SIGN) ParamsDigest signature,
+ @HeaderParam(X_BAPI_TIMESTAMP) SynchronizedValueFactory timestamp,
+ @QueryParam("memberId") String memberId,
+ @QueryParam("accountType") String accountType, //required
+ @QueryParam("coin") String coin,
+ @QueryParam("withBonus") Integer withBonus
+ ) throws IOException, BybitException;
+
+ @GET
+ @Path("/asset/transfer/query-account-coin-balance")
+ BybitResult getSingleCoinBalance(
+ @HeaderParam(X_BAPI_API_KEY) String apiKey,
+ @HeaderParam(X_BAPI_SIGN) ParamsDigest signature,
+ @HeaderParam(X_BAPI_TIMESTAMP) SynchronizedValueFactory timestamp,
+ @QueryParam("memberId") String memberId,
+ @QueryParam("toMemberId") String toMemberId,
+ @QueryParam("accountType") String accountType, //required
+ @QueryParam("toAccountType") String toAccountType,
+ @QueryParam("coin") String coin, //required
+ @QueryParam("withBonus") Integer withBonus,
+ @QueryParam("withTransferSafeAmount") Integer withTransferSafeAmount,
+ @QueryParam("withLtvTransferSafeAmount") Integer withLtvTransferSafeAmount
+ ) throws IOException, BybitException;
+
+ /** @apiSpec API */
+ @GET
+ @Path("/account/fee-rate")
+ BybitResult getFeeRates(
+ @HeaderParam(X_BAPI_API_KEY) String apiKey,
+ @HeaderParam(X_BAPI_SIGN) ParamsDigest signature,
+ @HeaderParam(X_BAPI_TIMESTAMP) SynchronizedValueFactory timestamp,
+ @QueryParam("category") String category,
+ @QueryParam("symbol") String symbol)
+ throws IOException, BybitException;
+
+ /** @apiSpec API */
+ @GET
+ @Path("/order/realtime")
+ BybitResult> getOpenOrders(
+ @HeaderParam(X_BAPI_API_KEY) String apiKey,
+ @HeaderParam(X_BAPI_SIGN) ParamsDigest signature,
+ @HeaderParam(X_BAPI_TIMESTAMP) SynchronizedValueFactory timestamp,
+ @QueryParam("category") String category,
+ @QueryParam("orderId") String orderId)
+ throws IOException, BybitException;
+
+ /** @apiSpec API */
+ @POST
+ @Path("/order/create")
+ BybitResult placeOrder(
+ @HeaderParam(X_BAPI_API_KEY) String apiKey,
+ @HeaderParam(X_BAPI_SIGN) ParamsDigest signature,
+ @HeaderParam(X_BAPI_TIMESTAMP) SynchronizedValueFactory timestamp,
+ @FormParam("category") String category,
+ @FormParam("symbol") String symbol,
+ @FormParam("side") String side,
+ @FormParam("orderType") String orderType,
+ @FormParam("qty") BigDecimal qty)
+ throws IOException, BybitException;
+
+ @GET
+ @Path("/execution/list")
+ BybitResult getBybitTradeHistory(
+ @HeaderParam(X_BAPI_API_KEY) String apiKey,
+ @HeaderParam(X_BAPI_SIGN) ParamsDigest signature,
+ @HeaderParam(X_BAPI_TIMESTAMP) SynchronizedValueFactory timestamp,
+ @QueryParam("category") String category,
+ @QueryParam("symbol") String symbol,
+ @QueryParam("orderId") String orderId,
+ @QueryParam("orderLinkId") String userReferenceId,
+ @QueryParam("baseCoin") String baseCoin, // Base coin. Unified account - inverse and Classic account do not support this param
+ @QueryParam("startTime") Long startTime,
+ @QueryParam("endTime") Long endTime,
+ @QueryParam("execType") String execType,
+ @QueryParam("limit") Integer limit,
+ @QueryParam("cursor") String cursor
+ ) throws IOException, BybitException;
+
+ @GET
+ @Path("/asset/transfer/query-inter-transfer-list")
+ BybitResult getInternalTransferRecords(
+ @HeaderParam(X_BAPI_API_KEY) String apiKey,
+ @HeaderParam(X_BAPI_SIGN) ParamsDigest signature,
+ @HeaderParam(X_BAPI_TIMESTAMP) SynchronizedValueFactory timestamp,
+ @QueryParam("transferId") String transferId,
+ @QueryParam("coin") String coin,
+ @QueryParam("status") String status,
+ @QueryParam("startTime") Long startTime,
+ @QueryParam("endTime") Long endTime,
+ @QueryParam("limit") Integer limit,
+ @QueryParam("cursor") String cursor
+ ) throws IOException, BybitException;
+
+ @GET
+ @Path("/asset/transfer/query-universal-transfer-list")
+ BybitResult getUniversalTransferRecords(
+ @HeaderParam(X_BAPI_API_KEY) String apiKey,
+ @HeaderParam(X_BAPI_SIGN) ParamsDigest signature,
+ @HeaderParam(X_BAPI_TIMESTAMP) SynchronizedValueFactory timestamp,
+ @QueryParam("transferId") String transferId,
+ @QueryParam("coin") String coin,
+ @QueryParam("status") String status,
+ @QueryParam("startTime") Long startTime,
+ @QueryParam("endTime") Long endTime,
+ @QueryParam("limit") Integer limit,
+ @QueryParam("cursor") String cursor
+ ) throws IOException, BybitException;
+
+ @GET
+ @Path("/account/transaction-log")
+ BybitResult getTransactionLogRecords(
+ @HeaderParam(X_BAPI_API_KEY) String apiKey,
+ @HeaderParam(X_BAPI_SIGN) ParamsDigest signature,
+ @HeaderParam(X_BAPI_TIMESTAMP) SynchronizedValueFactory timestamp,
+ @QueryParam("accountType") String accountType,
+ @QueryParam("category") String category,
+ @QueryParam("currency") String currency,
+ @QueryParam("baseCoin") String baseCoin,
+ @QueryParam("type") String type,
+ @QueryParam("startTime") Long startTime,
+ @QueryParam("endTime") Long endTime,
+ @QueryParam("limit") Integer limit,
+ @QueryParam("cursor") String cursor
+ ) throws IOException, BybitException;
+
+ @GET
+ @Path("/asset/withdraw/query-record")
+ BybitResult getWithdrawRecords(
+ @HeaderParam(X_BAPI_API_KEY) String apiKey,
+ @HeaderParam(X_BAPI_SIGN) ParamsDigest signature,
+ @HeaderParam(X_BAPI_TIMESTAMP) SynchronizedValueFactory timestamp,
+ @QueryParam("withdrawId") String withdrawID,
+ @QueryParam("coin") String coin,
+ @QueryParam("withdrawType") Integer withdrawType, //0(default): on chain. 1: off chain. 2: all
+ @QueryParam("startTime") Long startTime,
+ @QueryParam("endTime") Long endTime,
+ @QueryParam("limit") Integer limit,
+ @QueryParam("cursor") String cursor
+ ) throws IOException, BybitException;
+
+ @GET
+ @Path("/asset/deposit/query-record")
+ BybitResult getOnChainDepositRecords(
+ @HeaderParam(X_BAPI_API_KEY) String apiKey,
+ @HeaderParam(X_BAPI_SIGN) ParamsDigest signature,
+ @HeaderParam(X_BAPI_TIMESTAMP) SynchronizedValueFactory timestamp,
+ @QueryParam("coin") String coin,
+ @QueryParam("startTime") Long startTime,
+ @QueryParam("endTime") Long endTime,
+ @QueryParam("limit") Integer limit,
+ @QueryParam("cursor") String cursor
+ ) throws IOException, BybitException;
+
+ /**
+ * Query the internal transfer records between different account types under the same UID.
+ */
+ @GET
+ @Path("/asset/deposit/query-internal-record")
+ BybitResult getInternalDepositRecords(
+ @HeaderParam(X_BAPI_API_KEY) String apiKey,
+ @HeaderParam(X_BAPI_SIGN) ParamsDigest signature,
+ @HeaderParam(X_BAPI_TIMESTAMP) SynchronizedValueFactory timestamp,
+ @QueryParam("startTime") Long startTime,
+ @QueryParam("endTime") Long endTime,
+ @QueryParam("coin") String coin,
+ @QueryParam("cursor") String cursor,
+ @QueryParam("limit") Integer limit
+ ) throws IOException, BybitException;
+
+ /**
+ * Query subaccount's deposit records by main UID's API key.
+ */
+ @GET
+ @Path("/asset/deposit/query-sub-member-record")
+ BybitResult getSubAccountDepositRecords(
+ @HeaderParam(X_BAPI_API_KEY) String apiKey,
+ @HeaderParam(X_BAPI_SIGN) ParamsDigest signature,
+ @HeaderParam(X_BAPI_TIMESTAMP) SynchronizedValueFactory timestamp,
+ @QueryParam("subMemberId") String subMemberId, //required
+ @QueryParam("coin") String coin,
+ @QueryParam("startTime") Long startTime,
+ @QueryParam("endTime") Long endTime,
+ @QueryParam("limit") Integer limit,
+ @QueryParam("cursor") String cursor
+ ) throws IOException, BybitException;
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/BybitExchange.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/BybitExchange.java
index 6639acabb13..00eb1cccad4 100644
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/BybitExchange.java
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/BybitExchange.java
@@ -1,16 +1,13 @@
package org.knowm.xchange.bybit;
-
import java.io.IOException;
-import java.util.List;
import org.knowm.xchange.BaseExchange;
import org.knowm.xchange.ExchangeSpecification;
-import org.knowm.xchange.bybit.dto.marketdata.BybitSymbol;
-import org.knowm.xchange.bybit.mappers.MarketDataMapper;
+import org.knowm.xchange.bybit.dto.account.walletbalance.BybitAccountType;
import org.knowm.xchange.bybit.service.BybitAccountService;
import org.knowm.xchange.bybit.service.BybitMarketDataService;
-import org.knowm.xchange.bybit.service.BybitMarketDataServiceRaw;
import org.knowm.xchange.bybit.service.BybitTradeService;
+import org.knowm.xchange.dto.meta.ExchangeMetaData;
import org.knowm.xchange.exceptions.ExchangeException;
public class BybitExchange extends BaseExchange {
@@ -19,27 +16,45 @@ public class BybitExchange extends BaseExchange {
protected void initServices() {
marketDataService = new BybitMarketDataService(this);
tradeService = new BybitTradeService(this);
- accountService = new BybitAccountService(this);
+ accountService =
+ new BybitAccountService(
+ this, ((BybitExchangeSpecification) getExchangeSpecification()).getAccountType());
}
-
@Override
public ExchangeSpecification getDefaultExchangeSpecification() {
- ExchangeSpecification exchangeSpecification = new ExchangeSpecification(this.getClass());
+ BybitExchangeSpecification exchangeSpecification =
+ new BybitExchangeSpecification(this.getClass());
exchangeSpecification.setSslUri("https://api.bybit.com");
exchangeSpecification.setHost("bybit.com");
exchangeSpecification.setPort(80);
exchangeSpecification.setExchangeName("Bybit");
exchangeSpecification.setExchangeDescription("BYBIT");
+ exchangeSpecification.setAccountType(BybitAccountType.UNIFIED);
+ exchangeSpecification.setExchangeSpecificParametersItem(USE_SANDBOX, false);
return exchangeSpecification;
}
+ @Override
+ public void applySpecification(ExchangeSpecification exchangeSpecification) {
+ if(useSandbox(exchangeSpecification)){
+ exchangeSpecification.setSslUri("https://api-testnet.bybit.com");
+ }
+ super.applySpecification(exchangeSpecification);
+ }
+
@Override
public void remoteInit() throws IOException, ExchangeException {
- //initialize currency pairs
- List symbols = ((BybitMarketDataServiceRaw) marketDataService).getSymbols().getResult();
- symbols.forEach(bybitSymbol -> exchangeMetaData.getInstruments().put(
- MarketDataMapper.symbolToCurrencyPair(bybitSymbol),
- MarketDataMapper.symbolToCurrencyPairMetaData(bybitSymbol))
- );
+ // initialize currency pairs & currencies
+ exchangeMetaData = new ExchangeMetaData(
+ marketDataService.getInstruments(),
+ marketDataService.getCurrencies(),
+ null,
+ null,
+ true);
+ }
+
+ protected boolean useSandbox(ExchangeSpecification exchangeSpecification){
+ return Boolean.TRUE.equals(
+ exchangeSpecification.getExchangeSpecificParametersItem(USE_SANDBOX));
}
}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/BybitExchangeSpecification.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/BybitExchangeSpecification.java
new file mode 100644
index 00000000000..28f942e5014
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/BybitExchangeSpecification.java
@@ -0,0 +1,16 @@
+package org.knowm.xchange.bybit;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.knowm.xchange.Exchange;
+import org.knowm.xchange.ExchangeSpecification;
+import org.knowm.xchange.bybit.dto.account.walletbalance.BybitAccountType;
+
+public class BybitExchangeSpecification extends ExchangeSpecification {
+
+ @Getter @Setter private BybitAccountType accountType = BybitAccountType.UNIFIED;
+
+ public BybitExchangeSpecification(Class extends Exchange> exchangeClass) {
+ super(exchangeClass);
+ }
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/BybitCategorizedPayload.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/BybitCategorizedPayload.java
new file mode 100644
index 00000000000..34a25a41e87
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/BybitCategorizedPayload.java
@@ -0,0 +1,15 @@
+package org.knowm.xchange.bybit.dto;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+
+@Data
+public class BybitCategorizedPayload {
+
+ @JsonProperty("category")
+ BybitCategory category;
+
+ @JsonProperty("list")
+ List list;
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/BybitCategory.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/BybitCategory.java
new file mode 100644
index 00000000000..3a4548edb94
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/BybitCategory.java
@@ -0,0 +1,16 @@
+package org.knowm.xchange.bybit.dto;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum BybitCategory {
+ SPOT("spot"),
+ LINEAR("linear"),
+ INVERSE("inverse"),
+ OPTION("option");
+
+ @JsonValue private final String value;
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/BybitResult.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/BybitResult.java
index 9d9ea219c53..46dd46b37ba 100644
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/BybitResult.java
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/BybitResult.java
@@ -1,39 +1,32 @@
package org.knowm.xchange.bybit.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.util.Date;
import lombok.Builder;
import lombok.Value;
import lombok.extern.jackson.Jacksonized;
-import org.knowm.xchange.utils.jackson.UnixTimestampNanoSecondsDeserializer;
@Builder
@Jacksonized
@Value
public class BybitResult {
- @JsonProperty("ret_code")
+ @JsonProperty("retCode")
int retCode;
- @JsonProperty("ret_msg")
+ @JsonProperty("retMsg")
String retMsg;
- @JsonProperty("ext_code")
- String extCode;
-
- @JsonProperty("ext_info")
- String extInfo;
-
@JsonProperty("result")
V result;
- @JsonProperty("time_now")
- @JsonDeserialize(using = UnixTimestampNanoSecondsDeserializer.class)
- Date timeNow;
+ @JsonProperty("retExtInfo")
+ Object retExtInfo;
+
+ @JsonProperty("time")
+ Date time;
public boolean isSuccess() {
return retCode == 0;
}
-
}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitAllCoinsBalance.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitAllCoinsBalance.java
new file mode 100644
index 00000000000..3d31c0cb5f9
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitAllCoinsBalance.java
@@ -0,0 +1,54 @@
+package org.knowm.xchange.bybit.dto.account;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.math.BigDecimal;
+import java.util.List;
+import lombok.Builder;
+import lombok.Value;
+import lombok.extern.jackson.Jacksonized;
+import org.knowm.xchange.bybit.dto.account.walletbalance.BybitAccountType;
+
+@Builder
+@Jacksonized
+@Value
+public class BybitAllCoinsBalance {
+
+ @JsonProperty("accountType")
+ BybitAccountType accountType;
+
+ @JsonProperty("bizType")
+ Integer bizType;
+
+ @JsonProperty("accountId")
+ String accountId;
+
+ @JsonProperty("memberId")
+ String memberId;
+
+ @JsonProperty("balance")
+ List balance;
+
+ @Builder
+ @Jacksonized
+ @Value
+ public static class BybitCoinBalance {
+
+ @JsonProperty("coin")
+ String coin;
+
+ @JsonProperty("walletBalance")
+ BigDecimal walletBalance;
+
+ @JsonProperty("transferBalance")
+ BigDecimal transferBalance;
+
+ @JsonProperty("bonus")
+ BigDecimal bonus;
+
+ @JsonProperty("transferSafeAmount")
+ BigDecimal transferSafeAmount;
+
+ @JsonProperty("ltvTransferSafeAmount")
+ BigDecimal ltvTransferSafeAmount;
+ }
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitBalance.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitBalance.java
deleted file mode 100644
index 495af4e98d2..00000000000
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitBalance.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.knowm.xchange.bybit.dto.account;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Builder;
-import lombok.Value;
-import lombok.extern.jackson.Jacksonized;
-
-@Builder
-@Jacksonized
-@Value
-public class BybitBalance {
-
- @JsonProperty("coin")
- String coin;
-
- @JsonProperty("coinId")
- String coinId;
-
- @JsonProperty("coinName")
- String coinName;
-
- @JsonProperty("total")
- String total;
-
- @JsonProperty("free")
- String free;
-
- @JsonProperty("locked")
- String locked;
-
-}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitDepositRecordsResponse.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitDepositRecordsResponse.java
new file mode 100644
index 00000000000..b04cbac2879
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitDepositRecordsResponse.java
@@ -0,0 +1,102 @@
+package org.knowm.xchange.bybit.dto.account;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonValue;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.ToString;
+import lombok.extern.jackson.Jacksonized;
+
+@Getter
+@ToString
+@Builder
+@Jacksonized
+public class BybitDepositRecordsResponse {
+
+ @JsonProperty("rows")
+ private List rows;
+
+ @JsonProperty("nextPageCursor")
+ private String nextPageCursor;
+
+ @Getter
+ @ToString
+ @Builder
+ @Jacksonized
+ public static class BybitDepositRecord {
+
+ @JsonProperty("coin")
+ private String coin;
+
+ @JsonProperty("chain")
+ private String chain;
+
+ @JsonProperty("amount")
+ private BigDecimal amount;
+
+ @JsonProperty("txID")
+ private String txID;
+
+ @JsonProperty("status")
+ private BybitDepositStatus status;
+
+ @JsonProperty("toAddress")
+ private String toAddress;
+
+ @JsonProperty("tag")
+ private String tag;
+
+ @JsonProperty("depositFee")
+ private BigDecimal depositFee;
+
+ @JsonProperty("successAt")
+ private Date successAt;
+
+ @JsonProperty("confirmations")
+ private Integer confirmations;
+
+ @JsonProperty("txIndex")
+ private Integer txIndex;
+
+ @JsonProperty("blockHash")
+ private String blockHash;
+
+ @JsonProperty("batchReleaseLimit")
+ private BigDecimal batchReleaseLimit;
+
+ @JsonProperty("depositType")
+ private BybitDepositType depositType;
+
+ @Getter
+ @AllArgsConstructor
+ public enum BybitDepositStatus {
+
+ UNKNOWN(0),
+ TO_BE_CONFIRMED(1),
+ PROCESSING(2),
+ SUCCESS(3),
+ DEPOSIT_FAILED(4),
+ PENDING_TO_BE_CREDITED_TO_FUNDING_POOL(10011),
+ CREDITED_TO_FUNDING_POOL_SUCCESSFULLY(10012);
+
+ @JsonValue
+ private final Integer value;
+ }
+
+ @Getter
+ @AllArgsConstructor
+ public enum BybitDepositType {
+
+ NORMAL_DEPOSIT(0),
+ DAILY_DEPOSIT_LIMIT_REACHED(10),
+ ABNORMAL_DEPOSIT(20);
+
+ @JsonValue
+ private final Integer value;
+ }
+ }
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitFeeRates.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitFeeRates.java
new file mode 100644
index 00000000000..6250aad8303
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitFeeRates.java
@@ -0,0 +1,32 @@
+package org.knowm.xchange.bybit.dto.account;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.math.BigDecimal;
+import java.util.List;
+import lombok.Builder;
+import lombok.Value;
+import lombok.extern.jackson.Jacksonized;
+
+@Builder
+@Jacksonized
+@Value
+public class BybitFeeRates {
+
+ @JsonProperty("list")
+ List list;
+
+ @Builder
+ @Jacksonized
+ @Value
+ public static class BybitFeeRate {
+
+ @JsonProperty("symbol")
+ String symbol;
+
+ @JsonProperty("takerFeeRate")
+ BigDecimal takerFeeRate;
+
+ @JsonProperty("makerFeeRate")
+ BigDecimal makerFeeRate;
+ }
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitInternalDepositRecordsResponse.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitInternalDepositRecordsResponse.java
new file mode 100644
index 00000000000..291d16b5333
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitInternalDepositRecordsResponse.java
@@ -0,0 +1,66 @@
+package org.knowm.xchange.bybit.dto.account;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonValue;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.ToString;
+import lombok.extern.jackson.Jacksonized;
+
+@Getter
+@ToString
+@Builder
+@Jacksonized
+public class BybitInternalDepositRecordsResponse {
+
+ @JsonProperty("rows")
+ private List rows;
+
+ @JsonProperty("nextPageCursor")
+ private String nextPageCursor;
+ @Getter
+ @ToString
+ @Builder
+ @Jacksonized
+ public static class BybitInternalDepositRecord {
+
+ @JsonProperty("id")
+ private String id;
+
+ @JsonProperty("type")
+ private Integer type;
+
+ @JsonProperty("coin")
+ private String coin;
+
+ @JsonProperty("amount")
+ private BigDecimal amount;
+
+ @JsonProperty("status")
+ private BybitInternalDepositStatus status;
+
+ @JsonProperty("address")
+ private String address;
+
+ @JsonProperty("createdTime")
+ private Date createdTime;
+
+ @Getter
+ @AllArgsConstructor
+ public enum BybitInternalDepositStatus {
+
+ PROCESSING(0),
+
+ SUCCESS(1),
+
+ FAILED(2);
+
+ @JsonValue
+ private final int value;
+ }
+ }
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitTransactionLogResponse.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitTransactionLogResponse.java
new file mode 100644
index 00000000000..44633c7a810
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitTransactionLogResponse.java
@@ -0,0 +1,115 @@
+package org.knowm.xchange.bybit.dto.account;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.ToString;
+import lombok.extern.jackson.Jacksonized;
+
+@Getter
+@ToString
+@Builder
+@Jacksonized
+public class BybitTransactionLogResponse {
+
+ @JsonProperty("list")
+ private List list;
+
+ @JsonProperty("nextPageCursor")
+ private String nextPageCursor;
+
+ @Getter
+ @ToString
+ @Builder
+ @Jacksonized
+ public static class BybitTransactionLog {
+
+ @JsonProperty("id")
+ private String id;
+
+ @JsonProperty("symbol")
+ private String symbol;
+
+ @JsonProperty("category")
+ private String category;
+
+ @JsonProperty("side")
+ private String side;
+
+ @JsonProperty("transactionTime")
+ private Date transactionTime;
+
+ @JsonProperty("type")
+ private BybitTransactionLogType type;
+
+ @JsonProperty("qty")
+ private BigDecimal qty;
+
+ @JsonProperty("size")
+ private BigDecimal size;
+
+ @JsonProperty("currency")
+ private String currency;
+
+ @JsonProperty("tradePrice")
+ private BigDecimal tradePrice;
+
+ @JsonProperty("funding")
+ private BigDecimal funding;
+
+ @JsonProperty("fee")
+ private BigDecimal fee;
+
+ @JsonProperty("cashFlow")
+ private BigDecimal cashFlow;
+
+ @JsonProperty("change")
+ private BigDecimal change;
+
+ @JsonProperty("cashBalance")
+ private BigDecimal cashBalance;
+
+ @JsonProperty("feeRate")
+ private BigDecimal feeRate;
+
+ @JsonProperty("bonusChange")
+ private BigDecimal bonusChange;
+
+ @JsonProperty("tradeId")
+ private String tradeId;
+
+ @JsonProperty("orderId")
+ private String orderId;
+
+ @JsonProperty("orderLinkId")
+ private String orderLinkId; //userReference
+
+ public enum BybitTransactionLogType {
+ TRANSFER_IN,
+ TRANSFER_OUT,
+ TRADE,
+ SETTLEMENT,
+ DELIVERY,
+ LIQUIDATION,
+ BONUS,
+ FEE_REFUND,
+ INTEREST,
+ CURRENCY_BUY,
+ CURRENCY_SELL,
+ BORROWED_AMOUNT_INS_LOAN,
+ PRINCIPLE_REPAYMENT_INS_LOAN,
+ INTEREST_REPAYMENT_INS_LOAN,
+ AUTO_SOLD_COLLATERAL_INS_LOAN,
+ AUTO_BUY_LIABILITY_INS_LOAN,
+ AUTO_PRINCIPLE_REPAYMENT_INS_LOAN,
+ AUTO_INTEREST_REPAYMENT_INS_LOAN,
+ TRANSFER_IN_INS_LOAN, //Transfer In when in the liquidation of OTC loan
+ TRANSFER_OUT_INS_LOAN, //Transfer Out when in the liquidation of OTC loan
+ SPOT_REPAYMENT_SELL, //One-click repayment currency sell
+ SPOT_REPAYMENT_BUY //One-click repayment currency buy
+ }
+ }
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitTransfersResponse.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitTransfersResponse.java
new file mode 100644
index 00000000000..fb93c5cabac
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitTransfersResponse.java
@@ -0,0 +1,64 @@
+package org.knowm.xchange.bybit.dto.account;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.ToString;
+import lombok.extern.jackson.Jacksonized;
+import org.knowm.xchange.bybit.dto.account.walletbalance.BybitAccountType;
+
+@Getter
+@ToString
+@Builder
+@Jacksonized
+public class BybitTransfersResponse {
+
+ @JsonProperty("list")
+ private List internalTransfers;
+
+ @JsonProperty("nextPageCursor")
+ private String nextPageCursor;
+
+ @Getter
+ @ToString
+ @Builder
+ @Jacksonized
+ public static class BybitTransfer {
+
+ @JsonProperty("transferId")
+ private String transferId;
+
+ @JsonProperty("coin")
+ private String coin;
+
+ @JsonProperty("amount")
+ private BigDecimal amount;
+
+ @JsonProperty("fromMemberId")
+ private String fromMember;
+
+ @JsonProperty("toMemberId")
+ private String toMember;
+
+ @JsonProperty("fromAccountType")
+ private BybitAccountType fromAccountType;
+
+ @JsonProperty("toAccountType")
+ private BybitAccountType toAccountType;
+
+ @JsonProperty("timestamp")
+ private Date timestamp;
+
+ @JsonProperty("status")
+ private BybitTransferStatus status;
+ }
+
+ public enum BybitTransferStatus {
+ SUCCESS,
+ FAILED,
+ PENDING
+ }
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitWithdrawRecordsResponse.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitWithdrawRecordsResponse.java
new file mode 100644
index 00000000000..af04f61f0cf
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitWithdrawRecordsResponse.java
@@ -0,0 +1,93 @@
+package org.knowm.xchange.bybit.dto.account;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonValue;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.ToString;
+import lombok.extern.jackson.Jacksonized;
+
+@Getter
+@ToString
+@Builder
+@Jacksonized
+public class BybitWithdrawRecordsResponse {
+
+ @JsonProperty("rows")
+ private List rows;
+
+ @JsonProperty("nextPageCursor")
+ private String nextPageCursor;
+
+ @Getter
+ @ToString
+ @Builder
+ @Jacksonized
+ public static class BybitWithdrawRecord {
+
+ @JsonProperty("withdrawId")
+ private String withdrawId;
+
+ @JsonProperty("txID")
+ private String txID;
+
+ @JsonProperty("withdrawType")
+ private Integer withdrawType;
+
+ @JsonProperty("coin")
+ private String coin;
+
+ @JsonProperty("chain")
+ private String chain;
+
+ @JsonProperty("amount")
+ private BigDecimal amount;
+
+ @JsonProperty("withdrawFee")
+ private BigDecimal withdrawFee;
+
+ @JsonProperty("status")
+ private BybitWithdrawStatus status;
+
+ @JsonProperty("toAddress")
+ private String toAddress;
+
+ @JsonProperty("tag")
+ private String tag;
+
+ @JsonProperty("createTime")
+ private Date createTime;
+
+ @JsonProperty("updateTime")
+ private Date updateTime;
+
+ @Getter
+ @AllArgsConstructor
+ public enum BybitWithdrawStatus {
+ SECURITY_CHECK("SecurityCheck"),
+ PENDING("Pending"),
+ SUCCESS("success"),
+ CANCEL_BY_USER("CancelByUser"),
+ REJECT("Reject"),
+ FAIL("Fail"),
+ BLOCKCHAIN_CONFIRMED("BlockchainConfirmed"),
+ UNKNOWN("Unknown");
+
+ @JsonValue private final String value;
+ }
+
+ @Getter
+ @AllArgsConstructor
+ public enum BybitWithdrawType {
+ ON_CHAIN(0),
+ OFF_CHAIN(1),
+ ALL(2);
+
+ @JsonValue private final Integer value;
+ }
+ }
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/walletbalance/BybitAccountBalance.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/walletbalance/BybitAccountBalance.java
new file mode 100644
index 00000000000..3e5a4837eda
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/walletbalance/BybitAccountBalance.java
@@ -0,0 +1,49 @@
+package org.knowm.xchange.bybit.dto.account.walletbalance;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Builder;
+import lombok.Value;
+import lombok.extern.jackson.Jacksonized;
+
+@Builder
+@Jacksonized
+@Value
+public class BybitAccountBalance {
+
+ @JsonProperty("accountType")
+ BybitAccountType accountType;
+
+ @JsonProperty("accountLTV")
+ String accountLTV;
+
+ @JsonProperty("accountIMRate")
+ String accountIMRate;
+
+ @JsonProperty("accountMMRate")
+ String accountMMRate;
+
+ @JsonProperty("totalEquity")
+ String totalEquity;
+
+ @JsonProperty("totalWalletBalance")
+ String totalWalletBalance;
+
+ @JsonProperty("totalMarginBalance")
+ String totalMarginBalance;
+
+ @JsonProperty("totalAvailableBalance")
+ String totalAvailableBalance;
+
+ @JsonProperty("totalPerpUPL")
+ String totalPerpUPL;
+
+ @JsonProperty("totalInitialMargin")
+ String totalInitialMargin;
+
+ @JsonProperty("totalMaintenanceMargin")
+ String totalMaintenanceMargin;
+
+ @JsonProperty("coin")
+ List coin;
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/walletbalance/BybitAccountType.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/walletbalance/BybitAccountType.java
new file mode 100644
index 00000000000..038c12bbb3f
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/walletbalance/BybitAccountType.java
@@ -0,0 +1,10 @@
+package org.knowm.xchange.bybit.dto.account.walletbalance;
+
+public enum BybitAccountType {
+ CONTRACT,
+ SPOT,
+ OPTION,
+ UNIFIED,
+ CLASSIC,
+ FUND
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/walletbalance/BybitCoinWalletBalance.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/walletbalance/BybitCoinWalletBalance.java
new file mode 100644
index 00000000000..5ab2193c849
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/walletbalance/BybitCoinWalletBalance.java
@@ -0,0 +1,66 @@
+package org.knowm.xchange.bybit.dto.account.walletbalance;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Builder;
+import lombok.Value;
+import lombok.extern.jackson.Jacksonized;
+
+@Builder
+@Jacksonized
+@Value
+public class BybitCoinWalletBalance {
+
+ @JsonProperty("coin")
+ String coin;
+
+ @JsonProperty("equity")
+ String equity;
+
+ @JsonProperty("usdValue")
+ String usdValue;
+
+ @JsonProperty("walletBalance")
+ String walletBalance;
+
+ @JsonProperty("free")
+ String free;
+
+ @JsonProperty("locked")
+ String locked;
+
+ @JsonProperty("borrowAmount")
+ String borrowAmount;
+
+ @JsonProperty("availableToBorrow")
+ String availableToBorrow;
+
+ @JsonProperty("availableToWithdraw")
+ String availableToWithdraw;
+
+ @JsonProperty("accruedInterest")
+ String accruedInterest;
+
+ @JsonProperty("totalOrderIM")
+ String totalOrderIM;
+
+ @JsonProperty("totalPositionIM")
+ String totalPositionIM;
+
+ @JsonProperty("totalPositionMM")
+ String totalPositionMM;
+
+ @JsonProperty("unrealisedPnl")
+ String unrealisedPnl;
+
+ @JsonProperty("cumRealisedPnl")
+ String cumRealisedPnl;
+
+ @JsonProperty("bonus")
+ String bonus;
+
+ @JsonProperty("collateralSwitch")
+ boolean collateralSwitch;
+
+ @JsonProperty("marginCollateral")
+ boolean marginCollateral;
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitBalances.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/walletbalance/BybitWalletBalance.java
similarity index 56%
rename from xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitBalances.java
rename to xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/walletbalance/BybitWalletBalance.java
index efb92f61443..f46befe7f8d 100644
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/BybitBalances.java
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/account/walletbalance/BybitWalletBalance.java
@@ -1,4 +1,4 @@
-package org.knowm.xchange.bybit.dto.account;
+package org.knowm.xchange.bybit.dto.account.walletbalance;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
@@ -9,9 +9,8 @@
@Builder
@Jacksonized
@Value
-public class BybitBalances {
-
- @JsonProperty("balances")
- List balances;
+public class BybitWalletBalance {
+ @JsonProperty("list")
+ List list;
}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/BybitAssetsInfo.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/BybitAssetsInfo.java
new file mode 100644
index 00000000000..f8d5437ecc7
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/BybitAssetsInfo.java
@@ -0,0 +1,24 @@
+package org.knowm.xchange.bybit.dto.marketdata;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.math.BigDecimal;
+import lombok.Data;
+import lombok.Getter;
+import lombok.ToString;
+
+public class BybitAssetsInfo {
+ @ToString
+ @Getter
+ @Data
+ public static class BybitSpotAsset {
+
+ @JsonProperty("coin")
+ private final String coin;
+ @JsonProperty("frozen")
+ private final BigDecimal frozen;
+ @JsonProperty("free")
+ private final BigDecimal free;
+ @JsonProperty("withdraw")
+ private final BigDecimal withdraw;
+ }
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/BybitSymbol.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/BybitSymbol.java
deleted file mode 100644
index 280cc753600..00000000000
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/BybitSymbol.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package org.knowm.xchange.bybit.dto.marketdata;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import java.math.BigDecimal;
-import lombok.Builder;
-import lombok.Value;
-import lombok.extern.jackson.Jacksonized;
-
-@Builder
-@Jacksonized
-@Value
-public class BybitSymbol {
-
- @JsonProperty("name")
- String name;
-
- @JsonProperty("alias")
- String alias;
-
- @JsonProperty("status")
- String status;
-
- @JsonProperty("base_currency")
- String baseCurrency;
-
- @JsonProperty("quote_currency")
- String quoteCurrency;
-
- @JsonProperty("price_scale")
- Integer priceScale;
-
- @JsonProperty("taker_fee")
- BigDecimal takerFee;
-
- @JsonProperty("maker_fee")
- BigDecimal makerFee;
-
- @JsonProperty("funding_interval")
- Integer fundingInterval;
-
- @JsonProperty("leverage_filter")
- LeverageFilter leverageFilter;
-
- @JsonProperty("price_filter")
- PriceFilter priceFilter;
-
- @JsonProperty("lot_size_filter")
- LotSizeFilter lotSizeFilter;
-
-
- @Builder
- @Jacksonized
- @Value
- public static class LeverageFilter {
-
- @JsonProperty("min_leverage")
- Integer minLeverage;
-
- @JsonProperty("max_leverage")
- Integer maxLeverage;
-
- @JsonProperty("leverage_step")
- BigDecimal leverageStep;
-
- }
-
-
- @Builder
- @Jacksonized
- @Value
- public static class PriceFilter {
- @JsonProperty("min_price")
- BigDecimal minPrice;
-
- @JsonProperty("max_price")
- BigDecimal maxPrice;
-
- @JsonProperty("tick_size")
- BigDecimal tickSize;
- }
-
-
- @Builder
- @Jacksonized
- @Value
- public static class LotSizeFilter {
-
- @JsonProperty("max_trading_qty")
- BigDecimal maxTradingQty;
-
- @JsonProperty("min_trading_qty")
- BigDecimal minTradingQty;
-
- @JsonProperty("qty_step")
- BigDecimal qtyStep;
-
- @JsonProperty("post_only_max_trading_qty")
- BigDecimal postOnlyMaxTradingQty;
-
- }
-
-
-}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/BybitTicker.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/BybitTicker.java
deleted file mode 100644
index 6a0fd544725..00000000000
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/BybitTicker.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package org.knowm.xchange.bybit.dto.marketdata;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import java.math.BigDecimal;
-import java.util.Date;
-import lombok.Builder;
-import lombok.Value;
-import lombok.extern.jackson.Jacksonized;
-
-@Builder
-@Jacksonized
-@Value
-public class BybitTicker {
-
- @JsonProperty("symbol")
- String symbol;
-
- @JsonProperty("bid_price")
- BigDecimal bestBidPrice;
-
- @JsonProperty("ask_price")
- BigDecimal bestAskPrice;
-
- @JsonProperty("last_price")
- BigDecimal lastPrice;
-
- @JsonProperty("last_tick_direction")
- String lastTickDirection;
-
- @JsonProperty("prev_price_24h")
- BigDecimal prevPrice24h;
-
- @JsonProperty("price_24h_pcnt")
- BigDecimal price24hPercentageChange;
-
- @JsonProperty("high_price_24h")
- BigDecimal highPrice;
-
- @JsonProperty("low_price_24h")
- BigDecimal lowPrice;
-
- @JsonProperty("prev_price_1h")
- BigDecimal prevPrice1h;
-
- @JsonProperty("price_1h_pcnt")
- BigDecimal price1hPercentageChange;
-
- @JsonProperty("mark_price")
- BigDecimal markPrice;
-
- @JsonProperty("index_price")
- BigDecimal indexPrice;
-
- @JsonProperty("open_interest")
- BigDecimal openInterest;
-
- @JsonProperty("open_value")
- BigDecimal openValue;
-
- @JsonProperty("total_turnover")
- BigDecimal totalTurnover;
-
- @JsonProperty("turnover_24h")
- BigDecimal turnover24h;
-
- @JsonProperty("total_volume")
- BigDecimal totalVolume;
-
- @JsonProperty("volume_24h")
- BigDecimal volume24h;
-
- @JsonProperty("funding_rate")
- BigDecimal fundingRate;
-
- @JsonProperty("predicted_funding_rate")
- BigDecimal predictedFundingRate;
-
- @JsonProperty("next_funding_time")
- Date nextFundingTime;
-
- @JsonProperty("countdown_hour")
- Integer countdownHour;
-
- @JsonProperty("delivery_fee_rate")
- BigDecimal deliveryFeeRate;
-
- @JsonProperty("predicted_delivery_price")
- BigDecimal predictedDeliveryPrice;
-
- @JsonProperty("delivery_time")
- Date deliveryTime;
-
-}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/instruments/BybitInstrumentInfo.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/instruments/BybitInstrumentInfo.java
new file mode 100644
index 00000000000..e12e65551c0
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/instruments/BybitInstrumentInfo.java
@@ -0,0 +1,37 @@
+package org.knowm.xchange.bybit.dto.marketdata.instruments;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.ToString;
+import lombok.experimental.SuperBuilder;
+
+@SuperBuilder
+@ToString
+@Data
+public abstract class BybitInstrumentInfo {
+
+ @JsonProperty("symbol")
+ String symbol;
+
+ @JsonProperty("baseCoin")
+ String baseCoin;
+
+ @JsonProperty("quoteCoin")
+ String quoteCoin;
+
+ @JsonProperty("status")
+ InstrumentStatus status;
+
+ public enum InstrumentStatus {
+ @JsonProperty("PreLaunch")
+ PRE_LAUNCH,
+ @JsonProperty("Trading")
+ TRADING,
+ @JsonProperty("Settling")
+ SETTLING,
+ @JsonProperty("Delivering")
+ DELIVERING,
+ @JsonProperty("Closed")
+ CLOSED
+ }
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/instruments/BybitInstrumentsInfo.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/instruments/BybitInstrumentsInfo.java
new file mode 100644
index 00000000000..8f8e0beb955
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/instruments/BybitInstrumentsInfo.java
@@ -0,0 +1,40 @@
+package org.knowm.xchange.bybit.dto.marketdata.instruments;
+
+import com.fasterxml.jackson.annotation.JsonSubTypes;
+import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import lombok.Value;
+import lombok.extern.jackson.Jacksonized;
+import org.knowm.xchange.bybit.dto.BybitCategorizedPayload;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.BybitInstrumentsInfo.BybitLinearInverseInstrumentsInfo;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.BybitInstrumentsInfo.BybitOptionInstrumentsInfo;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.BybitInstrumentsInfo.BybitSpotInstrumentsInfo;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.linear.BybitLinearInverseInstrumentInfo;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.option.BybitOptionInstrumentInfo;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.spot.BybitSpotInstrumentInfo;
+
+@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "category", visible = true)
+@JsonSubTypes({
+ @Type(value = BybitLinearInverseInstrumentsInfo.class, name = "linear"),
+ @Type(value = BybitLinearInverseInstrumentsInfo.class, name = "inverse"),
+ @Type(value = BybitOptionInstrumentsInfo.class, name = "option"),
+ @Type(value = BybitSpotInstrumentsInfo.class, name = "spot"),
+})
+public abstract class BybitInstrumentsInfo
+ extends BybitCategorizedPayload {
+
+ @Jacksonized
+ @Value
+ public static class BybitLinearInverseInstrumentsInfo
+ extends BybitInstrumentsInfo {}
+
+ @Jacksonized
+ @Value
+ public static class BybitOptionInstrumentsInfo
+ extends BybitInstrumentsInfo {}
+
+ @Jacksonized
+ @Value
+ public static class BybitSpotInstrumentsInfo
+ extends BybitInstrumentsInfo {}
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/instruments/linear/BybitLinearInverseInstrumentInfo.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/instruments/linear/BybitLinearInverseInstrumentInfo.java
new file mode 100644
index 00000000000..567b1667f06
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/instruments/linear/BybitLinearInverseInstrumentInfo.java
@@ -0,0 +1,122 @@
+package org.knowm.xchange.bybit.dto.marketdata.instruments.linear;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.math.BigDecimal;
+import java.util.Date;
+import lombok.Builder;
+import lombok.ToString;
+import lombok.Value;
+import lombok.experimental.SuperBuilder;
+import lombok.extern.jackson.Jacksonized;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.BybitInstrumentInfo;
+
+@SuperBuilder
+@Jacksonized
+@ToString(callSuper = true)
+@Value
+public class BybitLinearInverseInstrumentInfo extends BybitInstrumentInfo {
+
+ @JsonProperty("contractType")
+ ContractType contractType;
+
+ @JsonProperty("launchTime")
+ Date launchTime;
+
+ @JsonProperty("deliveryTime")
+ Date deliveryTime;
+
+ @JsonProperty("deliveryFeeRate")
+ BigDecimal deliveryFeeRate;
+
+ @JsonProperty("priceScale")
+ Integer priceScale;
+
+ @JsonProperty("leverageFilter")
+ LeverageFilter leverageFilter;
+
+ @JsonProperty("priceFilter")
+ PriceFilter priceFilter;
+
+ @JsonProperty("lotSizeFilter")
+ LotSizeFilter lotSizeFilter;
+
+ @JsonProperty("unifiedMarginTrade")
+ boolean unifiedMarginTrade;
+
+ @JsonProperty("fundingInterval")
+ Integer fundingInterval;
+
+ @JsonProperty("settleCoin")
+ String settleCoin;
+
+ @JsonProperty("copyTrading")
+ CopyTrading copyTrading;
+
+ public enum CopyTrading {
+ @JsonProperty("none")
+ NONE,
+ @JsonProperty("both")
+ BOTH,
+ @JsonProperty("utaOnly")
+ UTA_ONLY,
+ @JsonProperty("normalOnly")
+ NORMAL_ONLY
+ }
+
+ public enum ContractType {
+ @JsonProperty("InversePerpetual")
+ INVERSE_PERPETUAL,
+ @JsonProperty("LinearPerpetual")
+ LINEAR_PERPETUAL,
+ @JsonProperty("LinearFutures")
+ LINEAR_FUTURES,
+ @JsonProperty("InverseFutures")
+ INVERSE_FUTURES
+ }
+
+ @Builder
+ @Jacksonized
+ @Value
+ public static class LeverageFilter {
+
+ @JsonProperty("minLeverage")
+ Integer minLeverage;
+
+ @JsonProperty("maxLeverage")
+ BigDecimal maxLeverage;
+
+ @JsonProperty("leverageStep")
+ BigDecimal leverageStep;
+ }
+
+ @Builder
+ @Jacksonized
+ @Value
+ public static class PriceFilter {
+ @JsonProperty("tickSize")
+ BigDecimal tickSize;
+
+ @JsonProperty("minPrice")
+ BigDecimal minPrice;
+
+ @JsonProperty("maxPrice")
+ BigDecimal maxPrice;
+ }
+
+ @Builder
+ @Jacksonized
+ @Value
+ public static class LotSizeFilter {
+ @JsonProperty("maxOrderQty")
+ BigDecimal maxOrderQty;
+
+ @JsonProperty("minOrderQty")
+ BigDecimal minOrderQty;
+
+ @JsonProperty("qtyStep")
+ BigDecimal qtyStep;
+
+ @JsonProperty("postOnlyMaxOrderQty")
+ BigDecimal postOnlyMaxOrderQty;
+ }
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/instruments/option/BybitOptionInstrumentInfo.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/instruments/option/BybitOptionInstrumentInfo.java
new file mode 100644
index 00000000000..e4f889608c1
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/instruments/option/BybitOptionInstrumentInfo.java
@@ -0,0 +1,81 @@
+package org.knowm.xchange.bybit.dto.marketdata.instruments.option;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.math.BigDecimal;
+import java.util.Date;
+import lombok.Builder;
+import lombok.ToString;
+import lombok.Value;
+import lombok.experimental.SuperBuilder;
+import lombok.extern.jackson.Jacksonized;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.BybitInstrumentInfo;
+
+@SuperBuilder
+@Jacksonized
+@ToString(callSuper = true)
+@Value
+public class BybitOptionInstrumentInfo extends BybitInstrumentInfo {
+
+ @JsonProperty("nextPageCursor")
+ String nextPageCursor;
+
+ @JsonProperty("list")
+ Object list;
+
+ @JsonProperty("optionsType")
+ BybitOptionType optionsType;
+
+ @JsonProperty("settleCoin")
+ String settleCoin;
+
+ @JsonProperty("launchTime")
+ Date launchTime;
+
+ @JsonProperty("deliveryTime")
+ Date deliveryTime;
+
+ @JsonProperty("deliveryFeeRate")
+ BigDecimal deliveryFeeRate;
+
+ @JsonProperty("priceFilter")
+ PriceFilter priceFilter;
+
+ @JsonProperty("lotSizeFilter")
+ LotSizeFilter lotSizeFilter;
+
+ public enum BybitOptionType {
+ @JsonProperty("Call")
+ CALL,
+
+ @JsonProperty("Put")
+ PUT
+ }
+
+ @Builder
+ @Jacksonized
+ @Value
+ public static class PriceFilter {
+ @JsonProperty("tickSize")
+ BigDecimal tickSize;
+
+ @JsonProperty("minPrice")
+ BigDecimal minPrice;
+
+ @JsonProperty("maxPrice")
+ BigDecimal maxPrice;
+ }
+
+ @Builder
+ @Jacksonized
+ @Value
+ public static class LotSizeFilter {
+ @JsonProperty("maxOrderQty")
+ BigDecimal maxOrderQty;
+
+ @JsonProperty("minOrderQty")
+ BigDecimal minOrderQty;
+
+ @JsonProperty("qtyStep")
+ BigDecimal qtyStep;
+ }
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/instruments/spot/BybitSpotInstrumentInfo.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/instruments/spot/BybitSpotInstrumentInfo.java
new file mode 100644
index 00000000000..4e626574234
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/instruments/spot/BybitSpotInstrumentInfo.java
@@ -0,0 +1,72 @@
+package org.knowm.xchange.bybit.dto.marketdata.instruments.spot;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.math.BigDecimal;
+import lombok.Builder;
+import lombok.ToString;
+import lombok.Value;
+import lombok.experimental.SuperBuilder;
+import lombok.extern.jackson.Jacksonized;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.BybitInstrumentInfo;
+
+@SuperBuilder
+@Jacksonized
+@ToString(callSuper = true)
+@Value
+public class BybitSpotInstrumentInfo extends BybitInstrumentInfo {
+
+ @JsonProperty("innovation")
+ int innovation;
+
+ @JsonProperty("marginTrading")
+ MarginTrading marginTrading;
+
+ @JsonProperty("lotSizeFilter")
+ LotSizeFilter lotSizeFilter;
+
+ @JsonProperty("priceFilter")
+ PriceFilter priceFilter;
+
+ public enum MarginTrading {
+ @JsonProperty("none")
+ NONE,
+ @JsonProperty("both")
+ BOTH,
+ @JsonProperty("utaOnly")
+ UTA_ONLY,
+ @JsonProperty("normalSpotOnly")
+ NORMAL_SPOT_ONLY
+ }
+
+ @Builder
+ @Jacksonized
+ @Value
+ public static class PriceFilter {
+ @JsonProperty("tickSize")
+ BigDecimal tickSize;
+ }
+
+ @Builder
+ @Jacksonized
+ @Value
+ public static class LotSizeFilter {
+
+ @JsonProperty("basePrecision")
+ BigDecimal basePrecision;
+
+ @JsonProperty("quotePrecision")
+ BigDecimal quotePrecision;
+
+ @JsonProperty("minOrderQty")
+ BigDecimal minOrderQty;
+
+ @JsonProperty("maxOrderQty")
+ BigDecimal maxOrderQty;
+
+ @JsonProperty("minOrderAmt")
+ BigDecimal minOrderAmt;
+
+ @JsonProperty("maxOrderAmt")
+ BigDecimal maxOrderAmt;
+ }
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/tickers/BybitTicker.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/tickers/BybitTicker.java
new file mode 100644
index 00000000000..3293289ba47
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/tickers/BybitTicker.java
@@ -0,0 +1,41 @@
+package org.knowm.xchange.bybit.dto.marketdata.tickers;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.math.BigDecimal;
+import lombok.Data;
+import lombok.experimental.SuperBuilder;
+
+@SuperBuilder
+@Data
+public abstract class BybitTicker {
+
+ @JsonProperty("symbol")
+ String symbol;
+
+ @JsonProperty("lastPrice")
+ BigDecimal lastPrice;
+
+ @JsonProperty("bid1Price")
+ BigDecimal bid1Price;
+
+ @JsonProperty("bid1Size")
+ BigDecimal bid1Size;
+
+ @JsonProperty("ask1Price")
+ BigDecimal ask1Price;
+
+ @JsonProperty("ask1Size")
+ BigDecimal ask1Size;
+
+ @JsonProperty("highPrice24h")
+ BigDecimal highPrice24h;
+
+ @JsonProperty("lowPrice24h")
+ BigDecimal lowPrice24h;
+
+ @JsonProperty("turnover24h")
+ BigDecimal turnover24h;
+
+ @JsonProperty("volume24h")
+ BigDecimal volume24h;
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/tickers/BybitTickers.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/tickers/BybitTickers.java
new file mode 100644
index 00000000000..1955314dd36
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/tickers/BybitTickers.java
@@ -0,0 +1,36 @@
+package org.knowm.xchange.bybit.dto.marketdata.tickers;
+
+import com.fasterxml.jackson.annotation.JsonSubTypes;
+import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import lombok.Value;
+import lombok.extern.jackson.Jacksonized;
+import org.knowm.xchange.bybit.dto.BybitCategorizedPayload;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.BybitTickers.BybitLinearInverseTickers;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.BybitTickers.BybitOptionTickers;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.BybitTickers.BybitSpotTickers;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.linear.BybitLinearInverseTicker;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.option.BybitOptionTicker;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.spot.BybitSpotTicker;
+
+@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "category", visible = true)
+@JsonSubTypes({
+ @Type(value = BybitLinearInverseTickers.class, name = "linear"),
+ @Type(value = BybitLinearInverseTickers.class, name = "inverse"),
+ @Type(value = BybitOptionTickers.class, name = "option"),
+ @Type(value = BybitSpotTickers.class, name = "spot")
+})
+public abstract class BybitTickers extends BybitCategorizedPayload {
+
+ @Jacksonized
+ @Value
+ public static class BybitLinearInverseTickers extends BybitTickers {}
+
+ @Jacksonized
+ @Value
+ public static class BybitOptionTickers extends BybitTickers {}
+
+ @Jacksonized
+ @Value
+ public static class BybitSpotTickers extends BybitTickers {}
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/tickers/linear/BybitLinearInverseTicker.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/tickers/linear/BybitLinearInverseTicker.java
new file mode 100644
index 00000000000..0a665519bd2
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/tickers/linear/BybitLinearInverseTicker.java
@@ -0,0 +1,57 @@
+package org.knowm.xchange.bybit.dto.marketdata.tickers.linear;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.math.BigDecimal;
+import java.util.Date;
+import lombok.Value;
+import lombok.experimental.SuperBuilder;
+import lombok.extern.jackson.Jacksonized;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.BybitTicker;
+
+@SuperBuilder
+@Jacksonized
+@Value
+public class BybitLinearInverseTicker extends BybitTicker {
+
+ @JsonProperty("indexPrice")
+ BigDecimal indexPrice;
+
+ @JsonProperty("markPrice")
+ BigDecimal markPrice;
+
+ @JsonProperty("prevPrice1h")
+ BigDecimal prevPrice1h;
+
+ @JsonProperty("prevPrice24h")
+ BigDecimal prevPrice24h;
+
+ @JsonProperty("price24hPcnt")
+ BigDecimal price24hPcnt;
+
+ @JsonProperty("openInterest")
+ BigDecimal openInterest;
+
+ @JsonProperty("openInterestValue")
+ BigDecimal openInterestValue;
+
+ @JsonProperty("fundingRate")
+ BigDecimal fundingRate;
+
+ @JsonProperty("nextFundingTime")
+ Date nextFundingTime;
+
+ @JsonProperty("predictedDeliveryPrice")
+ BigDecimal predictedDeliveryPrice;
+
+ @JsonProperty("basisRate")
+ BigDecimal basisRate;
+
+ @JsonProperty("basis")
+ BigDecimal basis;
+
+ @JsonProperty("deliveryFeeRate")
+ BigDecimal deliveryFeeRate;
+
+ @JsonProperty("deliveryTime")
+ Date deliveryTime;
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/tickers/option/BybitOptionTicker.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/tickers/option/BybitOptionTicker.java
new file mode 100644
index 00000000000..0606174b966
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/tickers/option/BybitOptionTicker.java
@@ -0,0 +1,59 @@
+package org.knowm.xchange.bybit.dto.marketdata.tickers.option;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.math.BigDecimal;
+import lombok.Value;
+import lombok.experimental.SuperBuilder;
+import lombok.extern.jackson.Jacksonized;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.BybitTicker;
+
+@SuperBuilder
+@Jacksonized
+@Value
+public class BybitOptionTicker extends BybitTicker {
+
+ @JsonProperty("bid1Iv")
+ BigDecimal bid1Iv;
+
+ @JsonProperty("ask1Iv")
+ BigDecimal ask1Iv;
+
+ @JsonProperty("markPrice")
+ BigDecimal markPrice;
+
+ @JsonProperty("indexPrice")
+ BigDecimal indexPrice;
+
+ @JsonProperty("markIv")
+ BigDecimal markIv;
+
+ @JsonProperty("underlyingPrice")
+ BigDecimal underlyingPrice;
+
+ @JsonProperty("openInterest")
+ BigDecimal openInterest;
+
+ @JsonProperty("totalVolume")
+ BigDecimal totalVolume;
+
+ @JsonProperty("totalTurnover")
+ BigDecimal totalTurnover;
+
+ @JsonProperty("delta")
+ BigDecimal delta;
+
+ @JsonProperty("gamma")
+ BigDecimal gamma;
+
+ @JsonProperty("vega")
+ BigDecimal vega;
+
+ @JsonProperty("theta")
+ BigDecimal theta;
+
+ @JsonProperty("predictedDeliveryPrice")
+ BigDecimal predictedDeliveryPrice;
+
+ @JsonProperty("change24h")
+ BigDecimal change24h;
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/tickers/spot/BybitSpotTicker.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/tickers/spot/BybitSpotTicker.java
new file mode 100644
index 00000000000..1ea18bea753
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/marketdata/tickers/spot/BybitSpotTicker.java
@@ -0,0 +1,23 @@
+package org.knowm.xchange.bybit.dto.marketdata.tickers.spot;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.math.BigDecimal;
+import lombok.Value;
+import lombok.experimental.SuperBuilder;
+import lombok.extern.jackson.Jacksonized;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.BybitTicker;
+
+@SuperBuilder
+@Jacksonized
+@Value
+public class BybitSpotTicker extends BybitTicker {
+
+ @JsonProperty("prevPrice24h")
+ BigDecimal prevPrice24h;
+
+ @JsonProperty("price24hPcnt")
+ BigDecimal price24hPcnt;
+
+ @JsonProperty("usdIndexPrice")
+ BigDecimal usdIndexPrice;
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitExecType.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitExecType.java
new file mode 100644
index 00000000000..0eaa40453fc
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitExecType.java
@@ -0,0 +1,23 @@
+package org.knowm.xchange.bybit.dto.trade;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum BybitExecType {
+ TRADE("Trade"),
+
+ ADL_TRADE("AdlTrade"),
+
+ FUNDING("Funding"),
+
+ BUST_TRADE("BustTrade"),
+
+ DELIVERY("Delivery"),
+
+ BLOCK_TRADE("BlockTrade");
+ @JsonValue
+ private final String value;
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitOrderDetails.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitOrderDetails.java
deleted file mode 100644
index 026119a4efd..00000000000
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitOrderDetails.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package org.knowm.xchange.bybit.dto.trade;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Builder;
-import lombok.Value;
-import lombok.extern.jackson.Jacksonized;
-
-@Builder
-@Jacksonized
-@Value
-public class BybitOrderDetails {
-
- @JsonProperty("accountId")
- String accountId;
-
- @JsonProperty("exchangeId")
- String exchangeId;
-
- @JsonProperty("symbol")
- String symbol;
-
- @JsonProperty("symbolName")
- String symbolName;
-
- @JsonProperty("orderLinkId")
- String orderLinkId;
-
- @JsonProperty("orderId")
- String orderId;
-
- @JsonProperty("price")
- String price;
-
- @JsonProperty("origQty")
- String origQty;
-
- @JsonProperty("executedQty")
- String executedQty;
-
- @JsonProperty("cummulativeQuoteQty")
- String cummulativeQuoteQty;
-
- @JsonProperty("avgPrice")
- String avgPrice;
-
- @JsonProperty("status")
- String status;
-
- @JsonProperty("timeInForce")
- String timeInForce;
-
- @JsonProperty("type")
- String type;
-
- @JsonProperty("side")
- String side;
-
- @JsonProperty("stopPrice")
- String stopPrice;
-
- @JsonProperty("icebergQty")
- String icebergQty;
-
- @JsonProperty("time")
- String time;
-
- @JsonProperty("updateTime")
- String updateTime;
-
- @JsonProperty("isWorking")
- boolean isWorking;
-
- @JsonProperty("locked")
- String locked;
-
-}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitOrderRequest.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitOrderRequest.java
deleted file mode 100644
index 7bad682ae24..00000000000
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitOrderRequest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.knowm.xchange.bybit.dto.trade;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Builder;
-import lombok.Value;
-import lombok.extern.jackson.Jacksonized;
-
-@Builder
-@Jacksonized
-@Value
-public class BybitOrderRequest {
-
- @JsonProperty("accountId")
- String accountId;
-
- @JsonProperty("symbol")
- String symbol;
-
- @JsonProperty("symbolName")
- String symbolName;
-
- @JsonProperty("orderLinkId")
- String orderLinkId;
-
- @JsonProperty("orderId")
- String orderId;
-
- @JsonProperty("transactTime")
- String transactTime;
-
- @JsonProperty("price")
- String price;
-
- @JsonProperty("origQty")
- String origQty;
-
- @JsonProperty("executedQty")
- String executedQty;
-
- @JsonProperty("status")
- String status;
-
- @JsonProperty("timeInForce")
- String timeInForce;
-
- @JsonProperty("type")
- String type;
-
- @JsonProperty("side")
- String side;
-}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitOrderResponse.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitOrderResponse.java
new file mode 100644
index 00000000000..b327b87d5b5
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitOrderResponse.java
@@ -0,0 +1,18 @@
+package org.knowm.xchange.bybit.dto.trade;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Builder;
+import lombok.Value;
+import lombok.extern.jackson.Jacksonized;
+
+@Builder
+@Jacksonized
+@Value
+public class BybitOrderResponse {
+
+ @JsonProperty("orderId")
+ String orderId;
+
+ @JsonProperty("orderLinkId")
+ String orderLinkId;
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitOrderStatus.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitOrderStatus.java
new file mode 100644
index 00000000000..5e9d8258a92
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitOrderStatus.java
@@ -0,0 +1,38 @@
+package org.knowm.xchange.bybit.dto.trade;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public enum BybitOrderStatus {
+ @JsonProperty("Created")
+ CREATED,
+
+ @JsonProperty("New")
+ NEW,
+
+ @JsonProperty("Rejected")
+ REJECTED,
+
+ @JsonProperty("PartiallyFilled")
+ PARTIALLY_FILLED,
+
+ @JsonProperty("PartiallyFilledCanceled")
+ PARTIALLY_FILLED_CANCELED,
+
+ @JsonProperty("Filled")
+ FILLED,
+
+ @JsonProperty("Cancelled")
+ CANCELLED,
+
+ @JsonProperty("Untriggered")
+ UNTRIGGERED,
+
+ @JsonProperty("Triggered")
+ TRIGGERED,
+
+ @JsonProperty("Deactivated")
+ DEACTIVATED,
+
+ @JsonProperty("Active")
+ ACTIVE
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitOrderType.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitOrderType.java
new file mode 100644
index 00000000000..82b7e262317
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitOrderType.java
@@ -0,0 +1,31 @@
+package org.knowm.xchange.bybit.dto.trade;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum BybitOrderType {
+ MARKET("Market"),
+
+ LIMIT("Limit"),
+
+ UNKNOWN("UNKNOWN"),
+
+ STOP_LOSS("StopLoss"),
+
+ PARTIAL_TAKE_PROFIT("PartialTakeProfit"),
+
+ PARTIAL_STOP_LOSS("PartialStopLoss"),
+
+ TPSL_ORDER("tpslOrder"),
+
+ MM_RATE_CLOSE("MmRateClose"),
+
+ STOP("Stop"),
+
+ TAKE_PROFIT("TakeProfit");
+
+ @JsonValue private final String value;
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitSide.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitSide.java
new file mode 100644
index 00000000000..758fbbdf355
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitSide.java
@@ -0,0 +1,17 @@
+package org.knowm.xchange.bybit.dto.trade;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum BybitSide {
+ BUY("Buy"),
+
+ SELL("Sell"),
+
+ NONE("None");
+
+ @JsonValue private final String value;
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitTradeHistoryResponse.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitTradeHistoryResponse.java
new file mode 100644
index 00000000000..e6740ece07f
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitTradeHistoryResponse.java
@@ -0,0 +1,25 @@
+package org.knowm.xchange.bybit.dto.trade;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.ToString;
+import lombok.extern.jackson.Jacksonized;
+import org.knowm.xchange.bybit.dto.BybitCategory;
+
+@Getter
+@ToString
+@Builder
+@Jacksonized
+public class BybitTradeHistoryResponse {
+
+ @JsonProperty("category")
+ private BybitCategory category;
+
+ @JsonProperty("list")
+ private List tradeHistoryList;
+
+ @JsonProperty("nextPageCursor")
+ private String nextPageCursor;
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitUserTradeDto.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitUserTradeDto.java
new file mode 100644
index 00000000000..67dd6b0ab13
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/BybitUserTradeDto.java
@@ -0,0 +1,101 @@
+package org.knowm.xchange.bybit.dto.trade;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.math.BigDecimal;
+import java.util.Date;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.ToString;
+import lombok.extern.jackson.Jacksonized;
+import org.knowm.xchange.bybit.dto.BybitCategory;
+
+@Getter
+@ToString
+@Builder
+@Jacksonized
+public class BybitUserTradeDto {
+
+ @JsonProperty("category")
+ private BybitCategory category;
+
+ @JsonProperty("symbol")
+ private String symbol;
+
+ @JsonProperty("isLeverage")
+ private String isLeverage;
+
+ @JsonProperty("orderId")
+ private String orderId;
+
+ @JsonProperty("orderLinkId")
+ private String orderLinkId;
+
+ @JsonProperty("side")
+ private BybitSide side;
+
+ @JsonProperty("orderPrice")
+ private BigDecimal orderPrice;
+
+ @JsonProperty("orderQty")
+ private BigDecimal orderQty;
+
+ @JsonProperty("leavesQty")
+ private BigDecimal leavesQty;
+
+ @JsonProperty("orderType")
+ private BybitOrderType orderType;
+
+ @JsonProperty("stopOrderType")
+ private BybitOrderType stopOrderType;
+
+ @JsonProperty("execFee")
+ private BigDecimal execFee;
+
+ @JsonProperty("execId")
+ private String execId;
+
+ @JsonProperty("execPrice")
+ private BigDecimal execPrice;
+
+ @JsonProperty("execQty")
+ private BigDecimal execQty;
+
+ @JsonProperty("execType")
+ private BybitExecType execType;
+
+ @JsonProperty("execValue")
+ private BigDecimal execValue;
+
+ @JsonProperty("execTime")
+ private Date execTime;
+
+ @JsonProperty("isMaker")
+ private Boolean isMaker;
+
+ @JsonProperty("feeRate")
+ private BigDecimal feeRate;
+
+ @JsonProperty("tradeIv")
+ private BigDecimal tradeIv;
+
+ @JsonProperty("markIv")
+ private BigDecimal markIv;
+
+ @JsonProperty("markPrice")
+ private BigDecimal markPrice;
+
+ @JsonProperty("indexPrice")
+ private BigDecimal indexPrice;
+
+ @JsonProperty("underlyingPrice")
+ private BigDecimal underlyingPrice;
+
+ @JsonProperty("blockTradeId")
+ private String blockTradeId;
+
+ @JsonProperty("closedSize")
+ private BigDecimal closedSize;
+
+ @JsonProperty("seq")
+ private Long seq;
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/details/BybitOrderDetail.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/details/BybitOrderDetail.java
new file mode 100644
index 00000000000..016264cfe67
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/details/BybitOrderDetail.java
@@ -0,0 +1,41 @@
+package org.knowm.xchange.bybit.dto.trade.details;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.math.BigDecimal;
+import java.util.Date;
+import lombok.Data;
+import lombok.experimental.SuperBuilder;
+import org.knowm.xchange.bybit.dto.trade.BybitOrderStatus;
+import org.knowm.xchange.bybit.dto.trade.BybitSide;
+
+@SuperBuilder
+@Data
+public abstract class BybitOrderDetail {
+
+ @JsonProperty("symbol")
+ String symbol;
+
+ @JsonProperty("side")
+ BybitSide side;
+
+ @JsonProperty("qty")
+ BigDecimal qty;
+
+ @JsonProperty("cumExecQty")
+ BigDecimal cumExecQty;
+
+ @JsonProperty("orderId")
+ String orderId;
+
+ @JsonProperty("createdTime")
+ Date createdTime;
+
+ @JsonProperty("price")
+ BigDecimal price;
+
+ @JsonProperty("avgPrice")
+ BigDecimal avgPrice;
+
+ @JsonProperty("orderStatus")
+ BybitOrderStatus orderStatus;
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/details/BybitOrderDetails.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/details/BybitOrderDetails.java
new file mode 100644
index 00000000000..6e91fa6c733
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/details/BybitOrderDetails.java
@@ -0,0 +1,34 @@
+package org.knowm.xchange.bybit.dto.trade.details;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSubTypes;
+import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import lombok.Data;
+import lombok.Value;
+import lombok.extern.jackson.Jacksonized;
+import org.knowm.xchange.bybit.dto.BybitCategorizedPayload;
+import org.knowm.xchange.bybit.dto.trade.details.BybitOrderDetails.BybitLinearOrderDetails;
+import org.knowm.xchange.bybit.dto.trade.details.BybitOrderDetails.BybitSpotOrderDetails;
+import org.knowm.xchange.bybit.dto.trade.details.linear.BybitLinearOrderDetail;
+import org.knowm.xchange.bybit.dto.trade.details.spot.BybitSpotOrderDetail;
+
+@Data
+@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "category", visible = true)
+@JsonSubTypes({
+ @Type(value = BybitLinearOrderDetails.class, name = "linear"),
+ @Type(value = BybitSpotOrderDetails.class, name = "spot"),
+})
+public class BybitOrderDetails extends BybitCategorizedPayload {
+
+ @JsonProperty("nextPageCursor")
+ String nextPageCursor;
+
+ @Jacksonized
+ @Value
+ public static class BybitLinearOrderDetails extends BybitOrderDetails {}
+
+ @Jacksonized
+ @Value
+ public static class BybitSpotOrderDetails extends BybitOrderDetails {}
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/details/linear/BybitLinearOrderDetail.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/details/linear/BybitLinearOrderDetail.java
new file mode 100644
index 00000000000..6e83c6818e9
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/details/linear/BybitLinearOrderDetail.java
@@ -0,0 +1,112 @@
+package org.knowm.xchange.bybit.dto.trade.details.linear;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.math.BigDecimal;
+import java.util.Date;
+import lombok.Value;
+import lombok.experimental.SuperBuilder;
+import lombok.extern.jackson.Jacksonized;
+import org.knowm.xchange.bybit.dto.trade.BybitOrderType;
+import org.knowm.xchange.bybit.dto.trade.details.BybitOrderDetail;
+
+@SuperBuilder
+@Jacksonized
+@Value
+public class BybitLinearOrderDetail extends BybitOrderDetail {
+
+ @JsonProperty("orderLinkId")
+ String orderLinkId;
+
+ @JsonProperty("blockTradeId")
+ String blockTradeId;
+
+ @JsonProperty("isLeverage")
+ String isLeverage;
+
+ @JsonProperty("positionIdx")
+ int positionIdx;
+
+ @JsonProperty("cancelType")
+ String cancelType;
+
+ @JsonProperty("rejectReason")
+ String rejectReason;
+
+ @JsonProperty("leavesQty")
+ BigDecimal leavesQty;
+
+ @JsonProperty("leavesValue")
+ BigDecimal leavesValue;
+
+ @JsonProperty("cumExecValue")
+ BigDecimal cumExecValue;
+
+ @JsonProperty("cumExecFee")
+ BigDecimal cumExecFee;
+
+ @JsonProperty("timeInForce")
+ String timeInForce;
+
+ @JsonProperty("orderType")
+ BybitOrderType orderType;
+
+ @JsonProperty("stopOrderType")
+ String stopOrderType;
+
+ @JsonProperty("orderIv")
+ String orderIv;
+
+ @JsonProperty("triggerPrice")
+ BigDecimal triggerPrice;
+
+ @JsonProperty("takeProfit")
+ BigDecimal takeProfit;
+
+ @JsonProperty("stopLoss")
+ BigDecimal stopLoss;
+
+ @JsonProperty("tpTriggerBy")
+ String tpTriggerBy;
+
+ @JsonProperty("slTriggerBy")
+ String slTriggerBy;
+
+ @JsonProperty("triggerDirection")
+ int triggerDirection;
+
+ @JsonProperty("triggerBy")
+ String triggerBy;
+
+ @JsonProperty("lastPriceOnCreated")
+ String lastPriceOnCreated;
+
+ @JsonProperty("reduceOnly")
+ boolean reduceOnly;
+
+ @JsonProperty("closeOnTrigger")
+ boolean closeOnTrigger;
+
+ @JsonProperty("smpType")
+ String smpType;
+
+ @JsonProperty("smpGroup")
+ int smpGroup;
+
+ @JsonProperty("smpOrderId")
+ String smpOrderId;
+
+ @JsonProperty("tpslMode")
+ String tpslMode;
+
+ @JsonProperty("tpLimitPrice")
+ String tpLimitPrice;
+
+ @JsonProperty("slLimitPrice")
+ String slLimitPrice;
+
+ @JsonProperty("placeType")
+ String placeType;
+
+ @JsonProperty("updatedTime")
+ Date updatedTime;
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/details/spot/BybitSpotOrderDetail.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/details/spot/BybitSpotOrderDetail.java
new file mode 100644
index 00000000000..ddeb89e59c9
--- /dev/null
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/dto/trade/details/spot/BybitSpotOrderDetail.java
@@ -0,0 +1,103 @@
+package org.knowm.xchange.bybit.dto.trade.details.spot;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.math.BigDecimal;
+import java.util.Date;
+import lombok.Value;
+import lombok.experimental.SuperBuilder;
+import lombok.extern.jackson.Jacksonized;
+import org.knowm.xchange.bybit.dto.trade.BybitOrderType;
+import org.knowm.xchange.bybit.dto.trade.details.BybitOrderDetail;
+
+@SuperBuilder
+@Jacksonized
+@Value
+public class BybitSpotOrderDetail extends BybitOrderDetail {
+
+ @JsonProperty("orderType")
+ BybitOrderType orderType;
+
+ @JsonProperty("orderLinkId")
+ String orderLinkId;
+
+ @JsonProperty("cancelType")
+ String cancelType;
+
+ @JsonProperty("stopOrderType")
+ String stopOrderType;
+
+ @JsonProperty("lastPriceOnCreated")
+ BigDecimal lastPriceOnCreated;
+
+ @JsonProperty("takeProfit")
+ String takeProfit;
+
+ @JsonProperty("cumExecValue")
+ BigDecimal cumExecValue;
+
+ @JsonProperty("smpType")
+ String smpType;
+
+ @JsonProperty("triggerDirection")
+ int triggerDirection;
+
+ @JsonProperty("blockTradeId")
+ String blockTradeId;
+
+ @JsonProperty("isLeverage")
+ String isLeverage;
+
+ @JsonProperty("rejectReason")
+ String rejectReason;
+
+ @JsonProperty("orderIv")
+ String orderIv;
+
+ @JsonProperty("tpTriggerBy")
+ String tpTriggerBy;
+
+ @JsonProperty("positionIdx")
+ int positionIdx;
+
+ @JsonProperty("timeInForce")
+ String timeInForce;
+
+ @JsonProperty("leavesValue")
+ BigDecimal leavesValue;
+
+ @JsonProperty("updatedTime")
+ Date updatedTime;
+
+ @JsonProperty("smpGroup")
+ int smpGroup;
+
+ @JsonProperty("triggerPrice")
+ BigDecimal triggerPrice;
+
+ @JsonProperty("cumExecFee")
+ BigDecimal cumExecFee;
+
+ @JsonProperty("leavesQty")
+ BigDecimal leavesQty;
+
+ @JsonProperty("slTriggerBy")
+ String slTriggerBy;
+
+ @JsonProperty("closeOnTrigger")
+ boolean closeOnTrigger;
+
+ @JsonProperty("placeType")
+ String placeType;
+
+ @JsonProperty("reduceOnly")
+ boolean reduceOnly;
+
+ @JsonProperty("stopLoss")
+ String stopLoss;
+
+ @JsonProperty("smpOrderId")
+ String smpOrderId;
+
+ @JsonProperty("triggerBy")
+ String triggerBy;
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/mappers/MarketDataMapper.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/mappers/MarketDataMapper.java
deleted file mode 100644
index 313d69d8b76..00000000000
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/mappers/MarketDataMapper.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.knowm.xchange.bybit.mappers;
-
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import org.knowm.xchange.bybit.dto.marketdata.BybitSymbol;
-import org.knowm.xchange.currency.CurrencyPair;
-import org.knowm.xchange.dto.meta.InstrumentMetaData;
-
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public final class MarketDataMapper {
-
- public static CurrencyPair symbolToCurrencyPair(BybitSymbol symbol) {
- return new CurrencyPair(symbol.getBaseCurrency(), symbol.getQuoteCurrency());
- }
-
-
- public static InstrumentMetaData symbolToCurrencyPairMetaData(BybitSymbol bybitSymbol) {
- return new InstrumentMetaData.Builder()
- //workaround - get maximum of maker and taker fees
- .tradingFee(bybitSymbol.getTakerFee().max(bybitSymbol.getMakerFee()))
- .minimumAmount(bybitSymbol.getLotSizeFilter().getMinTradingQty())
- .maximumAmount(bybitSymbol.getLotSizeFilter().getMaxTradingQty())
- //e.g. 0.0010 -> 3
- .volumeScale(Math.max(bybitSymbol.getLotSizeFilter().getQtyStep().stripTrailingZeros().scale(), 0))
- .priceScale(bybitSymbol.getPriceScale())
- .counterMinimumAmount(bybitSymbol.getPriceFilter().getMinPrice())
- .counterMaximumAmount(bybitSymbol.getPriceFilter().getMaxPrice())
- .priceScale(bybitSymbol.getPriceScale())
- .amountStepSize(bybitSymbol.getLotSizeFilter().getQtyStep())
- .build();
-
- }
-
-}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitAccountService.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitAccountService.java
index ec236ed1ee9..c0177f38e44 100644
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitAccountService.java
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitAccountService.java
@@ -1,29 +1,334 @@
package org.knowm.xchange.bybit.service;
+import static org.knowm.xchange.bybit.BybitAdapters.adaptBybitDepositRecords;
+import static org.knowm.xchange.bybit.BybitAdapters.adaptBybitInternalDepositRecords;
+import static org.knowm.xchange.bybit.BybitAdapters.adaptBybitInternalTransfers;
+import static org.knowm.xchange.bybit.BybitAdapters.adaptBybitWithdrawRecords;
+
+import com.google.common.collect.Sets;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
import org.knowm.xchange.Exchange;
-import org.knowm.xchange.bybit.dto.BybitResult;
-import org.knowm.xchange.bybit.dto.account.BybitBalance;
-import org.knowm.xchange.bybit.dto.account.BybitBalances;
+import org.knowm.xchange.bybit.BybitAdapters;
+import org.knowm.xchange.bybit.dto.BybitCategory;
+import org.knowm.xchange.bybit.dto.account.BybitDepositRecordsResponse;
+import org.knowm.xchange.bybit.dto.account.BybitInternalDepositRecordsResponse;
+import org.knowm.xchange.bybit.dto.account.BybitTransactionLogResponse;
+import org.knowm.xchange.bybit.dto.account.BybitTransfersResponse;
+import org.knowm.xchange.bybit.dto.account.BybitWithdrawRecordsResponse;
+import org.knowm.xchange.bybit.dto.account.BybitWithdrawRecordsResponse.BybitWithdrawRecord.BybitWithdrawType;
+import org.knowm.xchange.bybit.dto.account.walletbalance.BybitAccountType;
import org.knowm.xchange.dto.account.AccountInfo;
+import org.knowm.xchange.dto.account.FundingRecord;
+import org.knowm.xchange.dto.account.Wallet;
+import org.knowm.xchange.dto.account.Wallet.WalletFeature;
+import org.knowm.xchange.dto.account.params.FundingRecordParamAll;
import org.knowm.xchange.service.account.AccountService;
-import java.io.IOException;
-import java.util.List;
+public class BybitAccountService extends BybitAccountServiceRaw implements AccountService {
-import static org.knowm.xchange.bybit.BybitAdapters.adaptBybitBalances;
+ private final BybitAccountType accountType;
-public class BybitAccountService extends BybitAccountServiceRaw implements AccountService {
+ private static final Integer MAX_PAGINATION_LIMIT = 50;
+
+ public BybitAccountService(Exchange exchange, BybitAccountType accountType) {
+ super(exchange);
+ this.accountType = accountType;
+ }
+
+ @Override
+ public AccountInfo getAccountInfo() throws IOException {
+ List wallets = new ArrayList<>();
+
+ if(accountType == BybitAccountType.UNIFIED){
+ wallets.add(BybitAdapters.adaptBybitBalances(getAllCoinsBalance(BybitAccountType.UNIFIED, null, null, false).getResult(),
+ Sets.newHashSet(WalletFeature.MARGIN_TRADING, WalletFeature.TRADING, WalletFeature.FUTURES_TRADING, WalletFeature.OPTIONS_TRADING)));
+ } else if(accountType == BybitAccountType.CLASSIC) {
+ wallets.add(BybitAdapters.adaptBybitBalances(getAllCoinsBalance(BybitAccountType.SPOT, null, null, false).getResult(),
+ Sets.newHashSet(WalletFeature.TRADING, WalletFeature.MARGIN_TRADING)));
+ }
+
+ return new AccountInfo(wallets);
+ }
+
+ @Override
+ public AccountInfo getSubAccountInfo(String subAccountId) throws IOException {
+ List wallets = new ArrayList<>();
+
+ if(accountType == BybitAccountType.UNIFIED){
+ wallets.add(BybitAdapters.adaptBybitBalances(getAllCoinsBalance(BybitAccountType.UNIFIED, subAccountId, null, false).getResult(),
+ Sets.newHashSet(WalletFeature.MARGIN_TRADING, WalletFeature.TRADING, WalletFeature.FUTURES_TRADING, WalletFeature.OPTIONS_TRADING)));
+ } else if(accountType == BybitAccountType.CLASSIC) {
+ wallets.add(BybitAdapters.adaptBybitBalances(getAllCoinsBalance(BybitAccountType.SPOT, subAccountId, null, false).getResult(),
+ Sets.newHashSet(WalletFeature.TRADING, WalletFeature.MARGIN_TRADING)));
+ }
+
+ return new AccountInfo(wallets);
+ }
+
+ @Override
+ public List getInternalTransferHistory(FundingRecordParamAll params) throws IOException {
+
+ List fundingRecordList = new ArrayList<>();
+
+ BybitTransfersResponse res = getBybitUniversalTransfers(
+ params.getTransferId(),
+ params.getCurrency(),
+ BybitAdapters.convertToBybitStatus(params.getStatus()),
+ params.getStartTime(),
+ params.getEndTime(),
+ (params.getLimit() == null) ? MAX_PAGINATION_LIMIT : params.getLimit(), // 50 is the maximum
+ null
+ ).getResult();
+
+ fundingRecordList.addAll(BybitAdapters.adaptBybitUniversalTransfers(res.getInternalTransfers()));
+
+ if(params.isUsePagination()){
+ String nextPageCursor = res.getNextPageCursor();
+
+ while (nextPageCursor != null && !nextPageCursor.isEmpty()) {
+ res = getBybitUniversalTransfers(
+ params.getTransferId(),
+ params.getCurrency(),
+ BybitAdapters.convertToBybitStatus(params.getStatus()),
+ params.getStartTime(),
+ params.getEndTime(),
+ (params.getLimit() == null) ? MAX_PAGINATION_LIMIT : params.getLimit(), // 50 is the maximum
+ res.getNextPageCursor()
+ ).getResult();
+
+ fundingRecordList.addAll(BybitAdapters.adaptBybitUniversalTransfers(res.getInternalTransfers()));
+ nextPageCursor = res.getNextPageCursor();
+ }
+ }
+
+ return fundingRecordList;
+ }
+
+ @Override
+ public List getWalletTransferHistory(FundingRecordParamAll params)
+ throws IOException {
+ List fundingRecordList = new ArrayList<>();
+
+ BybitTransfersResponse res = getBybitInternalTransfers(
+ params.getTransferId(),
+ params.getCurrency(),
+ BybitAdapters.convertToBybitStatus(params.getStatus()),
+ params.getStartTime(),
+ params.getEndTime(),
+ (params.getLimit() == null) ? MAX_PAGINATION_LIMIT : params.getLimit(), // 50 is the maximum
+ null
+ ).getResult();
+
+ fundingRecordList.addAll(adaptBybitInternalTransfers(res.getInternalTransfers()));
+
+ if(params.isUsePagination()){
+ String nextPageCursor = res.getNextPageCursor();
+
+ while (nextPageCursor != null && !nextPageCursor.isEmpty()) {
+ res = getBybitInternalTransfers(
+ params.getTransferId(),
+ params.getCurrency(),
+ BybitAdapters.convertToBybitStatus(params.getStatus()),
+ params.getStartTime(),
+ params.getEndTime(),
+ (params.getLimit() == null) ? MAX_PAGINATION_LIMIT : params.getLimit(), // 50 is the maximum
+ res.getNextPageCursor()
+ ).getResult();
+
+ fundingRecordList.addAll(adaptBybitInternalTransfers(res.getInternalTransfers()));
+ nextPageCursor = res.getNextPageCursor();
+ }
+ }
+
+ return fundingRecordList;
+ }
+
+ @Override
+ public List getWithdrawHistory(FundingRecordParamAll params) throws IOException {
+ List fundingRecordList = new ArrayList<>();
+
+ BybitWithdrawRecordsResponse res = getBybitWithdrawRecords(
+ params.getTransferId(),
+ params.getCurrency(),
+ BybitWithdrawType.ALL,
+ params.getStartTime(),
+ params.getEndTime(),
+ (params.getLimit() == null) ? MAX_PAGINATION_LIMIT : params.getLimit(), // 50 is the maximum
+ null
+ ).getResult();
- public BybitAccountService(Exchange exchange) {
- super(exchange);
+ fundingRecordList.addAll(adaptBybitWithdrawRecords(res.getRows()));
+
+ if(params.isUsePagination()){
+ String nextPageCursor = res.getNextPageCursor();
+
+ while (nextPageCursor != null && !nextPageCursor.isEmpty()) {
+ res = getBybitWithdrawRecords(
+ params.getTransferId(),
+ params.getCurrency(),
+ BybitWithdrawType.ALL,
+ params.getStartTime(),
+ params.getEndTime(),
+ (params.getLimit() == null) ? MAX_PAGINATION_LIMIT : params.getLimit(), // 50 is the maximum
+ res.getNextPageCursor()
+ ).getResult();
+
+ fundingRecordList.addAll(adaptBybitWithdrawRecords(res.getRows()));
+ nextPageCursor = res.getNextPageCursor();
+ }
}
- @Override
- public AccountInfo getAccountInfo() throws IOException {
- BybitResult walletBalances = getWalletBalances();
- BybitBalances walletBalancesResult = walletBalances.getResult();
- List balances = walletBalancesResult.getBalances();
- return new AccountInfo(adaptBybitBalances(balances));
+ return fundingRecordList;
+ }
+
+ @Override
+ public List getSubAccountDepositHistory(FundingRecordParamAll params)
+ throws IOException {
+
+ if (params.getSubAccountId() == null) {
+ throw new IllegalArgumentException("Sub account id is required");
+ }
+
+ List fundingRecordList = new ArrayList<>();
+
+ BybitDepositRecordsResponse res = getBybitSubAccountDepositRecords(
+ params.getSubAccountId(),
+ params.getCurrency(),
+ params.getStartTime(),
+ params.getEndTime(),
+ (params.getLimit() == null) ? MAX_PAGINATION_LIMIT : params.getLimit(), // 50 is the maximum
+ null
+ ).getResult();
+
+ fundingRecordList.addAll(adaptBybitDepositRecords(res.getRows()));
+
+ if(params.isUsePagination()){
+ String nextPageCursor = res.getNextPageCursor();
+ while (nextPageCursor != null && !nextPageCursor.isEmpty()) {
+ res = getBybitSubAccountDepositRecords(
+ params.getSubAccountId(),
+ params.getCurrency(),
+ params.getStartTime(),
+ params.getEndTime(),
+ (params.getLimit() == null) ? MAX_PAGINATION_LIMIT : params.getLimit(), // 50 is the maximum
+ res.getNextPageCursor()
+ ).getResult();
+
+ fundingRecordList.addAll(adaptBybitDepositRecords(res.getRows()));
+ nextPageCursor = res.getNextPageCursor();
+ }
}
+ return fundingRecordList;
+ }
+
+ @Override
+ public List getDepositHistory(FundingRecordParamAll params) throws IOException {
+
+ BybitDepositRecordsResponse res = getBybitDepositRecords(
+ params.getCurrency(),
+ params.getStartTime(),
+ params.getEndTime(),
+ (params.getLimit() == null) ? MAX_PAGINATION_LIMIT : params.getLimit(), // 50 is the maximum
+ null
+ ).getResult();
+
+ List fundingRecordList = new ArrayList<>();
+
+ BybitInternalDepositRecordsResponse internalRes = getBybitInternalDepositRecords(
+ params.getCurrency(),
+ params.getStartTime(),
+ params.getEndTime(),
+ (params.getLimit() == null) ? MAX_PAGINATION_LIMIT : params.getLimit(), // 50 is the maximum
+ null
+ ).getResult();
+
+ fundingRecordList.addAll(adaptBybitDepositRecords(res.getRows()));
+ fundingRecordList.addAll(adaptBybitInternalDepositRecords(internalRes.getRows()));
+
+ if(params.isUsePagination()){
+ // Make calls to main deposit history
+ String nextPageCursor = res.getNextPageCursor();
+
+ while (nextPageCursor != null && !nextPageCursor.isEmpty()) {
+
+ res = getBybitDepositRecords(
+ params.getCurrency(),
+ params.getStartTime(),
+ params.getEndTime(),
+ (params.getLimit() == null) ? MAX_PAGINATION_LIMIT : params.getLimit(), // 50 is the maximum
+ res.getNextPageCursor()
+ ).getResult();
+
+ fundingRecordList.addAll(adaptBybitDepositRecords(res.getRows()));
+ nextPageCursor = res.getNextPageCursor();
+ }
+
+ // Make calls to internal deposit history
+ nextPageCursor = internalRes.getNextPageCursor();
+
+ while (nextPageCursor != null && !nextPageCursor.isEmpty()) {
+
+ internalRes = getBybitInternalDepositRecords(
+ params.getCurrency(),
+ params.getStartTime(),
+ params.getEndTime(),
+ (params.getLimit() == null) ? MAX_PAGINATION_LIMIT : params.getLimit(), // 50 is the maximum
+ internalRes.getNextPageCursor()
+ ).getResult();
+
+ fundingRecordList.addAll(adaptBybitInternalDepositRecords(internalRes.getRows()));
+ nextPageCursor = internalRes.getNextPageCursor();
+ }
+ }
+
+ return fundingRecordList;
+ }
+
+ @Override
+ public List getLedger(FundingRecordParamAll params) throws IOException {
+ List fundingRecordList = new ArrayList<>();
+
+ BybitTransactionLogResponse res = getBybitLedger(
+ accountType,
+ params.getAccountCategory() == null ? null : BybitCategory.valueOf(params.getAccountCategory()),
+ params.getCurrency(),
+ null,
+ null,
+ params.getStartTime(),
+ params.getEndTime(),
+ (params.getLimit() == null) ? MAX_PAGINATION_LIMIT : params.getLimit(),
+ null
+ ).getResult();
+
+ fundingRecordList.addAll(BybitAdapters.adaptBybitLedger(res.getList()));
+
+ if(params.isUsePagination()){
+ String nextPageCursor = res.getNextPageCursor();
+
+ while (nextPageCursor != null && !nextPageCursor.isEmpty()) {
+ res = getBybitLedger(
+ accountType,
+ null,
+ params.getCurrency(),
+ null,
+ null,
+ params.getStartTime(),
+ params.getEndTime(),
+ (params.getLimit() == null) ? MAX_PAGINATION_LIMIT : params.getLimit(),
+ res.getNextPageCursor()
+ ).getResult();
+
+ fundingRecordList.addAll(BybitAdapters.adaptBybitLedger(res.getList()));
+
+ nextPageCursor = res.getNextPageCursor();
+ }
+
+ return fundingRecordList;
+ } else {
+ return BybitAdapters.adaptBybitLedger(res.getList());
+ }
+ }
}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitAccountServiceRaw.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitAccountServiceRaw.java
index 776e55b552c..a5ef2742a96 100644
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitAccountServiceRaw.java
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitAccountServiceRaw.java
@@ -1,13 +1,25 @@
package org.knowm.xchange.bybit.service;
-import org.knowm.xchange.Exchange;
-import org.knowm.xchange.bybit.BybitAdapters;
-import org.knowm.xchange.bybit.dto.BybitResult;
-import org.knowm.xchange.bybit.dto.account.BybitBalances;
+import static org.knowm.xchange.bybit.BybitAdapters.createBybitExceptionFromResult;
import java.io.IOException;
-
-import static org.knowm.xchange.bybit.BybitAdapters.createBybitExceptionFromResult;
+import java.util.Date;
+import org.knowm.xchange.Exchange;
+import org.knowm.xchange.bybit.dto.BybitCategory;
+import org.knowm.xchange.bybit.dto.BybitResult;
+import org.knowm.xchange.bybit.dto.account.BybitDepositRecordsResponse;
+import org.knowm.xchange.bybit.dto.account.BybitInternalDepositRecordsResponse;
+import org.knowm.xchange.bybit.dto.account.BybitTransactionLogResponse;
+import org.knowm.xchange.bybit.dto.account.BybitTransactionLogResponse.BybitTransactionLog.BybitTransactionLogType;
+import org.knowm.xchange.bybit.dto.account.BybitTransfersResponse;
+import org.knowm.xchange.bybit.dto.account.BybitTransfersResponse.BybitTransferStatus;
+import org.knowm.xchange.bybit.dto.account.BybitAllCoinsBalance;
+import org.knowm.xchange.bybit.dto.account.BybitFeeRates;
+import org.knowm.xchange.bybit.dto.account.BybitWithdrawRecordsResponse;
+import org.knowm.xchange.bybit.dto.account.BybitWithdrawRecordsResponse.BybitWithdrawRecord.BybitWithdrawType;
+import org.knowm.xchange.bybit.dto.account.walletbalance.BybitAccountType;
+import org.knowm.xchange.bybit.dto.account.walletbalance.BybitWalletBalance;
+import org.knowm.xchange.currency.Currency;
public class BybitAccountServiceRaw extends BybitBaseService {
@@ -15,12 +27,263 @@ public BybitAccountServiceRaw(Exchange exchange) {
super(exchange);
}
- public BybitResult getWalletBalances() throws IOException {
- BybitResult walletBalances = bybitAuthenticated.getWalletBalances(apiKey, nonceFactory, signatureCreator);
+ public BybitResult getWalletBalances(BybitAccountType accountType)
+ throws IOException {
+ BybitResult walletBalances =
+ bybitAuthenticated.getWalletBalance(
+ apiKey, signatureCreator, nonceFactory, accountType.name());
if (!walletBalances.isSuccess()) {
throw createBybitExceptionFromResult(walletBalances);
}
return walletBalances;
}
+ public BybitResult getAllCoinsBalance(
+ BybitAccountType accountType, String memberId, String coin, boolean withBonus)
+ throws IOException {
+ BybitResult allCoinsBalance =
+ bybitAuthenticated.getAllCoinsBalance(
+ apiKey,
+ signatureCreator,
+ nonceFactory,
+ memberId,
+ accountType.name(),
+ coin,
+ !withBonus ? 0 : 1);
+ if (!allCoinsBalance.isSuccess()) {
+ throw createBybitExceptionFromResult(allCoinsBalance);
+ }
+ return allCoinsBalance;
+ }
+
+ public BybitResult getSingleCoinBalance(
+ String memberId,
+ String toMemberId,
+ BybitAccountType accountType,
+ BybitAccountType toAccountType,
+ Currency coin,
+ boolean withBonus,
+ boolean withTransferSafeAmount,
+ boolean withLtvTransferSafeAmount)
+ throws IOException {
+ BybitResult singleCoinBalance =
+ bybitAuthenticated.getSingleCoinBalance(
+ apiKey,
+ signatureCreator,
+ nonceFactory,
+ memberId,
+ toMemberId,
+ (accountType == null) ? null : accountType.name(),
+ (toAccountType == null) ? null : toAccountType.name(),
+ (coin == null) ? null : coin.toString(),
+ (!withBonus) ? 0 : 1,
+ (!withTransferSafeAmount) ? 0 : 1,
+ (!withLtvTransferSafeAmount) ? 0 : 1);
+ if (!singleCoinBalance.isSuccess()) {
+ throw createBybitExceptionFromResult(singleCoinBalance);
+ }
+ return singleCoinBalance;
+ }
+
+ public BybitResult getBybitInternalTransfers(
+ String transferId,
+ Currency coin,
+ BybitTransferStatus status,
+ Date startTime,
+ Date endTime,
+ Integer limit,
+ String cursor)
+ throws IOException {
+ BybitResult internalTransfers =
+ bybitAuthenticated.getInternalTransferRecords(
+ apiKey,
+ signatureCreator,
+ nonceFactory,
+ transferId,
+ (coin == null) ? null : coin.toString(),
+ (status == null) ? null : status.name(),
+ (startTime == null) ? null : startTime.toInstant().toEpochMilli(),
+ (endTime == null) ? null : endTime.toInstant().toEpochMilli(),
+ limit,
+ cursor);
+ if (!internalTransfers.isSuccess()) {
+ throw createBybitExceptionFromResult(internalTransfers);
+ }
+ return internalTransfers;
+ }
+
+ public BybitResult getBybitUniversalTransfers(
+ String transferId,
+ Currency coin,
+ BybitTransferStatus status,
+ Date startTime,
+ Date endTime,
+ Integer limit,
+ String cursor)
+ throws IOException {
+ BybitResult universalTransfers =
+ bybitAuthenticated.getUniversalTransferRecords(
+ apiKey,
+ signatureCreator,
+ nonceFactory,
+ transferId,
+ (coin == null) ? null : coin.toString(),
+ (status == null) ? null : status.name(),
+ (startTime == null) ? null : startTime.toInstant().toEpochMilli(),
+ (endTime == null) ? null : endTime.toInstant().toEpochMilli(),
+ limit,
+ cursor);
+ if (!universalTransfers.isSuccess()) {
+ throw createBybitExceptionFromResult(universalTransfers);
+ }
+ return universalTransfers;
+ }
+
+ public BybitResult getBybitLedger(
+ BybitAccountType accountType,
+ BybitCategory category,
+ Currency currency,
+ Currency baseCoin,
+ BybitTransactionLogType type,
+ Date startTime,
+ Date endTime,
+ Integer limit,
+ String cursor)
+ throws IOException {
+ BybitResult ledger =
+ bybitAuthenticated.getTransactionLogRecords(
+ apiKey,
+ signatureCreator,
+ nonceFactory,
+ (accountType == null) ? null : accountType.name(),
+ (category == null) ? null : category.getValue(),
+ (currency == null) ? null : currency.toString(),
+ (baseCoin == null) ? null : baseCoin.toString(),
+ (type == null) ? null : type.name(),
+ (startTime == null) ? null : startTime.toInstant().toEpochMilli(),
+ (endTime == null) ? null : endTime.toInstant().toEpochMilli(),
+ limit,
+ cursor);
+ if (!ledger.isSuccess()) {
+ throw createBybitExceptionFromResult(ledger);
+ }
+ return ledger;
+ }
+
+ public BybitResult getBybitWithdrawRecords(
+ String withdrawId,
+ Currency coin,
+ BybitWithdrawType withdrawType,
+ Date startTime,
+ Date endTime,
+ Integer limit,
+ String cursor
+ )
+ throws IOException {
+ BybitResult withdrawRecords =
+ bybitAuthenticated.getWithdrawRecords(
+ apiKey,
+ signatureCreator,
+ nonceFactory,
+ withdrawId,
+ (coin == null) ? null : coin.toString(),
+ (withdrawType == null) ? null : withdrawType.getValue(),
+ (startTime == null) ? null : startTime.toInstant().toEpochMilli(),
+ (endTime == null) ? null : endTime.toInstant().toEpochMilli(),
+ limit,
+ cursor
+ );
+ if (!withdrawRecords.isSuccess()) {
+ throw createBybitExceptionFromResult(withdrawRecords);
+ }
+ return withdrawRecords;
+ }
+
+ public BybitResult getBybitDepositRecords(
+ Currency coin,
+ Date startTime,
+ Date endTime,
+ Integer limit,
+ String cursor
+ )
+ throws IOException {
+ BybitResult depositRecords =
+ bybitAuthenticated.getOnChainDepositRecords(
+ apiKey,
+ signatureCreator,
+ nonceFactory,
+ (coin == null) ? null : coin.toString(),
+ (startTime == null) ? null : startTime.toInstant().toEpochMilli(),
+ (endTime == null) ? null : endTime.toInstant().toEpochMilli(),
+ limit,
+ cursor
+ );
+ if (!depositRecords.isSuccess()) {
+ throw createBybitExceptionFromResult(depositRecords);
+ }
+ return depositRecords;
+ }
+
+ public BybitResult getBybitInternalDepositRecords(
+ Currency coin,
+ Date startTime,
+ Date endTime,
+ Integer limit,
+ String cursor
+ )
+ throws IOException {
+ BybitResult internalDepositRecords =
+ bybitAuthenticated.getInternalDepositRecords(
+ apiKey,
+ signatureCreator,
+ nonceFactory,
+ (startTime == null) ? null : startTime.toInstant().toEpochMilli(),
+ (endTime == null) ? null : endTime.toInstant().toEpochMilli(),
+ (coin == null) ? null : coin.toString(),
+ cursor,
+ limit
+ );
+ if (!internalDepositRecords.isSuccess()) {
+ throw createBybitExceptionFromResult(internalDepositRecords);
+ }
+ return internalDepositRecords;
+ }
+
+ public BybitResult getBybitSubAccountDepositRecords(
+ String subMemberId,
+ Currency coin,
+ Date startTime,
+ Date endTime,
+ Integer limit,
+ String cursor
+ )
+ throws IOException {
+ BybitResult subAccountDepositRecords =
+ bybitAuthenticated.getSubAccountDepositRecords(
+ apiKey,
+ signatureCreator,
+ nonceFactory,
+ subMemberId,
+ (coin == null) ? null : coin.toString(),
+ (startTime == null) ? null : startTime.toInstant().toEpochMilli(),
+ (endTime == null) ? null : endTime.toInstant().toEpochMilli(),
+ limit,
+ cursor
+ );
+ if (!subAccountDepositRecords.isSuccess()) {
+ throw createBybitExceptionFromResult(subAccountDepositRecords);
+ }
+ return subAccountDepositRecords;
+ }
+
+ public BybitResult getFeeRates(BybitCategory category, String symbol)
+ throws IOException {
+ BybitResult bybitFeeRatesResult =
+ bybitAuthenticated.getFeeRates(
+ apiKey, signatureCreator, nonceFactory, category.getValue(), symbol);
+ if (!bybitFeeRatesResult.isSuccess()) {
+ throw createBybitExceptionFromResult(bybitFeeRatesResult);
+ }
+ return bybitFeeRatesResult;
+ }
}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitBaseService.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitBaseService.java
index d236d910cd4..1f7ade4a5ce 100644
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitBaseService.java
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitBaseService.java
@@ -1,10 +1,12 @@
package org.knowm.xchange.bybit.service;
import java.util.concurrent.TimeUnit;
+import lombok.SneakyThrows;
import org.knowm.xchange.Exchange;
import org.knowm.xchange.bybit.Bybit;
import org.knowm.xchange.bybit.BybitAuthenticated;
import org.knowm.xchange.client.ExchangeRestProxyBuilder;
+import org.knowm.xchange.client.ProxyConfig;
import org.knowm.xchange.service.BaseService;
import org.knowm.xchange.utils.nonce.CurrentTimeIncrementalNonceFactory;
import si.mazi.rescu.ParamsDigest;
@@ -15,21 +17,33 @@ public class BybitBaseService implements BaseService {
protected final BybitAuthenticated bybitAuthenticated;
protected final Bybit bybit;
protected final ParamsDigest signatureCreator;
- protected final SynchronizedValueFactory nonceFactory = new CurrentTimeIncrementalNonceFactory(TimeUnit.MILLISECONDS);
+ protected final SynchronizedValueFactory nonceFactory =
+ new CurrentTimeIncrementalNonceFactory(TimeUnit.MILLISECONDS);
protected final String apiKey;
+ @SneakyThrows
public BybitBaseService(Exchange exchange) {
- bybit = ExchangeRestProxyBuilder
- .forInterface(Bybit.class, exchange.getExchangeSpecification())
- .clientConfigCustomizer(clientConfig -> clientConfig.setJacksonObjectMapperFactory(new BybitJacksonObjectMapperFactory()))
- .build();
- bybitAuthenticated = ExchangeRestProxyBuilder
- .forInterface(BybitAuthenticated.class, exchange.getExchangeSpecification())
- .clientConfigCustomizer(clientConfig -> clientConfig.setJacksonObjectMapperFactory(new BybitJacksonObjectMapperFactory()))
- .build();
- signatureCreator = BybitDigest.createInstance(exchange.getExchangeSpecification().getSecretKey());
+ bybit =
+ ExchangeRestProxyBuilder.forInterface(Bybit.class, exchange.getExchangeSpecification())
+ .clientConfigCustomizer(
+ clientConfig ->
+ clientConfig.setJacksonObjectMapperFactory(
+ new BybitJacksonObjectMapperFactory()))
+ .restProxyFactory(
+ ProxyConfig.getInstance().getRestProxyFactoryClass().getDeclaredConstructor().newInstance())
+ .build();
+ bybitAuthenticated =
+ ExchangeRestProxyBuilder.forInterface(
+ BybitAuthenticated.class, exchange.getExchangeSpecification())
+ .clientConfigCustomizer(
+ clientConfig ->
+ clientConfig.setJacksonObjectMapperFactory(
+ new BybitJacksonObjectMapperFactory()))
+ .restProxyFactory(
+ ProxyConfig.getInstance().getRestProxyFactoryClass().getDeclaredConstructor().newInstance())
+ .build();
+ signatureCreator =
+ BybitDigest.createInstance(exchange.getExchangeSpecification().getSecretKey());
apiKey = exchange.getExchangeSpecification().getApiKey();
}
-
-
}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitDigest.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitDigest.java
index d8f1659080a..faf66ca7289 100644
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitDigest.java
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitDigest.java
@@ -1,53 +1,58 @@
package org.knowm.xchange.bybit.service;
+import static org.knowm.xchange.utils.DigestUtils.bytesToHex;
+
+import jakarta.ws.rs.HeaderParam;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import javax.crypto.Mac;
+import lombok.SneakyThrows;
import org.knowm.xchange.exceptions.NotYetImplementedForExchangeException;
import org.knowm.xchange.service.BaseParamsDigest;
-import si.mazi.rescu.Params;
import si.mazi.rescu.ParamsDigest;
import si.mazi.rescu.RestInvocation;
-import javax.crypto.Mac;
-import jakarta.ws.rs.FormParam;
-import jakarta.ws.rs.QueryParam;
-import java.nio.charset.StandardCharsets;
-import java.util.Map;
-import java.util.TreeMap;
-
-import static org.knowm.xchange.utils.DigestUtils.bytesToHex;
-
public class BybitDigest extends BaseParamsDigest {
- private static final String SIGNATURE = "sign";
-
- public BybitDigest(String secretKeyBase64) {
- super(secretKeyBase64, HMAC_SHA_256);
+ public static final String X_BAPI_API_KEY = "X-BAPI-API-KEY";
+ public static final String X_BAPI_SIGN = "X-BAPI-SIGN";
+ public static final String X_BAPI_TIMESTAMP = "X-BAPI-TIMESTAMP";
+ public static final String X_BAPI_RECV_WINDOW = "X-BAPI-RECV-WINDOW";
+
+ public BybitDigest(String secretKeyBase64) {
+ super(secretKeyBase64, HMAC_SHA_256);
+ }
+
+ public static ParamsDigest createInstance(String secretKeyBase64) {
+ return secretKeyBase64 == null ? null : new BybitDigest(secretKeyBase64);
+ }
+
+ @SneakyThrows
+ @Override
+ public String digestParams(RestInvocation restInvocation) {
+ Map headers = restInvocation.getParamsMap().get(HeaderParam.class).asHttpHeaders();
+
+ // timestamp + API key + (recv_window) + (queryString | jsonBodyString)
+ String plainText = getPlainText(restInvocation);
+
+ String input =
+ headers.get(X_BAPI_TIMESTAMP)
+ + headers.get(X_BAPI_API_KEY)
+ + headers.getOrDefault(X_BAPI_RECV_WINDOW, "")
+ + plainText;
+ Mac mac = getMac();
+ mac.update(input.getBytes(StandardCharsets.UTF_8));
+ return bytesToHex(mac.doFinal());
+ }
+
+ private static String getPlainText(RestInvocation restInvocation) {
+ if ("GET".equals(restInvocation.getHttpMethod())) {
+ return restInvocation.getQueryString();
}
-
- public static ParamsDigest createInstance(String secretKeyBase64) {
- return new BybitDigest(secretKeyBase64);
+ if ("POST".equals(restInvocation.getHttpMethod())) {
+ return restInvocation.getRequestBody();
}
-
- @Override
- public String digestParams(RestInvocation restInvocation) {
- Params p = Params.of();
- Map params = getInputParams(restInvocation);
- params.remove(SIGNATURE);
- Map sortedParams = new TreeMap<>(params);
- sortedParams.forEach(p::add);
- String input = p.asQueryString();
- Mac mac = getMac();
- mac.update(input.getBytes(StandardCharsets.UTF_8));
- return bytesToHex(mac.doFinal());
- }
-
- private Map getInputParams(RestInvocation restInvocation) {
- if ("GET".equals(restInvocation.getHttpMethod())) {
- return restInvocation.getParamsMap().get(QueryParam.class).asHttpHeaders();
- }
- if ("POST".equals(restInvocation.getHttpMethod())) {
- return restInvocation.getParamsMap().get(FormParam.class).asHttpHeaders();
- }
- throw new NotYetImplementedForExchangeException("Only GET and POST are supported in digest");
- }
-
-}
\ No newline at end of file
+ throw new NotYetImplementedForExchangeException(
+ "Only GET and POST are supported for plain text");
+ }
+}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitException.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitException.java
index 3222e15c10c..b03ab3a8754 100644
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitException.java
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitException.java
@@ -1,43 +1,29 @@
package org.knowm.xchange.bybit.service;
import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Getter;
+import lombok.ToString;
import si.mazi.rescu.HttpStatusExceptionSupport;
+@ToString
+@Getter
public class BybitException extends HttpStatusExceptionSupport {
private final int retCode;
private final String retMsg;
- private final String extCode;
- private final String extInfo;
+ private final Object retExtInfo;
- public BybitException(@JsonProperty("ret_code") int retCode,
- @JsonProperty("ret_msg") String retMsg,
- @JsonProperty("ext_code") String extCode,
- @JsonProperty("ext_info") String extInfo) {
+ public BybitException(
+ @JsonProperty("retCode") int retCode,
+ @JsonProperty("retMsg") String retMsg,
+ @JsonProperty("retExtInfo") Object retExtInfo) {
this.retCode = retCode;
this.retMsg = retMsg;
- this.extCode = extCode;
- this.extInfo = extInfo;
+ this.retExtInfo = retExtInfo;
}
@Override
public String getMessage() {
- return "{" +
- "retCode=" + retCode +
- ", retMsg='" + retMsg + '\'' +
- ", extCode='" + extCode + '\'' +
- ", extInfo='" + extInfo + '\'' +
- '}';
+ return toString();
}
-
- @Override
- public String toString() {
- return "BybitException{" +
- "retCode=" + retCode +
- ", retMsg='" + retMsg + '\'' +
- ", extCode='" + extCode + '\'' +
- ", extInfo='" + extInfo + '\'' +
- '}';
- }
-
}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitJacksonObjectMapperFactory.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitJacksonObjectMapperFactory.java
index 7c4ca13d982..250d5568ed6 100644
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitJacksonObjectMapperFactory.java
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitJacksonObjectMapperFactory.java
@@ -9,8 +9,7 @@ public class BybitJacksonObjectMapperFactory extends DefaultJacksonObjectMapperF
@Override
public void configureObjectMapper(ObjectMapper objectMapper) {
super.configureObjectMapper(objectMapper);
- //depending on api version bybit sends jsons with double- and single-quotes
+ // depending on api version bybit sends jsons with double- and single-quotes
objectMapper.configure(Feature.ALLOW_SINGLE_QUOTES, true);
-
}
}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitMarketDataService.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitMarketDataService.java
index b4104924286..52b6981ebc7 100644
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitMarketDataService.java
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitMarketDataService.java
@@ -1,13 +1,22 @@
package org.knowm.xchange.bybit.service;
import java.io.IOException;
-import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
import org.knowm.xchange.bybit.BybitAdapters;
import org.knowm.xchange.bybit.BybitExchange;
+import org.knowm.xchange.bybit.dto.BybitCategory;
import org.knowm.xchange.bybit.dto.BybitResult;
-import org.knowm.xchange.bybit.dto.marketdata.BybitTicker;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.BybitTicker;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.BybitTickers;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.linear.BybitLinearInverseTicker;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.option.BybitOptionTicker;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.spot.BybitSpotTicker;
+import org.knowm.xchange.currency.Currency;
import org.knowm.xchange.currency.CurrencyPair;
import org.knowm.xchange.dto.marketdata.Ticker;
+import org.knowm.xchange.dto.meta.CurrencyMetaData;
+import org.knowm.xchange.dto.meta.InstrumentMetaData;
import org.knowm.xchange.instrument.Instrument;
import org.knowm.xchange.service.marketdata.MarketDataService;
import org.knowm.xchange.utils.Assert;
@@ -18,37 +27,65 @@ public BybitMarketDataService(BybitExchange exchange) {
super(exchange);
}
-
@Override
public Ticker getTicker(Instrument instrument, Object... args) throws IOException {
Assert.notNull(instrument, "Null instrument");
- BybitResult> response = getTicker24h(BybitAdapters.convertToBybitSymbol(instrument.toString()));
+ BybitCategory category = getCategory(args);
+
+ BybitResult> response =
+ getTicker24h(category, BybitAdapters.convertToBybitSymbol(instrument.toString()));
- if (response.getResult().isEmpty()) {
+ if (response.getResult().getList().isEmpty()) {
return new Ticker.Builder().build();
} else {
- BybitTicker bybitTicker = response.getResult().get(0);
- return new Ticker.Builder()
- .timestamp(response.getTimeNow())
- .instrument(instrument)
- .bid(bybitTicker.getBestBidPrice())
- .ask(bybitTicker.getBestAskPrice())
- .volume(bybitTicker.getVolume24h())
- .quoteVolume(bybitTicker.getTurnover24h())
- .last(bybitTicker.getLastPrice())
- .high(bybitTicker.getHighPrice())
- .low(bybitTicker.getLowPrice())
- .open(bybitTicker.getPrevPrice24h())
- .percentageChange(bybitTicker.getPrice24hPercentageChange())
- .build();
+ BybitTicker bybitTicker = response.getResult().getList().get(0);
+ switch (category) {
+ case SPOT:
+ return BybitAdapters.adaptBybitSpotTicker(
+ instrument, response.getTime(), (BybitSpotTicker) bybitTicker);
+ case LINEAR:
+ case INVERSE:
+ return BybitAdapters.adaptBybitLinearInverseTicker(
+ instrument, response.getTime(), (BybitLinearInverseTicker) bybitTicker);
+ case OPTION:
+ return BybitAdapters.adaptBybitOptionTicker(
+ instrument, response.getTime(), (BybitOptionTicker) bybitTicker);
+ default:
+ throw new IllegalStateException("Unexpected value: " + category);
+ }
}
}
+ private static BybitCategory getCategory(Object[] args) {
+ if (args.length > 0 && args[0] != null) {
+ return (BybitCategory) args[0];
+ } else {
+ return BybitCategory.LINEAR;
+ }
+ }
@Override
public Ticker getTicker(CurrencyPair currencyPair, Object... args) throws IOException {
return getTicker((Instrument) currencyPair, args);
}
+
+ @Override
+ public Map getInstruments() throws IOException {
+ Map instrumentsMap = new HashMap<>();
+
+ instrumentsMap.putAll(BybitAdapters.adaptBybitInstruments(getInstrumentsInfo(BybitCategory.SPOT, null, null, null, 1000, null).getResult().getList()));
+ instrumentsMap.putAll(BybitAdapters.adaptBybitInstruments(getInstrumentsInfo(BybitCategory.LINEAR, null, null, null, 1000, null).getResult().getList()));
+ instrumentsMap.putAll(BybitAdapters.adaptBybitInstruments(getInstrumentsInfo(BybitCategory.INVERSE, null, null, null, 1000, null).getResult().getList()));
+ instrumentsMap.putAll(BybitAdapters.adaptBybitInstruments(getInstrumentsInfo(BybitCategory.OPTION, null, null, null, 1000, null).getResult().getList()));
+
+ return instrumentsMap;
+ }
+ @Override
+ public Map getCurrencies() throws IOException {
+ return new HashMap<>(BybitAdapters.adaptBybitCurrencies(
+ getInstrumentsInfo(BybitCategory.SPOT, null, null, null, 1000, null).getResult()
+ .getList()));
+ }
}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitMarketDataServiceRaw.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitMarketDataServiceRaw.java
index 3c8aba80f59..3c49e8aab47 100644
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitMarketDataServiceRaw.java
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitMarketDataServiceRaw.java
@@ -1,12 +1,14 @@
package org.knowm.xchange.bybit.service;
import java.io.IOException;
-import java.util.List;
import org.knowm.xchange.bybit.BybitAdapters;
import org.knowm.xchange.bybit.BybitExchange;
+import org.knowm.xchange.bybit.dto.BybitCategory;
import org.knowm.xchange.bybit.dto.BybitResult;
-import org.knowm.xchange.bybit.dto.marketdata.BybitSymbol;
-import org.knowm.xchange.bybit.dto.marketdata.BybitTicker;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.BybitInstrumentInfo;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.BybitInstrumentsInfo;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.BybitTicker;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.BybitTickers;
public class BybitMarketDataServiceRaw extends BybitBaseService {
@@ -14,8 +16,9 @@ public BybitMarketDataServiceRaw(BybitExchange exchange) {
super(exchange);
}
- public BybitResult> getTicker24h(String symbol) throws IOException {
- BybitResult> result = bybit.getTicker24h(symbol);
+ public BybitResult> getTicker24h(BybitCategory category, String symbol)
+ throws IOException {
+ BybitResult> result = bybit.getTicker24h(category.getValue(), symbol);
if (!result.isSuccess()) {
throw BybitAdapters.createBybitExceptionFromResult(result);
@@ -23,9 +26,23 @@ public BybitResult> getTicker24h(String symbol) throws IOExcep
return result;
}
-
- public BybitResult> getSymbols() throws IOException {
- BybitResult> result = bybit.getSymbols();
+ public BybitResult> getInstrumentsInfo(
+ BybitCategory category,
+ String symbol,
+ String status,
+ String baseCoin,
+ Integer limit,
+ String cursor
+ ) throws IOException {
+ BybitResult> result =
+ bybit.getInstrumentsInfo(
+ category.getValue(),
+ symbol,
+ status,
+ baseCoin,
+ limit,
+ cursor
+ );
if (!result.isSuccess()) {
throw BybitAdapters.createBybitExceptionFromResult(result);
@@ -33,4 +50,19 @@ public BybitResult> getSymbols() throws IOException {
return result;
}
+ public BybitResult getAssetsInfo(
+ String accountType,
+ String coin
+ ) throws IOException {
+ BybitResult result =
+ bybit.getAssetsInfo(
+ accountType,
+ coin
+ );
+
+ if (!result.isSuccess()) {
+ throw BybitAdapters.createBybitExceptionFromResult(result);
+ }
+ return result;
+ }
}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitTradeService.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitTradeService.java
index 12ca1a37bf2..ccbae718a54 100644
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitTradeService.java
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitTradeService.java
@@ -1,49 +1,145 @@
package org.knowm.xchange.bybit.service;
+import static org.knowm.xchange.bybit.BybitAdapters.adaptBybitOrderDetails;
+import static org.knowm.xchange.bybit.BybitAdapters.convertToBybitSymbol;
+import static org.knowm.xchange.bybit.BybitAdapters.getSideString;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
import org.knowm.xchange.Exchange;
+import org.knowm.xchange.bybit.BybitAdapters;
+import org.knowm.xchange.bybit.dto.BybitCategory;
import org.knowm.xchange.bybit.dto.BybitResult;
-import org.knowm.xchange.bybit.dto.trade.BybitOrderDetails;
-import org.knowm.xchange.bybit.dto.trade.BybitOrderRequest;
+import org.knowm.xchange.bybit.dto.trade.BybitOrderResponse;
+import org.knowm.xchange.bybit.dto.trade.BybitOrderType;
+import org.knowm.xchange.bybit.dto.trade.BybitTradeHistoryResponse;
+import org.knowm.xchange.bybit.dto.trade.details.BybitOrderDetail;
+import org.knowm.xchange.bybit.dto.trade.details.BybitOrderDetails;
import org.knowm.xchange.dto.Order;
+import org.knowm.xchange.dto.marketdata.Trades.TradeSortType;
import org.knowm.xchange.dto.trade.MarketOrder;
+import org.knowm.xchange.dto.trade.UserTrade;
+import org.knowm.xchange.dto.trade.UserTrades;
+import org.knowm.xchange.instrument.Instrument;
import org.knowm.xchange.service.trade.TradeService;
+import org.knowm.xchange.service.trade.params.TradeHistoryParamId;
+import org.knowm.xchange.service.trade.params.TradeHistoryParamInstrument;
+import org.knowm.xchange.service.trade.params.TradeHistoryParamLimit;
+import org.knowm.xchange.service.trade.params.TradeHistoryParamUserReference;
+import org.knowm.xchange.service.trade.params.TradeHistoryParams;
+import org.knowm.xchange.service.trade.params.TradeHistoryParamsTimeSpan;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
+public class BybitTradeService extends BybitTradeServiceRaw implements TradeService {
-import static org.knowm.xchange.bybit.BybitAdapters.*;
+ public BybitTradeService(Exchange exchange) {
+ super(exchange);
+ }
-public class BybitTradeService extends BybitTradeServiceRaw implements TradeService {
+ @Override
+ public String placeMarketOrder(MarketOrder marketOrder) throws IOException {
+ BybitResult order =
+ placeOrder(
+ BybitCategory.SPOT,
+ convertToBybitSymbol(marketOrder.getInstrument().toString()),
+ getSideString(marketOrder.getType()),
+ BybitOrderType.MARKET,
+ marketOrder.getOriginalAmount());
+
+ return order.getResult().getOrderId();
+ }
+
+ @Override
+ public Collection getOrder(String... orderIds) throws IOException {
+ List results = new ArrayList<>();
+
+ for (String orderId : orderIds) {
+ BybitResult> bybitOrder =
+ getBybitOrder(BybitCategory.SPOT, orderId);
+ BybitOrderDetail bybitOrderResult = bybitOrder.getResult().getList().get(0);
+ Order order = adaptBybitOrderDetails(bybitOrderResult);
+ results.add(order);
+ }
+
+ return results;
+ }
+
+ @Override
+ public UserTrades getTradeHistory(TradeHistoryParams params) throws IOException {
+
+ if (!(params instanceof TradeHistoryParamInstrument)) {
+ throw new IOException(
+ "Params must be instance of " + TradeHistoryParamInstrument.class.getSimpleName());
+ }
+
+ if(((TradeHistoryParamInstrument) params).getInstrument() == null){
+ throw new IllegalArgumentException("Instrument must not be null.");
+ }
- public BybitTradeService(Exchange exchange) {
- super(exchange);
+ Instrument instrument = ((TradeHistoryParamInstrument) params).getInstrument();
+ BybitCategory category = BybitAdapters.getBybitCategoryFromInstrument(instrument);
+ String orderId = null;
+ String userReference = null;
+ Date startTime = null;
+ Date endTime = null;
+ Integer limit = 100;
+
+ if(params instanceof TradeHistoryParamId) {
+ orderId = ((TradeHistoryParamId) params).getId();
+ }
+
+ if(params instanceof TradeHistoryParamUserReference){
+ userReference = ((TradeHistoryParamUserReference) params).getUserReference();
}
- @Override
- public String placeMarketOrder(MarketOrder marketOrder) throws IOException {
- BybitResult order = placeOrder(
- convertToBybitSymbol(marketOrder.getInstrument().toString()),
- marketOrder.getOriginalAmount().longValue(),
- getSideString(marketOrder.getType()),
- "MARKET");
+ if(params instanceof TradeHistoryParamsTimeSpan){
+ startTime = ((TradeHistoryParamsTimeSpan) params).getStartTime();
+ endTime = ((TradeHistoryParamsTimeSpan) params).getEndTime();
+ }
- return order.getResult().getOrderId();
+ if(params instanceof TradeHistoryParamLimit) {
+ limit = ((TradeHistoryParamLimit) params).getLimit();
}
- @Override
- public Collection getOrder(String... orderIds) throws IOException {
- List results = new ArrayList<>();
+ BybitTradeHistoryResponse res = getBybitTradeHistory(
+ category,
+ instrument,
+ orderId,
+ userReference,
+ null,
+ startTime,
+ endTime,
+ null,
+ limit,
+ null).getResult();
+
+ String nextPageCursor = res.getNextPageCursor();
+
+ List userTradeList = new ArrayList<>();
+
+ while (nextPageCursor != null) {
+ userTradeList.addAll(BybitAdapters.adaptUserTrades(res));
- for (String orderId : orderIds) {
- BybitResult bybitOrder = getBybitOrder(orderId);
- BybitOrderDetails bybitOrderResult = bybitOrder.getResult();
- Order order = adaptBybitOrderDetails(bybitOrderResult);
- results.add(order);
- }
+ res = getBybitTradeHistory(
+ category,
+ instrument,
+ orderId,
+ userReference,
+ null,
+ startTime,
+ endTime,
+ null,
+ limit,
+ nextPageCursor).getResult();
- return results;
+ nextPageCursor = res.getNextPageCursor();
+ if(nextPageCursor.isEmpty()){
+ break;
+ }
}
+ return new UserTrades(userTradeList, TradeSortType.SortByTimestamp);
+ }
}
diff --git a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitTradeServiceRaw.java b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitTradeServiceRaw.java
index b2e0b9fb20e..ad605c694c4 100644
--- a/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitTradeServiceRaw.java
+++ b/xchange-bybit/src/main/java/org/knowm/xchange/bybit/service/BybitTradeServiceRaw.java
@@ -1,13 +1,23 @@
package org.knowm.xchange.bybit.service;
-import org.knowm.xchange.Exchange;
-import org.knowm.xchange.bybit.dto.BybitResult;
-import org.knowm.xchange.bybit.dto.trade.BybitOrderDetails;
-import org.knowm.xchange.bybit.dto.trade.BybitOrderRequest;
+import static org.knowm.xchange.bybit.BybitAdapters.createBybitExceptionFromResult;
import java.io.IOException;
-
-import static org.knowm.xchange.bybit.BybitAdapters.createBybitExceptionFromResult;
+import java.math.BigDecimal;
+import java.util.Date;
+import org.knowm.xchange.Exchange;
+import org.knowm.xchange.bybit.BybitAdapters;
+import org.knowm.xchange.bybit.dto.BybitCategory;
+import org.knowm.xchange.bybit.dto.BybitResult;
+import org.knowm.xchange.bybit.dto.trade.BybitExecType;
+import org.knowm.xchange.bybit.dto.trade.BybitTradeHistoryResponse;
+import org.knowm.xchange.bybit.dto.trade.BybitOrderResponse;
+import org.knowm.xchange.bybit.dto.trade.BybitOrderType;
+import org.knowm.xchange.bybit.dto.trade.BybitSide;
+import org.knowm.xchange.bybit.dto.trade.details.BybitOrderDetail;
+import org.knowm.xchange.bybit.dto.trade.details.BybitOrderDetails;
+import org.knowm.xchange.currency.Currency;
+import org.knowm.xchange.instrument.Instrument;
public class BybitTradeServiceRaw extends BybitBaseService {
@@ -15,28 +25,70 @@ public BybitTradeServiceRaw(Exchange exchange) {
super(exchange);
}
- public BybitResult getBybitOrder(String orderId) throws IOException {
- BybitResult order = bybitAuthenticated.getOrder(apiKey, orderId, nonceFactory, signatureCreator);
+ public BybitResult> getBybitOrder(
+ BybitCategory category, String orderId) throws IOException {
+ BybitResult> order =
+ bybitAuthenticated.getOpenOrders(
+ apiKey, signatureCreator, nonceFactory, category.getValue(), orderId);
if (!order.isSuccess()) {
throw createBybitExceptionFromResult(order);
}
return order;
}
- public BybitResult placeOrder(String symbol, long qty, String side, String type) throws IOException {
- BybitResult placeOrder = bybitAuthenticated.placeOrder(
+ public BybitResult placeOrder(
+ BybitCategory category,
+ String symbol,
+ BybitSide side,
+ BybitOrderType orderType,
+ BigDecimal qty)
+ throws IOException {
+ BybitResult placeOrder =
+ bybitAuthenticated.placeOrder(
apiKey,
- symbol,
- qty,
- side,
- type,
+ signatureCreator,
nonceFactory,
- signatureCreator
- );
+ category.getValue(),
+ symbol,
+ side.getValue(),
+ orderType.getValue(),
+ qty);
if (!placeOrder.isSuccess()) {
throw createBybitExceptionFromResult(placeOrder);
}
return placeOrder;
}
+ public BybitResult getBybitTradeHistory(
+ BybitCategory category,
+ Instrument instrument,
+ String orderId,
+ String userReferenceId,
+ Currency baseCoin,
+ Date startTime,
+ Date endTime,
+ BybitExecType execType,
+ Integer limit,
+ String cursor)
+ throws BybitException, IOException {
+ BybitResult userTrades =
+ bybitAuthenticated.getBybitTradeHistory(
+ apiKey,
+ signatureCreator,
+ nonceFactory,
+ category.getValue(),
+ BybitAdapters.adaptBybitSymbol(instrument),
+ orderId,
+ userReferenceId,
+ baseCoin == null ? null : baseCoin.getCurrencyCode(),
+ startTime == null ? null : startTime.toInstant().toEpochMilli(),
+ endTime == null ? null : endTime.toInstant().toEpochMilli(),
+ execType == null ? null : execType.getValue(),
+ limit,
+ cursor);
+ if (!userTrades.isSuccess()) {
+ throw createBybitExceptionFromResult(userTrades);
+ }
+ return userTrades;
+ }
}
diff --git a/xchange-bybit/src/test/java/org/knowm/xchange/bybit/BybitAdaptersTest.java b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/BybitAdaptersTest.java
index e689abf00a9..b55631abe20 100644
--- a/xchange-bybit/src/test/java/org/knowm/xchange/bybit/BybitAdaptersTest.java
+++ b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/BybitAdaptersTest.java
@@ -1,22 +1,19 @@
package org.knowm.xchange.bybit;
-import org.junit.Test;
-import org.knowm.xchange.currency.CurrencyPair;
-
import static org.assertj.core.api.Assertions.assertThat;
import static org.knowm.xchange.bybit.BybitAdapters.guessSymbol;
-public class BybitAdaptersTest {
-
-
- @Test
- public void testGuessSymbol() {
- assertThat(guessSymbol("BTCUSDT")).isEqualTo(new CurrencyPair("BTC", "USDT"));
- assertThat(guessSymbol("BTCUSDC")).isEqualTo(new CurrencyPair("BTC", "USDC"));
- assertThat(guessSymbol("LTCBTC")).isEqualTo(new CurrencyPair("LTC", "BTC"));
- assertThat(guessSymbol("BTCDAI")).isEqualTo(new CurrencyPair("BTC", "DAI"));
- assertThat(guessSymbol("ABCDEFG")).isEqualTo(new CurrencyPair("ABCD", "EFG"));
+import org.junit.Test;
+import org.knowm.xchange.currency.CurrencyPair;
- }
+public class BybitAdaptersTest {
+ @Test
+ public void testGuessSymbol() {
+ assertThat(guessSymbol("BTCUSDT")).isEqualTo(new CurrencyPair("BTC", "USDT"));
+ assertThat(guessSymbol("BTCUSDC")).isEqualTo(new CurrencyPair("BTC", "USDC"));
+ assertThat(guessSymbol("LTCBTC")).isEqualTo(new CurrencyPair("LTC", "BTC"));
+ assertThat(guessSymbol("BTCDAI")).isEqualTo(new CurrencyPair("BTC", "DAI"));
+ assertThat(guessSymbol("ABCDEFG")).isEqualTo(new CurrencyPair("ABCD", "EFG"));
+ }
}
diff --git a/xchange-bybit/src/test/java/org/knowm/xchange/bybit/BybitExchangeInit.java b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/BybitExchangeInit.java
new file mode 100644
index 00000000000..188220426ee
--- /dev/null
+++ b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/BybitExchangeInit.java
@@ -0,0 +1,11 @@
+package org.knowm.xchange.bybit;
+
+import org.knowm.xchange.Exchange;
+import org.knowm.xchange.ExchangeFactory;
+
+public class BybitExchangeInit {
+
+ public static Exchange getBybitExchange() {
+ return ExchangeFactory.INSTANCE.createExchange(BybitExchange.class);
+ }
+}
diff --git a/xchange-bybit/src/test/java/org/knowm/xchange/bybit/BybitExchangeTest.java b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/BybitExchangeTest.java
index 23059b7d133..7be4ea463e6 100644
--- a/xchange-bybit/src/test/java/org/knowm/xchange/bybit/BybitExchangeTest.java
+++ b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/BybitExchangeTest.java
@@ -1,15 +1,8 @@
package org.knowm.xchange.bybit;
-import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
-import static com.github.tomakehurst.wiremock.client.WireMock.get;
-import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import jakarta.ws.rs.core.Response.Status;
-import org.apache.commons.io.IOUtils;
import org.junit.Test;
import org.knowm.xchange.Exchange;
import org.knowm.xchange.ExchangeSpecification;
@@ -17,26 +10,17 @@
public class BybitExchangeTest extends BaseWiremockTest {
-
@Test
public void testSymbolLoading() throws IOException {
Exchange bybitExchange = createExchange();
- stubFor(
- get(urlPathEqualTo("/v2/public/symbols"))
- .willReturn(
- aResponse()
- .withStatus(Status.OK.getStatusCode())
- .withHeader("Content-Type", "application/json")
- .withBody(IOUtils.resourceToString("/getSymbols.json5", StandardCharsets.UTF_8))
- )
- );
+ initGetStub("/v5/market/instruments-info", "/getInstrumentSpot.json5");
+ initGetStub("/v5/account/fee-rate", "/getFeeRates.json5");
ExchangeSpecification specification = bybitExchange.getExchangeSpecification();
specification.setShouldLoadRemoteMetaData(true);
bybitExchange.applySpecification(specification);
- assertThat(bybitExchange.getExchangeMetaData().getInstruments()).hasSize(2);
-
+ assertThat(bybitExchange.getExchangeMetaData().getInstruments()).hasSize(1);
}
-}
\ No newline at end of file
+}
diff --git a/xchange-bybit/src/test/java/org/knowm/xchange/bybit/BybitPrivateEndpointsTest.java b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/BybitPrivateEndpointsTest.java
new file mode 100644
index 00000000000..b88c88f67eb
--- /dev/null
+++ b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/BybitPrivateEndpointsTest.java
@@ -0,0 +1,257 @@
+package org.knowm.xchange.bybit;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Properties;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.knowm.xchange.Exchange;
+import org.knowm.xchange.ExchangeFactory;
+import org.knowm.xchange.ExchangeSpecification;
+import org.knowm.xchange.bybit.dto.account.walletbalance.BybitAccountType;
+import org.knowm.xchange.currency.CurrencyPair;
+import org.knowm.xchange.dto.account.AccountInfo;
+import org.knowm.xchange.dto.account.FundingRecord;
+import org.knowm.xchange.dto.account.params.FundingRecordParamAll;
+import org.knowm.xchange.dto.trade.UserTrade;
+import org.knowm.xchange.instrument.Instrument;
+import org.knowm.xchange.service.trade.params.TradeHistoryParamsAll;
+
+@Ignore
+public class BybitPrivateEndpointsTest {
+
+ static Exchange exchange;
+
+ Instrument instrument = new CurrencyPair("BTC/USDT");
+ static String subAccountId;
+
+ @BeforeClass
+ public static void setUp(){
+ Properties properties = new Properties();
+
+ try {
+ properties.load(BybitPrivateEndpointsTest.class.getResourceAsStream("/secret.keys"));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ ExchangeSpecification spec = new BybitExchange().getDefaultExchangeSpecification();
+
+ spec.setApiKey(properties.getProperty("apikey"));
+ spec.setSecretKey(properties.getProperty("secret"));
+ spec.setExchangeSpecificParametersItem(Exchange.USE_SANDBOX, true);
+
+ exchange = ExchangeFactory.INSTANCE.createExchange(BybitExchange.class);
+ exchange.applySpecification(spec);
+
+ subAccountId = properties.getProperty("subAccountId");
+ }
+
+ @Test
+ public void testTradeHistory() throws IOException {
+
+ TradeHistoryParamsAll params = new TradeHistoryParamsAll();
+
+ params.setInstrument(instrument);
+
+ List userTrades = exchange
+ .getTradeService()
+ .getTradeHistory(params)
+ .getUserTrades();
+
+ assertThat(userTrades.isEmpty()).isFalse();
+
+ userTrades.forEach(
+ userTrade -> {
+ assertThat(userTrade.getId()).isNotNull();
+ assertThat(userTrade.getOrderId()).isNotNull();
+ assertThat(userTrade.getOrderUserReference()).isNotNull();
+ assertThat(userTrade.getOriginalAmount()).isGreaterThan(BigDecimal.ZERO);
+ assertThat(userTrade.getPrice()).isGreaterThan(BigDecimal.ZERO);
+ assertThat(userTrade.getFeeAmount()).isGreaterThan(BigDecimal.ZERO);
+ assertThat(userTrade.getType()).isNotNull();
+ assertThat(userTrade.getFeeCurrency()).isNotNull();
+ assertThat(userTrade.getTimestamp()).isNotNull();
+ });
+ }
+
+ @Test
+ public void testAccountInfo() throws IOException {
+ AccountInfo accountInfo = exchange.getAccountService().getAccountInfo();
+
+ assertThat(accountInfo.getWallets().size()).isGreaterThan(1);
+ accountInfo
+ .getWallets()
+ .forEach(
+ (s, wallet) -> {
+ assertThat(BybitAccountType.valueOf(s)).isInstanceOf(BybitAccountType.class);
+ assertThat(BybitAccountType.valueOf(wallet.getId())).isInstanceOf(BybitAccountType.class);
+ assertThat(wallet.getFeatures()).isNotNull();
+
+ wallet.getBalances().forEach((currency, balance) -> {
+ assertThat(currency).isNotNull();
+ assertThat(balance.getAvailable()).isNotNull();
+ assertThat(balance.getTotal()).isNotNull();
+ assertThat(balance.getFrozen()).isNotNull();
+ assertThat(balance.getBorrowed()).isNotNull();
+ });
+ });
+ }
+
+ @Test
+ public void testSubAccountInfo() throws IOException {
+ AccountInfo accountInfo = exchange.getAccountService().getSubAccountInfo(subAccountId);
+
+ assertThat(accountInfo.getWallets().size()).isGreaterThan(1);
+ accountInfo
+ .getWallets()
+ .forEach(
+ (s, wallet) -> {
+ assertThat(BybitAccountType.valueOf(s)).isInstanceOf(BybitAccountType.class);
+ assertThat(BybitAccountType.valueOf(wallet.getId())).isInstanceOf(BybitAccountType.class);
+ assertThat(wallet.getFeatures()).isNotNull();
+
+ wallet.getBalances().forEach((currency, balance) -> {
+ assertThat(currency).isNotNull();
+ assertThat(balance.getAvailable()).isNotNull();
+ assertThat(balance.getTotal()).isNotNull();
+ assertThat(balance.getFrozen()).isNotNull();
+ assertThat(balance.getBorrowed()).isNotNull();
+ });
+ });
+ }
+
+ @Test
+ public void testWalletTransfers() throws IOException {
+ FundingRecordParamAll paramAll = FundingRecordParamAll.builder()
+ .status(FundingRecord.Status.COMPLETE)
+ .build();
+ List records = exchange.getAccountService().getWalletTransferHistory(paramAll);
+
+ assertThat(records.isEmpty()).isFalse();
+
+ records.forEach(
+ internalFundingRecord -> {
+ assertThat(internalFundingRecord.getInternalId()).isNotNull();
+ assertThat(internalFundingRecord.getDate()).isNotNull();
+ assertThat(internalFundingRecord.getAmount()).isNotNull();
+ assertThat(internalFundingRecord.getFromWallet()).isNotNull();
+ assertThat(internalFundingRecord.getToWallet()).isNotNull();
+ assertThat(internalFundingRecord.getStatus()).isNotNull();
+ assertThat(internalFundingRecord.getDescription()).isNotNull();
+ });
+ }
+
+ @Test
+ public void testSubAccountTransfers() throws IOException {
+ FundingRecordParamAll paramAll = FundingRecordParamAll.builder()
+ .build();
+ List records = exchange.getAccountService().getInternalTransferHistory(paramAll);
+
+ assertThat(records.isEmpty()).isFalse();
+
+ records.forEach(
+ fundingRecord -> {
+ assertThat(fundingRecord.getInternalId()).isNotNull();
+ assertThat(fundingRecord.getDate()).isNotNull();
+ assertThat(fundingRecord.getAmount()).isNotNull();
+ assertThat(fundingRecord.getStatus()).isNotNull();
+ assertThat(fundingRecord.getToSubAccount()).isNotNull();
+ assertThat(fundingRecord.getFromSubAccount()).isNotNull();
+ assertThat(fundingRecord.getToWallet()).isNotNull();
+ assertThat(fundingRecord.getFromWallet()).isNotNull();
+ assertThat(fundingRecord.getDescription()).isNotNull();
+ });
+ }
+
+ @Test
+ public void testAccountDepositHistory() throws IOException {
+ FundingRecordParamAll paramAll = FundingRecordParamAll.builder()
+ .build();
+ List records = exchange.getAccountService().getDepositHistory(paramAll);
+
+ assertThat(records.isEmpty()).isFalse();
+
+ records.forEach(
+ fundingRecord -> {
+ assertThat(fundingRecord.getInternalId()).isNotNull();
+ assertThat(fundingRecord.getDate()).isNotNull();
+ assertThat(fundingRecord.getAmount()).isNotNull();
+ assertThat(fundingRecord.getStatus()).isNotNull();
+ assertThat(fundingRecord.getAddress()).isNotNull();
+ assertThat(fundingRecord.getAddressTag()).isNotNull();
+ assertThat(fundingRecord.getFee()).isNotNull();
+ assertThat(fundingRecord.getType()).isNotNull();
+ assertThat(fundingRecord.getBlockchainTransactionHash()).isNotNull();
+ });
+ }
+
+ @Test
+ public void testAccountWithdrawHistory() throws IOException {
+ FundingRecordParamAll paramAll = FundingRecordParamAll.builder()
+ .build();
+ List records = exchange.getAccountService().getWithdrawHistory(paramAll);
+
+ assertThat(records.isEmpty()).isFalse();
+
+ records.forEach(
+ fundingRecord -> {
+ assertThat(fundingRecord.getInternalId()).isNotNull();
+ assertThat(fundingRecord.getDate()).isNotNull();
+ assertThat(fundingRecord.getAmount()).isNotNull();
+ assertThat(fundingRecord.getStatus()).isNotNull();
+ assertThat(fundingRecord.getAddress()).isNotNull();
+ assertThat(fundingRecord.getAddressTag()).isNotNull();
+ assertThat(fundingRecord.getFee()).isNotNull();
+ assertThat(fundingRecord.getType()).isNotNull();
+ assertThat(fundingRecord.getBlockchainTransactionHash()).isNotNull();
+ });
+ }
+ @Test
+ public void testSubAccountDepositHistory() throws IOException {
+ FundingRecordParamAll paramAll = FundingRecordParamAll.builder()
+ .subAccountId(subAccountId)
+ .build();
+ List records = exchange.getAccountService().getSubAccountDepositHistory(paramAll);
+
+ records.forEach(
+ fundingRecord -> {
+ assertThat(fundingRecord.getInternalId()).isNotNull();
+ assertThat(fundingRecord.getDate()).isNotNull();
+ assertThat(fundingRecord.getAmount()).isNotNull();
+ assertThat(fundingRecord.getStatus()).isNotNull();
+ assertThat(fundingRecord.getAddress()).isNotNull();
+ assertThat(fundingRecord.getAddressTag()).isNotNull();
+ assertThat(fundingRecord.getFee()).isNotNull();
+ assertThat(fundingRecord.getType()).isNotNull();
+ assertThat(fundingRecord.getBlockchainTransactionHash()).isNotNull();
+ assertThat(fundingRecord.getDescription()).isNotNull();
+ });
+ }
+
+ @Test
+ public void testLedger() throws IOException {
+ FundingRecordParamAll paramAll = FundingRecordParamAll.builder()
+ .usePagination(true)
+ .build();
+ List records = exchange.getAccountService().getLedger(paramAll);
+
+ assertThat(records.isEmpty()).isFalse();
+
+ records.forEach(
+ fundingRecord -> {
+ assertThat(fundingRecord.getInternalId()).isNotNull();
+ assertThat(fundingRecord.getDate()).isNotNull();
+ assertThat(fundingRecord.getAmount()).isNotNull();
+ assertThat(fundingRecord.getBalance()).isNotNull();
+ assertThat(fundingRecord.getStatus()).isEqualTo(FundingRecord.Status.COMPLETE);
+ assertThat(fundingRecord.getType()).isNotNull();
+ assertThat(fundingRecord.getFee()).isNotNull();
+ assertThat(fundingRecord.getCurrency()).isNotNull();
+ });
+ }
+}
diff --git a/xchange-bybit/src/test/java/org/knowm/xchange/bybit/BybitPublicEndpointsTest.java b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/BybitPublicEndpointsTest.java
new file mode 100644
index 00000000000..d5986e99dc8
--- /dev/null
+++ b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/BybitPublicEndpointsTest.java
@@ -0,0 +1,54 @@
+package org.knowm.xchange.bybit;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.Test;
+import org.knowm.xchange.Exchange;
+import org.knowm.xchange.currency.Currency;
+import org.knowm.xchange.dto.meta.CurrencyMetaData;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BybitPublicEndpointsTest {
+
+ private static final Exchange exchange = BybitExchangeInit.getBybitExchange();
+ private final Logger LOG = LoggerFactory.getLogger(BybitPublicEndpointsTest.class);
+ @Test
+ public void checkInstrumentMetaData() {
+ exchange
+ .getExchangeMetaData()
+ .getInstruments()
+ .forEach(
+ (instrument1, instrumentMetaData) -> {
+ LOG.debug(instrument1 + "||" + instrumentMetaData);
+ assertThat(instrumentMetaData.getMinimumAmount()).isGreaterThan(BigDecimal.ZERO);
+ assertThat(instrumentMetaData.getMaximumAmount()).isGreaterThan(BigDecimal.ZERO);
+ assertThat(instrumentMetaData.getAmountStepSize()).isGreaterThan(BigDecimal.ZERO);
+ assertThat(instrumentMetaData.getPriceStepSize()).isGreaterThan(BigDecimal.ZERO);
+ assertThat(instrumentMetaData.getPriceScale()).isNotNegative();
+ assertThat(instrumentMetaData.getVolumeScale()).isNotNegative();
+ });
+ }
+
+ @Test
+ public void checkCurrenciesMetaData() {
+ Map currencyMetaDataMap = exchange.getExchangeMetaData().getCurrencies();
+ Map numberOfOccurrences = new HashMap<>();
+
+ currencyMetaDataMap.forEach((currency,currencyMetaData) -> {
+ assertThat(currency).isNotNull();
+ assertThat(currencyMetaData.getScale()).isNotNegative();
+
+ if(numberOfOccurrences.containsKey(currency)){
+ numberOfOccurrences.put(currency, numberOfOccurrences.get(currency) + 1);
+ } else {
+ numberOfOccurrences.put(currency, 1);
+ }
+ });
+
+ numberOfOccurrences.forEach((currency,integer) -> assertThat(integer).isEqualTo(1));
+ }
+}
diff --git a/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BaseWiremockTest.java b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BaseWiremockTest.java
index 6530e230eb2..e43d187daab 100644
--- a/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BaseWiremockTest.java
+++ b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BaseWiremockTest.java
@@ -1,30 +1,46 @@
package org.knowm.xchange.bybit.service;
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
+
import com.github.tomakehurst.wiremock.junit.WireMockRule;
+import jakarta.ws.rs.core.Response.Status;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import org.apache.commons.io.IOUtils;
import org.junit.Rule;
import org.knowm.xchange.Exchange;
import org.knowm.xchange.ExchangeFactory;
import org.knowm.xchange.ExchangeSpecification;
import org.knowm.xchange.bybit.BybitExchange;
-import java.io.IOException;
-
public class BaseWiremockTest {
- @Rule
- public WireMockRule wireMockRule = new WireMockRule();
+ @Rule public WireMockRule wireMockRule = new WireMockRule();
+
+ public Exchange createExchange() throws IOException {
+ Exchange exchange =
+ ExchangeFactory.INSTANCE.createExchangeWithoutSpecification(BybitExchange.class);
+ ExchangeSpecification specification = exchange.getDefaultExchangeSpecification();
+ specification.setHost("localhost");
+ specification.setSslUri("http://localhost:" + wireMockRule.port());
+ specification.setPort(wireMockRule.port());
+ specification.setApiKey("test_api_key");
+ specification.setSecretKey("test_secret_key");
+ specification.setShouldLoadRemoteMetaData(false);
+ exchange.applySpecification(specification);
+ return exchange;
+ }
- public Exchange createExchange() throws IOException {
- Exchange exchange =
- ExchangeFactory.INSTANCE.createExchangeWithoutSpecification(BybitExchange.class);
- ExchangeSpecification specification = exchange.getDefaultExchangeSpecification();
- specification.setHost("localhost");
- specification.setSslUri("http://localhost:" + wireMockRule.port());
- specification.setPort(wireMockRule.port());
- specification.setApiKey("test_api_key");
- specification.setSecretKey("test_secret_key");
- specification.setShouldLoadRemoteMetaData(false);
- exchange.applySpecification(specification);
- return exchange;
- }
+ protected void initGetStub(String url, String responseBody) throws IOException {
+ stubFor(
+ get(urlPathEqualTo(url))
+ .willReturn(
+ aResponse()
+ .withStatus(Status.OK.getStatusCode())
+ .withHeader("Content-Type", "application/json")
+ .withBody(IOUtils.resourceToString(responseBody, StandardCharsets.UTF_8))));
+ }
}
diff --git a/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitAccountServiceRawTest.java b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitAccountServiceRawTest.java
index 5ef8e44d5f1..1ee2b89065b 100644
--- a/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitAccountServiceRawTest.java
+++ b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitAccountServiceRawTest.java
@@ -1,82 +1,115 @@
package org.knowm.xchange.bybit.service;
-import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
-import static com.github.tomakehurst.wiremock.client.WireMock.get;
-import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.IOException;
import java.util.List;
-import jakarta.ws.rs.core.Response.Status;
+import org.junit.Before;
import org.junit.Test;
import org.knowm.xchange.Exchange;
+import org.knowm.xchange.bybit.dto.BybitCategory;
import org.knowm.xchange.bybit.dto.BybitResult;
-import org.knowm.xchange.bybit.dto.account.BybitBalance;
-import org.knowm.xchange.bybit.dto.account.BybitBalances;
+import org.knowm.xchange.bybit.dto.account.BybitAllCoinsBalance;
+import org.knowm.xchange.bybit.dto.account.BybitAllCoinsBalance.BybitCoinBalance;
+import org.knowm.xchange.bybit.dto.account.BybitFeeRates;
+import org.knowm.xchange.bybit.dto.account.BybitFeeRates.BybitFeeRate;
+import org.knowm.xchange.bybit.dto.account.walletbalance.BybitAccountBalance;
+import org.knowm.xchange.bybit.dto.account.walletbalance.BybitAccountType;
+import org.knowm.xchange.bybit.dto.account.walletbalance.BybitCoinWalletBalance;
+import org.knowm.xchange.bybit.dto.account.walletbalance.BybitWalletBalance;
public class BybitAccountServiceRawTest extends BaseWiremockTest {
+ private BybitAccountServiceRaw bybitAccountServiceRaw;
+
+ @Before
+ public void setUp() throws Exception {
+ Exchange bybitExchange = createExchange();
+ bybitAccountServiceRaw = new BybitAccountServiceRaw(bybitExchange);
+ }
+
@Test
public void testGetWalletBalances() throws IOException {
- Exchange bybitExchange = createExchange();
- BybitAccountServiceRaw bybitAccountServiceRaw = new BybitAccountServiceRaw(bybitExchange);
-
- String walletBalanceDetails = "{\n" +
- " \"ret_code\":0,\n" +
- " \"ret_msg\":\"\",\n" +
- " \"ext_code\":null,\n" +
- " \"ext_info\":null,\n" +
- " \"result\":{\n" +
- " \"balances\":[\n" +
- " {\n" +
- " \"coin\":\"COIN\",\n" +
- " \"coinId\":\"COIN\",\n" +
- " \"coinName\":\"COIN\",\n" +
- " \"total\":\"66419.616666666666666666\",\n" +
- " \"free\":\"56583.326666666666666666\",\n" +
- " \"locked\":\"9836.29\"\n" +
- " },\n" +
- " {\n" +
- " \"coin\":\"USDT\",\n" +
- " \"coinId\":\"USDT\",\n" +
- " \"coinName\":\"USDT\",\n" +
- " \"total\":\"61.50059688096\",\n" +
- " \"free\":\"61.50059688096\",\n" +
- " \"locked\":\"0\"\n" +
- " }\n" +
- " ]\n" +
- " }\n" +
- "}";
-
- stubFor(
- get(urlPathEqualTo("/spot/v1/account"))
- .willReturn(
- aResponse()
- .withStatus(Status.OK.getStatusCode())
- .withHeader("Content-Type", "application/json")
- .withBody(walletBalanceDetails)
- )
- );
-
- BybitResult walletBalances = bybitAccountServiceRaw.getWalletBalances();
-
- BybitBalances walletBalancesResult = walletBalances.getResult();
- List balances = walletBalancesResult.getBalances();
-
- assertThat(balances.get(0).getTotal()).isEqualTo("66419.616666666666666666");
- assertThat(balances.get(0).getFree()).isEqualTo("56583.326666666666666666");
- assertThat(balances.get(0).getLocked()).isEqualTo("9836.29");
- assertThat(balances.get(0).getCoin()).isEqualTo("COIN");
- assertThat(balances.get(0).getCoinId()).isEqualTo("COIN");
- assertThat(balances.get(0).getCoinName()).isEqualTo("COIN");
-
- assertThat(balances.get(1).getTotal()).isEqualTo("61.50059688096");
- assertThat(balances.get(1).getFree()).isEqualTo("61.50059688096");
- assertThat(balances.get(1).getLocked()).isEqualTo("0");
- assertThat(balances.get(1).getCoin()).isEqualTo("USDT");
- assertThat(balances.get(1).getCoinId()).isEqualTo("USDT");
- assertThat(balances.get(1).getCoinName()).isEqualTo("USDT");
+ initGetStub("/v5/account/wallet-balance", "/getWalletBalance.json5");
+
+ BybitResult walletBalances =
+ bybitAccountServiceRaw.getWalletBalances(BybitAccountType.UNIFIED);
+
+ BybitWalletBalance walletBalance = walletBalances.getResult();
+
+ assertThat(walletBalance.getList()).hasSize(1);
+ BybitAccountBalance accountBalance = walletBalance.getList().get(0);
+
+ assertThat(accountBalance.getTotalEquity()).isEqualTo("3.31216591");
+ assertThat(accountBalance.getAccountIMRate()).isEqualTo("0");
+ assertThat(accountBalance.getTotalMarginBalance()).isEqualTo("3.00326056");
+ assertThat(accountBalance.getTotalInitialMargin()).isEqualTo("0");
+ assertThat(accountBalance.getAccountType()).isEqualTo(BybitAccountType.UNIFIED);
+ assertThat(accountBalance.getTotalAvailableBalance()).isEqualTo("3.00326056");
+ assertThat(accountBalance.getAccountMMRate()).isEqualTo("0");
+ assertThat(accountBalance.getTotalPerpUPL()).isEqualTo("0");
+ assertThat(accountBalance.getTotalWalletBalance()).isEqualTo("3.00326056");
+ assertThat(accountBalance.getAccountLTV()).isEqualTo("0");
+ assertThat(accountBalance.getTotalMaintenanceMargin()).isEqualTo("0");
+
+ assertThat(accountBalance.getCoin()).hasSize(1);
+ List coins = accountBalance.getCoin();
+
+ assertThat(coins.get(0).getAvailableToBorrow()).isEqualTo("3");
+ assertThat(coins.get(0).getBonus()).isEqualTo("0");
+ assertThat(coins.get(0).getAccruedInterest()).isEqualTo("0");
+ assertThat(coins.get(0).getAvailableToWithdraw()).isEqualTo("0");
+ assertThat(coins.get(0).getTotalOrderIM()).isEqualTo("0");
+ assertThat(coins.get(0).getEquity()).isEqualTo("0");
+ assertThat(coins.get(0).getTotalPositionMM()).isEqualTo("0");
+ assertThat(coins.get(0).getUsdValue()).isEqualTo("0");
+ assertThat(coins.get(0).getUnrealisedPnl()).isEqualTo("0");
+ assertThat(coins.get(0).isCollateralSwitch()).isTrue();
+ assertThat(coins.get(0).getBorrowAmount()).isEqualTo("0.0");
+ assertThat(coins.get(0).getTotalPositionIM()).isEqualTo("0");
+ assertThat(coins.get(0).getWalletBalance()).isEqualTo("0");
+ assertThat(coins.get(0).getFree()).isNull();
+ assertThat(coins.get(0).getCumRealisedPnl()).isEqualTo("0");
+ assertThat(coins.get(0).getLocked()).isEqualTo("0");
+ assertThat(coins.get(0).isMarginCollateral()).isTrue();
+ assertThat(coins.get(0).getCoin()).isEqualTo("BTC");
}
-}
\ No newline at end of file
+ @Test
+ public void testGetAllCoinsBalances() throws IOException {
+ initGetStub("/v5/asset/transfer/query-account-coins-balance", "/getAllCoinsBalance.json5");
+
+ BybitResult coinsBalanceBybitResult =
+ bybitAccountServiceRaw.getAllCoinsBalance(BybitAccountType.FUND, null, null, false);
+
+ BybitAllCoinsBalance coinsBalance = coinsBalanceBybitResult.getResult();
+
+ assertThat(coinsBalance.getMemberId()).isEqualTo("XXXX");
+ assertThat(coinsBalance.getAccountType()).isEqualTo(BybitAccountType.FUND);
+
+ assertThat(coinsBalance.getBalance()).hasSize(1);
+ BybitCoinBalance coinBalance = coinsBalance.getBalance().get(0);
+
+ assertThat(coinBalance.getCoin()).isEqualTo("USDC");
+ assertThat(coinBalance.getTransferBalance()).isEqualTo("0");
+ assertThat(coinBalance.getWalletBalance()).isEqualTo("0");
+ assertThat(coinBalance.getBonus()).isNull();
+ }
+
+ @Test
+ public void testGetFeeRates() throws IOException {
+ initGetStub("/v5/account/fee-rate", "/getFeeRates.json5");
+
+ BybitResult bybitFeeRatesBybitResult =
+ bybitAccountServiceRaw.getFeeRates(BybitCategory.SPOT, "ETHUSDT");
+
+ BybitFeeRates feeRates = bybitFeeRatesBybitResult.getResult();
+
+ assertThat(feeRates.getList()).hasSize(1);
+ BybitFeeRate feeRate = feeRates.getList().get(0);
+
+ assertThat(feeRate.getSymbol()).isEqualTo("ETHUSDT");
+ assertThat(feeRate.getTakerFeeRate()).isEqualTo("0.0006");
+ assertThat(feeRate.getMakerFeeRate()).isEqualTo("0.0001");
+ }
+}
diff --git a/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitAccountServiceTest.java b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitAccountServiceTest.java
deleted file mode 100644
index edc48a9a5b3..00000000000
--- a/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitAccountServiceTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package org.knowm.xchange.bybit.service;
-
-import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
-import static com.github.tomakehurst.wiremock.client.WireMock.get;
-import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.io.IOException;
-import java.math.BigDecimal;
-import jakarta.ws.rs.core.Response.Status;
-import org.junit.Test;
-import org.knowm.xchange.Exchange;
-import org.knowm.xchange.currency.Currency;
-import org.knowm.xchange.dto.account.AccountInfo;
-
-public class BybitAccountServiceTest extends BaseWiremockTest {
-
- @Test
- public void testGetWalletBalances() throws IOException {
- Exchange bybitExchange = createExchange();
- BybitAccountService bybitAccountService = new BybitAccountService(bybitExchange);
-
- String walletBalanceDetails = "{\n" +
- " \"ret_code\":0,\n" +
- " \"ret_msg\":\"\",\n" +
- " \"ext_code\":null,\n" +
- " \"ext_info\":null,\n" +
- " \"result\":{\n" +
- " \"balances\":[\n" +
- " {\n" +
- " \"coin\":\"COIN\",\n" +
- " \"coinId\":\"COIN\",\n" +
- " \"coinName\":\"COIN\",\n" +
- " \"total\":\"66419.616666666666666666\",\n" +
- " \"free\":\"56583.326666666666666666\",\n" +
- " \"locked\":\"9836.29\"\n" +
- " },\n" +
- " {\n" +
- " \"coin\":\"USDT\",\n" +
- " \"coinId\":\"USDT\",\n" +
- " \"coinName\":\"USDT\",\n" +
- " \"total\":\"61.50059688096\",\n" +
- " \"free\":\"61.50059688096\",\n" +
- " \"locked\":\"0\"\n" +
- " }\n" +
- " ]\n" +
- " }\n" +
- "}";
-
- stubFor(
- get(urlPathEqualTo("/spot/v1/account"))
- .willReturn(
- aResponse()
- .withStatus(Status.OK.getStatusCode())
- .withHeader("Content-Type", "application/json")
- .withBody(walletBalanceDetails)
- )
- );
-
- AccountInfo accountInfo = bybitAccountService.getAccountInfo();
- assertThat(accountInfo.getWallet().getBalance(new Currency("COIN")).getTotal()).isEqualTo(
- new BigDecimal("66419.616666666666666666"));
- assertThat(accountInfo.getWallet().getBalance(new Currency("COIN")).getAvailable()).isEqualTo(
- new BigDecimal("56583.326666666666666666"));
-
- assertThat(accountInfo.getWallet().getBalance(new Currency("USDT")).getTotal()).isEqualTo(
- new BigDecimal("61.50059688096"));
- assertThat(accountInfo.getWallet().getBalance(new Currency("USDT")).getAvailable()).isEqualTo(
- new BigDecimal("61.50059688096"));
- }
-
-}
\ No newline at end of file
diff --git a/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitMarketDataServiceRawTest.java b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitMarketDataServiceRawTest.java
index 8f7ff99b95c..24d94188692 100644
--- a/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitMarketDataServiceRawTest.java
+++ b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitMarketDataServiceRawTest.java
@@ -1,62 +1,260 @@
package org.knowm.xchange.bybit.service;
-import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
-import static com.github.tomakehurst.wiremock.client.WireMock.get;
-import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
import static org.assertj.core.api.Assertions.assertThat;
+import java.io.IOException;
import java.math.BigDecimal;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import jakarta.ws.rs.core.Response.Status;
-import org.apache.commons.io.IOUtils;
+import java.util.Date;
+import org.junit.Before;
import org.junit.Test;
import org.knowm.xchange.Exchange;
-import org.knowm.xchange.bybit.dto.marketdata.BybitSymbol;
+import org.knowm.xchange.bybit.dto.BybitCategory;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.BybitInstrumentInfo;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.BybitInstrumentInfo.InstrumentStatus;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.BybitInstrumentsInfo;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.linear.BybitLinearInverseInstrumentInfo;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.linear.BybitLinearInverseInstrumentInfo.ContractType;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.option.BybitOptionInstrumentInfo;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.option.BybitOptionInstrumentInfo.BybitOptionType;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.spot.BybitSpotInstrumentInfo;
+import org.knowm.xchange.bybit.dto.marketdata.instruments.spot.BybitSpotInstrumentInfo.MarginTrading;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.BybitTicker;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.BybitTickers;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.linear.BybitLinearInverseTicker;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.option.BybitOptionTicker;
+import org.knowm.xchange.bybit.dto.marketdata.tickers.spot.BybitSpotTicker;
public class BybitMarketDataServiceRawTest extends BaseWiremockTest {
- @Test
- public void testGetSymbols() throws Exception {
+ private BybitMarketDataServiceRaw marketDataServiceRaw;
+
+ @Before
+ public void setUp() throws Exception {
Exchange bybitExchange = createExchange();
- BybitMarketDataServiceRaw marketDataServiceRaw = (BybitMarketDataServiceRaw) bybitExchange.getMarketDataService();
-
- stubFor(
- get(urlPathEqualTo("/v2/public/symbols"))
- .willReturn(
- aResponse()
- .withStatus(Status.OK.getStatusCode())
- .withHeader("Content-Type", "application/json")
- .withBody(IOUtils.resourceToString("/getSymbols.json5", StandardCharsets.UTF_8))
- )
- );
-
- List symbols = marketDataServiceRaw.getSymbols().getResult();
-
- assertThat(symbols).hasSize(2);
-
- BybitSymbol btcusdt = symbols.get(0);
- assertThat(btcusdt.getName()).isEqualTo("BTCUSDT");
- assertThat(btcusdt.getAlias()).isEqualTo("BTCUSDT");
- assertThat(btcusdt.getStatus()).isEqualTo("Trading");
- assertThat(btcusdt.getBaseCurrency()).isEqualTo("BTC");
- assertThat(btcusdt.getQuoteCurrency()).isEqualTo("USDT");
- assertThat(btcusdt.getPriceScale()).isEqualTo(2);
- assertThat(btcusdt.getTakerFee()).isEqualTo(new BigDecimal("0.0006"));
- assertThat(btcusdt.getMakerFee()).isEqualTo(new BigDecimal("0.0001"));
- assertThat(btcusdt.getFundingInterval()).isEqualTo(480);
- assertThat(btcusdt.getLeverageFilter().getMinLeverage()).isEqualTo(1);
- assertThat(btcusdt.getLeverageFilter().getMaxLeverage()).isEqualTo(100);
- assertThat(btcusdt.getLeverageFilter().getLeverageStep()).isEqualTo(new BigDecimal("0.01"));
- assertThat(btcusdt.getPriceFilter().getMinPrice()).isEqualTo(new BigDecimal("0.5"));
- assertThat(btcusdt.getPriceFilter().getMaxPrice()).isEqualTo(new BigDecimal("999999"));
- assertThat(btcusdt.getPriceFilter().getTickSize()).isEqualTo(new BigDecimal("0.5"));
- assertThat(btcusdt.getLotSizeFilter().getMaxTradingQty()).isEqualTo(new BigDecimal("20"));
- assertThat(btcusdt.getLotSizeFilter().getMinTradingQty()).isEqualTo(new BigDecimal("0.001"));
- assertThat(btcusdt.getLotSizeFilter().getQtyStep()).isEqualTo(new BigDecimal("0.001"));
- assertThat(btcusdt.getLotSizeFilter().getPostOnlyMaxTradingQty()).isEqualTo(new BigDecimal("100"));
-
- }
-
-}
\ No newline at end of file
+ marketDataServiceRaw = (BybitMarketDataServiceRaw) bybitExchange.getMarketDataService();
+ }
+
+ private void initTickerStub(String responseBody) throws IOException {
+ initGetStub("/v5/market/tickers", responseBody);
+ }
+
+ private void initInstrumentsInfoStub(String responseBody) throws IOException {
+ initGetStub("/v5/market/instruments-info", responseBody);
+ }
+
+ @Test
+ public void testGetLinearInverseInstrumentsInfo() throws Exception {
+ initInstrumentsInfoStub("/getInstrumentLinear.json5");
+
+ BybitInstrumentsInfo instrumentsInfo =
+ marketDataServiceRaw.getInstrumentsInfo(BybitCategory.LINEAR, null, null, null, 1000, null).getResult();
+
+ assertThat(instrumentsInfo.getList()).hasSize(1);
+
+ BybitLinearInverseInstrumentInfo actualInstrumentInfo =
+ (BybitLinearInverseInstrumentInfo) instrumentsInfo.getList().get(0);
+
+ assertThat(actualInstrumentInfo.getSymbol()).isEqualTo("BTCUSDT");
+ assertThat(actualInstrumentInfo.getContractType()).isEqualTo(ContractType.LINEAR_PERPETUAL);
+ assertThat(actualInstrumentInfo.getStatus()).isEqualTo(InstrumentStatus.TRADING);
+ assertThat(actualInstrumentInfo.getBaseCoin()).isEqualTo("BTC");
+ assertThat(actualInstrumentInfo.getQuoteCoin()).isEqualTo("USDT");
+ assertThat(actualInstrumentInfo.getLaunchTime()).isEqualTo(new Date(1585526400000L));
+ assertThat(actualInstrumentInfo.getDeliveryTime()).isEqualTo(new Date(0L));
+ assertThat(actualInstrumentInfo.getDeliveryFeeRate()).isNull();
+ assertThat(actualInstrumentInfo.getPriceScale()).isEqualTo(2);
+ assertThat(actualInstrumentInfo.getLeverageFilter().getMinLeverage()).isEqualTo(1);
+ assertThat(actualInstrumentInfo.getLeverageFilter().getMaxLeverage())
+ .isEqualTo(new BigDecimal("100.00"));
+ assertThat(actualInstrumentInfo.getLeverageFilter().getLeverageStep())
+ .isEqualTo(new BigDecimal("0.01"));
+ assertThat(actualInstrumentInfo.getPriceFilter().getTickSize())
+ .isEqualTo(new BigDecimal("0.50"));
+ assertThat(actualInstrumentInfo.getPriceFilter().getMinPrice())
+ .isEqualTo(new BigDecimal("0.50"));
+ assertThat(actualInstrumentInfo.getPriceFilter().getMaxPrice())
+ .isEqualTo(new BigDecimal("999999.00"));
+ assertThat(actualInstrumentInfo.getLotSizeFilter().getMaxOrderQty())
+ .isEqualTo(new BigDecimal("100.000"));
+ assertThat(actualInstrumentInfo.getLotSizeFilter().getMinOrderQty())
+ .isEqualTo(new BigDecimal("0.001"));
+ assertThat(actualInstrumentInfo.getLotSizeFilter().getQtyStep())
+ .isEqualTo(new BigDecimal("0.001"));
+ assertThat(actualInstrumentInfo.getLotSizeFilter().getPostOnlyMaxOrderQty())
+ .isEqualTo(new BigDecimal("1000.000"));
+ assertThat(actualInstrumentInfo.isUnifiedMarginTrade()).isTrue();
+ assertThat(actualInstrumentInfo.getFundingInterval()).isEqualTo(480);
+ assertThat(actualInstrumentInfo.getSettleCoin()).isEqualTo("USDT");
+ assertThat(actualInstrumentInfo.getCopyTrading()).isNull();
+ }
+
+ @Test
+ public void testGetOptionInstrumentsInfo() throws Exception {
+ initInstrumentsInfoStub("/getInstrumentOption.json5");
+
+ BybitInstrumentsInfo instrumentsInfo =
+ marketDataServiceRaw.getInstrumentsInfo(BybitCategory.OPTION, null, null, null, 1000, null).getResult();
+
+ assertThat(instrumentsInfo.getList()).hasSize(1);
+
+ BybitOptionInstrumentInfo actualInstrumentInfo =
+ (BybitOptionInstrumentInfo) instrumentsInfo.getList().get(0);
+
+ assertThat(actualInstrumentInfo.getSymbol()).isEqualTo("ETH-3JAN23-1250-P");
+ assertThat(actualInstrumentInfo.getOptionsType()).isEqualTo(BybitOptionType.PUT);
+ assertThat(actualInstrumentInfo.getStatus()).isEqualTo(InstrumentStatus.TRADING);
+ assertThat(actualInstrumentInfo.getBaseCoin()).isEqualTo("ETH");
+ assertThat(actualInstrumentInfo.getQuoteCoin()).isEqualTo("USD");
+ assertThat(actualInstrumentInfo.getLaunchTime()).isEqualTo(new Date(1672560000000L));
+ assertThat(actualInstrumentInfo.getDeliveryTime()).isEqualTo(new Date(1672732800000L));
+ assertThat(actualInstrumentInfo.getDeliveryFeeRate()).isEqualTo(new BigDecimal("0.00015"));
+ assertThat(actualInstrumentInfo.getPriceFilter().getTickSize())
+ .isEqualTo(new BigDecimal("0.1"));
+ assertThat(actualInstrumentInfo.getPriceFilter().getMinPrice())
+ .isEqualTo(new BigDecimal("0.1"));
+ assertThat(actualInstrumentInfo.getPriceFilter().getMaxPrice())
+ .isEqualTo(new BigDecimal("10000000"));
+ assertThat(actualInstrumentInfo.getLotSizeFilter().getMaxOrderQty())
+ .isEqualTo(new BigDecimal("1500"));
+ assertThat(actualInstrumentInfo.getLotSizeFilter().getMinOrderQty())
+ .isEqualTo(new BigDecimal("0.1"));
+ assertThat(actualInstrumentInfo.getLotSizeFilter().getQtyStep())
+ .isEqualTo(new BigDecimal("0.1"));
+ assertThat(actualInstrumentInfo.getSettleCoin()).isEqualTo("USDC");
+ }
+
+ @Test
+ public void testGetSpotInstrumentsInfo() throws Exception {
+ initInstrumentsInfoStub("/getInstrumentSpot.json5");
+
+ BybitInstrumentsInfo instrumentsInfo =
+ marketDataServiceRaw.getInstrumentsInfo(BybitCategory.SPOT, null, null, null, 1000, null).getResult();
+
+ assertThat(instrumentsInfo.getList()).hasSize(1);
+
+ BybitSpotInstrumentInfo actualInstrumentInfo =
+ (BybitSpotInstrumentInfo) instrumentsInfo.getList().get(0);
+
+ assertThat(actualInstrumentInfo.getSymbol()).isEqualTo("BTCUSDT");
+ assertThat(actualInstrumentInfo.getStatus()).isEqualTo(InstrumentStatus.TRADING);
+ assertThat(actualInstrumentInfo.getMarginTrading()).isEqualTo(MarginTrading.BOTH);
+ assertThat(actualInstrumentInfo.getBaseCoin()).isEqualTo("BTC");
+ assertThat(actualInstrumentInfo.getQuoteCoin()).isEqualTo("USDT");
+ assertThat(actualInstrumentInfo.getPriceFilter().getTickSize())
+ .isEqualTo(new BigDecimal("0.01"));
+ assertThat(actualInstrumentInfo.getLotSizeFilter().getMaxOrderQty())
+ .isEqualTo(new BigDecimal("71.73956243"));
+ assertThat(actualInstrumentInfo.getLotSizeFilter().getMaxOrderAmt())
+ .isEqualTo(new BigDecimal("2000000"));
+ assertThat(actualInstrumentInfo.getLotSizeFilter().getMinOrderQty())
+ .isEqualTo(new BigDecimal("0.000048"));
+ assertThat(actualInstrumentInfo.getLotSizeFilter().getMinOrderAmt())
+ .isEqualTo(new BigDecimal("1"));
+ assertThat(actualInstrumentInfo.getLotSizeFilter().getBasePrecision())
+ .isEqualTo(new BigDecimal("0.000001"));
+ assertThat(actualInstrumentInfo.getLotSizeFilter().getQuotePrecision())
+ .isEqualTo(new BigDecimal("0.00000001"));
+ }
+
+ @Test
+ public void testGetLinearInverseTicker() throws Exception {
+ initTickerStub("/getTickerInverse.json5");
+
+ BybitTickers bybitTickers =
+ marketDataServiceRaw.getTicker24h(BybitCategory.INVERSE, "BTCUSD").getResult();
+
+ assertThat(bybitTickers.getList()).hasSize(1);
+
+ BybitLinearInverseTicker actualTicker =
+ (BybitLinearInverseTicker) bybitTickers.getList().get(0);
+
+ assertThat(actualTicker.getSymbol()).isEqualTo("BTCUSD");
+ assertThat(actualTicker.getLastPrice()).isEqualTo(new BigDecimal("16597.00"));
+ assertThat(actualTicker.getIndexPrice()).isEqualTo(new BigDecimal("16598.54"));
+ assertThat(actualTicker.getMarkPrice()).isEqualTo(new BigDecimal("16596.00"));
+ assertThat(actualTicker.getPrevPrice24h()).isEqualTo(new BigDecimal("16464.50"));
+ assertThat(actualTicker.getPrice24hPcnt()).isEqualTo(new BigDecimal("0.008047"));
+ assertThat(actualTicker.getHighPrice24h()).isEqualTo(new BigDecimal("30912.50"));
+ assertThat(actualTicker.getLowPrice24h()).isEqualTo(new BigDecimal("15700.00"));
+ assertThat(actualTicker.getPrevPrice1h()).isEqualTo(new BigDecimal("16595.50"));
+ assertThat(actualTicker.getOpenInterest()).isEqualTo(new BigDecimal("373504107"));
+ assertThat(actualTicker.getOpenInterestValue()).isEqualTo(new BigDecimal("22505.67"));
+ assertThat(actualTicker.getTurnover24h()).isEqualTo(new BigDecimal("2352.94950046"));
+ assertThat(actualTicker.getVolume24h()).isEqualTo(new BigDecimal("49337318"));
+ assertThat(actualTicker.getFundingRate()).isEqualTo(new BigDecimal("-0.001034"));
+ assertThat(actualTicker.getNextFundingTime()).isEqualTo(new Date(1672387200000L));
+ assertThat(actualTicker.getPredictedDeliveryPrice()).isNull();
+ assertThat(actualTicker.getBasisRate()).isNull();
+ assertThat(actualTicker.getDeliveryFeeRate()).isNull();
+ assertThat(actualTicker.getDeliveryTime()).isEqualTo(new Date(0L));
+ assertThat(actualTicker.getAsk1Size()).isEqualTo(new BigDecimal("1"));
+ assertThat(actualTicker.getBid1Price()).isEqualTo(new BigDecimal("16596.00"));
+ assertThat(actualTicker.getAsk1Price()).isEqualTo(new BigDecimal("16597.50"));
+ assertThat(actualTicker.getBid1Size()).isEqualTo(new BigDecimal("1"));
+ assertThat(actualTicker.getBasis()).isNull();
+ }
+
+ @Test
+ public void testGetOptionTicker() throws Exception {
+ initTickerStub("/getTickerOption.json5");
+
+ BybitTickers bybitTickers =
+ marketDataServiceRaw.getTicker24h(BybitCategory.OPTION, "BTC-30DEC22-18000-C").getResult();
+
+ assertThat(bybitTickers.getList()).hasSize(1);
+
+ BybitOptionTicker actualTicker = (BybitOptionTicker) bybitTickers.getList().get(0);
+
+ assertThat(actualTicker.getSymbol()).isEqualTo("BTC-30DEC22-18000-C");
+ assertThat(actualTicker.getBid1Price()).isEqualTo(new BigDecimal("0"));
+ assertThat(actualTicker.getBid1Size()).isEqualTo(new BigDecimal("0"));
+ assertThat(actualTicker.getBid1Iv()).isEqualTo(new BigDecimal("0"));
+ assertThat(actualTicker.getAsk1Price()).isEqualTo(new BigDecimal("435"));
+ assertThat(actualTicker.getAsk1Size()).isEqualTo(new BigDecimal("0.66"));
+ assertThat(actualTicker.getAsk1Iv()).isEqualTo(new BigDecimal("5"));
+ assertThat(actualTicker.getLastPrice()).isEqualTo(new BigDecimal("435"));
+ assertThat(actualTicker.getHighPrice24h()).isEqualTo(new BigDecimal("435"));
+ assertThat(actualTicker.getLowPrice24h()).isEqualTo(new BigDecimal("165"));
+ assertThat(actualTicker.getMarkPrice()).isEqualTo(new BigDecimal("0.00000009"));
+ assertThat(actualTicker.getIndexPrice()).isEqualTo(new BigDecimal("16600.55"));
+ assertThat(actualTicker.getMarkIv()).isEqualTo(new BigDecimal("0.7567"));
+ assertThat(actualTicker.getUnderlyingPrice()).isEqualTo(new BigDecimal("16590.42"));
+ assertThat(actualTicker.getOpenInterest()).isEqualTo(new BigDecimal("6.3"));
+ assertThat(actualTicker.getTurnover24h()).isEqualTo(new BigDecimal("2482.73"));
+ assertThat(actualTicker.getVolume24h()).isEqualTo(new BigDecimal("0.15"));
+ assertThat(actualTicker.getTotalVolume()).isEqualTo(new BigDecimal("99"));
+ assertThat(actualTicker.getTotalTurnover()).isEqualTo(new BigDecimal("1967653"));
+ assertThat(actualTicker.getDelta()).isEqualTo(new BigDecimal("0.00000001"));
+ assertThat(actualTicker.getGamma()).isEqualTo(new BigDecimal("0.00000001"));
+ assertThat(actualTicker.getVega()).isEqualTo(new BigDecimal("0.00000004"));
+ assertThat(actualTicker.getTheta()).isEqualTo(new BigDecimal("-0.00000152"));
+ assertThat(actualTicker.getPredictedDeliveryPrice()).isEqualTo(new BigDecimal("0"));
+ assertThat(actualTicker.getChange24h()).isEqualTo(new BigDecimal("86"));
+ }
+
+ @Test
+ public void testGetSpotTicker() throws Exception {
+ initTickerStub("/getTickerSpot.json5");
+
+ BybitTickers bybitTickers =
+ marketDataServiceRaw.getTicker24h(BybitCategory.SPOT, "BTCUSDT").getResult();
+
+ assertThat(bybitTickers.getList()).hasSize(1);
+
+ BybitSpotTicker actualTicker = (BybitSpotTicker) bybitTickers.getList().get(0);
+
+ assertThat(actualTicker.getSymbol()).isEqualTo("BTCUSDT");
+ assertThat(actualTicker.getBid1Price()).isEqualTo(new BigDecimal("20517.96"));
+ assertThat(actualTicker.getBid1Size()).isEqualTo(new BigDecimal("2"));
+ assertThat(actualTicker.getAsk1Price()).isEqualTo(new BigDecimal("20527.77"));
+ assertThat(actualTicker.getAsk1Size()).isEqualTo(new BigDecimal("1.862172"));
+ assertThat(actualTicker.getLastPrice()).isEqualTo(new BigDecimal("20533.13"));
+ assertThat(actualTicker.getPrevPrice24h()).isEqualTo(new BigDecimal("20393.48"));
+ assertThat(actualTicker.getPrice24hPcnt()).isEqualTo(new BigDecimal("0.0068"));
+ assertThat(actualTicker.getHighPrice24h()).isEqualTo(new BigDecimal("21128.12"));
+ assertThat(actualTicker.getLowPrice24h()).isEqualTo(new BigDecimal("20318.89"));
+ assertThat(actualTicker.getTurnover24h()).isEqualTo(new BigDecimal("243765620.65899866"));
+ assertThat(actualTicker.getVolume24h()).isEqualTo(new BigDecimal("11801.27771"));
+ assertThat(actualTicker.getUsdIndexPrice()).isEqualTo(new BigDecimal("20784.12009279"));
+ }
+}
diff --git a/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitMarketDataServiceTest.java b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitMarketDataServiceTest.java
index 9dbe3d1283a..5abb57bfd72 100644
--- a/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitMarketDataServiceTest.java
+++ b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitMarketDataServiceTest.java
@@ -1,56 +1,68 @@
package org.knowm.xchange.bybit.service;
-import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
-import static com.github.tomakehurst.wiremock.client.WireMock.get;
-import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
import static org.assertj.core.api.Assertions.assertThat;
import java.math.BigDecimal;
-import java.nio.charset.StandardCharsets;
-import java.time.Instant;
-import jakarta.ws.rs.core.Response.Status;
-import org.apache.commons.io.IOUtils;
+import java.util.Date;
+import org.junit.Before;
import org.junit.Test;
import org.knowm.xchange.Exchange;
+import org.knowm.xchange.bybit.dto.BybitCategory;
import org.knowm.xchange.currency.CurrencyPair;
import org.knowm.xchange.dto.marketdata.Ticker;
import org.knowm.xchange.service.marketdata.MarketDataService;
public class BybitMarketDataServiceTest extends BaseWiremockTest {
- @Test
- public void testGetTicker() throws Exception {
+ private MarketDataService marketDataService;
+
+ @Before
+ public void setUp() throws Exception {
Exchange bybitExchange = createExchange();
- MarketDataService marketDataService = bybitExchange.getMarketDataService();
-
- stubFor(
- get(urlPathEqualTo("/v2/public/tickers"))
- .willReturn(
- aResponse()
- .withStatus(Status.OK.getStatusCode())
- .withHeader("Content-Type", "application/json")
- .withBody(IOUtils.resourceToString("/getTicker.json5", StandardCharsets.UTF_8))
- )
- );
-
- Ticker ticker = marketDataService.getTicker(CurrencyPair.BTC_USDT);
-
- assertThat(ticker.getInstrument().toString()).isEqualTo("BTC/USDT");
- assertThat(ticker.getOpen()).isEqualTo(new BigDecimal("21670.00"));
- assertThat(ticker.getLast()).isEqualTo(new BigDecimal("21333.00"));
- assertThat(ticker.getBid()).isEqualTo(new BigDecimal("21323"));
- assertThat(ticker.getAsk()).isEqualTo(new BigDecimal("21334"));
- assertThat(ticker.getHigh()).isEqualTo(new BigDecimal("22024.50"));
- assertThat(ticker.getLow()).isEqualTo(new BigDecimal("21120.00"));
- assertThat(ticker.getVwap()).isNull();
- assertThat(ticker.getVolume()).isEqualTo(new BigDecimal("10028.87"));
- assertThat(ticker.getQuoteVolume()).isEqualTo(new BigDecimal("216158761.48"));
- assertThat(ticker.getTimestamp()).isEqualTo(Instant.parse("2022-07-10T09:09:11.611Z"));
- assertThat(ticker.getBidSize()).isNull();
- assertThat(ticker.getAskSize()).isNull();
- assertThat(ticker.getPercentageChange()).isEqualTo(new BigDecimal("-0.015551"));
+ marketDataService = bybitExchange.getMarketDataService();
+ }
+
+ @Test
+ public void testGetTickerWithInverseArg() throws Exception {
+ initGetStub("/v5/market/tickers", "/getTickerInverse.json5");
+ Ticker ticker = marketDataService.getTicker(CurrencyPair.BTC_USD, BybitCategory.INVERSE);
+
+ assertThat(ticker.getInstrument().toString()).isEqualTo("BTC/USD");
+ assertThat(ticker.getOpen()).isEqualTo(new BigDecimal("16464.50"));
+ assertThat(ticker.getLast()).isEqualTo(new BigDecimal("16597.00"));
+ assertThat(ticker.getBid()).isEqualTo(new BigDecimal("16596.00"));
+ assertThat(ticker.getAsk()).isEqualTo(new BigDecimal("16597.50"));
+ assertThat(ticker.getHigh()).isEqualTo(new BigDecimal("30912.50"));
+ assertThat(ticker.getLow()).isEqualTo(new BigDecimal("15700.00"));
+ assertThat(ticker.getVwap()).isNull();
+ assertThat(ticker.getVolume()).isEqualTo(new BigDecimal("49337318"));
+ assertThat(ticker.getQuoteVolume()).isEqualTo(new BigDecimal("2352.94950046"));
+ assertThat(ticker.getTimestamp()).isEqualTo(new Date(1672376496682L));
+ assertThat(ticker.getBidSize()).isEqualTo(new BigDecimal("1"));
+ assertThat(ticker.getAskSize()).isEqualTo(new BigDecimal("1"));
+ assertThat(ticker.getPercentageChange()).isEqualTo(new BigDecimal("0.008047"));
}
-}
\ No newline at end of file
+ @Test
+ public void testGetTickerWithSpotArg() throws Exception {
+ initGetStub("/v5/market/tickers", "/getTickerSpot.json5");
+
+ Ticker ticker = marketDataService.getTicker(CurrencyPair.BTC_USD, BybitCategory.SPOT);
+
+ assertThat(ticker.getInstrument().toString()).isEqualTo("BTC/USD");
+ assertThat(ticker.getOpen()).isEqualTo(new BigDecimal("20393.48"));
+ assertThat(ticker.getLast()).isEqualTo(new BigDecimal("20533.13"));
+ assertThat(ticker.getBid()).isEqualTo(new BigDecimal("20517.96"));
+ assertThat(ticker.getAsk()).isEqualTo(new BigDecimal("20527.77"));
+ assertThat(ticker.getHigh()).isEqualTo(new BigDecimal("21128.12"));
+ assertThat(ticker.getLow()).isEqualTo(new BigDecimal("20318.89"));
+ assertThat(ticker.getVwap()).isNull(); // If it's supposed to be null
+ assertThat(ticker.getVolume()).isEqualTo(new BigDecimal("11801.27771"));
+ assertThat(ticker.getQuoteVolume()).isEqualTo(new BigDecimal("243765620.65899866"));
+ assertThat(ticker.getTimestamp()).isEqualTo(new Date(1673859087947L));
+ assertThat(ticker.getBidSize()).isEqualTo(new BigDecimal("2"));
+ assertThat(ticker.getAskSize()).isEqualTo(new BigDecimal("1.862172"));
+ assertThat(ticker.getPercentageChange()).isEqualTo(new BigDecimal("0.0068"));
+ }
+}
diff --git a/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitTradeServiceRawTest.java b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitTradeServiceRawTest.java
index 7cf4a5f6d58..a148538c227 100644
--- a/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitTradeServiceRawTest.java
+++ b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitTradeServiceRawTest.java
@@ -1,7 +1,6 @@
package org.knowm.xchange.bybit.service;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
-import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
@@ -9,165 +8,265 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
-import java.io.IOException;
import jakarta.ws.rs.core.Response.Status;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import org.apache.commons.io.IOUtils;
import org.junit.Test;
import org.knowm.xchange.Exchange;
+import org.knowm.xchange.bybit.dto.BybitCategory;
import org.knowm.xchange.bybit.dto.BybitResult;
-import org.knowm.xchange.bybit.dto.trade.BybitOrderDetails;
-import org.knowm.xchange.bybit.dto.trade.BybitOrderRequest;
+import org.knowm.xchange.bybit.dto.trade.BybitOrderResponse;
+import org.knowm.xchange.bybit.dto.trade.BybitOrderStatus;
+import org.knowm.xchange.bybit.dto.trade.BybitOrderType;
+import org.knowm.xchange.bybit.dto.trade.BybitSide;
+import org.knowm.xchange.bybit.dto.trade.details.BybitOrderDetail;
+import org.knowm.xchange.bybit.dto.trade.details.BybitOrderDetails;
+import org.knowm.xchange.bybit.dto.trade.details.linear.BybitLinearOrderDetail;
+import org.knowm.xchange.bybit.dto.trade.details.spot.BybitSpotOrderDetail;
public class BybitTradeServiceRawTest extends BaseWiremockTest {
@Test
- public void testGetBybitOrder() throws IOException {
+ public void testGetBybitLinearDetailOrder() throws IOException {
Exchange bybitExchange = createExchange();
BybitTradeServiceRaw bybitAccountServiceRaw = new BybitTradeServiceRaw(bybitExchange);
- String orderDetails = "{\n" +
- " \"ret_code\":0,\n" +
- " \"ret_msg\":\"\",\n" +
- " \"ext_code\":null,\n" +
- " \"ext_info\":null,\n" +
- " \"result\":{\n" +
- " \"accountId\":\"123456789\",\n" +
- " \"exchangeId\":\"301\",\n" +
- " \"symbol\":\"COINUSDT\",\n" +
- " \"symbolName\":\"COINUSDT\",\n" +
- " \"orderLinkId\":\"1234567891011121\",\n" +
- " \"orderId\":\"1234567891011121314\",\n" +
- " \"price\":\"0\",\n" +
- " \"origQty\":\"352\",\n" +
- " \"executedQty\":\"352\",\n" +
- " \"cummulativeQuoteQty\":\"0.569888\",\n" +
- " \"avgPrice\":\"0.001619\",\n" +
- " \"status\":\"FILLED\",\n" +
- " \"timeInForce\":\"GTC\",\n" +
- " \"type\":\"MARKET\",\n" +
- " \"side\":\"SELL\",\n" +
- " \"stopPrice\":\"0.0\",\n" +
- " \"icebergQty\":\"0.0\",\n" +
- " \"time\":\"1655997749601\",\n" +
- " \"updateTime\":\"1655997749662\",\n" +
- " \"isWorking\":true,\n" +
- " \"locked\":\"0\"\n" +
- " }\n" +
- "}";
+ String responseFilePath = "/getOrderDetailsLinear.json5";
+ initGetStub("/v5/order/realtime", responseFilePath);
+ String expectedOrderDetails =
+ IOUtils.resourceToString(responseFilePath, StandardCharsets.UTF_8);
- stubFor(
- get(urlPathEqualTo("/spot/v1/order"))
- .willReturn(
- aResponse()
- .withStatus(Status.OK.getStatusCode())
- .withHeader("Content-Type", "application/json")
- .withBody(orderDetails)
- )
- );
- BybitResult order = bybitAccountServiceRaw.getBybitOrder("1234567891011121314");
+ BybitResult> actualOrderDetails =
+ bybitAccountServiceRaw.getBybitOrder(
+ BybitCategory.LINEAR, "fd4300ae-7847-404e-b947-b46980a4d140");
+
+ assertThat(actualOrderDetails.getResult().getList()).hasSize(1);
ObjectMapper mapper = new ObjectMapper();
- JsonNode responseObject = mapper.readTree(orderDetails);
+ JsonNode responseObject = mapper.readTree(expectedOrderDetails);
- BybitOrderDetails orderResult = order.getResult();
+ BybitLinearOrderDetail actualOrderDetail =
+ (BybitLinearOrderDetail) actualOrderDetails.getResult().getList().get(0);
JsonNode responseObjectResult = responseObject.get("result");
+ JsonNode listNode = responseObjectResult.get("list");
+ JsonNode expectedOrderDetail = listNode.get(0);
- assertThat(responseObjectResult.get("accountId").textValue()).isEqualTo(orderResult.getAccountId());
- assertThat(responseObjectResult.get("exchangeId").textValue()).isEqualTo(orderResult.getExchangeId());
- assertThat(responseObjectResult.get("symbol").textValue()).isEqualTo(orderResult.getSymbol());
- assertThat(responseObjectResult.get("symbolName").textValue()).isEqualTo(orderResult.getSymbolName());
- assertThat(responseObjectResult.get("orderLinkId").textValue()).isEqualTo(orderResult.getOrderLinkId());
- assertThat(responseObjectResult.get("orderId").textValue()).isEqualTo(orderResult.getOrderId());
- assertThat(responseObjectResult.get("price").textValue()).isEqualTo(orderResult.getPrice());
- assertThat(responseObjectResult.get("origQty").textValue()).isEqualTo(orderResult.getOrigQty());
- assertThat(responseObjectResult.get("executedQty").textValue()).isEqualTo(orderResult.getExecutedQty());
- assertThat(responseObjectResult.get("cummulativeQuoteQty").textValue()).isEqualTo(
- orderResult.getCummulativeQuoteQty());
- assertThat(responseObjectResult.get("avgPrice").textValue()).isEqualTo(orderResult.getAvgPrice());
- assertThat(responseObjectResult.get("status").textValue()).isEqualTo(orderResult.getStatus());
- assertThat(responseObjectResult.get("timeInForce").textValue()).isEqualTo(orderResult.getTimeInForce());
- assertThat(responseObjectResult.get("type").textValue()).isEqualTo(orderResult.getType());
- assertThat(responseObjectResult.get("side").textValue()).isEqualTo(orderResult.getSide());
- assertThat(responseObjectResult.get("stopPrice").textValue()).isEqualTo(orderResult.getStopPrice());
- assertThat(responseObjectResult.get("icebergQty").textValue()).isEqualTo(orderResult.getIcebergQty());
- assertThat(responseObjectResult.get("time").textValue()).isEqualTo(orderResult.getTime());
- assertThat(responseObjectResult.get("updateTime").textValue()).isEqualTo(orderResult.getUpdateTime());
- assertThat(responseObjectResult.get("isWorking").booleanValue()).isEqualTo(orderResult.isWorking());
- assertThat(responseObjectResult.get("locked").textValue()).isEqualTo(orderResult.getLocked());
+ assertThat(actualOrderDetail.getSymbol())
+ .isEqualTo(expectedOrderDetail.get("symbol").textValue());
+ assertThat(actualOrderDetail.getPrice().doubleValue())
+ .isEqualTo(expectedOrderDetail.get("price").asDouble());
+ assertThat(actualOrderDetail.getQty().doubleValue())
+ .isEqualTo(expectedOrderDetail.get("qty").asDouble());
+ assertThat(actualOrderDetail.getSide().name())
+ .isEqualToIgnoringCase(expectedOrderDetail.get("side").textValue());
+ assertThat(actualOrderDetail.getIsLeverage())
+ .isEqualTo(expectedOrderDetail.get("isLeverage").textValue());
+ assertThat(actualOrderDetail.getPositionIdx())
+ .isEqualTo(expectedOrderDetail.get("positionIdx").intValue());
+ assertThat(actualOrderDetail.getOrderStatus().name())
+ .isEqualToIgnoringCase(expectedOrderDetail.get("orderStatus").textValue());
+ assertThat(actualOrderDetail.getCancelType())
+ .isEqualTo(expectedOrderDetail.get("cancelType").textValue());
+ assertThat(actualOrderDetail.getRejectReason())
+ .isEqualTo(expectedOrderDetail.get("rejectReason").textValue());
+ assertThat(actualOrderDetail.getAvgPrice().doubleValue())
+ .isEqualTo(expectedOrderDetail.get("avgPrice").asDouble());
+ assertThat(actualOrderDetail.getLeavesQty().doubleValue())
+ .isEqualTo(expectedOrderDetail.get("leavesQty").asDouble());
+ assertThat(actualOrderDetail.getLeavesValue().doubleValue())
+ .isEqualTo(expectedOrderDetail.get("leavesValue").asDouble());
+ assertThat(actualOrderDetail.getCumExecQty().doubleValue())
+ .isEqualTo(expectedOrderDetail.get("cumExecQty").asDouble());
+ assertThat(actualOrderDetail.getCumExecValue().doubleValue())
+ .isEqualTo(expectedOrderDetail.get("cumExecValue").asDouble());
+ assertThat(actualOrderDetail.getCumExecFee().doubleValue())
+ .isEqualTo(expectedOrderDetail.get("cumExecFee").asDouble());
+ assertThat(actualOrderDetail.getTimeInForce())
+ .isEqualTo(expectedOrderDetail.get("timeInForce").textValue());
+ assertThat(actualOrderDetail.getOrderType().name())
+ .isEqualToIgnoringCase(expectedOrderDetail.get("orderType").textValue());
+ assertThat(actualOrderDetail.getStopOrderType())
+ .isEqualTo(expectedOrderDetail.get("stopOrderType").textValue());
+ assertThat(actualOrderDetail.getOrderIv())
+ .isEqualTo(expectedOrderDetail.get("orderIv").textValue());
+ assertThat(actualOrderDetail.getTriggerPrice().doubleValue())
+ .isEqualTo(expectedOrderDetail.get("triggerPrice").asDouble());
+ assertThat(actualOrderDetail.getTakeProfit().doubleValue())
+ .isEqualTo(expectedOrderDetail.get("takeProfit").asDouble());
+ assertThat(actualOrderDetail.getStopLoss().doubleValue())
+ .isEqualTo(expectedOrderDetail.get("stopLoss").asDouble());
+ assertThat(actualOrderDetail.getTpTriggerBy())
+ .isEqualTo(expectedOrderDetail.get("tpTriggerBy").textValue());
+ assertThat(actualOrderDetail.getSlTriggerBy())
+ .isEqualTo(expectedOrderDetail.get("slTriggerBy").textValue());
+ assertThat(actualOrderDetail.getTriggerDirection())
+ .isEqualTo(expectedOrderDetail.get("triggerDirection").intValue());
+ assertThat(actualOrderDetail.getTriggerBy())
+ .isEqualTo(expectedOrderDetail.get("triggerBy").textValue());
+ assertThat(actualOrderDetail.getLastPriceOnCreated())
+ .isEqualTo(expectedOrderDetail.get("lastPriceOnCreated").textValue());
+ assertThat(actualOrderDetail.isReduceOnly())
+ .isEqualTo(expectedOrderDetail.get("reduceOnly").booleanValue());
+ assertThat(actualOrderDetail.isCloseOnTrigger())
+ .isEqualTo(expectedOrderDetail.get("closeOnTrigger").booleanValue());
+ assertThat(actualOrderDetail.getSmpType())
+ .isEqualTo(expectedOrderDetail.get("smpType").textValue());
+ assertThat(actualOrderDetail.getSmpGroup())
+ .isEqualTo(expectedOrderDetail.get("smpGroup").intValue());
+ assertThat(actualOrderDetail.getSmpOrderId())
+ .isEqualTo(expectedOrderDetail.get("smpOrderId").textValue());
+ assertThat(actualOrderDetail.getTpslMode())
+ .isEqualTo(expectedOrderDetail.get("tpslMode").textValue());
+ assertThat(actualOrderDetail.getTpLimitPrice())
+ .isEqualTo(expectedOrderDetail.get("tpLimitPrice").textValue());
+ assertThat(actualOrderDetail.getSlLimitPrice())
+ .isEqualTo(expectedOrderDetail.get("slLimitPrice").textValue());
+ assertThat(actualOrderDetail.getPlaceType())
+ .isEqualTo(expectedOrderDetail.get("placeType").textValue());
+ assertThat(actualOrderDetail.getCreatedTime().getTime())
+ .isEqualTo(expectedOrderDetail.get("createdTime").asLong());
+ assertThat(actualOrderDetail.getUpdatedTime().getTime())
+ .isEqualTo(expectedOrderDetail.get("updatedTime").asLong());
}
+ @Test
+ public void testGetBybitSpotDetailOrder() throws IOException {
+ Exchange bybitExchange = createExchange();
+ BybitTradeServiceRaw bybitAccountServiceRaw = new BybitTradeServiceRaw(bybitExchange);
+
+ String responseFilePath = "/getOrderDetailsSpot.json5";
+ initGetStub("/v5/order/realtime", responseFilePath);
+ String expectedOrderDetails =
+ IOUtils.resourceToString(responseFilePath, StandardCharsets.UTF_8);
+
+ BybitResult> actualOrderDetails =
+ bybitAccountServiceRaw.getBybitOrder(
+ BybitCategory.SPOT, "fd4300ae-7847-404e-b947-b46980a4d140");
+
+ assertThat(actualOrderDetails.getResult().getList()).hasSize(1);
+
+ ObjectMapper mapper = new ObjectMapper();
+ JsonNode responseObject = mapper.readTree(expectedOrderDetails);
+
+ BybitSpotOrderDetail actualOrderDetail =
+ (BybitSpotOrderDetail) actualOrderDetails.getResult().getList().get(0);
+ JsonNode responseObjectResult = responseObject.get("result");
+ JsonNode listNode = responseObjectResult.get("list");
+ JsonNode expectedOrderDetail = listNode.get(0);
+
+ assertThat(actualOrderDetail.getSymbol())
+ .isEqualTo(expectedOrderDetail.get("symbol").textValue());
+ assertThat(actualOrderDetail.getPrice().doubleValue())
+ .isEqualTo(expectedOrderDetail.get("price").asDouble());
+ assertThat(actualOrderDetail.getQty().doubleValue())
+ .isEqualTo(expectedOrderDetail.get("qty").asDouble());
+ assertThat(actualOrderDetail.getSide().name())
+ .isEqualToIgnoringCase(expectedOrderDetail.get("side").textValue());
+ assertThat(actualOrderDetail.getIsLeverage())
+ .isEqualTo(expectedOrderDetail.get("isLeverage").textValue());
+ assertThat(actualOrderDetail.getPositionIdx())
+ .isEqualTo(expectedOrderDetail.get("positionIdx").intValue());
+ assertThat(actualOrderDetail.getOrderStatus())
+ .isEqualTo(BybitOrderStatus.PARTIALLY_FILLED_CANCELED);
+ assertThat(actualOrderDetail.getCancelType())
+ .isEqualTo(expectedOrderDetail.get("cancelType").textValue());
+ assertThat(actualOrderDetail.getRejectReason())
+ .isEqualTo(expectedOrderDetail.get("rejectReason").textValue());
+ assertThat(actualOrderDetail.getAvgPrice().doubleValue())
+ .isEqualTo(expectedOrderDetail.get("avgPrice").asDouble());
+ assertThat(actualOrderDetail.getLeavesQty().doubleValue())
+ .isEqualTo(expectedOrderDetail.get("leavesQty").asDouble());
+ assertThat(actualOrderDetail.getLeavesValue().doubleValue())
+ .isEqualTo(expectedOrderDetail.get("leavesValue").asDouble());
+ assertThat(actualOrderDetail.getCumExecQty().doubleValue())
+ .isEqualTo(expectedOrderDetail.get("cumExecQty").asDouble());
+ assertThat(actualOrderDetail.getCumExecValue().doubleValue())
+ .isEqualTo(expectedOrderDetail.get("cumExecValue").asDouble());
+ assertThat(actualOrderDetail.getCumExecFee().doubleValue())
+ .isEqualTo(expectedOrderDetail.get("cumExecFee").asDouble());
+ assertThat(actualOrderDetail.getTimeInForce())
+ .isEqualTo(expectedOrderDetail.get("timeInForce").textValue());
+ assertThat(actualOrderDetail.getOrderType().name())
+ .isEqualToIgnoringCase(expectedOrderDetail.get("orderType").textValue());
+ assertThat(actualOrderDetail.getStopOrderType())
+ .isEqualTo(expectedOrderDetail.get("stopOrderType").textValue());
+ assertThat(actualOrderDetail.getOrderIv())
+ .isEqualTo(expectedOrderDetail.get("orderIv").textValue());
+ assertThat(actualOrderDetail.getTriggerPrice().doubleValue())
+ .isEqualTo(expectedOrderDetail.get("triggerPrice").asDouble());
+ assertThat(actualOrderDetail.getTpTriggerBy())
+ .isEqualTo(expectedOrderDetail.get("tpTriggerBy").textValue());
+ assertThat(actualOrderDetail.getSlTriggerBy())
+ .isEqualTo(expectedOrderDetail.get("slTriggerBy").textValue());
+ assertThat(actualOrderDetail.getTriggerDirection())
+ .isEqualTo(expectedOrderDetail.get("triggerDirection").intValue());
+ assertThat(actualOrderDetail.getTriggerBy())
+ .isEqualTo(expectedOrderDetail.get("triggerBy").textValue());
+ assertThat(actualOrderDetail.getLastPriceOnCreated()).isNull();
+ assertThat(actualOrderDetail.isReduceOnly())
+ .isEqualTo(expectedOrderDetail.get("reduceOnly").booleanValue());
+ assertThat(actualOrderDetail.isCloseOnTrigger())
+ .isEqualTo(expectedOrderDetail.get("closeOnTrigger").booleanValue());
+ assertThat(actualOrderDetail.getSmpType())
+ .isEqualTo(expectedOrderDetail.get("smpType").textValue());
+ assertThat(actualOrderDetail.getSmpGroup())
+ .isEqualTo(expectedOrderDetail.get("smpGroup").intValue());
+ assertThat(actualOrderDetail.getSmpOrderId())
+ .isEqualTo(expectedOrderDetail.get("smpOrderId").textValue());
+ assertThat(actualOrderDetail.getPlaceType())
+ .isEqualTo(expectedOrderDetail.get("placeType").textValue());
+ assertThat(actualOrderDetail.getCreatedTime().getTime())
+ .isEqualTo(expectedOrderDetail.get("createdTime").asLong());
+ assertThat(actualOrderDetail.getUpdatedTime().getTime())
+ .isEqualTo(expectedOrderDetail.get("updatedTime").asLong());
+ }
@Test
public void testPlaceBybitOrder() throws IOException {
Exchange bybitExchange = createExchange();
BybitTradeServiceRaw bybitAccountServiceRaw = new BybitTradeServiceRaw(bybitExchange);
- String orderPlacementResponse = "{\n" +
- " \"ret_code\":0,\n" +
- " \"ret_msg\":\"\",\n" +
- " \"ext_code\":null,\n" +
- " \"ext_info\":null,\n" +
- " \"result\":{\n" +
- " \"accountId\":\"28649557\",\n" +
- " \"exchangeId\":\"301\",\n" +
- " \"symbol\":\"COINUSDT\",\n" +
- " \"symbolName\":\"COINUSDT\",\n" +
- " \"orderLinkId\":\"1655997749596563\",\n" +
- " \"orderId\":\"1184989442799045889\",\n" +
- " \"price\":\"0\",\n" +
- " \"origQty\":\"352\",\n" +
- " \"executedQty\":\"352\",\n" +
- " \"cummulativeQuoteQty\":\"0.569888\",\n" +
- " \"avgPrice\":\"0.001619\",\n" +
- " \"status\":\"FILLED\",\n" +
- " \"timeInForce\":\"GTC\",\n" +
- " \"type\":\"MARKET\",\n" +
- " \"side\":\"SELL\",\n" +
- " \"stopPrice\":\"0.0\",\n" +
- " \"icebergQty\":\"0.0\",\n" +
- " \"time\":\"1655997749601\",\n" +
- " \"updateTime\":\"1655997749662\",\n" +
- " \"isWorking\":true,\n" +
- " \"locked\":\"0\"\n" +
- " }\n" +
- "}";
+ String orderPlacementResponse =
+ "{\n"
+ + " \"retCode\": 0,\n"
+ + " \"retMsg\": \"OK\",\n"
+ + " \"result\": {\n"
+ + " \"orderId\": \"1321003749386327552\",\n"
+ + " \"orderLinkId\": \"spot-test-postonly\"\n"
+ + " },\n"
+ + " \"retExtInfo\": {},\n"
+ + " \"time\": 1672211918471\n"
+ + "}";
stubFor(
- post(urlPathEqualTo("/spot/v1/order"))
+ post(urlPathEqualTo("/v5/order/create"))
.willReturn(
aResponse()
.withStatus(Status.OK.getStatusCode())
.withHeader("Content-Type", "application/json")
- .withBody(orderPlacementResponse)
- )
- );
+ .withBody(orderPlacementResponse)));
- BybitResult order = bybitAccountServiceRaw.placeOrder(
- "COINUSDT",
- 300,
- "SELL",
- "MARKET"
- );
+ BybitResult order =
+ bybitAccountServiceRaw.placeOrder(
+ BybitCategory.SPOT,
+ "BTCUSDT",
+ BybitSide.BUY,
+ BybitOrderType.LIMIT,
+ BigDecimal.valueOf(0.1));
ObjectMapper mapper = new ObjectMapper();
JsonNode responseObject = mapper.readTree(orderPlacementResponse);
- BybitOrderRequest orderRequestResult = order.getResult();
+ BybitOrderResponse orderRequestResult = order.getResult();
JsonNode responseObjectResult = responseObject.get("result");
- assertThat(responseObjectResult.get("accountId").textValue()).isEqualTo(orderRequestResult.getAccountId());
- assertThat(responseObjectResult.get("symbol").textValue()).isEqualTo(orderRequestResult.getSymbol());
- assertThat(responseObjectResult.get("symbolName").textValue()).isEqualTo(orderRequestResult.getSymbolName());
- assertThat(responseObjectResult.get("orderLinkId").textValue()).isEqualTo(orderRequestResult.getOrderLinkId());
- assertThat(responseObjectResult.get("orderId").textValue()).isEqualTo(orderRequestResult.getOrderId());
- assertThat(responseObjectResult.get("price").textValue()).isEqualTo(orderRequestResult.getPrice());
- assertThat(responseObjectResult.get("origQty").textValue()).isEqualTo(orderRequestResult.getOrigQty());
- assertThat(responseObjectResult.get("executedQty").textValue()).isEqualTo(orderRequestResult.getExecutedQty());
- assertThat(responseObjectResult.get("status").textValue()).isEqualTo(orderRequestResult.getStatus());
- assertThat(responseObjectResult.get("timeInForce").textValue()).isEqualTo(orderRequestResult.getTimeInForce());
- assertThat(responseObjectResult.get("type").textValue()).isEqualTo(orderRequestResult.getType());
- assertThat(responseObjectResult.get("side").textValue()).isEqualTo(orderRequestResult.getSide());
+ assertThat(responseObjectResult.get("orderLinkId").textValue())
+ .isEqualTo(orderRequestResult.getOrderLinkId());
+ assertThat(responseObjectResult.get("orderId").textValue())
+ .isEqualTo(orderRequestResult.getOrderId());
System.out.println(order);
}
-
-}
\ No newline at end of file
+}
diff --git a/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitTradeServiceTest.java b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitTradeServiceTest.java
index 72255344a0c..8c036deb505 100644
--- a/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitTradeServiceTest.java
+++ b/xchange-bybit/src/test/java/org/knowm/xchange/bybit/service/BybitTradeServiceTest.java
@@ -7,14 +7,16 @@
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
import static org.assertj.core.api.Assertions.assertThat;
+import jakarta.ws.rs.core.Response.Status;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Collection;
-import jakarta.ws.rs.core.Response.Status;
import org.junit.Test;
import org.knowm.xchange.Exchange;
import org.knowm.xchange.currency.CurrencyPair;
import org.knowm.xchange.dto.Order;
+import org.knowm.xchange.dto.Order.OrderStatus;
+import org.knowm.xchange.dto.Order.OrderType;
import org.knowm.xchange.dto.trade.MarketOrder;
public class BybitTradeServiceTest extends BaseWiremockTest {
@@ -24,110 +26,111 @@ public void testGetBybitOrder() throws IOException {
Exchange bybitExchange = createExchange();
BybitTradeService bybitAccountService = new BybitTradeService(bybitExchange);
- String orderDetails = "{\n" +
- " \"ret_code\":0,\n" +
- " \"ret_msg\":\"\",\n" +
- " \"ext_code\":null,\n" +
- " \"ext_info\":null,\n" +
- " \"result\":{\n" +
- " \"accountId\":\"123456789\",\n" +
- " \"exchangeId\":\"301\",\n" +
- " \"symbol\":\"COINUSDT\",\n" +
- " \"symbolName\":\"COINUSDT\",\n" +
- " \"orderLinkId\":\"1234567891011121\",\n" +
- " \"orderId\":\"1234567891011121314\",\n" +
- " \"price\":\"0\",\n" +
- " \"origQty\":\"352\",\n" +
- " \"executedQty\":\"352\",\n" +
- " \"cummulativeQuoteQty\":\"0.569888\",\n" +
- " \"avgPrice\":\"0.001619\",\n" +
- " \"status\":\"FILLED\",\n" +
- " \"timeInForce\":\"GTC\",\n" +
- " \"type\":\"MARKET\",\n" +
- " \"side\":\"SELL\",\n" +
- " \"stopPrice\":\"0.0\",\n" +
- " \"icebergQty\":\"0.0\",\n" +
- " \"time\":\"1655997749601\",\n" +
- " \"updateTime\":\"1655997749662\",\n" +
- " \"isWorking\":true,\n" +
- " \"locked\":\"0\"\n" +
- " }\n" +
- "}";
+ String orderDetails =
+ "{\n"
+ + " \"retCode\": 0,\n"
+ + " \"retMsg\": \"OK\",\n"
+ + " \"result\": {\n"
+ + " \"list\": [\n"
+ + " {\n"
+ + " \"orderId\": \"fd4300ae-7847-404e-b947-b46980a4d140\",\n"
+ + " \"orderLinkId\": \"test-000005\",\n"
+ + " \"blockTradeId\": \"\",\n"
+ + " \"symbol\": \"ETHUSDT\",\n"
+ + " \"price\": \"1600.00\",\n"
+ + " \"qty\": \"0.10\",\n"
+ + " \"side\": \"Buy\",\n"
+ + " \"isLeverage\": \"\",\n"
+ + " \"positionIdx\": 1,\n"
+ + " \"orderStatus\": \"New\",\n"
+ + " \"cancelType\": \"UNKNOWN\",\n"
+ + " \"rejectReason\": \"EC_NoError\",\n"
+ + " \"avgPrice\": \"0\",\n"
+ + " \"leavesQty\": \"0.10\",\n"
+ + " \"leavesValue\": \"160\",\n"
+ + " \"cumExecQty\": \"0.00\",\n"
+ + " \"cumExecValue\": \"0\",\n"
+ + " \"cumExecFee\": \"0\",\n"
+ + " \"timeInForce\": \"GTC\",\n"
+ + " \"orderType\": \"Limit\",\n"
+ + " \"stopOrderType\": \"UNKNOWN\",\n"
+ + " \"orderIv\": \"\",\n"
+ + " \"triggerPrice\": \"0.00\",\n"
+ + " \"takeProfit\": \"2500.00\",\n"
+ + " \"stopLoss\": \"1500.00\",\n"
+ + " \"tpTriggerBy\": \"LastPrice\",\n"
+ + " \"slTriggerBy\": \"LastPrice\",\n"
+ + " \"triggerDirection\": 0,\n"
+ + " \"triggerBy\": \"UNKNOWN\",\n"
+ + " \"lastPriceOnCreated\": \"\",\n"
+ + " \"reduceOnly\": false,\n"
+ + " \"closeOnTrigger\": false,\n"
+ + " \"smpType\": \"None\",\n"
+ + " \"smpGroup\": 0,\n"
+ + " \"smpOrderId\": \"\",\n"
+ + " \"tpslMode\": \"Full\",\n"
+ + " \"tpLimitPrice\": \"\",\n"
+ + " \"slLimitPrice\": \"\",\n"
+ + " \"placeType\": \"\",\n"
+ + " \"createdTime\": \"1684738540559\",\n"
+ + " \"updatedTime\": \"1684738540561\"\n"
+ + " }\n"
+ + " ],\n"
+ + " \"nextPageCursor\": \"page_args%3Dfd4300ae-7847-404e-b947-b46980a4d140%26symbol%3D6%26\",\n"
+ + " \"category\": \"linear\"\n"
+ + " },\n"
+ + " \"retExtInfo\": {},\n"
+ + " \"time\": 1684765770483\n"
+ + "}";
stubFor(
- get(urlPathEqualTo("/spot/v1/order"))
+ get(urlPathEqualTo("/v5/order/realtime"))
.willReturn(
aResponse()
.withStatus(Status.OK.getStatusCode())
.withHeader("Content-Type", "application/json")
- .withBody(orderDetails)
- )
- );
+ .withBody(orderDetails)));
- Collection orders = bybitAccountService.getOrder("1234567891011121314");
+ Collection orders = bybitAccountService.getOrder("fd4300ae-7847-404e-b947-b46980a4d140");
assertThat(orders.size()).isEqualTo(1);
Order order = (Order) orders.toArray()[0];
- assertThat(order.getType()).isEqualTo(Order.OrderType.ASK);
- assertThat(order.getInstrument()).isEqualTo(new CurrencyPair("COIN", "USDT"));
- assertThat(order.getAveragePrice()).isEqualTo(new BigDecimal("0.001619"));
- assertThat(order.getStatus()).isEqualTo(Order.OrderStatus.FILLED);
- assertThat(order.getOriginalAmount()).isEqualTo(new BigDecimal("352"));
-
+ assertThat(order.getType()).isEqualTo(OrderType.BID);
+ assertThat(order.getInstrument()).isEqualTo(new CurrencyPair("ETH", "USDT"));
+ assertThat(order.getAveragePrice()).isEqualTo(new BigDecimal("0"));
+ assertThat(order.getStatus()).isEqualTo(OrderStatus.NEW);
+ assertThat(order.getOriginalAmount()).isEqualTo(new BigDecimal("0.10"));
}
-
@Test
public void testPlaceBybitOrder() throws IOException {
Exchange bybitExchange = createExchange();
BybitTradeService bybitAccountService = new BybitTradeService(bybitExchange);
- String orderPlacementResponse = "{\n" +
- " \"ret_code\":0,\n" +
- " \"ret_msg\":\"\",\n" +
- " \"ext_code\":null,\n" +
- " \"ext_info\":null,\n" +
- " \"result\":{\n" +
- " \"accountId\":\"28649557\",\n" +
- " \"exchangeId\":\"301\",\n" +
- " \"symbol\":\"COINUSDT\",\n" +
- " \"symbolName\":\"COINUSDT\",\n" +
- " \"orderLinkId\":\"1655997749596563\",\n" +
- " \"orderId\":\"1184989442799045889\",\n" +
- " \"price\":\"0\",\n" +
- " \"origQty\":\"352\",\n" +
- " \"executedQty\":\"352\",\n" +
- " \"cummulativeQuoteQty\":\"0.569888\",\n" +
- " \"avgPrice\":\"0.001619\",\n" +
- " \"status\":\"FILLED\",\n" +
- " \"timeInForce\":\"GTC\",\n" +
- " \"type\":\"MARKET\",\n" +
- " \"side\":\"SELL\",\n" +
- " \"stopPrice\":\"0.0\",\n" +
- " \"icebergQty\":\"0.0\",\n" +
- " \"time\":\"1655997749601\",\n" +
- " \"updateTime\":\"1655997749662\",\n" +
- " \"isWorking\":true,\n" +
- " \"locked\":\"0\"\n" +
- " }\n" +
- "}";
+ String orderPlacementResponse =
+ "{\n"
+ + " \"retCode\": 0,\n"
+ + " \"retMsg\": \"OK\",\n"
+ + " \"result\": {\n"
+ + " \"orderId\": \"1321003749386327552\",\n"
+ + " \"orderLinkId\": \"spot-test-postonly\"\n"
+ + " },\n"
+ + " \"retExtInfo\": {},\n"
+ + " \"time\": 1672211918471\n"
+ + "}";
stubFor(
- post(urlPathEqualTo("/spot/v1/order"))
+ post(urlPathEqualTo("/v5/order/create"))
.willReturn(
aResponse()
.withStatus(Status.OK.getStatusCode())
.withHeader("Content-Type", "application/json")
- .withBody(orderPlacementResponse)
- )
- );
-
- String orderId = bybitAccountService.placeMarketOrder(
- new MarketOrder(Order.OrderType.ASK, new BigDecimal("300"), new CurrencyPair("COIN", "USDT"))
- );
+ .withBody(orderPlacementResponse)));
- assertThat(orderId).isEqualTo("1184989442799045889");
+ String orderId =
+ bybitAccountService.placeMarketOrder(
+ new MarketOrder(OrderType.ASK, new BigDecimal("0.1"), new CurrencyPair("BTC", "USDT")));
+ assertThat(orderId).isEqualTo("1321003749386327552");
}
-
-}
\ No newline at end of file
+}
diff --git a/xchange-bybit/src/test/resources/getAllCoinsBalance.json5 b/xchange-bybit/src/test/resources/getAllCoinsBalance.json5
new file mode 100644
index 00000000000..2733ac94e8d
--- /dev/null
+++ b/xchange-bybit/src/test/resources/getAllCoinsBalance.json5
@@ -0,0 +1,18 @@
+{
+ "retCode": 0,
+ "retMsg": "success",
+ "result": {
+ "memberId": "XXXX",
+ "accountType": "FUND",
+ "balance": [
+ {
+ "coin": "USDC",
+ "transferBalance": "0",
+ "walletBalance": "0",
+ "bonus": ""
+ }
+ ]
+ },
+ "retExtInfo": {},
+ "time": 1675866354913
+}
\ No newline at end of file
diff --git a/xchange-bybit/src/test/resources/getFeeRates.json5 b/xchange-bybit/src/test/resources/getFeeRates.json5
new file mode 100644
index 00000000000..3f400105c5e
--- /dev/null
+++ b/xchange-bybit/src/test/resources/getFeeRates.json5
@@ -0,0 +1,15 @@
+{
+ "retCode": 0,
+ "retMsg": "OK",
+ "result": {
+ "list": [
+ {
+ "symbol": "ETHUSDT",
+ "takerFeeRate": "0.0006",
+ "makerFeeRate": "0.0001"
+ }
+ ]
+ },
+ "retExtInfo": {},
+ "time": 1676360412576
+}
\ No newline at end of file
diff --git a/xchange-bybit/src/test/resources/getInstrumentLinear.json5 b/xchange-bybit/src/test/resources/getInstrumentLinear.json5
new file mode 100644
index 00000000000..047fc7c8745
--- /dev/null
+++ b/xchange-bybit/src/test/resources/getInstrumentLinear.json5
@@ -0,0 +1,42 @@
+{
+ "retCode": 0,
+ "retMsg": "OK",
+ "result": {
+ "category": "linear",
+ "list": [
+ {
+ "symbol": "BTCUSDT",
+ "contractType": "LinearPerpetual",
+ "status": "Trading",
+ "baseCoin": "BTC",
+ "quoteCoin": "USDT",
+ "launchTime": "1585526400000",
+ "deliveryTime": "0",
+ "deliveryFeeRate": "",
+ "priceScale": "2",
+ "leverageFilter": {
+ "minLeverage": "1",
+ "maxLeverage": "100.00",
+ "leverageStep": "0.01"
+ },
+ "priceFilter": {
+ "minPrice": "0.50",
+ "maxPrice": "999999.00",
+ "tickSize": "0.50"
+ },
+ "lotSizeFilter": {
+ "maxOrderQty": "100.000",
+ "minOrderQty": "0.001",
+ "qtyStep": "0.001",
+ "postOnlyMaxOrderQty": "1000.000"
+ },
+ "unifiedMarginTrade": true,
+ "fundingInterval": 480,
+ "settleCoin": "USDT"
+ }
+ ],
+ "nextPageCursor": ""
+ },
+ "retExtInfo": {},
+ "time": 1672712495660
+}
\ No newline at end of file
diff --git a/xchange-bybit/src/test/resources/getInstrumentOption.json5 b/xchange-bybit/src/test/resources/getInstrumentOption.json5
new file mode 100644
index 00000000000..c5be1d3bd16
--- /dev/null
+++ b/xchange-bybit/src/test/resources/getInstrumentOption.json5
@@ -0,0 +1,33 @@
+{
+ "retCode": 0,
+ "retMsg": "OK",
+ "result": {
+ "category": "option",
+ "nextPageCursor": "",
+ "list": [
+ {
+ "symbol": "ETH-3JAN23-1250-P",
+ "status": "Trading",
+ "baseCoin": "ETH",
+ "quoteCoin": "USD",
+ "settleCoin": "USDC",
+ "optionsType": "Put",
+ "launchTime": "1672560000000",
+ "deliveryTime": "1672732800000",
+ "deliveryFeeRate": "0.00015",
+ "priceFilter": {
+ "minPrice": "0.1",
+ "maxPrice": "10000000",
+ "tickSize": "0.1"
+ },
+ "lotSizeFilter": {
+ "maxOrderQty": "1500",
+ "minOrderQty": "0.1",
+ "qtyStep": "0.1"
+ }
+ }
+ ]
+ },
+ "retExtInfo": {},
+ "time": 1672712537130
+}
\ No newline at end of file
diff --git a/xchange-bybit/src/test/resources/getInstrumentSpot.json5 b/xchange-bybit/src/test/resources/getInstrumentSpot.json5
new file mode 100644
index 00000000000..04c53443ab0
--- /dev/null
+++ b/xchange-bybit/src/test/resources/getInstrumentSpot.json5
@@ -0,0 +1,30 @@
+{
+ "retCode": 0,
+ "retMsg": "OK",
+ "result": {
+ "category": "spot",
+ "list": [
+ {
+ "symbol": "BTCUSDT",
+ "baseCoin": "BTC",
+ "quoteCoin": "USDT",
+ "innovation": "0",
+ "status": "Trading",
+ "marginTrading": "both",
+ "lotSizeFilter": {
+ "basePrecision": "0.000001",
+ "quotePrecision": "0.00000001",
+ "minOrderQty": "0.000048",
+ "maxOrderQty": "71.73956243",
+ "minOrderAmt": "1",
+ "maxOrderAmt": "2000000"
+ },
+ "priceFilter": {
+ "tickSize": "0.01"
+ }
+ }
+ ]
+ },
+ "retExtInfo": {},
+ "time": 1672712468011
+}
\ No newline at end of file
diff --git a/xchange-bybit/src/test/resources/getOrderDetailsLinear.json5 b/xchange-bybit/src/test/resources/getOrderDetailsLinear.json5
new file mode 100644
index 00000000000..f6078291770
--- /dev/null
+++ b/xchange-bybit/src/test/resources/getOrderDetailsLinear.json5
@@ -0,0 +1,55 @@
+{
+ "retCode": 0,
+ "retMsg": "OK",
+ "result": {
+ "list": [
+ {
+ "orderId": "fd4300ae-7847-404e-b947-b46980a4d140",
+ "orderLinkId": "test-000005",
+ "blockTradeId": "",
+ "symbol": "ETHUSDT",
+ "price": "1600.00",
+ "qty": "0.10",
+ "side": "Buy",
+ "isLeverage": "",
+ "positionIdx": 1,
+ "orderStatus": "New",
+ "cancelType": "UNKNOWN",
+ "rejectReason": "EC_NoError",
+ "avgPrice": "0",
+ "leavesQty": "0.10",
+ "leavesValue": "160",
+ "cumExecQty": "0.00",
+ "cumExecValue": "0",
+ "cumExecFee": "0",
+ "timeInForce": "GTC",
+ "orderType": "Limit",
+ "stopOrderType": "UNKNOWN",
+ "orderIv": "",
+ "triggerPrice": "0.00",
+ "takeProfit": "2500.00",
+ "stopLoss": "1500.00",
+ "tpTriggerBy": "LastPrice",
+ "slTriggerBy": "LastPrice",
+ "triggerDirection": 0,
+ "triggerBy": "UNKNOWN",
+ "lastPriceOnCreated": "",
+ "reduceOnly": false,
+ "closeOnTrigger": false,
+ "smpType": "None",
+ "smpGroup": 0,
+ "smpOrderId": "",
+ "tpslMode": "Full",
+ "tpLimitPrice": "",
+ "slLimitPrice": "",
+ "placeType": "",
+ "createdTime": "1684738540559",
+ "updatedTime": "1684738540561"
+ }
+ ],
+ "nextPageCursor": "page_args%3Dfd4300ae-7847-404e-b947-b46980a4d140%26symbol%3D6%26",
+ "category": "linear"
+ },
+ "retExtInfo": {},
+ "time": 1684765770483
+}
\ No newline at end of file
diff --git a/xchange-bybit/src/test/resources/getOrderDetailsSpot.json5 b/xchange-bybit/src/test/resources/getOrderDetailsSpot.json5
new file mode 100644
index 00000000000..a03f5092c78
--- /dev/null
+++ b/xchange-bybit/src/test/resources/getOrderDetailsSpot.json5
@@ -0,0 +1,52 @@
+{
+ "retCode": 0,
+ "retMsg": "OK",
+ "result": {
+ "nextPageCursor": "page_args%3Dfd4300ae-7847-404e-b947-b46980a4d140%26symbol%3D6%26",
+ "category": "spot",
+ "list": [
+ {
+ "symbol": "ETHUSDT",
+ "orderType": "Market",
+ "orderLinkId": "test-000005",
+ "orderId": "fd4300ae-7847-404e-b947-b46980a4d140",
+ "cancelType": "UNKNOWN",
+ "avgPrice": "25905.97",
+ "stopOrderType": "",
+ "lastPriceOnCreated": "",
+ "orderStatus": "PartiallyFilledCanceled",
+ "takeProfit": "",
+ "cumExecValue": "19.99940884",
+ "smpType": "None",
+ "triggerDirection": 0,
+ "blockTradeId": "",
+ "isLeverage": "0",
+ "rejectReason": "EC_CancelForNoFullFill",
+ "price": "0",
+ "orderIv": "",
+ "createdTime": "1684738540559",
+ "tpTriggerBy": "",
+ "positionIdx": 0,
+ "timeInForce": "IOC",
+ "leavesValue": "0.00059116",
+ "updatedTime": "1684738540561",
+ "side": "Buy",
+ "smpGroup": 0,
+ "triggerPrice": "0.00",
+ "cumExecFee": "0.000000772",
+ "leavesQty": "0.000000",
+ "slTriggerBy": "",
+ "closeOnTrigger": false,
+ "placeType": "",
+ "cumExecQty": "0.000772",
+ "reduceOnly": false,
+ "qty": "20.000000",
+ "stopLoss": "",
+ "smpOrderId": "",
+ "triggerBy": ""
+ }
+ ]
+ },
+ "retExtInfo": {},
+ "time": 1694634580983
+}
diff --git a/xchange-bybit/src/test/resources/getSymbols.json5 b/xchange-bybit/src/test/resources/getSymbols.json5
deleted file mode 100644
index 1a442c1b100..00000000000
--- a/xchange-bybit/src/test/resources/getSymbols.json5
+++ /dev/null
@@ -1,63 +0,0 @@
-{
- 'ret_code': 0,
- 'ret_msg': 'OK',
- 'ext_code': '',
- 'ext_info': '',
- 'result': [
- {
- 'name': 'BTCUSDT',
- 'alias': 'BTCUSDT',
- 'status': 'Trading',
- 'base_currency': 'BTC',
- 'quote_currency': 'USDT',
- 'price_scale': 2,
- 'taker_fee': '0.0006',
- 'maker_fee': '0.0001',
- 'funding_interval': 480,
- 'leverage_filter': {
- 'min_leverage': 1,
- 'max_leverage': 100,
- 'leverage_step': '0.01'
- },
- 'price_filter': {
- 'min_price': '0.5',
- 'max_price': '999999',
- 'tick_size': '0.5'
- },
- 'lot_size_filter': {
- 'max_trading_qty': 20,
- 'min_trading_qty': 0.001,
- 'qty_step': 0.001,
- 'post_only_max_trading_qty': '100'
- }
- },
- {
- 'name': 'ETHUSDT',
- 'alias': 'ETHUSDT',
- 'status': 'Trading',
- 'base_currency': 'ETH',
- 'quote_currency': 'USDT',
- 'price_scale': 2,
- 'taker_fee': '0.0006',
- 'maker_fee': '0.0001',
- 'funding_interval': 480,
- 'leverage_filter': {
- 'min_leverage': 1,
- 'max_leverage': 100,
- 'leverage_step': '0.01'
- },
- 'price_filter': {
- 'min_price': '0.05',
- 'max_price': '99999.9',
- 'tick_size': '0.05'
- },
- 'lot_size_filter': {
- 'max_trading_qty': 1000,
- 'min_trading_qty': 0.01,
- 'qty_step': 0.01,
- 'post_only_max_trading_qty': '5000'
- }
- }
- ],
- 'time_now': '1657475395.487439'
-}
\ No newline at end of file
diff --git a/xchange-bybit/src/test/resources/getTicker.json5 b/xchange-bybit/src/test/resources/getTicker.json5
deleted file mode 100644
index 57d24add04c..00000000000
--- a/xchange-bybit/src/test/resources/getTicker.json5
+++ /dev/null
@@ -1,37 +0,0 @@
-{
- 'ret_code': 0,
- 'ret_msg': 'OK',
- 'ext_code': '',
- 'ext_info': '',
- 'result': [
- {
- 'symbol': 'BTCUSDT',
- 'bid_price': '21323',
- 'ask_price': '21334',
- 'last_price': '21333.00',
- 'last_tick_direction': 'PlusTick',
- 'prev_price_24h': '21670.00',
- 'price_24h_pcnt': '-0.015551',
- 'high_price_24h': '22024.50',
- 'low_price_24h': '21120.00',
- 'prev_price_1h': '21307.00',
- 'price_1h_pcnt': '0.00122',
- 'mark_price': '21331.00',
- 'index_price': '21334.53',
- 'open_interest': 16028.75,
- 'open_value': '0.00',
- 'total_turnover': '38884574628.30',
- 'turnover_24h': '216158761.48',
- 'total_volume': 9588193.5,
- 'volume_24h': 10028.87,
- 'funding_rate': '0.0001',
- 'predicted_funding_rate': '0.0001',
- 'next_funding_time': '2022-07-10T16:00:00Z',
- 'countdown_hour': 7,
- 'delivery_fee_rate': '',
- 'predicted_delivery_price': '',
- 'delivery_time': ''
- }
- ],
- 'time_now': '1657444151.611671'
-}
diff --git a/xchange-bybit/src/test/resources/getTickerInverse.json5 b/xchange-bybit/src/test/resources/getTickerInverse.json5
new file mode 100644
index 00000000000..69684c5ffd8
--- /dev/null
+++ b/xchange-bybit/src/test/resources/getTickerInverse.json5
@@ -0,0 +1,37 @@
+{
+ "retCode": 0,
+ "retMsg": "OK",
+ "result": {
+ "category": "inverse",
+ "list": [
+ {
+ "symbol": "BTCUSD",
+ "lastPrice": "16597.00",
+ "indexPrice": "16598.54",
+ "markPrice": "16596.00",
+ "prevPrice24h": "16464.50",
+ "price24hPcnt": "0.008047",
+ "highPrice24h": "30912.50",
+ "lowPrice24h": "15700.00",
+ "prevPrice1h": "16595.50",
+ "openInterest": "373504107",
+ "openInterestValue": "22505.67",
+ "turnover24h": "2352.94950046",
+ "volume24h": "49337318",
+ "fundingRate": "-0.001034",
+ "nextFundingTime": "1672387200000",
+ "predictedDeliveryPrice": "",
+ "basisRate": "",
+ "deliveryFeeRate": "",
+ "deliveryTime": "0",
+ "ask1Size": "1",
+ "bid1Price": "16596.00",
+ "ask1Price": "16597.50",
+ "bid1Size": "1",
+ "basis": ""
+ }
+ ]
+ },
+ "retExtInfo": {},
+ "time": 1672376496682
+}
\ No newline at end of file
diff --git a/xchange-bybit/src/test/resources/getTickerOption.json5 b/xchange-bybit/src/test/resources/getTickerOption.json5
new file mode 100644
index 00000000000..33250ff6cb8
--- /dev/null
+++ b/xchange-bybit/src/test/resources/getTickerOption.json5
@@ -0,0 +1,38 @@
+{
+ "retCode": 0,
+ "retMsg": "OK",
+ "result": {
+ "category": "option",
+ "list": [
+ {
+ "symbol": "BTC-30DEC22-18000-C",
+ "bid1Price": "0",
+ "bid1Size": "0",
+ "bid1Iv": "0",
+ "ask1Price": "435",
+ "ask1Size": "0.66",
+ "ask1Iv": "5",
+ "lastPrice": "435",
+ "highPrice24h": "435",
+ "lowPrice24h": "165",
+ "markPrice": "0.00000009",
+ "indexPrice": "16600.55",
+ "markIv": "0.7567",
+ "underlyingPrice": "16590.42",
+ "openInterest": "6.3",
+ "turnover24h": "2482.73",
+ "volume24h": "0.15",
+ "totalVolume": "99",
+ "totalTurnover": "1967653",
+ "delta": "0.00000001",
+ "gamma": "0.00000001",
+ "vega": "0.00000004",
+ "theta": "-0.00000152",
+ "predictedDeliveryPrice": "0",
+ "change24h": "86"
+ }
+ ]
+ },
+ "retExtInfo": {},
+ "time": 1672376592395
+}
\ No newline at end of file
diff --git a/xchange-bybit/src/test/resources/getTickerSpot.json5 b/xchange-bybit/src/test/resources/getTickerSpot.json5
new file mode 100644
index 00000000000..d7870658e7e
--- /dev/null
+++ b/xchange-bybit/src/test/resources/getTickerSpot.json5
@@ -0,0 +1,26 @@
+{
+ "retCode": 0,
+ "retMsg": "OK",
+ "result": {
+ "category": "spot",
+ "list": [
+ {
+ "symbol": "BTCUSDT",
+ "bid1Price": "20517.96",
+ "bid1Size": "2",
+ "ask1Price": "20527.77",
+ "ask1Size": "1.862172",
+ "lastPrice": "20533.13",
+ "prevPrice24h": "20393.48",
+ "price24hPcnt": "0.0068",
+ "highPrice24h": "21128.12",
+ "lowPrice24h": "20318.89",
+ "turnover24h": "243765620.65899866",
+ "volume24h": "11801.27771",
+ "usdIndexPrice": "20784.12009279"
+ }
+ ]
+ },
+ "retExtInfo": {},
+ "time": 1673859087947
+}
\ No newline at end of file
diff --git a/xchange-bybit/src/test/resources/getWalletBalance.json5 b/xchange-bybit/src/test/resources/getWalletBalance.json5
new file mode 100644
index 00000000000..7da7b5e1300
--- /dev/null
+++ b/xchange-bybit/src/test/resources/getWalletBalance.json5
@@ -0,0 +1,44 @@
+{
+ "retCode": 0,
+ "retMsg": "OK",
+ "result": {
+ "list": [
+ {
+ "totalEquity": "3.31216591",
+ "accountIMRate": "0",
+ "totalMarginBalance": "3.00326056",
+ "totalInitialMargin": "0",
+ "accountType": "UNIFIED",
+ "totalAvailableBalance": "3.00326056",
+ "accountMMRate": "0",
+ "totalPerpUPL": "0",
+ "totalWalletBalance": "3.00326056",
+ "accountLTV": "0",
+ "totalMaintenanceMargin": "0",
+ "coin": [
+ {
+ "availableToBorrow": "3",
+ "bonus": "0",
+ "accruedInterest": "0",
+ "availableToWithdraw": "0",
+ "totalOrderIM": "0",
+ "equity": "0",
+ "totalPositionMM": "0",
+ "usdValue": "0",
+ "unrealisedPnl": "0",
+ "collateralSwitch": true,
+ "borrowAmount": "0.0",
+ "totalPositionIM": "0",
+ "walletBalance": "0",
+ "cumRealisedPnl": "0",
+ "locked": "0",
+ "marginCollateral": true,
+ "coin": "BTC"
+ }
+ ]
+ }
+ ]
+ },
+ "retExtInfo": {},
+ "time": 1690872862481
+}
\ No newline at end of file
diff --git a/xchange-coinbasepro/src/main/java/org/knowm/xchange/coinbasepro/CoinbasePro.java b/xchange-coinbasepro/src/main/java/org/knowm/xchange/coinbasepro/CoinbasePro.java
index a6b4b430e97..b93a212b0b0 100644
--- a/xchange-coinbasepro/src/main/java/org/knowm/xchange/coinbasepro/CoinbasePro.java
+++ b/xchange-coinbasepro/src/main/java/org/knowm/xchange/coinbasepro/CoinbasePro.java
@@ -4,7 +4,6 @@
import com.fasterxml.jackson.databind.JsonNode;
import java.io.IOException;
import java.util.Date;
-import java.util.List;
import java.util.Map;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE;
@@ -20,7 +19,9 @@
import org.knowm.xchange.coinbasepro.dto.CoinbaseProException;
import org.knowm.xchange.coinbasepro.dto.CoinbaseProTrades;
import org.knowm.xchange.coinbasepro.dto.CoinbaseProTransfers;
+import org.knowm.xchange.coinbasepro.dto.account.CoinbaseProAccount;
import org.knowm.xchange.coinbasepro.dto.account.CoinbaseProFee;
+import org.knowm.xchange.coinbasepro.dto.account.CoinbaseProLedger;
import org.knowm.xchange.coinbasepro.dto.account.CoinbaseProSendMoneyRequest;
import org.knowm.xchange.coinbasepro.dto.account.CoinbaseProWithdrawCryptoResponse;
import org.knowm.xchange.coinbasepro.dto.account.CoinbaseProWithdrawFundsRequest;
@@ -32,15 +33,14 @@
import org.knowm.xchange.coinbasepro.dto.marketdata.CoinbaseProProductTicker;
import org.knowm.xchange.coinbasepro.dto.marketdata.CoinbaseProStats;
import org.knowm.xchange.coinbasepro.dto.marketdata.CoinbaseProTrade;
-import org.knowm.xchange.coinbasepro.dto.trade.CoinbaseProAccount;
-import org.knowm.xchange.coinbasepro.dto.trade.CoinbaseProAccountAddress;
+import org.knowm.xchange.coinbasepro.dto.trade.CoinbaseProWallet;
+import org.knowm.xchange.coinbasepro.dto.trade.CoinbaseProWalletAddress;
import org.knowm.xchange.coinbasepro.dto.trade.CoinbaseProFill;
import org.knowm.xchange.coinbasepro.dto.trade.CoinbaseProIdResponse;
import org.knowm.xchange.coinbasepro.dto.trade.CoinbaseProOrder;
import org.knowm.xchange.coinbasepro.dto.trade.CoinbaseProPlaceOrder;
import org.knowm.xchange.coinbasepro.dto.trade.CoinbaseProSendMoneyResponse;
import org.knowm.xchange.utils.DateUtils;
-import si.mazi.rescu.HttpStatusIOException;
import si.mazi.rescu.ParamsDigest;
@Path("/")
@@ -110,13 +110,23 @@ CoinbaseProCandle[] getHistoricalCandles(
/** Authenticated calls */
@GET
@Path("accounts")
- org.knowm.xchange.coinbasepro.dto.account.CoinbaseProAccount[] getAccounts(
+ CoinbaseProAccount[] getAccounts(
@HeaderParam("CB-ACCESS-KEY") String apiKey,
@HeaderParam("CB-ACCESS-SIGN") ParamsDigest signer,
@HeaderParam("CB-ACCESS-TIMESTAMP") long timestamp,
@HeaderParam("CB-ACCESS-PASSPHRASE") String passphrase)
throws CoinbaseProException, IOException;
+ @GET
+ @Path("accounts/{account_id}")
+ CoinbaseProAccount getAccountById(
+ @HeaderParam("CB-ACCESS-KEY") String apiKey,
+ @HeaderParam("CB-ACCESS-SIGN") ParamsDigest signer,
+ @HeaderParam("CB-ACCESS-TIMESTAMP") long timestamp,
+ @HeaderParam("CB-ACCESS-PASSPHRASE") String passphrase,
+ @PathParam("account_id") String accountId)
+ throws CoinbaseProException, IOException;
+
@GET
@Path("fees")
CoinbaseProFee getFees(
@@ -192,17 +202,22 @@ CoinbaseProOrder getOrder(
throws CoinbaseProException, IOException;
/**
- * @param apiKey for account
- * @param signer for account
- * @param timestamp of message
- * @param passphrase for account
- * @param tradeIdAfter Return trades before this tradeId.
- * @param tradeIdBefore Return trades after this tradeId.
- * @param orderId to get fills for
- * @param productId to get fills for
- * @return fill array
- * @throws CoinbaseProException when exchange throws exception
- * @throws IOException when connection issue arises
+ * Get a list of fills. A fill is a partial or complete match on a specific order.
+ * @param apiKey
+ * @param signer
+ * @param timestamp
+ * @param passphrase
+ * @param orderId
+ * @param productId
+ * @param limit
+ * @param tradeIdBefore
+ * @param tradeIdAfter
+ * @param marketType
+ * @param startDate
+ * @param endDate
+ * @return CoinbasePagedResponse
+ * @throws CoinbaseProException
+ * @throws IOException
*/
@GET
@Path("fills")
@@ -211,12 +226,15 @@ CoinbasePagedResponse getFills(
@HeaderParam("CB-ACCESS-SIGN") ParamsDigest signer,
@HeaderParam("CB-ACCESS-TIMESTAMP") long timestamp,
@HeaderParam("CB-ACCESS-PASSPHRASE") String passphrase,
- @QueryParam("after") Integer tradeIdAfter,
- @QueryParam("before") Integer tradeIdBefore,
- @QueryParam("limit") Integer limit,
@QueryParam("order_id") String orderId,
- @QueryParam("product_id") String productId)
- throws CoinbaseProException, IOException;
+ @QueryParam("product_id") String productId,
+ @QueryParam("limit") Integer limit,
+ @QueryParam("before") Integer tradeIdBefore,
+ @QueryParam("after") Integer tradeIdAfter,
+ @QueryParam("market_type") String marketType,
+ @QueryParam("start_date") String startDate,
+ @QueryParam("end_date") String endDate
+ ) throws CoinbaseProException, IOException;
@POST
@Path("accounts/{account_id}/transactions")
@@ -233,41 +251,55 @@ CoinbaseProSendMoneyResponse sendMoney(
@GET
@Path("accounts/{account_id}/ledger")
@Consumes(MediaType.APPLICATION_JSON)
- List