diff --git a/README.md b/README.md
index 5ca9870..cd8fe6f 100644
--- a/README.md
+++ b/README.md
@@ -40,29 +40,25 @@ Maven Example
io.github.wuhewuhe
bybit-java-api
- 1.2.3
+ 1.2.4
```
Gradle Example
```java
-implementation group: 'io.github.wuhewuhe', name: 'bybit-java-api', version: '1.2.3'
+implementation group: 'io.github.wuhewuhe', name: 'bybit-java-api', version: '1.2.4'
```
Furthermore, build tool, please check [sonar type central repository](https://central.sonatype.com/artifact/io.github.wuhewuhe/bybit-java-api/1.2.3)
## Release-Notes
-### HTTP Sync & Async Request
-- Position new endpoints: Move Positions and Get Move Positions History
-- Account new endpoint: Batch Set Collateral Coin
-- TradeOrderRequest add a new parameter: marketUnit
+### Websockets
+- Add WebSocketMessage handler class to all public and private channels
### Improvements
-- Fix Switch Position Mode Issue
+- public and private websocket channel set message handler
### Change Log
-- C:\Net\GithubProjects\open-api-sdk\bybit-java-api
-- Set Tp/SL and Set Risk Limit endpoints are deprecated
-- GetExecutionList move from PositionService to TradeService and rename to GetTradeHistory
-
+- Spot Margin Trade endpoints are decrypted for classical users
+-
## Usage
Note: Replace placeholders (like YOUR_API_KEY, links, or other details) with the actual information. You can also customize this template to better fit the actual state and details of your Java API.
### HttP Client Factory & Websocket Client
@@ -224,16 +220,42 @@ client.getPublicChannelStream(List.of("orderbook.50.BTCUSDT"), BybitApiConfig.V5
client.getPublicChannelStream(List.of("orderbook.50.BTCUSDT","orderbook.1.ETHUSDT"), BybitApiConfig.V5_PUBLIC_LINEAR);
```
+- Ticker Subscribe
+```java
+var client = BybitApiClientFactory.newInstance(BybitApiConfig.STREAM_MAINNET_DOMAIN, true).newWebsocketClient();
+
+client.setMessageHandler(message -> {
+ var tickerData = (new ObjectMapper()).readValue(message, WebSocketTickerMessage.class);
+ // Process message data here
+ System.out.println("Websocket Message Data: " + tickerData.getData().toString());
+});
+
+// Ticker
+client.getPublicChannelStream(List.of("tickers.BTCUSDT"), BybitApiConfig.V5_PUBLIC_LINEAR);
+```
+
### Websocket private channel
-- Order Subscribe
+- Position Subscribe
```java
-var client = BybitApiClientFactory.newInstance("YOUR_API_KEY", "YOUR_API_SECRET", BybitApiConfig.STREAM_TESTNET_DOMAIN).newWebsocketClient(5, "60s", (message) -> System.out.println("Handle message :" + message));
+var client = BybitApiClientFactory.newInstance("YOUR_API_KEY", "YOUR_API_SECRET", BybitApiConfig.STREAM_TESTNET_DOMAIN).newWebsocketClient();
+
// Position
-// client.getOrderBookStream(List.of("position.linear"), BybitApiConfig.V5_PRIVATE);
+client.getPrivateChannelStream(List.of("position"), BybitApiConfig.V5_PRIVATE);
+```
+
+- Order Channel active Message Handler & Max Alive Time & Ping Interval
+```java
+var client = BybitApiClientFactory.newInstance("YOUR_API_KEY", "YOUR_API_SECRET", BybitApiConfig.STREAM_TESTNET_DOMAIN, true)
+ .newWebsocketClient(5, "60s", (message) -> {
+ var orderMessage = (new ObjectMapper()).readValue(message, WebSocketOrderMessage.class);
+ // Process message data here
+ System.out.println("Websocket Message Data: " + orderMessage.getData().toString());
+ });
// Order
client.getPrivateChannelStream(List.of("order"), BybitApiConfig.V5_PRIVATE);
```
+
## Contact
For support, join our Bybit API community on [Telegram](https://t.me/Bybitapi).
diff --git a/pom.xml b/pom.xml
index 0b8f3ff..32d5101 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
io.github.wuhewuhe
bybit-java-api
- 1.2.3
+ 1.2.4-SNAPSHOT
bybit-java-api
https://github.com/wuhewuhe/bybit-java-api
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/CoinData.java b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/CoinData.java
new file mode 100644
index 0000000..4c0098c
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/CoinData.java
@@ -0,0 +1,30 @@
+package com.bybit.api.client.domain.websocket_message.private_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class CoinData {
+ private String coin;
+ private String equity;
+ private String usdValue;
+ private String walletBalance;
+ private String free;
+ private String locked;
+ private String spotHedgingQty;
+ private String borrowAmount;
+ private String availableToBorrow;
+ private String availableToWithdraw;
+ private String accruedInterest;
+ private String totalOrderIM;
+ private String totalPositionIM;
+ private String totalPositionMM;
+ private String unrealisedPnl;
+ private String cumRealisedPnl;
+ private String bonus;
+ private Boolean collateralSwitch;
+ private Boolean marginCollateral;
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/ExecutionData.java b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/ExecutionData.java
new file mode 100644
index 0000000..19ff812
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/ExecutionData.java
@@ -0,0 +1,40 @@
+package com.bybit.api.client.domain.websocket_message.private_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ExecutionData {
+ private String category;
+ private String symbol;
+ private String isLeverage;
+ private String orderId;
+ private String orderLinkId;
+ private String side;
+ private String orderPrice;
+ private String orderQty;
+ private String leavesQty;
+ private String createType;
+ private String orderType;
+ private String stopOrderType;
+ private String execFee;
+ private String execId;
+ private String execPrice;
+ private String execQty;
+ private String execType;
+ private String execValue;
+ private String execTime;
+ private Boolean isMaker;
+ private String feeRate;
+ private String tradeIv;
+ private String markIv;
+ private String markPrice;
+ private String indexPrice;
+ private String underlyingPrice;
+ private String blockTradeId;
+ private String closedSize;
+ private Long seq;
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/GreekData.java b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/GreekData.java
new file mode 100644
index 0000000..1d09b3e
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/GreekData.java
@@ -0,0 +1,16 @@
+package com.bybit.api.client.domain.websocket_message.private_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class GreekData {
+ private String baseCoin;
+ private String totalDelta;
+ private String totalGamma;
+ private String totalVega;
+ private String totalTheta;
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/OrderData.java b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/OrderData.java
new file mode 100644
index 0000000..1cd6613
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/OrderData.java
@@ -0,0 +1,57 @@
+package com.bybit.api.client.domain.websocket_message.private_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class OrderData {
+ private String category;
+ private String orderId;
+ private String orderLinkId;
+ private String isLeverage;
+ private String blockTradeId;
+ private String symbol;
+ private String price;
+ private String qty;
+ private String side;
+ private Integer positionIdx;
+ private String orderStatus;
+ private String createType;
+ private String cancelType;
+ private String rejectReason;
+ private String avgPrice;
+ private String leavesQty;
+ private String leavesValue;
+ private String cumExecQty;
+ private String cumExecValue;
+ private String cumExecFee;
+ private String feeCurrency;
+ private String timeInForce;
+ private String orderType;
+ private String stopOrderType;
+ private String ocoTriggerType;
+ private String orderIv;
+ private String marketUnit;
+ private String triggerPrice;
+ private String takeProfit;
+ private String stopLoss;
+ private String tpslMode;
+ private String tpLimitPrice;
+ private String slLimitPrice;
+ private String tpTriggerBy;
+ private String slTriggerBy;
+ private Integer triggerDirection;
+ private String triggerBy;
+ private String lastPriceOnCreated;
+ private Boolean reduceOnly;
+ private Boolean closeOnTrigger;
+ private String placeType;
+ private String smpType;
+ private Integer smpGroup;
+ private String smpOrderId;
+ private String createdTime;
+ private String updatedTime;
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/PositionData.java b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/PositionData.java
new file mode 100644
index 0000000..9b07bed
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/PositionData.java
@@ -0,0 +1,43 @@
+package com.bybit.api.client.domain.websocket_message.private_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class PositionData {
+ private String category;
+ private String symbol;
+ private String side;
+ private String size;
+ private Integer positionIdx;
+ private Integer tradeMode;
+ private String positionValue;
+ private Integer riskId;
+ private String riskLimitValue;
+ private String entryPrice;
+ private String markPrice;
+ private String leverage;
+ private String positionBalance;
+ private Integer autoAddMargin;
+ private String positionMM;
+ private String positionIM;
+ private String liqPrice;
+ private String bustPrice;
+ private String tpslMode;
+ private String takeProfit;
+ private String stopLoss;
+ private String trailingStop;
+ private String unrealisedPnl;
+ private String cumRealisedPnl;
+ private String positionStatus;
+ private Integer adlRankIndicator;
+ private Boolean isReduceOnly;
+ private String mmrSysUpdatedTime;
+ private String leverageSysUpdatedTime;
+ private String createdTime;
+ private String updatedTime;
+ private Long seq;
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/WalletData.java b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/WalletData.java
new file mode 100644
index 0000000..a151270
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/WalletData.java
@@ -0,0 +1,26 @@
+package com.bybit.api.client.domain.websocket_message.private_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class WalletData {
+ private String accountType;
+ private String accountLTV;
+ private String accountIMRate;
+ private String accountMMRate;
+ private String totalEquity;
+ private String totalWalletBalance;
+ private String totalMarginBalance;
+ private String totalAvailableBalance;
+ private String totalPerpUPL;
+ private String totalInitialMargin;
+ private String totalMaintenanceMargin;
+ private List coin;
+
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/WebSocketExecutionMessage.java b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/WebSocketExecutionMessage.java
new file mode 100644
index 0000000..bbe0c95
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/WebSocketExecutionMessage.java
@@ -0,0 +1,15 @@
+package com.bybit.api.client.domain.websocket_message.private_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class WebSocketExecutionMessage {
+ private String id;
+ private String topic;
+ private Long creationTime;
+ private List data; // Assuming 'data' is an array of KlineData objects
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/WebSocketGreekMessage.java b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/WebSocketGreekMessage.java
new file mode 100644
index 0000000..fde28a5
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/WebSocketGreekMessage.java
@@ -0,0 +1,15 @@
+package com.bybit.api.client.domain.websocket_message.private_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class WebSocketGreekMessage {
+ private String id;
+ private String topic;
+ private Long creationTime;
+ private List data; // Assuming 'data' is an array of KlineData objects
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/WebSocketOrderMessage.java b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/WebSocketOrderMessage.java
new file mode 100644
index 0000000..e983f69
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/WebSocketOrderMessage.java
@@ -0,0 +1,16 @@
+package com.bybit.api.client.domain.websocket_message.private_channel;
+
+import com.bybit.api.client.domain.websocket_message.public_channel.KlineData;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class WebSocketOrderMessage {
+ private String id;
+ private String topic;
+ private Long creationTime;
+ private List data; // Assuming 'data' is an array of KlineData objects
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/WebSocketPositionMessage.java b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/WebSocketPositionMessage.java
new file mode 100644
index 0000000..e1e39a9
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/WebSocketPositionMessage.java
@@ -0,0 +1,15 @@
+package com.bybit.api.client.domain.websocket_message.private_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class WebSocketPositionMessage {
+ private String id;
+ private String topic;
+ private Long creationTime;
+ private List data; // Assuming 'data' is an array of KlineData objects
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/WebSocketWalletMessage.java b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/WebSocketWalletMessage.java
new file mode 100644
index 0000000..9047ede
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/private_channel/WebSocketWalletMessage.java
@@ -0,0 +1,15 @@
+package com.bybit.api.client.domain.websocket_message.private_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class WebSocketWalletMessage {
+ private String id;
+ private String topic;
+ private Long creationTime;
+ private List data; // Assuming 'data' is an array of KlineData objects
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/KlineData.java b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/KlineData.java
new file mode 100644
index 0000000..3e47109
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/KlineData.java
@@ -0,0 +1,22 @@
+package com.bybit.api.client.domain.websocket_message.public_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class KlineData {
+ private Long start;
+ private Long end;
+ private String interval;
+ private String open;
+ private String close;
+ private String high;
+ private String low;
+ private String volume;
+ private String turnover;
+ private Boolean confirm;
+ private Long timestamp;
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/LiquidationData.java b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/LiquidationData.java
new file mode 100644
index 0000000..066d2d2
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/LiquidationData.java
@@ -0,0 +1,16 @@
+package com.bybit.api.client.domain.websocket_message.public_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class LiquidationData {
+ private Long updateTime;
+ private String symbol;
+ private String side;
+ private String size;
+ private String price;
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/LtKlineData.java b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/LtKlineData.java
new file mode 100644
index 0000000..92b9cae
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/LtKlineData.java
@@ -0,0 +1,20 @@
+package com.bybit.api.client.domain.websocket_message.public_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class LtKlineData {
+ private Long start;
+ private Long end;
+ private String interval;
+ private String open;
+ private String close;
+ private String high;
+ private String low;
+ private Boolean confirm;
+ private Long timestamp;
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/LtTicketData.java b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/LtTicketData.java
new file mode 100644
index 0000000..c327dbe
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/LtTicketData.java
@@ -0,0 +1,17 @@
+package com.bybit.api.client.domain.websocket_message.public_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class LtTicketData {
+ private String symbol;
+ private String price24hPcnt;
+ private String lastPrice;
+ private String prevPrice24h;
+ private String highPrice24h;
+ private String lowPrice24h;
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/NavData.java b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/NavData.java
new file mode 100644
index 0000000..69570e3
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/NavData.java
@@ -0,0 +1,19 @@
+package com.bybit.api.client.domain.websocket_message.public_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class NavData {
+ private Long time;
+ private String symbol;
+ private String nav;
+ private String basketPosition;
+ private String leverage;
+ private String basketLoan;
+ private String circulation;
+ private String basket;
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/PublicOrderBookData.java b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/PublicOrderBookData.java
new file mode 100644
index 0000000..166b6f7
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/PublicOrderBookData.java
@@ -0,0 +1,19 @@
+package com.bybit.api.client.domain.websocket_message.public_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class PublicOrderBookData {
+ private String s; // Symbol name
+ private List> b; // Bids
+ private List> a; // Asks
+ private Long u; // Update ID
+ private Long seq; // Sequence
+ private Long cts; // Timestamp from the match engine
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/PublicTickerData.java b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/PublicTickerData.java
new file mode 100644
index 0000000..591e1bb
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/PublicTickerData.java
@@ -0,0 +1,102 @@
+package com.bybit.api.client.domain.websocket_message.public_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class PublicTickerData {
+ private String symbol;
+ private String tickDirection;
+ private String bidPrice;
+ private String bidSize;
+ private String bidIv;
+ private String askPrice;
+ private String askSize;
+ private String askIv;
+ private String lastPrice;
+ private String highPrice24h;
+ private String lowPrice24h;
+ private String prevPrice24h;
+ private String volume24h;
+ private String turnover24h;
+ private String price24hPcnt;
+ private String usdIndexPrice;
+ private String underlyingPrice;
+ private String markPrice;
+ private String indexPrice;
+ private String markPriceIv;
+ private String openInterest;
+ private String openInterestValue;
+ private String totalVolume;
+ private String totalTurnover;
+ private String nextFundingTime;
+ private String fundingRate;
+ private String bid1Price;
+ private String bid1Size;
+ private String ask1Price;
+ private String ask1Size;
+ private String delta; // Option
+ private String gamma; // Option
+ private String vega; // Option
+ private String theta; // Option
+ private String deliveryTime; // Linear and Inverse
+ private String basisRate; // Linear and Inverse
+ private String deliveryFeeRate; // Linear and Inverse
+ private String predictedDeliveryPrice;
+ private String change24h;
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("PublicTickerData{");
+
+ if (symbol != null) sb.append("symbol='").append(symbol).append("', ");
+ if (tickDirection != null) sb.append("tickDirection='").append(tickDirection).append("', ");
+ if (bidPrice != null) sb.append("bidPrice='").append(bidPrice).append("', ");
+ if (bidSize != null) sb.append("bidSize='").append(bidSize).append("', ");
+ if (bidIv != null) sb.append("bidIv='").append(bidIv).append("', ");
+ if (askPrice != null) sb.append("askPrice='").append(askPrice).append("', ");
+ if (askSize != null) sb.append("askSize='").append(askSize).append("', ");
+ if (askIv != null) sb.append("askIv='").append(askIv).append("', ");
+ if (lastPrice != null) sb.append("lastPrice='").append(lastPrice).append("', ");
+ if (highPrice24h != null) sb.append("highPrice24h='").append(highPrice24h).append("', ");
+ if (lowPrice24h != null) sb.append("lowPrice24h='").append(lowPrice24h).append("', ");
+ if (prevPrice24h != null) sb.append("prevPrice24h='").append(prevPrice24h).append("', ");
+ if (volume24h != null) sb.append("volume24h='").append(volume24h).append("', ");
+ if (turnover24h != null) sb.append("turnover24h='").append(turnover24h).append("', ");
+ if (price24hPcnt != null) sb.append("price24hPcnt='").append(price24hPcnt).append("', ");
+ if (usdIndexPrice != null) sb.append("usdIndexPrice='").append(usdIndexPrice).append("', ");
+ if (underlyingPrice != null) sb.append("underlyingPrice='").append(underlyingPrice).append("', ");
+ if (markPrice != null) sb.append("markPrice='").append(markPrice).append("', ");
+ if (indexPrice != null) sb.append("indexPrice='").append(indexPrice).append("', ");
+ if (markPriceIv != null) sb.append("markPriceIv='").append(markPriceIv).append("', ");
+ if (openInterest != null) sb.append("openInterest='").append(openInterest).append("', ");
+ if (openInterestValue != null) sb.append("openInterestValue='").append(openInterestValue).append("', ");
+ if (totalVolume != null) sb.append("totalVolume='").append(totalVolume).append("', ");
+ if (totalTurnover != null) sb.append("totalTurnover='").append(totalTurnover).append("', ");
+ if (nextFundingTime != null) sb.append("nextFundingTime='").append(nextFundingTime).append("', ");
+ if (fundingRate != null) sb.append("fundingRate='").append(fundingRate).append("', ");
+ if (bid1Price != null) sb.append("bid1Price='").append(bid1Price).append("', ");
+ if (bid1Size != null) sb.append("bid1Size='").append(bid1Size).append("', ");
+ if (ask1Price != null) sb.append("ask1Price='").append(ask1Price).append("', ");
+ if (ask1Size != null) sb.append("ask1Size='").append(ask1Size).append("', ");
+ if (delta != null) sb.append("delta='").append(delta).append("', ");
+ if (gamma != null) sb.append("gamma='").append(gamma).append("', ");
+ if (vega != null) sb.append("vega='").append(vega).append("', ");
+ if (theta != null) sb.append("theta='").append(theta).append("', ");
+ if (deliveryTime != null) sb.append("deliveryTime='").append(deliveryTime).append("', ");
+ if (basisRate != null) sb.append("basisRate='").append(basisRate).append("', ");
+ if (deliveryFeeRate != null) sb.append("deliveryFeeRate='").append(deliveryFeeRate).append("', ");
+ if (predictedDeliveryPrice != null) sb.append("predictedDeliveryPrice='").append(predictedDeliveryPrice).append("', ");
+ if (change24h != null) sb.append("change24h='").append(change24h).append("'");
+
+ if (sb.length() > "PublicTickerData{".length()) {
+ sb.setLength(sb.length() - (sb.charAt(sb.length() - 2) == ',' ? 2 : 0)); // Remove last comma and space if present
+ }
+ sb.append("}");
+ return sb.toString();
+ }
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/TradeData.java b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/TradeData.java
new file mode 100644
index 0000000..92a092b
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/TradeData.java
@@ -0,0 +1,19 @@
+package com.bybit.api.client.domain.websocket_message.public_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class TradeData {
+ private Long T; // Timestamp of the order filled
+ private String s; // Symbol name
+ private String S; // Side of taker (Buy, Sell)
+ private String v; // Trade size
+ private String p; // Trade price
+ private String L; // Direction of price change
+ private String i; // Trade ID
+ private Boolean BT; // Whether it is a block trade order or not
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebSocketKlineMessage.java b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebSocketKlineMessage.java
new file mode 100644
index 0000000..05ad7de
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebSocketKlineMessage.java
@@ -0,0 +1,15 @@
+package com.bybit.api.client.domain.websocket_message.public_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class WebSocketKlineMessage {
+ private String topic;
+ private String type;
+ private Long ts;
+ private List data; // Assuming 'data' is an array of KlineData objects
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebSocketLiquidationMessage.java b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebSocketLiquidationMessage.java
new file mode 100644
index 0000000..8db56ea
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebSocketLiquidationMessage.java
@@ -0,0 +1,13 @@
+package com.bybit.api.client.domain.websocket_message.public_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class WebSocketLiquidationMessage {
+ private String topic;
+ private String type;
+ private Long ts;
+ private LiquidationData data; // Assuming 'data' is an array of KlineData objects
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebSocketLtKlineMessage.java b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebSocketLtKlineMessage.java
new file mode 100644
index 0000000..5c07baa
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebSocketLtKlineMessage.java
@@ -0,0 +1,15 @@
+package com.bybit.api.client.domain.websocket_message.public_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class WebSocketLtKlineMessage {
+ private String topic;
+ private String type;
+ private Long ts;
+ private List data; // Assuming 'data' is an array of LtKlineData objects
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebSocketLtTicketMessage.java b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebSocketLtTicketMessage.java
new file mode 100644
index 0000000..20affcc
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebSocketLtTicketMessage.java
@@ -0,0 +1,15 @@
+package com.bybit.api.client.domain.websocket_message.public_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class WebSocketLtTicketMessage {
+ private String topic;
+ private String type;
+ private Long ts;
+ private List data; // Assuming 'data' is an array of LtTicketData objects
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebSocketTickerMessage.java b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebSocketTickerMessage.java
new file mode 100644
index 0000000..6bd485f
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebSocketTickerMessage.java
@@ -0,0 +1,14 @@
+package com.bybit.api.client.domain.websocket_message.public_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class WebSocketTickerMessage {
+ private String topic;
+ private Long ts;
+ private String type;
+ private Long cs;
+ private PublicTickerData data;
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebSocketTradeMessage.java b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebSocketTradeMessage.java
new file mode 100644
index 0000000..4a412a1
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebSocketTradeMessage.java
@@ -0,0 +1,16 @@
+package com.bybit.api.client.domain.websocket_message.public_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class WebSocketTradeMessage {
+ private String id;
+ private String topic;
+ private String type;
+ private Long ts;
+ private List data;
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebsocketLtNavMessage.java b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebsocketLtNavMessage.java
new file mode 100644
index 0000000..6fb6c9d
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebsocketLtNavMessage.java
@@ -0,0 +1,15 @@
+package com.bybit.api.client.domain.websocket_message.public_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class WebsocketLtNavMessage {
+ private String topic;
+ private String type;
+ private Long ts;
+ private List data;
+}
diff --git a/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebsocketOrderbookMessage.java b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebsocketOrderbookMessage.java
new file mode 100644
index 0000000..adf4816
--- /dev/null
+++ b/src/main/java/com/bybit/api/client/domain/websocket_message/public_channel/WebsocketOrderbookMessage.java
@@ -0,0 +1,13 @@
+package com.bybit.api.client.domain.websocket_message.public_channel;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class WebsocketOrderbookMessage {
+ private String topic;
+ private String type;
+ private Long ts;
+ private PublicOrderBookData data;
+}
diff --git a/src/main/java/com/bybit/api/client/impl/BybitApiAsyncSpotMarginRestClientImpl.java b/src/main/java/com/bybit/api/client/impl/BybitApiAsyncSpotMarginRestClientImpl.java
index 09efd45..da98fe5 100644
--- a/src/main/java/com/bybit/api/client/impl/BybitApiAsyncSpotMarginRestClientImpl.java
+++ b/src/main/java/com/bybit/api/client/impl/BybitApiAsyncSpotMarginRestClientImpl.java
@@ -85,6 +85,7 @@ public void getUTASpotMarginTradeLeverageState(BybitApiCallback