Skip to content

Commit 5fbf783

Browse files
Merge pull request #475 from crypto-chassis/feat-bybit-v5
feat: upgrade bybit API from v3 to v5
2 parents 80174c8 + fa26678 commit 5fbf783

13 files changed

+503
-1369
lines changed

README.md

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# Announcement: We have upgraded bybit API from v3 to v5 due to bybit will discontinue v3 on August 31, 2024. We've moved derivatives support from bybit-derivatives to bybit and updated documentions accordingly (See #specify-instrument-type section). We've also added websocket balance/position realtime update support on bybit. In addition, please use bybit's Unified Trading Account (https://www.bybit.com/en/help-center/article/Introduction-to-Bybit-Unified-Trading-Account) for best API support. Thank you.
2+
13
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
24
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
35
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
@@ -35,6 +37,7 @@
3537
- [Override exchange urls](#override-exchange-urls)
3638
- [Complex request parameters](#complex-request-parameters-1)
3739
- [Send request by Websocket API](#send-request-by-websocket-api)
40+
- [Specify instrument type](#specify-instrument-type)
3841
- [FIX API](#fix-api)
3942
- [More Advanced Topics](#more-advanced-topics)
4043
- [Handle events in "immediate" vs. "batching" mode](#handle-events-in-immediate-vs-batching-mode)
@@ -56,8 +59,8 @@
5659
* Code closely follows Bloomberg's API: https://www.bloomberg.com/professional/support/api-library/.
5760
* It is ultra fast thanks to very careful optimizations: move semantics, regex optimization, locality of reference, lock contention minimization, etc.
5861
* Supported exchanges:
59-
* Market Data: ascendex, binance, binance-usds-futures, binance-coin-futures, binance-us, bitfinex, bitget, bitget-futures, bitmart, bitmex, bitstamp, bybit, bybit-derivatives, coinbase, cryptocom, deribit, erisx (Cboe Digital), gateio, gateio-perpetual-futures, gemini, huobi, huobi-usdt-swap, huobi-coin-swap, kraken, kraken-futures, kucoin, kucoin-futures, mexc, mexc-futures, okx, whitebit.
60-
* Execution Management: ascendex, binance, binance-usds-futures, binance-coin-futures, binance-us, bitfinex, bitget, bitget-futures, bitmart, bitmex, bitstamp, bybit, bybit-derivatives, coinbase, cryptocom, deribit, erisx (Cboe Digital), gateio, gateio-perpetual-futures, gemini, huobi, huobi-usdt-swap, huobi-coin-swap, kraken, kraken-futures, kucoin, kucoin-futures, mexc, okx.
62+
* Market Data: ascendex, binance, binance-usds-futures, binance-coin-futures, binance-us, bitfinex, bitget, bitget-futures, bitmart, bitmex, bitstamp, bybit, coinbase, cryptocom, deribit, erisx (Cboe Digital), gateio, gateio-perpetual-futures, gemini, huobi, huobi-usdt-swap, huobi-coin-swap, kraken, kraken-futures, kucoin, kucoin-futures, mexc, mexc-futures, okx, whitebit.
63+
* Execution Management: ascendex, binance, binance-usds-futures, binance-coin-futures, binance-us, bitfinex, bitget, bitget-futures, bitmart, bitmex, bitstamp, bybit, coinbase, cryptocom, deribit, erisx (Cboe Digital), gateio, gateio-perpetual-futures, gemini, huobi, huobi-usdt-swap, huobi-coin-swap, kraken, kraken-futures, kucoin, kucoin-futures, mexc, okx.
6164
* FIX: coinbase, gemini.
6265
* A spot market making application is provided as an end-to-end solution for liquidity providers.
6366
* A single order execution application is provided as an end-to-end solution for executing large orders.
@@ -792,6 +795,14 @@ request.appendParam({
792795
session.sendRequestByWebsocket(request);
793796
```
794797

798+
#### Specify instrument type
799+
Some exchanges (i.e. bybit) might need instrument type for `Subscription`. Use `Subscription`'s `setInstrumentType` method.
800+
```
801+
Subscription subscription("bybit", "BTCUSDT", "MARKET_DEPTH");
802+
subscription.setInstrumentType("spot");
803+
session.subscribe(subscription);
804+
```
805+
795806
### FIX API
796807

797808
**Objective:**

include/ccapi_cpp/ccapi_macro.h

+1-20
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,6 @@
136136
#ifndef CCAPI_EXCHANGE_NAME_BYBIT
137137
#define CCAPI_EXCHANGE_NAME_BYBIT "bybit"
138138
#endif
139-
#ifndef CCAPI_EXCHANGE_NAME_BYBIT_DERIVATIVES
140-
#define CCAPI_EXCHANGE_NAME_BYBIT_DERIVATIVES "bybit-derivatives"
141-
#endif
142139
#ifndef CCAPI_EXCHANGE_NAME_ASCENDEX
143140
#define CCAPI_EXCHANGE_NAME_ASCENDEX "ascendex"
144141
#endif
@@ -355,13 +352,9 @@
355352
#define CCAPI_WEBSOCKET_CRYPTOCOM_CHANNEL_TRADE "trade.{instrument_name}"
356353
#define CCAPI_WEBSOCKET_CRYPTOCOM_CHANNEL_BOOK "book.{instrument_name}.{depth}"
357354
#define CCAPI_WEBSOCKET_BYBIT_CHANNEL_TRADE "publicTrade.{symbol}"
358-
#define CCAPI_WEBSOCKET_BYBIT_CHANNEL_DEPTH "orderbook.{depth}.{symbol}"
355+
#define CCAPI_WEBSOCKET_BYBIT_CHANNEL_ORDERBOOK "orderbook.{depth}.{symbol}"
359356
#define CCAPI_WEBSOCKET_BYBIT_CHANNEL_KLINE "kline.{interval}.{symbol}"
360357
#define CCAPI_WEBSOCKET_BYBIT_CHANNEL_KLINE_2 "kline"
361-
#define CCAPI_WEBSOCKET_BYBIT_DERIVATIVES_CHANNEL_TRADE "publicTrade.{symbol}"
362-
#define CCAPI_WEBSOCKET_BYBIT_DERIVATIVES_CHANNEL_ORDERBOOK "orderbook.{depth}.{symbol}"
363-
#define CCAPI_WEBSOCKET_BYBIT_DERIVATIVES_CHANNEL_KLINE "kline.{interval}.{symbol}"
364-
#define CCAPI_WEBSOCKET_BYBIT_DERIVATIVES_CHANNEL_KLINE_2 "kline"
365358
#define CCAPI_WEBSOCKET_ASCENDEX_CHANNEL_TRADES "trades"
366359
#define CCAPI_WEBSOCKET_ASCENDEX_CHANNEL_BBO "bbo"
367360
#define CCAPI_WEBSOCKET_ASCENDEX_CHANNEL_DEPTH "depth"
@@ -766,9 +759,6 @@
766759
#ifndef CCAPI_BYBIT_URL_REST_BASE
767760
#define CCAPI_BYBIT_URL_REST_BASE "https://api.bybit.com"
768761
#endif
769-
#ifndef CCAPI_BYBIT_DERIVATIVES_URL_REST_BASE
770-
#define CCAPI_BYBIT_DERIVATIVES_URL_REST_BASE "https://api.bybit.com"
771-
#endif
772762
#ifndef CCAPI_ASCENDEX_URL_REST_BASE
773763
#define CCAPI_ASCENDEX_URL_REST_BASE "https://ascendex.com"
774764
#endif
@@ -895,9 +885,6 @@
895885
#ifndef CCAPI_BYBIT_URL_WS_BASE
896886
#define CCAPI_BYBIT_URL_WS_BASE "wss://stream.bybit.com"
897887
#endif
898-
#ifndef CCAPI_BYBIT_DERIVATIVES_URL_WS_BASE
899-
#define CCAPI_BYBIT_DERIVATIVES_URL_WS_BASE "wss://stream.bybit.com"
900-
#endif
901888
#ifndef CCAPI_ASCENDEX_URL_WS_BASE
902889
#define CCAPI_ASCENDEX_URL_WS_BASE "wss://ascendex.com"
903890
#endif
@@ -1123,12 +1110,6 @@
11231110
#ifndef CCAPI_BYBIT_API_SECRET
11241111
#define CCAPI_BYBIT_API_SECRET "BYBIT_API_SECRET"
11251112
#endif
1126-
#ifndef CCAPI_BYBIT_DERIVATIVES_API_KEY
1127-
#define CCAPI_BYBIT_DERIVATIVES_API_KEY "BYBIT_DERIVATIVES_API_KEY"
1128-
#endif
1129-
#ifndef CCAPI_BYBIT_DERIVATIVES_API_SECRET
1130-
#define CCAPI_BYBIT_DERIVATIVES_API_SECRET "BYBIT_DERIVATIVES_API_SECRET"
1131-
#endif
11321113
#ifndef CCAPI_ASCENDEX_API_KEY
11331114
#define CCAPI_ASCENDEX_API_KEY "ASCENDEX_API_KEY"
11341115
#endif

include/ccapi_cpp/ccapi_session.h

+18-38
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,6 @@
7979
#ifdef CCAPI_ENABLE_EXCHANGE_BYBIT
8080
#include "ccapi_cpp/service/ccapi_market_data_service_bybit.h"
8181
#endif
82-
#ifdef CCAPI_ENABLE_EXCHANGE_BYBIT_DERIVATIVES
83-
#include "ccapi_cpp/service/ccapi_market_data_service_bybit_derivatives.h"
84-
#endif
8582
#ifdef CCAPI_ENABLE_EXCHANGE_ASCENDEX
8683
#include "ccapi_cpp/service/ccapi_market_data_service_ascendex.h"
8784
#endif
@@ -186,9 +183,6 @@
186183
#ifdef CCAPI_ENABLE_EXCHANGE_BYBIT
187184
#include "ccapi_cpp/service/ccapi_execution_management_service_bybit.h"
188185
#endif
189-
#ifdef CCAPI_ENABLE_EXCHANGE_BYBIT_DERIVATIVES
190-
#include "ccapi_cpp/service/ccapi_execution_management_service_bybit_derivatives.h"
191-
#endif
192186
#ifdef CCAPI_ENABLE_EXCHANGE_ASCENDEX
193187
#include "ccapi_cpp/service/ccapi_execution_management_service_ascendex.h"
194188
#endif
@@ -412,10 +406,6 @@ class Session {
412406
this->serviceByServiceNameExchangeMap[CCAPI_MARKET_DATA][CCAPI_EXCHANGE_NAME_BYBIT] =
413407
std::make_shared<MarketDataServiceBybit>(this->internalEventHandler, sessionOptions, sessionConfigs, this->serviceContextPtr);
414408
#endif
415-
#ifdef CCAPI_ENABLE_EXCHANGE_BYBIT_DERIVATIVES
416-
this->serviceByServiceNameExchangeMap[CCAPI_MARKET_DATA][CCAPI_EXCHANGE_NAME_BYBIT_DERIVATIVES] =
417-
std::make_shared<MarketDataServiceBybitDerivatives>(this->internalEventHandler, sessionOptions, sessionConfigs, this->serviceContextPtr);
418-
#endif
419409
#ifdef CCAPI_ENABLE_EXCHANGE_ASCENDEX
420410
this->serviceByServiceNameExchangeMap[CCAPI_MARKET_DATA][CCAPI_EXCHANGE_NAME_ASCENDEX] =
421411
std::make_shared<MarketDataServiceAscendex>(this->internalEventHandler, sessionOptions, sessionConfigs, this->serviceContextPtr);
@@ -550,10 +540,6 @@ class Session {
550540
this->serviceByServiceNameExchangeMap[CCAPI_EXECUTION_MANAGEMENT][CCAPI_EXCHANGE_NAME_BYBIT] =
551541
std::make_shared<ExecutionManagementServiceBybit>(this->internalEventHandler, sessionOptions, sessionConfigs, this->serviceContextPtr);
552542
#endif
553-
#ifdef CCAPI_ENABLE_EXCHANGE_BYBIT_DERIVATIVES
554-
this->serviceByServiceNameExchangeMap[CCAPI_EXECUTION_MANAGEMENT][CCAPI_EXCHANGE_NAME_BYBIT_DERIVATIVES] =
555-
std::make_shared<ExecutionManagementServiceBybitDerivatives>(this->internalEventHandler, sessionOptions, sessionConfigs, this->serviceContextPtr);
556-
#endif
557543
#ifdef CCAPI_ENABLE_EXCHANGE_ASCENDEX
558544
this->serviceByServiceNameExchangeMap[CCAPI_EXECUTION_MANAGEMENT][CCAPI_EXCHANGE_NAME_ASCENDEX] =
559545
std::make_shared<ExecutionManagementServiceAscendex>(this->internalEventHandler, sessionOptions, sessionConfigs, this->serviceContextPtr);
@@ -636,6 +622,22 @@ class Session {
636622
}
637623
virtual void subscribe(std::vector<Subscription>& subscriptionList) {
638624
CCAPI_LOGGER_FUNCTION_ENTER;
625+
for (auto& subscription : subscriptionList) {
626+
auto exchange = subscription.getExchange();
627+
if (exchange == CCAPI_EXCHANGE_NAME_BYBIT) {
628+
auto instrumentType = subscription.getInstrumentType();
629+
if (instrumentType.empty()) {
630+
instrumentType = "spot";
631+
}
632+
std::vector<std::string> instrumentTypeList = {"spot", "linear", "inverse", "option"};
633+
if (std::find(instrumentTypeList.begin(), instrumentTypeList.end(), instrumentType) == instrumentTypeList.end()) {
634+
this->onError(Event::Type::SUBSCRIPTION_STATUS, Message::Type::SUBSCRIPTION_FAILURE,
635+
"unsupported exchange instrument types: " + toString(instrumentType) + ". Allowed values: " + toString(instrumentTypeList) + ".");
636+
return;
637+
}
638+
subscription.setInstrumentType(instrumentType);
639+
}
640+
}
639641
std::map<std::string, std::vector<Subscription> > subscriptionListByServiceNameMap;
640642
for (const auto& subscription : subscriptionList) {
641643
auto serviceName = subscription.getServiceName();
@@ -650,19 +652,10 @@ class Session {
650652
return;
651653
}
652654
if (serviceName == CCAPI_MARKET_DATA) {
653-
// std::set<std::string> correlationIdSet;
654-
// std::set<std::string> duplicateCorrelationIdSet;
655655
std::unordered_set<std::string> unsupportedExchangeFieldSet;
656-
std::map<std::string, std::vector<Subscription> > subscriptionListByExchangeMap;
657656
auto exchangeFieldMap = this->sessionConfigs.getExchangeFieldMap();
658657
CCAPI_LOGGER_DEBUG("exchangeFieldMap = " + toString(exchangeFieldMap));
659658
for (const auto& subscription : subscriptionList) {
660-
// auto correlationId = subscription.getCorrelationId();
661-
// if (correlationIdSet.find(correlationId) != correlationIdSet.end()) {
662-
// duplicateCorrelationIdSet.insert(correlationId);
663-
// } else {
664-
// correlationIdSet.insert(correlationId);
665-
// }
666659
auto exchange = subscription.getExchange();
667660
CCAPI_LOGGER_DEBUG("exchange = " + exchange);
668661
auto field = subscription.getField();
@@ -674,29 +667,16 @@ class Session {
674667
CCAPI_LOGGER_DEBUG("unsupported exchange " + exchange + ", field = " + field);
675668
unsupportedExchangeFieldSet.insert(exchange + "|" + field);
676669
}
677-
subscriptionListByExchangeMap[exchange].push_back(subscription);
678670
}
679-
// if (!duplicateCorrelationIdSet.empty()) {
680-
// this->onError(Event::Type::SUBSCRIPTION_STATUS, Message::Type::SUBSCRIPTION_FAILURE,
681-
// "duplicated correlation ids: " + toString(duplicateCorrelationIdSet));
682-
// return;
683-
// }
684671
if (!unsupportedExchangeFieldSet.empty()) {
685672
this->onError(Event::Type::SUBSCRIPTION_STATUS, Message::Type::SUBSCRIPTION_FAILURE,
686673
"unsupported exchange fields: " + toString(unsupportedExchangeFieldSet));
687674
return;
688675
}
676+
std::map<std::string, std::vector<Subscription> > subscriptionListByExchangeMap;
689677
for (const auto& subscription : subscriptionList) {
690678
auto exchange = subscription.getExchange();
691-
if (exchange == CCAPI_EXCHANGE_NAME_BYBIT_DERIVATIVES) {
692-
const auto& instrumentType = subscription.getInstrumentType();
693-
std::vector<std::string> instrumentTypeList = {"usdt-contract", "usdc-contract", "usdc-options"};
694-
if (std::find(instrumentTypeList.begin(), instrumentTypeList.end(), instrumentType) == instrumentTypeList.end()) {
695-
this->onError(Event::Type::SUBSCRIPTION_STATUS, Message::Type::SUBSCRIPTION_FAILURE,
696-
"unsupported exchange instrument types: " + toString(instrumentType) + ". Allowed values: " + toString(instrumentTypeList) + ".");
697-
return;
698-
}
699-
}
679+
subscriptionListByExchangeMap[exchange].push_back(subscription);
700680
}
701681
CCAPI_LOGGER_TRACE("subscriptionListByExchangeMap = " + toString(subscriptionListByExchangeMap));
702682
for (auto& subscriptionListByExchange : subscriptionListByExchangeMap) {

include/ccapi_cpp/ccapi_session_configs.h

+1-12
Original file line numberDiff line numberDiff line change
@@ -146,14 +146,9 @@ class SessionConfigs CCAPI_FINAL {
146146
};
147147
std::map<std::string, std::string> fieldWebsocketChannelMapBybit = {
148148
{CCAPI_TRADE, CCAPI_WEBSOCKET_BYBIT_CHANNEL_TRADE},
149-
{CCAPI_MARKET_DEPTH, CCAPI_WEBSOCKET_BYBIT_CHANNEL_DEPTH},
149+
{CCAPI_MARKET_DEPTH, CCAPI_WEBSOCKET_BYBIT_CHANNEL_ORDERBOOK},
150150
{CCAPI_CANDLESTICK, CCAPI_WEBSOCKET_BYBIT_CHANNEL_KLINE},
151151
};
152-
std::map<std::string, std::string> fieldWebsocketChannelMapBybitDerivatives = {
153-
{CCAPI_TRADE, CCAPI_WEBSOCKET_BYBIT_DERIVATIVES_CHANNEL_TRADE},
154-
{CCAPI_MARKET_DEPTH, CCAPI_WEBSOCKET_BYBIT_DERIVATIVES_CHANNEL_ORDERBOOK},
155-
{CCAPI_CANDLESTICK, CCAPI_WEBSOCKET_BYBIT_DERIVATIVES_CHANNEL_KLINE},
156-
};
157152
std::map<std::string, std::string> fieldWebsocketChannelMapAscendex = {
158153
{CCAPI_TRADE, CCAPI_WEBSOCKET_ASCENDEX_CHANNEL_TRADES},
159154
{CCAPI_MARKET_DEPTH, CCAPI_WEBSOCKET_ASCENDEX_CHANNEL_DEPTH},
@@ -258,9 +253,6 @@ class SessionConfigs CCAPI_FINAL {
258253
for (auto const& fieldWebsocketChannel : fieldWebsocketChannelMapBybit) {
259254
this->exchangeFieldMap[CCAPI_EXCHANGE_NAME_BYBIT].push_back(fieldWebsocketChannel.first);
260255
}
261-
for (auto const& fieldWebsocketChannel : fieldWebsocketChannelMapBybitDerivatives) {
262-
this->exchangeFieldMap[CCAPI_EXCHANGE_NAME_BYBIT_DERIVATIVES].push_back(fieldWebsocketChannel.first);
263-
}
264256
for (auto const& fieldWebsocketChannel : fieldWebsocketChannelMapAscendex) {
265257
this->exchangeFieldMap[CCAPI_EXCHANGE_NAME_ASCENDEX].push_back(fieldWebsocketChannel.first);
266258
}
@@ -312,7 +304,6 @@ class SessionConfigs CCAPI_FINAL {
312304
{CCAPI_EXCHANGE_NAME_GATEIO_PERPETUAL_FUTURES, fieldWebsocketChannelMapGateioPerpetualFutures},
313305
{CCAPI_EXCHANGE_NAME_CRYPTOCOM, fieldWebsocketChannelMapCryptocom},
314306
{CCAPI_EXCHANGE_NAME_BYBIT, fieldWebsocketChannelMapBybit},
315-
{CCAPI_EXCHANGE_NAME_BYBIT_DERIVATIVES, fieldWebsocketChannelMapBybitDerivatives},
316307
{CCAPI_EXCHANGE_NAME_ASCENDEX, fieldWebsocketChannelMapAscendex},
317308
{CCAPI_EXCHANGE_NAME_BITGET, fieldWebsocketChannelMapBitget},
318309
{CCAPI_EXCHANGE_NAME_BITGET_FUTURES, fieldWebsocketChannelMapBitgetFutures},
@@ -350,7 +341,6 @@ class SessionConfigs CCAPI_FINAL {
350341
{CCAPI_EXCHANGE_NAME_GATEIO_PERPETUAL_FUTURES, CCAPI_GATEIO_PERPETUAL_FUTURES_URL_WS_BASE},
351342
{CCAPI_EXCHANGE_NAME_CRYPTOCOM, CCAPI_CRYPTOCOM_URL_WS_BASE},
352343
{CCAPI_EXCHANGE_NAME_BYBIT, CCAPI_BYBIT_URL_WS_BASE},
353-
{CCAPI_EXCHANGE_NAME_BYBIT_DERIVATIVES, CCAPI_BYBIT_DERIVATIVES_URL_WS_BASE},
354344
{CCAPI_EXCHANGE_NAME_ASCENDEX, CCAPI_ASCENDEX_URL_WS_BASE},
355345
{CCAPI_EXCHANGE_NAME_BITGET, CCAPI_BITGET_URL_WS_BASE},
356346
{CCAPI_EXCHANGE_NAME_BITGET_FUTURES, CCAPI_BITGET_FUTURES_URL_WS_BASE},
@@ -389,7 +379,6 @@ class SessionConfigs CCAPI_FINAL {
389379
{CCAPI_EXCHANGE_NAME_GATEIO_PERPETUAL_FUTURES, CCAPI_GATEIO_PERPETUAL_FUTURES_URL_REST_BASE},
390380
{CCAPI_EXCHANGE_NAME_CRYPTOCOM, CCAPI_CRYPTOCOM_URL_REST_BASE},
391381
{CCAPI_EXCHANGE_NAME_BYBIT, CCAPI_BYBIT_URL_REST_BASE},
392-
{CCAPI_EXCHANGE_NAME_BYBIT_DERIVATIVES, CCAPI_BYBIT_DERIVATIVES_URL_REST_BASE},
393382
{CCAPI_EXCHANGE_NAME_ASCENDEX, CCAPI_ASCENDEX_URL_REST_BASE},
394383
{CCAPI_EXCHANGE_NAME_BITGET, CCAPI_BITGET_URL_REST_BASE},
395384
{CCAPI_EXCHANGE_NAME_BITGET_FUTURES, CCAPI_BITGET_FUTURES_URL_REST_BASE},

0 commit comments

Comments
 (0)