Skip to content

Commit 6eaff58

Browse files
Merge pull request #554 from crypto-chassis/develop
Release
2 parents 5f63610 + 25f8dde commit 6eaff58

28 files changed

+231
-126
lines changed

README.md

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
- [Multiple subscription fields](#multiple-subscription-fields)
3333
- [Make Session::sendRequest blocking](#make-sessionsendrequest-blocking)
3434
- [Provide API credentials for an exchange](#provide-api-credentials-for-an-exchange)
35-
- [Override exchange urls](#override-exchange-urls)
3635
- [Complex request parameters](#complex-request-parameters-1)
3736
- [Send request by Websocket API](#send-request-by-websocket-api)
3837
- [Specify instrument type](#specify-instrument-type)
@@ -44,6 +43,9 @@
4443
- [Set timer](#set-timer)
4544
- [Heartbeat](#heartbeat)
4645
- [Use multiple sessions](#use-multiple-sessions)
46+
- [Override exchange urls](#override-exchange-urls)
47+
- [Connect to a proxy](#connect-to-a-proxy)
48+
- [Reduce build time](#reduce-build-time)
4749
- [Performance Tuning](#performance-tuning)
4850
- [Known Issues and Workarounds](#known-issues-and-workarounds)
4951

@@ -60,6 +62,7 @@
6062
* FIX: [binance](https://accounts.maxweb.academy/register?ref=1116718520), coinbase, gemini.
6163
* Join us on Discord https://discord.gg/b5EKcp9s8T and Medium https://cryptochassis.medium.com.
6264
* For any questions, email hello@cryptochassis.com.
65+
* We’re experts in market data collection, high-speed trading system, infrastructure optimization, and proprietary market making. Hire us as engineers, liquidity providers, traders, or asset managers.
6366

6467
## Branches
6568
* The `develop` branch may contain experimental features.
@@ -700,11 +703,11 @@ Bye
700703

701704
#### Specify correlation id
702705

703-
Instantiate `Request` with the desired correlationId. The `correlationId` should be unique.
706+
Instantiate `Request` with the desired `correlationId`. The `correlationId` should be unique.
704707
```
705708
Request request(Request::Operation::CREATE_ORDER, "okx", "BTC-USDT", "cool correlation id");
706709
```
707-
Instantiate `Subscription` with the desired correlationId.
710+
Instantiate `Subscription` with the desired `correlationId`.
708711
```
709712
Subscription subscription("okx", "BTC-USDT", "ORDER_UPDATE", "", "cool correlation id");
710713
```
@@ -767,9 +770,6 @@ Subscription subscription("okx", "BTC-USDT", "ORDER_UPDATE", "", "", {
767770
});
768771
```
769772

770-
#### Override exchange urls
771-
You can override exchange urls at compile time by using macros. See section "exchange REST urls", "exchange WS urls", and "exchange FIX urls" in [`include/ccapi_cpp/ccapi_macro.h`](include/ccapi_cpp/ccapi_macro.h). You can also override exchange urls at runtime. See [this example](example/src/override_exchange_url_at_runtime/main.cpp). These can be useful if you need to connect to test accounts (e.g. https://www.okx.com/docs-v5/en/#overview-demo-trading-services) or connect to an IP address (e.g. ws://172.30.0.146:9000).
772-
773773
#### Complex request parameters
774774
Please follow the exchange's API documentations: e.g. https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-order.
775775
```
@@ -1073,7 +1073,17 @@ Subscription subscription("", "", "HEARTBEAT", "HEARTBEAT_INTERVAL_MILLISECONDS=
10731073
session.subscribe(subscription);
10741074
```
10751075

1076+
#### Override exchange urls
1077+
You can override exchange urls at compile time by using macros. See section "exchange REST urls", "exchange WS urls", and "exchange FIX urls" in [`include/ccapi_cpp/ccapi_macro.h`](include/ccapi_cpp/ccapi_macro.h). You can also override exchange urls at runtime. See [this example](example/src/override_exchange_url_at_runtime/main.cpp). These can be useful if you need to connect to test accounts (e.g. https://www.okx.com/docs-v5/en/#overview-demo-trading-services).
1078+
1079+
#### Connect to a proxy
1080+
Instantiate `Subscription` with the desired `proxyUrl`.
1081+
```
1082+
Subscription subscription("okx", "BTC-USDT", "MARKET_DEPTH", "", "", {}, "172.30.0.146:9000");
1083+
```
10761084

1085+
#### Reduce build time
1086+
The Pimpl (Pointer to Implementation) idiom in C++ can significantly reduce build time. This reduction is achieved by minimizing compilation dependencies and isolating implementation details. See [this example](example/src/reduce_build_time).
10771087

10781088
## Performance Tuning
10791089
* Turn on compiler optimization flags (e.g. `cmake -DCMAKE_BUILD_TYPE=Release ...`).

example/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,4 @@ add_subdirectory(src/override_exchange_url_at_runtime)
8787
add_subdirectory(src/test_order_latency)
8888
add_subdirectory(src/test_cpu_usage)
8989
add_subdirectory(src/use_multiple_sessions)
90+
add_subdirectory(src/reduce_build_time)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
set(NAME reduce_build_time)
2+
project(${NAME})
3+
add_compile_definitions(CCAPI_ENABLE_SERVICE_MARKET_DATA)
4+
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_OKX)
5+
add_executable(${NAME} main.cpp my_session.cpp)
6+
add_dependencies(${NAME} boost rapidjson)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include "ccapi_cpp/ccapi_event_handler.h"
2+
#include "my_session.h"
3+
4+
namespace ccapi {
5+
6+
Logger* Logger::logger = nullptr; // This line is needed.
7+
8+
class MyEventHandler : public EventHandler {
9+
public:
10+
void processEvent(const Event& event, Session*) override { std::cout << "Received an event:\n" + event.toPrettyString(2, 2) << std::endl; }
11+
12+
void setMySessionPtr(MySession* mySessionPtr) { this->mySessionPtr = mySessionPtr; }
13+
14+
private:
15+
MySession* mySessionPtr{nullptr};
16+
};
17+
18+
} /* namespace ccapi */
19+
20+
using ::ccapi::MyEventHandler;
21+
using ::ccapi::MySession;
22+
using ::ccapi::SessionConfigs;
23+
using ::ccapi::SessionOptions;
24+
using ::ccapi::Subscription;
25+
26+
int main(int argc, char** argv) {
27+
SessionOptions sessionOptions;
28+
SessionConfigs sessionConfigs;
29+
MyEventHandler eventHandler;
30+
MySession mySession(sessionOptions, sessionConfigs, &eventHandler);
31+
eventHandler.setMySessionPtr(&mySession);
32+
Subscription subscription("okx", "BTC-USDT", "MARKET_DEPTH");
33+
mySession.subscribe(subscription);
34+
std::this_thread::sleep_for(std::chrono::seconds(10));
35+
mySession.stop();
36+
std::cout << "Bye" << std::endl;
37+
return EXIT_SUCCESS;
38+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include "my_session.h"
2+
3+
#include "ccapi_cpp/ccapi_session.h"
4+
5+
namespace ccapi {
6+
7+
MySession::MySession(const SessionOptions& sessionOptions, const SessionConfigs& sessionConfigs, EventHandler* eventHandler)
8+
: ccapiSessionPtr(new Session(sessionOptions, sessionConfigs, eventHandler)) {}
9+
10+
void MySession::subscribe(Subscription& subscription) { this->ccapiSessionPtr->subscribe(subscription); }
11+
12+
void MySession::stop() { this->ccapiSessionPtr->stop(); }
13+
14+
} // namespace ccapi
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#ifndef EXAMPLE_SRC_REDUCE_BUILD_TIME_MY_SESSION_H_
2+
#define EXAMPLE_SRC_REDUCE_BUILD_TIME_MY_SESSION_H_
3+
4+
#include "ccapi_cpp/ccapi_session_configs.h"
5+
#include "ccapi_cpp/ccapi_session_options.h"
6+
#include "ccapi_cpp/ccapi_subscription.h"
7+
8+
namespace ccapi {
9+
10+
class EventHandler;
11+
class Session; // forward declaration instead of including full header!
12+
13+
class MySession {
14+
public:
15+
explicit MySession(const SessionOptions& sessionOptions, const SessionConfigs& sessionConfigs, EventHandler* eventHandler);
16+
void subscribe(Subscription& subscription);
17+
void stop();
18+
19+
private:
20+
Session* ccapiSessionPtr{nullptr};
21+
};
22+
23+
} // namespace ccapi
24+
25+
#endif // EXAMPLE_SRC_REDUCE_BUILD_TIME_MY_SESSION_H_

include/ccapi_cpp/ccapi_inflate_stream.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,14 @@ class InflateStream {
5858
return boost::system::error_code();
5959
}
6060

61-
boost::system::error_code decompress(uint8_t const *buf, size_t len, std::string &out) {
61+
boost::system::error_code decompress(uint8_t const* buf, size_t len, std::string& out) {
6262
if (!this->initialized) {
6363
CCAPI_LOGGER_ERROR("decompress error");
6464
return boost::system::error_code();
6565
}
6666

6767
this->istate.avail_in = len;
68-
this->istate.next_in = const_cast<unsigned char *>(buf);
68+
this->istate.next_in = const_cast<unsigned char*>(buf);
6969
do {
7070
this->istate.avail_out = this->decompressBufferSize;
7171
this->istate.next_out = this->buffer.get();
@@ -74,7 +74,7 @@ class InflateStream {
7474
CCAPI_LOGGER_ERROR("decompress error");
7575
return boost::system::error_code();
7676
}
77-
out.append(reinterpret_cast<char *>(this->buffer.get()), this->decompressBufferSize - this->istate.avail_out);
77+
out.append(reinterpret_cast<char*>(this->buffer.get()), this->decompressBufferSize - this->istate.avail_out);
7878
} while (this->istate.avail_out == 0);
7979
return boost::system::error_code();
8080
}

include/ccapi_cpp/ccapi_macro.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,10 +1160,6 @@
11601160
#define CCAPI_HUOBI_USDT_SWAP_SUBSCRIBE_ORDER_DATA_TOPIC "orders_cross"
11611161
#endif
11621162

1163-
#ifndef CCAPI_HUOBI_USDT_SWAP_SUBSCRIBE_MATCH_ORDER_DATA_TOPIC
1164-
#define CCAPI_HUOBI_USDT_SWAP_SUBSCRIBE_MATCH_ORDER_DATA_TOPIC "matchOrders_cross"
1165-
#endif
1166-
11671163
#ifndef CCAPI_HUOBI_COIN_SWAP_URL_WS_BASE
11681164
#define CCAPI_HUOBI_COIN_SWAP_URL_WS_BASE "wss://api.hbdm.com"
11691165
#endif
@@ -1172,10 +1168,6 @@
11721168
#define CCAPI_HUOBI_COIN_SWAP_SUBSCRIBE_ORDER_DATA_TOPIC "orders"
11731169
#endif
11741170

1175-
#ifndef CCAPI_HUOBI_COIN_SWAP_SUBSCRIBE_MATCH_ORDER_DATA_TOPIC
1176-
#define CCAPI_HUOBI_COIN_SWAP_SUBSCRIBE_MATCH_ORDER_DATA_TOPIC "matchOrders"
1177-
#endif
1178-
11791171
#ifndef CCAPI_OKX_URL_WS_BASE
11801172
#define CCAPI_OKX_URL_WS_BASE "wss://ws.okx.com:8443"
11811173
#endif

include/ccapi_cpp/ccapi_subscription.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ namespace ccapi {
1616
class Subscription {
1717
public:
1818
explicit Subscription(const std::string& exchange = "", const std::string& instrument = "", const std::string& field = "", const std::string& options = "",
19-
const std::string& correlationId = "", const std::map<std::string, std::string>& credential = {})
20-
: exchange(exchange), instrument(instrument), field(field), correlationId(correlationId), credential(credential) {
19+
const std::string& correlationId = "", const std::map<std::string, std::string>& credential = {}, const std::string& proxyUrl = "")
20+
: exchange(exchange), instrument(instrument), field(field), correlationId(correlationId), credential(credential), proxyUrl(proxyUrl) {
2121
auto originalInstrumentSet = UtilString::splitToSet(instrument, ",");
2222
std::copy_if(originalInstrumentSet.begin(), originalInstrumentSet.end(), std::inserter(this->instrumentSet, this->instrumentSet.end()),
2323
[](const std::string& value) { return !value.empty(); });
@@ -68,8 +68,8 @@ class Subscription {
6868
}
6969
std::string output = "Subscription [exchange = " + exchange + ", marginType = " + marginType + ", instrumentType = " + instrumentType +
7070
", instrument = " + instrument + ", field = " + field + ", optionMap = " + ccapi::toString(optionMap) +
71-
", correlationId = " + correlationId + ", credential = " + ccapi::toString(shortCredential) + ", serviceName = " + serviceName +
72-
", timeSent = " + UtilTime::getISOTimestamp(timeSent) + "]";
71+
", correlationId = " + correlationId + ", credential = " + ccapi::toString(shortCredential) + ", proxyUrl = " + proxyUrl +
72+
", serviceName = " + serviceName + ", timeSent = " + UtilTime::getISOTimestamp(timeSent) + "]";
7373
return output;
7474
}
7575

@@ -89,6 +89,8 @@ class Subscription {
8989

9090
const std::map<std::string, std::string>& getCredential() const { return credential; }
9191

92+
const std::string& getProxyUrl() const { return proxyUrl; }
93+
9294
const std::string& getServiceName() const { return serviceName; }
9395

9496
const std::set<std::string>& getInstrumentSet() const { return instrumentSet; }
@@ -131,11 +133,14 @@ class Subscription {
131133

132134
void setField(const std::string& field) { this->field = field; }
133135

136+
void setProxyUrl(const std::string& proxyUrl) { this->proxyUrl = proxyUrl; }
137+
134138
void setTimeSent(TimePoint timeSent) { this->timeSent = timeSent; }
135139

136140
void setInstrumentType(const std::string& instrumentType) { this->instrumentType = instrumentType; }
137141

138142
void setMarginType(const std::string& marginType) { this->marginType = marginType; }
143+
139144
enum class Status {
140145
UNKNOWN,
141146
SUBSCRIBING,
@@ -180,6 +185,7 @@ class Subscription {
180185
std::map<std::string, std::string> optionMap;
181186
std::string correlationId;
182187
std::map<std::string, std::string> credential;
188+
std::string proxyUrl;
183189
std::string serviceName;
184190
std::set<std::string> instrumentSet;
185191
std::set<std::string> fieldSet;

include/ccapi_cpp/ccapi_url.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class Url {
3131
return output;
3232
}
3333

34-
static std::string urlEncode(const std::string &value) {
34+
static std::string urlEncode(const std::string& value) {
3535
std::ostringstream escaped;
3636
escaped.fill('0');
3737
escaped << std::hex;
@@ -50,7 +50,7 @@ class Url {
5050
return escaped.str();
5151
}
5252

53-
static std::string urlDecode(const std::string &value) {
53+
static std::string urlDecode(const std::string& value) {
5454
std::string ret;
5555
char ch;
5656
int i, ii;
@@ -67,18 +67,18 @@ class Url {
6767
return (ret);
6868
}
6969

70-
static std::map<std::string, std::string> convertQueryStringToMap(const std::string &input) {
70+
static std::map<std::string, std::string> convertQueryStringToMap(const std::string& input) {
7171
std::map<std::string, std::string> output;
72-
for (const auto &x : UtilString::split(input, "&")) {
72+
for (const auto& x : UtilString::split(input, "&")) {
7373
auto y = UtilString::split(x, "=");
7474
output.insert(std::make_pair(y.at(0), Url::urlDecode(y.at(1))));
7575
}
7676
return output;
7777
}
7878

79-
static std::string convertMapToQueryString(const std::map<std::string, std::string> &input) {
79+
static std::string convertMapToQueryString(const std::map<std::string, std::string>& input) {
8080
std::string output;
81-
for (const auto &x : input) {
81+
for (const auto& x : input) {
8282
output += x.first;
8383
output += "=";
8484
output += x.second;
@@ -90,10 +90,10 @@ class Url {
9090
return output;
9191
}
9292

93-
static std::string convertMapToFormUrlEncoded(const std::map<std::string, std::string> &input) {
93+
static std::string convertMapToFormUrlEncoded(const std::map<std::string, std::string>& input) {
9494
std::string output;
9595
int i = 0;
96-
for (const auto &x : input) {
96+
for (const auto& x : input) {
9797
output += Url::urlEncode(x.first);
9898
output += "=";
9999
output += Url::urlEncode(x.second);
@@ -104,9 +104,9 @@ class Url {
104104
return output;
105105
}
106106

107-
static std::map<std::string, std::string> convertFormUrlEncodedToMap(const std::string &input) {
107+
static std::map<std::string, std::string> convertFormUrlEncodedToMap(const std::string& input) {
108108
std::map<std::string, std::string> output;
109-
for (const auto &x : UtilString::split(input, "&")) {
109+
for (const auto& x : UtilString::split(input, "&")) {
110110
auto y = UtilString::split(x, "=");
111111
output.insert(std::make_pair(Url::urlDecode(y.at(0)), Url::urlDecode(y.at(1))));
112112
}

0 commit comments

Comments
 (0)