Skip to content

Commit

Permalink
Merge pull request #475 from crypto-chassis/feat-bybit-v5
Browse files Browse the repository at this point in the history
feat: upgrade bybit API from v3 to v5
  • Loading branch information
chassis-community authored Aug 2, 2024
2 parents 80174c8 + fa26678 commit 5fbf783
Show file tree
Hide file tree
Showing 13 changed files with 503 additions and 1,369 deletions.
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# 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.

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
Expand Down Expand Up @@ -35,6 +37,7 @@
- [Override exchange urls](#override-exchange-urls)
- [Complex request parameters](#complex-request-parameters-1)
- [Send request by Websocket API](#send-request-by-websocket-api)
- [Specify instrument type](#specify-instrument-type)
- [FIX API](#fix-api)
- [More Advanced Topics](#more-advanced-topics)
- [Handle events in "immediate" vs. "batching" mode](#handle-events-in-immediate-vs-batching-mode)
Expand All @@ -56,8 +59,8 @@
* Code closely follows Bloomberg's API: https://www.bloomberg.com/professional/support/api-library/.
* It is ultra fast thanks to very careful optimizations: move semantics, regex optimization, locality of reference, lock contention minimization, etc.
* Supported exchanges:
* 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.
* 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.
* 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.
* 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.
* FIX: coinbase, gemini.
* A spot market making application is provided as an end-to-end solution for liquidity providers.
* A single order execution application is provided as an end-to-end solution for executing large orders.
Expand Down Expand Up @@ -792,6 +795,14 @@ request.appendParam({
session.sendRequestByWebsocket(request);
```

#### Specify instrument type
Some exchanges (i.e. bybit) might need instrument type for `Subscription`. Use `Subscription`'s `setInstrumentType` method.
```
Subscription subscription("bybit", "BTCUSDT", "MARKET_DEPTH");
subscription.setInstrumentType("spot");
session.subscribe(subscription);
```

### FIX API

**Objective:**
Expand Down
21 changes: 1 addition & 20 deletions include/ccapi_cpp/ccapi_macro.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,6 @@
#ifndef CCAPI_EXCHANGE_NAME_BYBIT
#define CCAPI_EXCHANGE_NAME_BYBIT "bybit"
#endif
#ifndef CCAPI_EXCHANGE_NAME_BYBIT_DERIVATIVES
#define CCAPI_EXCHANGE_NAME_BYBIT_DERIVATIVES "bybit-derivatives"
#endif
#ifndef CCAPI_EXCHANGE_NAME_ASCENDEX
#define CCAPI_EXCHANGE_NAME_ASCENDEX "ascendex"
#endif
Expand Down Expand Up @@ -355,13 +352,9 @@
#define CCAPI_WEBSOCKET_CRYPTOCOM_CHANNEL_TRADE "trade.{instrument_name}"
#define CCAPI_WEBSOCKET_CRYPTOCOM_CHANNEL_BOOK "book.{instrument_name}.{depth}"
#define CCAPI_WEBSOCKET_BYBIT_CHANNEL_TRADE "publicTrade.{symbol}"
#define CCAPI_WEBSOCKET_BYBIT_CHANNEL_DEPTH "orderbook.{depth}.{symbol}"
#define CCAPI_WEBSOCKET_BYBIT_CHANNEL_ORDERBOOK "orderbook.{depth}.{symbol}"
#define CCAPI_WEBSOCKET_BYBIT_CHANNEL_KLINE "kline.{interval}.{symbol}"
#define CCAPI_WEBSOCKET_BYBIT_CHANNEL_KLINE_2 "kline"
#define CCAPI_WEBSOCKET_BYBIT_DERIVATIVES_CHANNEL_TRADE "publicTrade.{symbol}"
#define CCAPI_WEBSOCKET_BYBIT_DERIVATIVES_CHANNEL_ORDERBOOK "orderbook.{depth}.{symbol}"
#define CCAPI_WEBSOCKET_BYBIT_DERIVATIVES_CHANNEL_KLINE "kline.{interval}.{symbol}"
#define CCAPI_WEBSOCKET_BYBIT_DERIVATIVES_CHANNEL_KLINE_2 "kline"
#define CCAPI_WEBSOCKET_ASCENDEX_CHANNEL_TRADES "trades"
#define CCAPI_WEBSOCKET_ASCENDEX_CHANNEL_BBO "bbo"
#define CCAPI_WEBSOCKET_ASCENDEX_CHANNEL_DEPTH "depth"
Expand Down Expand Up @@ -766,9 +759,6 @@
#ifndef CCAPI_BYBIT_URL_REST_BASE
#define CCAPI_BYBIT_URL_REST_BASE "https://api.bybit.com"
#endif
#ifndef CCAPI_BYBIT_DERIVATIVES_URL_REST_BASE
#define CCAPI_BYBIT_DERIVATIVES_URL_REST_BASE "https://api.bybit.com"
#endif
#ifndef CCAPI_ASCENDEX_URL_REST_BASE
#define CCAPI_ASCENDEX_URL_REST_BASE "https://ascendex.com"
#endif
Expand Down Expand Up @@ -895,9 +885,6 @@
#ifndef CCAPI_BYBIT_URL_WS_BASE
#define CCAPI_BYBIT_URL_WS_BASE "wss://stream.bybit.com"
#endif
#ifndef CCAPI_BYBIT_DERIVATIVES_URL_WS_BASE
#define CCAPI_BYBIT_DERIVATIVES_URL_WS_BASE "wss://stream.bybit.com"
#endif
#ifndef CCAPI_ASCENDEX_URL_WS_BASE
#define CCAPI_ASCENDEX_URL_WS_BASE "wss://ascendex.com"
#endif
Expand Down Expand Up @@ -1123,12 +1110,6 @@
#ifndef CCAPI_BYBIT_API_SECRET
#define CCAPI_BYBIT_API_SECRET "BYBIT_API_SECRET"
#endif
#ifndef CCAPI_BYBIT_DERIVATIVES_API_KEY
#define CCAPI_BYBIT_DERIVATIVES_API_KEY "BYBIT_DERIVATIVES_API_KEY"
#endif
#ifndef CCAPI_BYBIT_DERIVATIVES_API_SECRET
#define CCAPI_BYBIT_DERIVATIVES_API_SECRET "BYBIT_DERIVATIVES_API_SECRET"
#endif
#ifndef CCAPI_ASCENDEX_API_KEY
#define CCAPI_ASCENDEX_API_KEY "ASCENDEX_API_KEY"
#endif
Expand Down
56 changes: 18 additions & 38 deletions include/ccapi_cpp/ccapi_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,6 @@
#ifdef CCAPI_ENABLE_EXCHANGE_BYBIT
#include "ccapi_cpp/service/ccapi_market_data_service_bybit.h"
#endif
#ifdef CCAPI_ENABLE_EXCHANGE_BYBIT_DERIVATIVES
#include "ccapi_cpp/service/ccapi_market_data_service_bybit_derivatives.h"
#endif
#ifdef CCAPI_ENABLE_EXCHANGE_ASCENDEX
#include "ccapi_cpp/service/ccapi_market_data_service_ascendex.h"
#endif
Expand Down Expand Up @@ -186,9 +183,6 @@
#ifdef CCAPI_ENABLE_EXCHANGE_BYBIT
#include "ccapi_cpp/service/ccapi_execution_management_service_bybit.h"
#endif
#ifdef CCAPI_ENABLE_EXCHANGE_BYBIT_DERIVATIVES
#include "ccapi_cpp/service/ccapi_execution_management_service_bybit_derivatives.h"
#endif
#ifdef CCAPI_ENABLE_EXCHANGE_ASCENDEX
#include "ccapi_cpp/service/ccapi_execution_management_service_ascendex.h"
#endif
Expand Down Expand Up @@ -412,10 +406,6 @@ class Session {
this->serviceByServiceNameExchangeMap[CCAPI_MARKET_DATA][CCAPI_EXCHANGE_NAME_BYBIT] =
std::make_shared<MarketDataServiceBybit>(this->internalEventHandler, sessionOptions, sessionConfigs, this->serviceContextPtr);
#endif
#ifdef CCAPI_ENABLE_EXCHANGE_BYBIT_DERIVATIVES
this->serviceByServiceNameExchangeMap[CCAPI_MARKET_DATA][CCAPI_EXCHANGE_NAME_BYBIT_DERIVATIVES] =
std::make_shared<MarketDataServiceBybitDerivatives>(this->internalEventHandler, sessionOptions, sessionConfigs, this->serviceContextPtr);
#endif
#ifdef CCAPI_ENABLE_EXCHANGE_ASCENDEX
this->serviceByServiceNameExchangeMap[CCAPI_MARKET_DATA][CCAPI_EXCHANGE_NAME_ASCENDEX] =
std::make_shared<MarketDataServiceAscendex>(this->internalEventHandler, sessionOptions, sessionConfigs, this->serviceContextPtr);
Expand Down Expand Up @@ -550,10 +540,6 @@ class Session {
this->serviceByServiceNameExchangeMap[CCAPI_EXECUTION_MANAGEMENT][CCAPI_EXCHANGE_NAME_BYBIT] =
std::make_shared<ExecutionManagementServiceBybit>(this->internalEventHandler, sessionOptions, sessionConfigs, this->serviceContextPtr);
#endif
#ifdef CCAPI_ENABLE_EXCHANGE_BYBIT_DERIVATIVES
this->serviceByServiceNameExchangeMap[CCAPI_EXECUTION_MANAGEMENT][CCAPI_EXCHANGE_NAME_BYBIT_DERIVATIVES] =
std::make_shared<ExecutionManagementServiceBybitDerivatives>(this->internalEventHandler, sessionOptions, sessionConfigs, this->serviceContextPtr);
#endif
#ifdef CCAPI_ENABLE_EXCHANGE_ASCENDEX
this->serviceByServiceNameExchangeMap[CCAPI_EXECUTION_MANAGEMENT][CCAPI_EXCHANGE_NAME_ASCENDEX] =
std::make_shared<ExecutionManagementServiceAscendex>(this->internalEventHandler, sessionOptions, sessionConfigs, this->serviceContextPtr);
Expand Down Expand Up @@ -636,6 +622,22 @@ class Session {
}
virtual void subscribe(std::vector<Subscription>& subscriptionList) {
CCAPI_LOGGER_FUNCTION_ENTER;
for (auto& subscription : subscriptionList) {
auto exchange = subscription.getExchange();
if (exchange == CCAPI_EXCHANGE_NAME_BYBIT) {
auto instrumentType = subscription.getInstrumentType();
if (instrumentType.empty()) {
instrumentType = "spot";
}
std::vector<std::string> instrumentTypeList = {"spot", "linear", "inverse", "option"};
if (std::find(instrumentTypeList.begin(), instrumentTypeList.end(), instrumentType) == instrumentTypeList.end()) {
this->onError(Event::Type::SUBSCRIPTION_STATUS, Message::Type::SUBSCRIPTION_FAILURE,
"unsupported exchange instrument types: " + toString(instrumentType) + ". Allowed values: " + toString(instrumentTypeList) + ".");
return;
}
subscription.setInstrumentType(instrumentType);
}
}
std::map<std::string, std::vector<Subscription> > subscriptionListByServiceNameMap;
for (const auto& subscription : subscriptionList) {
auto serviceName = subscription.getServiceName();
Expand All @@ -650,19 +652,10 @@ class Session {
return;
}
if (serviceName == CCAPI_MARKET_DATA) {
// std::set<std::string> correlationIdSet;
// std::set<std::string> duplicateCorrelationIdSet;
std::unordered_set<std::string> unsupportedExchangeFieldSet;
std::map<std::string, std::vector<Subscription> > subscriptionListByExchangeMap;
auto exchangeFieldMap = this->sessionConfigs.getExchangeFieldMap();
CCAPI_LOGGER_DEBUG("exchangeFieldMap = " + toString(exchangeFieldMap));
for (const auto& subscription : subscriptionList) {
// auto correlationId = subscription.getCorrelationId();
// if (correlationIdSet.find(correlationId) != correlationIdSet.end()) {
// duplicateCorrelationIdSet.insert(correlationId);
// } else {
// correlationIdSet.insert(correlationId);
// }
auto exchange = subscription.getExchange();
CCAPI_LOGGER_DEBUG("exchange = " + exchange);
auto field = subscription.getField();
Expand All @@ -674,29 +667,16 @@ class Session {
CCAPI_LOGGER_DEBUG("unsupported exchange " + exchange + ", field = " + field);
unsupportedExchangeFieldSet.insert(exchange + "|" + field);
}
subscriptionListByExchangeMap[exchange].push_back(subscription);
}
// if (!duplicateCorrelationIdSet.empty()) {
// this->onError(Event::Type::SUBSCRIPTION_STATUS, Message::Type::SUBSCRIPTION_FAILURE,
// "duplicated correlation ids: " + toString(duplicateCorrelationIdSet));
// return;
// }
if (!unsupportedExchangeFieldSet.empty()) {
this->onError(Event::Type::SUBSCRIPTION_STATUS, Message::Type::SUBSCRIPTION_FAILURE,
"unsupported exchange fields: " + toString(unsupportedExchangeFieldSet));
return;
}
std::map<std::string, std::vector<Subscription> > subscriptionListByExchangeMap;
for (const auto& subscription : subscriptionList) {
auto exchange = subscription.getExchange();
if (exchange == CCAPI_EXCHANGE_NAME_BYBIT_DERIVATIVES) {
const auto& instrumentType = subscription.getInstrumentType();
std::vector<std::string> instrumentTypeList = {"usdt-contract", "usdc-contract", "usdc-options"};
if (std::find(instrumentTypeList.begin(), instrumentTypeList.end(), instrumentType) == instrumentTypeList.end()) {
this->onError(Event::Type::SUBSCRIPTION_STATUS, Message::Type::SUBSCRIPTION_FAILURE,
"unsupported exchange instrument types: " + toString(instrumentType) + ". Allowed values: " + toString(instrumentTypeList) + ".");
return;
}
}
subscriptionListByExchangeMap[exchange].push_back(subscription);
}
CCAPI_LOGGER_TRACE("subscriptionListByExchangeMap = " + toString(subscriptionListByExchangeMap));
for (auto& subscriptionListByExchange : subscriptionListByExchangeMap) {
Expand Down
13 changes: 1 addition & 12 deletions include/ccapi_cpp/ccapi_session_configs.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,9 @@ class SessionConfigs CCAPI_FINAL {
};
std::map<std::string, std::string> fieldWebsocketChannelMapBybit = {
{CCAPI_TRADE, CCAPI_WEBSOCKET_BYBIT_CHANNEL_TRADE},
{CCAPI_MARKET_DEPTH, CCAPI_WEBSOCKET_BYBIT_CHANNEL_DEPTH},
{CCAPI_MARKET_DEPTH, CCAPI_WEBSOCKET_BYBIT_CHANNEL_ORDERBOOK},
{CCAPI_CANDLESTICK, CCAPI_WEBSOCKET_BYBIT_CHANNEL_KLINE},
};
std::map<std::string, std::string> fieldWebsocketChannelMapBybitDerivatives = {
{CCAPI_TRADE, CCAPI_WEBSOCKET_BYBIT_DERIVATIVES_CHANNEL_TRADE},
{CCAPI_MARKET_DEPTH, CCAPI_WEBSOCKET_BYBIT_DERIVATIVES_CHANNEL_ORDERBOOK},
{CCAPI_CANDLESTICK, CCAPI_WEBSOCKET_BYBIT_DERIVATIVES_CHANNEL_KLINE},
};
std::map<std::string, std::string> fieldWebsocketChannelMapAscendex = {
{CCAPI_TRADE, CCAPI_WEBSOCKET_ASCENDEX_CHANNEL_TRADES},
{CCAPI_MARKET_DEPTH, CCAPI_WEBSOCKET_ASCENDEX_CHANNEL_DEPTH},
Expand Down Expand Up @@ -258,9 +253,6 @@ class SessionConfigs CCAPI_FINAL {
for (auto const& fieldWebsocketChannel : fieldWebsocketChannelMapBybit) {
this->exchangeFieldMap[CCAPI_EXCHANGE_NAME_BYBIT].push_back(fieldWebsocketChannel.first);
}
for (auto const& fieldWebsocketChannel : fieldWebsocketChannelMapBybitDerivatives) {
this->exchangeFieldMap[CCAPI_EXCHANGE_NAME_BYBIT_DERIVATIVES].push_back(fieldWebsocketChannel.first);
}
for (auto const& fieldWebsocketChannel : fieldWebsocketChannelMapAscendex) {
this->exchangeFieldMap[CCAPI_EXCHANGE_NAME_ASCENDEX].push_back(fieldWebsocketChannel.first);
}
Expand Down Expand Up @@ -312,7 +304,6 @@ class SessionConfigs CCAPI_FINAL {
{CCAPI_EXCHANGE_NAME_GATEIO_PERPETUAL_FUTURES, fieldWebsocketChannelMapGateioPerpetualFutures},
{CCAPI_EXCHANGE_NAME_CRYPTOCOM, fieldWebsocketChannelMapCryptocom},
{CCAPI_EXCHANGE_NAME_BYBIT, fieldWebsocketChannelMapBybit},
{CCAPI_EXCHANGE_NAME_BYBIT_DERIVATIVES, fieldWebsocketChannelMapBybitDerivatives},
{CCAPI_EXCHANGE_NAME_ASCENDEX, fieldWebsocketChannelMapAscendex},
{CCAPI_EXCHANGE_NAME_BITGET, fieldWebsocketChannelMapBitget},
{CCAPI_EXCHANGE_NAME_BITGET_FUTURES, fieldWebsocketChannelMapBitgetFutures},
Expand Down Expand Up @@ -350,7 +341,6 @@ class SessionConfigs CCAPI_FINAL {
{CCAPI_EXCHANGE_NAME_GATEIO_PERPETUAL_FUTURES, CCAPI_GATEIO_PERPETUAL_FUTURES_URL_WS_BASE},
{CCAPI_EXCHANGE_NAME_CRYPTOCOM, CCAPI_CRYPTOCOM_URL_WS_BASE},
{CCAPI_EXCHANGE_NAME_BYBIT, CCAPI_BYBIT_URL_WS_BASE},
{CCAPI_EXCHANGE_NAME_BYBIT_DERIVATIVES, CCAPI_BYBIT_DERIVATIVES_URL_WS_BASE},
{CCAPI_EXCHANGE_NAME_ASCENDEX, CCAPI_ASCENDEX_URL_WS_BASE},
{CCAPI_EXCHANGE_NAME_BITGET, CCAPI_BITGET_URL_WS_BASE},
{CCAPI_EXCHANGE_NAME_BITGET_FUTURES, CCAPI_BITGET_FUTURES_URL_WS_BASE},
Expand Down Expand Up @@ -389,7 +379,6 @@ class SessionConfigs CCAPI_FINAL {
{CCAPI_EXCHANGE_NAME_GATEIO_PERPETUAL_FUTURES, CCAPI_GATEIO_PERPETUAL_FUTURES_URL_REST_BASE},
{CCAPI_EXCHANGE_NAME_CRYPTOCOM, CCAPI_CRYPTOCOM_URL_REST_BASE},
{CCAPI_EXCHANGE_NAME_BYBIT, CCAPI_BYBIT_URL_REST_BASE},
{CCAPI_EXCHANGE_NAME_BYBIT_DERIVATIVES, CCAPI_BYBIT_DERIVATIVES_URL_REST_BASE},
{CCAPI_EXCHANGE_NAME_ASCENDEX, CCAPI_ASCENDEX_URL_REST_BASE},
{CCAPI_EXCHANGE_NAME_BITGET, CCAPI_BITGET_URL_REST_BASE},
{CCAPI_EXCHANGE_NAME_BITGET_FUTURES, CCAPI_BITGET_FUTURES_URL_REST_BASE},
Expand Down
Loading

0 comments on commit 5fbf783

Please sign in to comment.