Skip to content

Commit

Permalink
Merge pull request #394 from crypto-chassis/develop
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
cryptochassis committed Jun 13, 2023
2 parents 4737348 + f46e5a7 commit d8871e4
Show file tree
Hide file tree
Showing 24 changed files with 98 additions and 208 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -76,7 +76,7 @@ Notification to Maintainers and Developers: we are aiming at an effort to transi
### C++
* This library is header-only.
* Example CMake: example/CMakeLists.txt.
* Require C++14 and OpenSSL.
* Require C++14 (prefer C++17) and OpenSSL.
* Macros in the compiler command line:
* Define service enablement macro such as `CCAPI_ENABLE_SERVICE_MARKET_DATA`, `CCAPI_ENABLE_SERVICE_EXECUTION_MANAGEMENT`, `CCAPI_ENABLE_SERVICE_FIX`, etc. and exchange enablement macros such as `CCAPI_ENABLE_EXCHANGE_COINBASE`, etc. These macros can be found at the top of [`include/ccapi_cpp/ccapi_session.h`](include/ccapi_cpp/ccapi_session.h).
* Include directories:
Expand Down
3 changes: 2 additions & 1 deletion app/CMakeLists.txt
Expand Up @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.14)
set(NAME app)
project(${NAME})
if(NOT "${CMAKE_CXX_STANDARD}")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17)
endif()
message(STATUS "CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD}")
if(NOT APPLE AND NOT MSVC)
Expand Down Expand Up @@ -37,5 +37,6 @@ if (WIN32)
set(ADDITIONAL_LINK_LIBRARIES ws2_32)
endif()
link_libraries(OpenSSL::Crypto OpenSSL::SSL ${ADDITIONAL_LINK_LIBRARIES})
add_compile_options(-Wno-deprecated)
add_subdirectory(src/spot_market_making)
add_subdirectory(src/single_order_execution)
132 changes: 0 additions & 132 deletions app/script/download_historical_market_data.py

This file was deleted.

1 change: 0 additions & 1 deletion app/script/requirements.txt

This file was deleted.

5 changes: 1 addition & 4 deletions app/src/single_order_execution/config.env.example
Expand Up @@ -24,10 +24,7 @@
# time_seconds,price,size,is_buyer_maker
# 1625097621.647,2278.15,0.0409,1
# ...
# You can choose to get the data from any vendor. If you choose https://github.com/crypto-chassis/cryptochassis-data-api-docs,
# you can use a convenience script app/script/download_historical_market_data.py. For example,
# python3 download_historical_market_data.py --exchange gemini --base-asset eth --quote-asset usd --start-date 2021-07-01
# --end-date 2021-07-03 --historical-market-data-directory <any-location-you-like> --market-depth 10
# You can choose to get the data from any vendor.


# 'live': Live trade.
Expand Down
5 changes: 1 addition & 4 deletions app/src/spot_market_making/config.env.example
Expand Up @@ -28,10 +28,7 @@
# time_seconds,price,size,is_buyer_maker
# 1625097621.647,2278.15,0.0409,1
# ...
# You can choose to get the data from any vendor. If you choose https://github.com/crypto-chassis/cryptochassis-data-api-docs,
# you can use a convenience script app/script/download_historical_market_data.py. For example,
# python3 download_historical_market_data.py --exchange gemini --base-asset eth --quote-asset usd --start-date 2021-07-01
# --end-date 2021-07-03 --historical-market-data-directory <any-location-you-like>
# You can choose to get the data from any vendor.


