Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release #476

Merged
merged 2 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading