Skip to content

Commit

Permalink
Merge pull request #437 from crypto-chassis/develop
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
cryptochassis committed Oct 7, 2023
2 parents 895381c + 368c54d commit a9b573a
Show file tree
Hide file tree
Showing 40 changed files with 929 additions and 220 deletions.
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Notification: we've added a new feature that allows our users to subscribe to exchange provided candlesticks. There is a small renaming: "OPEN" has been renamed to "OPEN_PRICE", "CLOSE" has been renamed to "CLOSE_PRICE", "HIGH" has been renamed to "HIGH_PRICE", "LOW" has been renamed to "LOW_PRICE". If you have any questions, feel free to directly ask us on Discord https://discord.gg/b5EKcp9s8T.

# Notifications:
* New features: added REST endpoints for fetching historical public trades, historical/recent candlesticks, and market depth (i.e. order book snapshot).
* Small breaking change to correct an English typo: In `SessionOptions`, the substring "MilliSeconds" has been renamed to "Milliseconds".

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
Expand Down Expand Up @@ -279,8 +280,8 @@ Received an event:
]
Bye
```
* Request operation types: `GET_INSTRUMENT`, `GET_INSTRUMENTS`, `GET_RECENT_TRADES`, `GET_RECENT_AGG_TRADES`(only applicable to binance family: https://binance-docs.github.io/apidocs/spot/en/#compressed-aggregate-trades-list).
* Request parameter names: `LIMIT`, `INSTRUMENT_TYPE`. Instead of these convenient names you can also choose to use arbitrary parameter names and they will be passed to the exchange's native API. See [this example](example/src/market_data_advanced_request/main.cpp).
* Request operation types: `GET_INSTRUMENT`, `GET_INSTRUMENTS`, `GET_RECENT_TRADES`, `GET_HISTORICAL_TRADES`, `GET_RECENT_CANDLESTICKS`, `GET_HISTORICAL_CANDLESTICKS`, `GET_RECENT_AGG_TRADES`, `GET_HISTORICAL_AGG_TRADES`(only applicable to binance family: https://binance-docs.github.io/apidocs/spot/en/#compressed-aggregate-trades-list), ``.
* Request parameter names: `LIMIT`, `INSTRUMENT_TYPE`, `CANDLESTICK_INTERVAL_SECONDS`, `START_TIME_SECONDS`, `END_TIME_SECONDS`, `START_TRADE_ID`, `END_TRADE_ID`, `START_AGG_TRADE_ID`, `END_AGG_TRADE_ID`. Instead of these convenient names you can also choose to use arbitrary parameter names and they will be passed to the exchange's native API. See [this example](example/src/market_data_advanced_request/main.cpp).
* Message's `time` represents the exchange's reported timestamp. Its `timeReceived` represents the library's receiving timestamp. `time` can be retrieved by `getTime` method and `timeReceived` can be retrieved by `getTimeReceived` method. (For non-C++, please use `getTimeUnix` and `getTimeReceivedUnix` methods or `getTimeISO` and `getTimeReceivedISO` methods).

**Objective 2:**
Expand Down Expand Up @@ -338,7 +339,7 @@ Best bid and ask at 2020-07-27T23:56:51.884855000Z are:
Best bid and ask at 2020-07-27T23:56:51.935993000Z are:
...
```
* Subscription fields: `MARKET_DEPTH`, `TRADE`, `AGG_TRADE`(only applicable to binance family: https://binance-docs.github.io/apidocs/spot/en/#aggregate-trade-streams).
* Subscription fields: `MARKET_DEPTH`, `TRADE`, `CANDLESTICK`, `AGG_TRADE`(only applicable to binance family: https://binance-docs.github.io/apidocs/spot/en/#aggregate-trade-streams).

### Advanced Market Data

Expand Down
2 changes: 1 addition & 1 deletion app/src/single_order_execution/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ int main(int argc, char** argv) {
eventHandler.promisePtr = promisePtr;
#ifndef CCAPI_APP_IS_BACKTEST
SessionOptions sessionOptions;
sessionOptions.httpConnectionPoolIdleTimeoutMilliSeconds = 1;
sessionOptions.httpConnectionPoolIdleTimeoutMilliseconds = 1;
sessionOptions.httpMaxNumRetry = 0;
sessionOptions.httpMaxNumRedirect = 0;
SessionConfigs sessionConfigs;
Expand Down
2 changes: 1 addition & 1 deletion app/src/spot_market_making/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ int main(int argc, char** argv) {
eventHandler.promisePtr = promisePtr;
#ifndef CCAPI_APP_IS_BACKTEST
SessionOptions sessionOptions;
sessionOptions.httpConnectionPoolIdleTimeoutMilliSeconds = 1 + eventHandler.accountBalanceRefreshWaitSeconds;
sessionOptions.httpConnectionPoolIdleTimeoutMilliseconds = 1 + eventHandler.accountBalanceRefreshWaitSeconds;
sessionOptions.httpMaxNumRetry = 0;
sessionOptions.httpMaxNumRedirect = 0;
SessionConfigs sessionConfigs;
Expand Down
4 changes: 2 additions & 2 deletions example/src/fix_advanced/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ int main(int argc, char** argv) {
return EXIT_FAILURE;
}
SessionOptions sessionOptions;
sessionOptions.heartbeatFixIntervalMilliSeconds = 30000; // Note the unit is millisecond
sessionOptions.heartbeatFixTimeoutMilliSeconds = 5000; // Note the unit is millisecond, should be less than heartbeatFixIntervalMilliSeconds
sessionOptions.heartbeatFixIntervalMilliseconds = 30000; // Note the unit is millisecond
sessionOptions.heartbeatFixTimeoutMilliseconds = 5000; // Note the unit is millisecond, should be less than heartbeatFixIntervalMilliseconds
SessionConfigs sessionConfigs;
MyEventHandler eventHandler;
Session session(sessionOptions, sessionConfigs, &eventHandler);
Expand Down
15 changes: 15 additions & 0 deletions include/ccapi_cpp/ccapi_macro.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,21 @@
#ifndef CCAPI_LIMIT
#define CCAPI_LIMIT "LIMIT"
#endif
#ifndef CCAPI_START_TRADE_ID
#define CCAPI_START_TRADE_ID "START_TRADE_ID"
#endif
#ifndef CCAPI_END_TRADE_ID
#define CCAPI_END_TRADE_ID "END_TRADE_ID"
#endif
#ifndef CCAPI_START_AGG_TRADE_ID
#define CCAPI_START_AGG_TRADE_ID "START_AGG_TRADE_ID"
#endif
#ifndef CCAPI_START_TIME_SECONDS
#define CCAPI_START_TIME_SECONDS "START_TIME_SECONDS"
#endif
#ifndef CCAPI_END_TIME_SECONDS
#define CCAPI_END_TIME_SECONDS "END_TIME_SECONDS"
#endif
#ifndef CCAPI_BASE_ASSET
#define CCAPI_BASE_ASSET "BASE_ASSET"
#endif
Expand Down
20 changes: 20 additions & 0 deletions include/ccapi_cpp/ccapi_message.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,12 @@ class Message CCAPI_FINAL {
GET_ACCOUNT_BALANCES,
GET_ACCOUNT_POSITIONS,
GET_RECENT_TRADES,
GET_HISTORICAL_TRADES,
GET_RECENT_AGG_TRADES,
GET_HISTORICAL_AGG_TRADES,
GET_RECENT_CANDLESTICKS,
GET_HISTORICAL_CANDLESTICKS,
GET_MARKET_DEPTH,
GET_INSTRUMENT,
GET_INSTRUMENTS,
RESPONSE_ERROR,
Expand Down Expand Up @@ -147,9 +152,24 @@ class Message CCAPI_FINAL {
case Type::GET_RECENT_TRADES:
output = "GET_RECENT_TRADES";
break;
case Type::GET_HISTORICAL_TRADES:
output = "GET_HISTORICAL_TRADES";
break;
case Type::GET_RECENT_AGG_TRADES:
output = "GET_RECENT_AGG_TRADES";
break;
case Type::GET_HISTORICAL_AGG_TRADES:
output = "GET_HISTORICAL_AGG_TRADES";
break;
case Type::GET_RECENT_CANDLESTICKS:
output = "GET_RECENT_CANDLESTICKS";
break;
case Type::GET_HISTORICAL_CANDLESTICKS:
output = "GET_HISTORICAL_CANDLESTICKS";
break;
case Type::GET_MARKET_DEPTH:
output = "GET_MARKET_DEPTH";
break;
case Type::GET_INSTRUMENT:
output = "GET_INSTRUMENT";
break;
Expand Down
20 changes: 20 additions & 0 deletions include/ccapi_cpp/ccapi_request.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ class Request CCAPI_FINAL {
GENERIC_PRIVATE_REQUEST = CCAPI_REQUEST_OPERATION_TYPE_GENERIC_PRIVATE_REQUEST,
FIX = CCAPI_REQUEST_OPERATION_TYPE_FIX,
GET_RECENT_TRADES = CCAPI_REQUEST_OPERATION_TYPE_MARKET_DATA,
GET_HISTORICAL_TRADES,
GET_RECENT_AGG_TRADES,
GET_HISTORICAL_AGG_TRADES,
GET_RECENT_CANDLESTICKS,
GET_HISTORICAL_CANDLESTICKS,
GET_MARKET_DEPTH,
GET_INSTRUMENT,
GET_INSTRUMENTS,
CREATE_ORDER = CCAPI_REQUEST_OPERATION_TYPE_EXECUTION_MANAGEMENT_ORDER,
Expand Down Expand Up @@ -61,9 +66,24 @@ class Request CCAPI_FINAL {
case Operation::GET_RECENT_TRADES:
output = "GET_RECENT_TRADES";
break;
case Operation::GET_HISTORICAL_TRADES:
output = "GET_HISTORICAL_TRADES";
break;
case Operation::GET_RECENT_AGG_TRADES:
output = "GET_RECENT_AGG_TRADES";
break;
case Operation::GET_HISTORICAL_AGG_TRADES:
output = "GET_HISTORICAL_AGG_TRADES";
break;
case Operation::GET_RECENT_CANDLESTICKS:
output = "GET_RECENT_CANDLESTICKS";
break;
case Operation::GET_HISTORICAL_CANDLESTICKS:
output = "GET_HISTORICAL_CANDLESTICKS";
break;
case Operation::GET_MARKET_DEPTH:
output = "GET_MARKET_DEPTH";
break;
case Operation::GET_INSTRUMENT:
output = "GET_INSTRUMENT";
break;
Expand Down
14 changes: 7 additions & 7 deletions include/ccapi_cpp/ccapi_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -821,13 +821,13 @@ class Session {
this->sendRequestByWebsocket(x);
}
}
virtual void sendRequest(Request& request, Queue<Event>* eventQueuePtr = nullptr, long delayMilliSeconds = 0) {
virtual void sendRequest(Request& request, Queue<Event>* eventQueuePtr = nullptr, long delayMilliseconds = 0) {
CCAPI_LOGGER_FUNCTION_ENTER;
std::vector<Request> requestList({request});
this->sendRequest(requestList, eventQueuePtr, delayMilliSeconds);
this->sendRequest(requestList, eventQueuePtr, delayMilliseconds);
CCAPI_LOGGER_FUNCTION_EXIT;
}
virtual void sendRequest(std::vector<Request>& requestList, Queue<Event>* eventQueuePtr = nullptr, long delayMilliSeconds = 0) {
virtual void sendRequest(std::vector<Request>& requestList, Queue<Event>* eventQueuePtr = nullptr, long delayMilliseconds = 0) {
CCAPI_LOGGER_FUNCTION_ENTER;
std::vector<std::shared_ptr<std::future<void> > > futurePtrList;
// std::set<std::string> serviceNameExchangeSet;
Expand All @@ -854,7 +854,7 @@ class Session {
// serviceNameExchangeSet.insert(key);
// }
auto now = UtilTime::now();
auto futurePtr = servicePtr->sendRequest(request, !!eventQueuePtr, now, delayMilliSeconds, eventQueuePtr);
auto futurePtr = servicePtr->sendRequest(request, !!eventQueuePtr, now, delayMilliseconds, eventQueuePtr);
if (eventQueuePtr) {
futurePtrList.push_back(futurePtr);
}
Expand Down Expand Up @@ -886,10 +886,10 @@ class Session {
this->onEvent(event, eventQueuePtr);
}
#ifndef SWIG
virtual void setTimer(const std::string& id, long delayMilliSeconds, std::function<void(const boost::system::error_code&)> errorHandler,
virtual void setTimer(const std::string& id, long delayMilliseconds, std::function<void(const boost::system::error_code&)> errorHandler,
std::function<void()> successHandler) {
boost::asio::post(*this->serviceContextPtr->ioContextPtr, [this, id, delayMilliSeconds, errorHandler, successHandler]() {
std::shared_ptr<steady_timer> timerPtr(new steady_timer(*this->serviceContextPtr->ioContextPtr, boost::asio::chrono::milliseconds(delayMilliSeconds)));
boost::asio::post(*this->serviceContextPtr->ioContextPtr, [this, id, delayMilliseconds, errorHandler, successHandler]() {
std::shared_ptr<steady_timer> timerPtr(new steady_timer(*this->serviceContextPtr->ioContextPtr, boost::asio::chrono::milliseconds(delayMilliseconds)));
timerPtr->async_wait([this, id, errorHandler, successHandler](const boost::system::error_code& ec) {
if (this->eventHandler) {
#ifdef CCAPI_USE_SINGLE_THREAD
Expand Down
36 changes: 18 additions & 18 deletions include/ccapi_cpp/ccapi_session_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,44 +18,44 @@ class SessionOptions CCAPI_FINAL {
", enableCheckPingPongWebsocketProtocolLevel = " + ccapi::toString(enableCheckPingPongWebsocketProtocolLevel) +
", enableCheckPingPongWebsocketApplicationLevel = " + ccapi::toString(enableCheckPingPongWebsocketApplicationLevel) +
", enableCheckHeartbeatFix = " + ccapi::toString(enableCheckHeartbeatFix) +
", pingWebsocketProtocolLevelIntervalMilliSeconds = " + ccapi::toString(pingWebsocketProtocolLevelIntervalMilliSeconds) +
", pongWebsocketProtocolLevelTimeoutMilliSeconds = " + ccapi::toString(pongWebsocketProtocolLevelTimeoutMilliSeconds) +
", pingWebsocketApplicationLevelIntervalMilliSeconds = " + ccapi::toString(pingWebsocketApplicationLevelIntervalMilliSeconds) +
", pongWebsocketApplicationLevelTimeoutMilliSeconds = " + ccapi::toString(pongWebsocketApplicationLevelTimeoutMilliSeconds) +
", heartbeatFixIntervalMilliSeconds = " + ccapi::toString(heartbeatFixIntervalMilliSeconds) +
", heartbeatFixTimeoutMilliSeconds = " + ccapi::toString(heartbeatFixTimeoutMilliSeconds) +
", pingWebsocketProtocolLevelIntervalMilliseconds = " + ccapi::toString(pingWebsocketProtocolLevelIntervalMilliseconds) +
", pongWebsocketProtocolLevelTimeoutMilliseconds = " + ccapi::toString(pongWebsocketProtocolLevelTimeoutMilliseconds) +
", pingWebsocketApplicationLevelIntervalMilliseconds = " + ccapi::toString(pingWebsocketApplicationLevelIntervalMilliseconds) +
", pongWebsocketApplicationLevelTimeoutMilliseconds = " + ccapi::toString(pongWebsocketApplicationLevelTimeoutMilliseconds) +
", heartbeatFixIntervalMilliseconds = " + ccapi::toString(heartbeatFixIntervalMilliseconds) +
", heartbeatFixTimeoutMilliseconds = " + ccapi::toString(heartbeatFixTimeoutMilliseconds) +
", maxEventQueueSize = " + ccapi::toString(maxEventQueueSize) + ", httpMaxNumRetry = " + ccapi::toString(httpMaxNumRetry) +
", httpMaxNumRedirect = " + ccapi::toString(httpMaxNumRedirect) +
", httpRequestTimeoutMilliSeconds = " + ccapi::toString(httpRequestTimeoutMilliSeconds) +
", httpRequestTimeoutMilliseconds = " + ccapi::toString(httpRequestTimeoutMilliseconds) +
", httpConnectionPoolMaxSize = " + ccapi::toString(httpConnectionPoolMaxSize) +
", httpConnectionPoolIdleTimeoutMilliSeconds = " + ccapi::toString(httpConnectionPoolIdleTimeoutMilliSeconds) +
", httpConnectionPoolIdleTimeoutMilliseconds = " + ccapi::toString(httpConnectionPoolIdleTimeoutMilliseconds) +
", enableOneHttpConnectionPerRequest = " + ccapi::toString(enableOneHttpConnectionPerRequest) + "]";
return output;
}
// long warnLateEventMaxMilliSeconds{}; // used to print a warning log message if en event arrives late
// long warnLateEventMaxMilliseconds{}; // used to print a warning log message if en event arrives late
bool enableCheckSequence{}; // used to check sequence number discontinuity
bool enableCheckOrderBookChecksum{}; // used to check order book checksum
bool enableCheckOrderBookCrossed{true}; // used to check order book cross, usually this should be set to true
bool enableCheckPingPongWebsocketProtocolLevel{true}; // used to check ping-pong health for exchange connections on websocket protocol level
bool enableCheckPingPongWebsocketApplicationLevel{true}; // used to check ping-pong health for exchange connections on websocket application level
bool enableCheckHeartbeatFix{true}; // used to check heartbeat health for exchange connections on FIX
long pingWebsocketProtocolLevelIntervalMilliSeconds{60000};
long pongWebsocketProtocolLevelTimeoutMilliSeconds{30000}; // should be less than pingWebsocketProtocolLevelIntervalMilliSeconds
long pingWebsocketApplicationLevelIntervalMilliSeconds{60000};
long pongWebsocketApplicationLevelTimeoutMilliSeconds{30000}; // should be less than pingWebsocketApplicationLevelIntervalMilliSeconds
long heartbeatFixIntervalMilliSeconds{60000};
long heartbeatFixTimeoutMilliSeconds{30000}; // should be less than heartbeatFixIntervalMilliSeconds
long pingWebsocketProtocolLevelIntervalMilliseconds{60000};
long pongWebsocketProtocolLevelTimeoutMilliseconds{30000}; // should be less than pingWebsocketProtocolLevelIntervalMilliseconds
long pingWebsocketApplicationLevelIntervalMilliseconds{60000};
long pongWebsocketApplicationLevelTimeoutMilliseconds{30000}; // should be less than pingWebsocketApplicationLevelIntervalMilliseconds
long heartbeatFixIntervalMilliseconds{60000};
long heartbeatFixTimeoutMilliseconds{30000}; // should be less than heartbeatFixIntervalMilliseconds
int maxEventQueueSize{0}; // if set to a positive integer, the event queue will throw an exception when overflown
int httpMaxNumRetry{1};
int httpMaxNumRedirect{1};
long httpRequestTimeoutMilliSeconds{10000};
long httpRequestTimeoutMilliseconds{10000};
int httpConnectionPoolMaxSize{1}; // used to set the maximal number of http connections to be kept in the pool (connections in the pool are idle)
long httpConnectionPoolIdleTimeoutMilliSeconds{0}; // used to purge the http connection pool if all connections in the
long httpConnectionPoolIdleTimeoutMilliseconds{0}; // used to purge the http connection pool if all connections in the
// pool have stayed idle for at least this amount of time
bool enableOneHttpConnectionPerRequest{}; // create a new http connection for each request
#ifdef CCAPI_LEGACY_USE_WEBSOCKETPP
#else
long websocketConnectTimeoutMilliSeconds{10000};
long websocketConnectTimeoutMilliseconds{10000};
#endif
};
} /* namespace ccapi */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class ExecutionManagementServiceBinanceBase : public ExecutionManagementService
}
that->onFail_(thisWsConnection);
},
this->sessionOptions.httpRequestTimeoutMilliSeconds);
this->sessionOptions.httpRequestTimeoutMilliseconds);
}
void onOpen(wspp::connection_hdl hdl) override {
ExecutionManagementService::onOpen(hdl);
Expand Down Expand Up @@ -138,7 +138,7 @@ class ExecutionManagementServiceBinanceBase : public ExecutionManagementService
[wsConnection, that_2 = that->shared_from_base<ExecutionManagementServiceBinanceBase>()](const http::response<http::string_body>& res) {
CCAPI_LOGGER_DEBUG("ping listen key success");
},
that->sessionOptions.httpRequestTimeoutMilliSeconds);
that->sessionOptions.httpRequestTimeoutMilliseconds);
});
}
void onClose(wspp::connection_hdl hdl) override {
Expand Down Expand Up @@ -201,7 +201,7 @@ class ExecutionManagementServiceBinanceBase : public ExecutionManagementService
}
that->onFail_(wsConnectionPtr);
},
this->sessionOptions.httpRequestTimeoutMilliSeconds);
this->sessionOptions.httpRequestTimeoutMilliseconds);
}
void onOpen(std::shared_ptr<WsConnection> wsConnectionPtr) override {
ExecutionManagementService::onOpen(wsConnectionPtr);
Expand Down Expand Up @@ -265,7 +265,7 @@ class ExecutionManagementServiceBinanceBase : public ExecutionManagementService
[wsConnectionPtr, that_2 = that->shared_from_base<ExecutionManagementServiceBinanceBase>()](const http::response<http::string_body>& res) {
CCAPI_LOGGER_DEBUG("ping listen key success");
},
that->sessionOptions.httpRequestTimeoutMilliSeconds);
that->sessionOptions.httpRequestTimeoutMilliseconds);
});
this->pingListenKeyTimerMapByConnectionIdMap[wsConnectionPtr->id] = timerPtr;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ class ExecutionManagementServiceBitstamp : public ExecutionManagementService {
}
that->onFail_(thisWsConnection);
},
this->sessionOptions.httpRequestTimeoutMilliSeconds);
this->sessionOptions.httpRequestTimeoutMilliseconds);
}
#else
void prepareConnect(std::shared_ptr<WsConnection> wsConnectionPtr) override {
Expand Down Expand Up @@ -381,7 +381,7 @@ class ExecutionManagementServiceBitstamp : public ExecutionManagementService {
}
that->onFail_(wsConnectionPtr);
},
this->sessionOptions.httpRequestTimeoutMilliSeconds);
this->sessionOptions.httpRequestTimeoutMilliseconds);
}
#endif
std::vector<std::string> createSendStringListFromSubscription(const WsConnection& wsConnection, const Subscription& subscription, const TimePoint& now,
Expand Down
Loading

0 comments on commit a9b573a

Please sign in to comment.