# 'live': Live trade.
Expand Down
3 changes: 2 additions & 1 deletion binding/CMakeLists.txt
Expand Up @@ -76,7 +76,7 @@ option(BUILD_PYTHON "Build Python Library" OFF)
option(INSTALL_PYTHON "Install Python Library" OFF)
message(STATUS "Build Python: ${BUILD_PYTHON}")

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
endif()
Expand Down Expand Up @@ -105,4 +105,5 @@ include(UseSWIG)
if(BUILD_TEST)
include(CTest)
endif()
add_compile_options(-Wno-deprecated)
add_subdirectory(python)
3 changes: 2 additions & 1 deletion example/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.14)
set(NAME example)
project(${NAME})
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17)
if(NOT APPLE AND NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
endif()
Expand Down Expand Up @@ -31,6 +31,7 @@ if (WIN32)
set(ADDITIONAL_LINK_LIBRARIES ws2_32)
endif()
link_libraries(OpenSSL::Crypto OpenSSL::SSL ${ADDITIONAL_LINK_LIBRARIES})
add_compile_options(-Wno-deprecated)
add_subdirectory(src/market_data_simple_request)
add_subdirectory(src/market_data_simple_subscription)
add_subdirectory(src/market_data_advanced_request)
Expand Down
70 changes: 45 additions & 25 deletions include/ccapi_cpp/ccapi_ws_connection.h
Expand Up @@ -93,29 +93,7 @@ class WsConnection CCAPI_FINAL {
this->correlationIdList.reserve(subscriptionList.size());
std::transform(subscriptionList.cbegin(), subscriptionList.cend(), this->correlationIdList.begin(),
[](Subscription subscription) { return subscription.getCorrelationId(); });
auto splitted1 = UtilString::split(url, "://");
auto foundSlash = splitted1.at(1).find_first_of('/');
auto foundQuestionMark = splitted1.at(1).find_first_of('?');
if (foundSlash == std::string::npos && foundQuestionMark == std::string::npos) {
this->path = "/";
} else if (foundSlash == std::string::npos && foundQuestionMark != std::string::npos) {
this->path = "/" + splitted1.at(1).substr(foundQuestionMark);
} else if (foundSlash != std::string::npos && foundQuestionMark == std::string::npos) {
this->path = splitted1.at(1).substr(foundSlash);
} else {
this->path = splitted1.at(1).substr(foundSlash);
}
auto splitted2 = UtilString::split(UtilString::split(splitted1.at(1), "/").at(0), ":");
this->host = splitted2.at(0);
if (splitted2.size() == 2) {
this->port = splitted2.at(1);
} else {
if (splitted1.at(0) == "https" || splitted1.at(0) == "wss") {
this->port = CCAPI_HTTPS_PORT_DEFAULT;
} else {
this->port = CCAPI_HTTP_PORT_DEFAULT;
}
}
this->setUrlParts();
}
WsConnection() {}
std::string toString() const {
Expand All @@ -127,7 +105,10 @@ class WsConnection CCAPI_FINAL {
oss << streamPtr;
std::string output = "WsConnection [id = " + id + ", url = " + url + ", group = " + group + ", subscriptionList = " + ccapi::toString(subscriptionList) +
", credential = " + ccapi::toString(shortCredential) + ", status = " + statusToString(status) +
", headers = " + ccapi::toString(headers) + ", streamPtr = " + oss.str() + "]";
", headers = " + ccapi::toString(headers) + ", streamPtr = " + oss.str() + ", remoteCloseCode = " + std::to_string(remoteCloseCode) +
", remoteCloseReason = " + std::string(remoteCloseReason.reason.c_str()) +
", hostHttpHeaderValue = " + ccapi::toString(hostHttpHeaderValue) + ", path = " + ccapi::toString(path) +
", host = " + ccapi::toString(host) + ", port = " + ccapi::toString(port) + "]";
return output;
}
enum class Status {
Expand Down Expand Up @@ -164,8 +145,43 @@ class WsConnection CCAPI_FINAL {
}
return output;
}
std::string getUrl() const { return url; }
void setUrl(const std::string& url) {
this->url = url;
this->setUrlParts();
}
void setUrlParts() {
auto splitted1 = UtilString::split(url, "://");
if (splitted1.size() >= 2) {
auto foundSlash = splitted1.at(1).find_first_of('/');
auto foundQuestionMark = splitted1.at(1).find_first_of('?');
if (foundSlash == std::string::npos && foundQuestionMark == std::string::npos) {
this->path = "/";
} else if (foundSlash == std::string::npos && foundQuestionMark != std::string::npos) {
this->path = "/" + splitted1.at(1).substr(foundQuestionMark);
} else if (foundSlash != std::string::npos && foundQuestionMark == std::string::npos) {
this->path = splitted1.at(1).substr(foundSlash);
} else {
this->path = splitted1.at(1).substr(foundSlash);
}
auto splitted2 = UtilString::split(UtilString::split(splitted1.at(1), "/").at(0), ":");
this->host = splitted2.at(0);
if (splitted2.size() == 2) {
this->port = splitted2.at(1);
} else {
if (splitted1.at(0) == "https" || splitted1.at(0) == "wss") {
this->port = CCAPI_HTTPS_PORT_DEFAULT;
} else {
this->port = CCAPI_HTTP_PORT_DEFAULT;
}
}
}
}
void appendUrlPart(const std::string& urlPart) {
this->url += urlPart;
this->setUrlParts();
}
std::string id;
std::string url;
std::string group;
std::vector<Subscription> subscriptionList;
std::vector<std::string> correlationIdList;
Expand All @@ -179,6 +195,10 @@ class WsConnection CCAPI_FINAL {
std::string path;
std::string host;
std::string port;
#ifndef CCAPI_EXPOSE_INTERNAL
private:
#endif
std::string url;
};
} /* namespace ccapi */
#endif
Expand Down
Expand Up @@ -61,7 +61,7 @@ class ExecutionManagementService : public Service {
#else
std::shared_ptr<beast::websocket::stream<beast::ssl_stream<beast::tcp_stream>>> streamPtr(nullptr);
try {
streamPtr = that->createStream<beast::websocket::stream<beast::ssl_stream<beast::tcp_stream>>>(that->serviceContextPtr->ioContextPtr, that->serviceContextPtr->sslContextPtr, that->hostWs);
streamPtr = that->createWsStream(that->serviceContextPtr->ioContextPtr, that->serviceContextPtr->sslContextPtr);
} catch (const beast::error_code& ec) {
CCAPI_LOGGER_TRACE("fail");
that->onError(Event::Type::SUBSCRIPTION_STATUS, Message::Type::SUBSCRIPTION_FAILURE, ec, "create stream", {subscription.getCorrelationId()});
Expand Down
Expand Up @@ -369,7 +369,7 @@ class ExecutionManagementServiceAscendex : public ExecutionManagementService {
#else
std::shared_ptr<beast::websocket::stream<beast::ssl_stream<beast::tcp_stream>>> streamPtr(nullptr);
try {
streamPtr = that->createStream<beast::websocket::stream<beast::ssl_stream<beast::tcp_stream>>>(that->serviceContextPtr->ioContextPtr, that->serviceContextPtr->sslContextPtr, that->hostWs);
streamPtr = that->createWsStream(that->serviceContextPtr->ioContextPtr, that->serviceContextPtr->sslContextPtr);
} catch (const beast::error_code& ec) {
CCAPI_LOGGER_TRACE("fail");
that->onError(Event::Type::SUBSCRIPTION_STATUS, Message::Type::SUBSCRIPTION_FAILURE, ec, "create stream", {subscription.getCorrelationId()});
Expand Down
Expand Up @@ -189,7 +189,7 @@ class ExecutionManagementServiceBinanceBase : public ExecutionManagementService
document.Parse<rj::kParseNumbersAsStringsFlag>(body.c_str());
std::string listenKey = document["listenKey"].GetString();
std::string url = that->baseUrlWs + "/" + listenKey;
wsConnectionPtr->url = url;
wsConnectionPtr->setUrl(url);
that->connect(wsConnectionPtr);
that->extraPropertyByConnectionIdMap[wsConnectionPtr->id].insert({
{"listenKey", listenKey},
Expand Down
Expand Up @@ -367,7 +367,7 @@ class ExecutionManagementServiceBitstamp : public ExecutionManagementService {
if (document.HasMember("token") && document.HasMember("user_id")) {
std::string token = document["token"].GetString();
std::string userId = document["user_id"].GetString();
wsConnectionPtr->url = that->baseUrlWs;
wsConnectionPtr->setUrl(that->baseUrlWs);
that->connect(wsConnectionPtr);
that->extraPropertyByConnectionIdMap[wsConnectionPtr->id].insert({
{"token", token},
Expand Down
Expand Up @@ -111,7 +111,7 @@ class ExecutionManagementServiceGateioPerpetualFutures : public ExecutionManagem
#else
std::shared_ptr<beast::websocket::stream<beast::ssl_stream<beast::tcp_stream>>> streamPtr(nullptr);
try {
streamPtr = that->createStream<beast::websocket::stream<beast::ssl_stream<beast::tcp_stream>>>(that->serviceContextPtr->ioContextPtr, that->serviceContextPtr->sslContextPtr, that->hostWs);
streamPtr = that->createWsStream(that->serviceContextPtr->ioContextPtr, that->serviceContextPtr->sslContextPtr);
} catch (const beast::error_code& ec) {
CCAPI_LOGGER_TRACE("fail");
that->onError(Event::Type::SUBSCRIPTION_STATUS, Message::Type::SUBSCRIPTION_FAILURE, ec, "create stream", {subscription.getCorrelationId()});
Expand Down
Expand Up @@ -315,16 +315,16 @@ class ExecutionManagementServiceGemini : public ExecutionManagementService {
credential = this->credentialDefault;
}
auto apiKey = mapGetWithDefault(credential, this->apiKeyName);
wsConnectionPtr->url += "?heartbeat=true";
wsConnectionPtr->appendUrlPart("?heartbeat=true");
if (fieldSet == std::set<std::string>({CCAPI_EM_PRIVATE_TRADE})) {
wsConnectionPtr->url += "&eventTypeFilter=fill";
wsConnectionPtr->appendUrlPart("&eventTypeFilter=fill");
}
if (!instrumentSet.empty()) {
for (const auto& instrument : instrumentSet) {
wsConnectionPtr->url += "&symbolFilter=" + instrument;
wsConnectionPtr->appendUrlPart("&symbolFilter=" + instrument);
}
}
wsConnectionPtr->url += "&apiSessionFilter=" + apiKey;
wsConnectionPtr->appendUrlPart("&apiSessionFilter=" + apiKey);
wsConnectionPtr->headers.insert({"X-GEMINI-APIKEY", apiKey});
int64_t nonce = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
std::string payload = R"({"request":"/v1/order/events","nonce":)" + std::to_string(nonce) + "}";
Expand Down
Expand Up @@ -361,7 +361,7 @@ class ExecutionManagementServiceKraken : public ExecutionManagementService {
document.Parse<rj::kParseNumbersAsStringsFlag>(body.c_str());
if (document.HasMember("result") && document["result"].HasMember("token")) {
std::string token = document["result"]["token"].GetString();
wsConnectionPtr->url = that->baseUrlWs;
wsConnectionPtr->setUrl(that->baseUrlWs);
that->connect(wsConnectionPtr);
that->extraPropertyByConnectionIdMap[wsConnectionPtr->id].insert({
{"token", token},
Expand Down

0 comments on commit d8871e4

Please sign in to comment.