Skip to content

Commit 7d88456

Browse files
author
ubuntu
committed
fix frequent disconnection issues
1 parent d479936 commit 7d88456

22 files changed

Lines changed: 279 additions & 153 deletions

README.md

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -841,20 +841,7 @@ For a specific exchange and instrument, submit a simple limit order.
841841
842842
namespace ccapi {
843843
844-
class MyLogger final : public Logger {
845-
public:
846-
void logMessage(const std::string& severity, const std::string& threadId, const std::string& timeISO, const std::string& fileName,
847-
const std::string& lineNumber, const std::string& message) override {
848-
std::lock_guard<std::mutex> lock(m);
849-
std::cout << threadId << ": [" << timeISO << "] {" << fileName << ":" << lineNumber << "} " << severity << std::string(8, ' ') << message << std::endl;
850-
}
851-
852-
private:
853-
std::mutex m;
854-
};
855-
856-
MyLogger myLogger;
857-
Logger* Logger::logger = &myLogger;
844+
Logger* Logger::logger = nullptr; // This line is needed.
858845
859846
class MyEventHandler : public EventHandler {
860847
public:
@@ -1054,7 +1041,7 @@ Logger* Logger::logger = &myLogger;
10541041

10551042
#### Set timer
10561043

1057-
[C++](example/src/utility_set_timer/main.cpp)
1044+
[C++](example/src/set_timer/main.cpp)
10581045

10591046
To perform an asynchronous wait, use the utility method `setTimer` in class `Session`. The handlers are invoked in the same threads as the `processEvent` method in the `EventHandler` class. The `id` of the timer should be unique. `delayMilliseconds` can be 0.
10601047
```
@@ -1066,6 +1053,16 @@ sessionPtr->setTimer(
10661053
[]() { std::cout << std::string("Timer success handler is triggered at ") + UtilTime::getISOTimestamp(UtilTime::now()) << std::endl; });
10671054
```
10681055

1056+
#### Heartbeat
1057+
1058+
[C++](example/src/heartbeat/main.cpp)
1059+
1060+
To receive heartbeat events, instantiate a `Subscription` object with field `HEARTBEAT` and subscribe it.
1061+
```
1062+
Subscription subscription("", "", "HEARTBEAT", "HEARTBEAT_INTERVAL_MILLISECONDS=1000");
1063+
session.subscribe(subscription);
1064+
```
1065+
10691066
## Performance Tuning
10701067
* Turn on compiler optimization flags (e.g. `cmake -DCMAKE_BUILD_TYPE=Release ...`).
10711068
* Enable link time optimization (e.g. in CMakeLists.txt `set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)` before a target is created). Note that link time optimization is only applicable to static linking.

binding/python/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ add_custom_target(
5656
# falls back to setup.py automatically)
5757
COMMAND ${Python_EXECUTABLE} -m build --wheel
5858
# install the freshly-built wheel
59-
COMMAND ${Python_EXECUTABLE} -m pip install --upgrade dist/*.whl
59+
COMMAND ${Python_EXECUTABLE} -m pip install --force-reinstall dist/*.whl
6060
# -----------------------
6161
WORKING_DIRECTORY ${PACKAGING_DIR_FULL})
6262
add_dependencies(${PYTHON_PACKAGING_TARGET_NAME} ${SWIG_TARGET_NAME})

binding/python/example/fix_simple/main.py

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,48 +5,55 @@
55

66

77
class MyEventHandler(EventHandler):
8-
def __init__(self):
8+
def __init__(self, fixSubscriptionCorrelationId):
99
super().__init__()
10+
self.fixSubscriptionCorrelationId = fixSubscriptionCorrelationId
11+
self.sentRequest = False
12+
self.firstProcessEventTime = None
1013

1114
def processEvent(self, event: Event, session: Session) -> None:
12-
if event.getType() == Event.Type_AUTHORIZATION_STATUS:
13-
print(f"Received an event of type AUTHORIZATION_STATUS:\n{event.toPrettyString(2, 2)}")
14-
message = event.getMessageList()[0]
15-
if message.getType() == Message.Type_AUTHORIZATION_SUCCESS:
16-
request = Request(Request.Operation_FIX, "coinbase", "", "any")
17-
request.appendFixParam(
18-
[
19-
(35, "D"),
20-
(11, "6d4eb0fb-2229-469f-873e-557dd78ac11e"),
21-
(55, "BTC-USD"),
22-
(54, "1"),
23-
(44, "20000"),
24-
(38, "0.001"),
25-
(40, "2"),
26-
(59, "1"),
27-
]
28-
)
29-
session.sendRequestByFix(request)
30-
elif event.getType() == Event.Type_FIX:
31-
print(f"Received an event of type FIX:\n{event.toPrettyString(2, 2)}")
15+
if event.getType() != Event.Type_HEARTBEAT:
16+
print(f"Received an event:\n{event.toPrettyString(2, 2)}")
17+
if self.firstProcessEventTime is None:
18+
self.firstProcessEventTime = time.time()
19+
elapsedSeconds = 0
20+
else:
21+
elapsedSeconds = time.time() - self.firstProcessEventTime
22+
23+
if elapsedSeconds >= 1 and not self.sentRequest:
24+
self.sentRequest = True
25+
request = Request(Request.Operation_FIX, "binance")
26+
request.appendFixParam(
27+
[
28+
(35, "D"),
29+
(11, request.generateNextClientOrderId()),
30+
(55, "BTCUSDT"),
31+
(54, "1"),
32+
(44, "100000"),
33+
(38, "0.0001"),
34+
(40, "2"),
35+
(59, "1"),
36+
]
37+
)
38+
session.sendRequestByFix(self.fixSubscriptionCorrelationId, request)
3239

3340

3441
if __name__ == "__main__":
35-
if not os.environ.get("COINBASE_API_KEY"):
36-
print("Please set environment variable COINBASE_API_KEY", file=sys.stderr)
37-
sys.exit(1)
38-
if not os.environ.get("COINBASE_API_SECRET"):
39-
print("Please set environment variable COINBASE_API_SECRET", file=sys.stderr)
42+
if not os.environ.get("BINANCE_FIX_API_KEY"):
43+
print("Please set environment variable BINANCE_FIX_API_KEY", file=sys.stderr)
4044
sys.exit(1)
41-
if not os.environ.get("COINBASE_API_PASSPHRASE"):
42-
print("Please set environment variable COINBASE_API_PASSPHRASE", file=sys.stderr)
45+
if not os.environ.get("BINANCE_FIX_API_PRIVATE_KEY_PATH"):
46+
print("Please set environment variable BINANCE_FIX_API_PRIVATE_KEY_PATH", file=sys.stderr)
4347
sys.exit(1)
44-
eventHandler = MyEventHandler()
48+
fixSubscriptionCorrelationId = "any"
49+
eventHandler = MyEventHandler(fixSubscriptionCorrelationId)
4550
option = SessionOptions()
4651
config = SessionConfigs()
4752
session = Session(option, config, eventHandler)
48-
subscription = Subscription("coinbase", "", "FIX", "", "any")
53+
subscription = Subscription("binance", "", "FIX", "", fixSubscriptionCorrelationId)
54+
session.subscribe(subscription)
55+
subscription = Subscription("", "", "HEARTBEAT", "HEARTBEAT_INTERVAL_MILLISECONDS=1000")
4956
session.subscribe(subscription)
50-
time.sleep(10)
57+
time.sleep(100)
5158
session.stop()
5259
print("Bye")
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import time
2+
from ccapi import EventHandler, SessionOptions, SessionConfigs, Session, Subscription, Event
3+
4+
5+
class MyEventHandler(EventHandler):
6+
def __init__(self):
7+
super().__init__()
8+
9+
def processEvent(self, event: Event, session: Session) -> None:
10+
if event.getType() == Event.Type_HEARTBEAT:
11+
print(f"Received an event of type HEARTBEAT:\n{event.toPrettyString(2, 2)}")
12+
13+
14+
if __name__ == "__main__":
15+
eventHandler = MyEventHandler()
16+
option = SessionOptions()
17+
config = SessionConfigs()
18+
session = Session(option, config, eventHandler)
19+
subscription = Subscription("", "", "HEARTBEAT", "HEARTBEAT_INTERVAL_MILLISECONDS=1000")
20+
session.subscribe(subscription)
21+
time.sleep(10)
22+
session.stop()
23+
print("Bye")

example/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ add_subdirectory(src/execution_management_advanced_subscription)
8181
add_subdirectory(src/fix_simple)
8282
add_subdirectory(src/fix_advanced)
8383
add_subdirectory(src/enable_library_logging)
84-
add_subdirectory(src/utility_set_timer)
84+
add_subdirectory(src/set_timer)
85+
add_subdirectory(src/heartbeat)
8586
add_subdirectory(src/override_exchange_url_at_runtime)
8687
add_subdirectory(src/test_order_latency)
8788
add_subdirectory(src/test_cpu_usage)

example/src/utility_set_timer/CMakeLists.txt renamed to example/src/heartbeat/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
set(NAME utility_set_timer)
1+
set(NAME heartbeat)
22
project(${NAME})
33
add_compile_definitions(CCAPI_ENABLE_SERVICE_MARKET_DATA)
44
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_OKX)

example/src/heartbeat/main.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#include "ccapi_cpp/ccapi_session.h"
2+
3+
namespace ccapi {
4+
5+
Logger* Logger::logger = nullptr; // This line is needed.
6+
7+
class MyEventHandler : public EventHandler {
8+
public:
9+
void processEvent(const Event& event, Session* sessionPtr) override {
10+
if (event.getType() == Event::Type::HEARTBEAT) {
11+
std::cout << "Received an event of type HEARTBEAT:\n" + event.toPrettyString(2, 2) << std::endl;
12+
}
13+
}
14+
};
15+
16+
} /* namespace ccapi */
17+
18+
using ::ccapi::MyEventHandler;
19+
using ::ccapi::Session;
20+
using ::ccapi::SessionConfigs;
21+
using ::ccapi::SessionOptions;
22+
using ::ccapi::Subscription;
23+
24+
int main(int argc, char** argv) {
25+
SessionOptions sessionOptions;
26+
SessionConfigs sessionConfigs;
27+
MyEventHandler eventHandler;
28+
Session session(sessionOptions, sessionConfigs, &eventHandler);
29+
Subscription subscription("", "", "HEARTBEAT", "HEARTBEAT_INTERVAL_MILLISECONDS=1000");
30+
session.subscribe(subscription);
31+
std::this_thread::sleep_for(std::chrono::seconds(10));
32+
session.stop();
33+
std::cout << "Bye" << std::endl;
34+
return EXIT_SUCCESS;
35+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
set(NAME set_timer)
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)
6+
add_dependencies(${NAME} boost rapidjson)

include/ccapi_cpp/ccapi_element.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,17 @@ class Element {
8686
}
8787

8888
std::string toString() const {
89-
std::string output =
90-
isFix ? "Element [tagValueList = " + ccapi::toString(tagValueList) + "]" : "Element [nameValueMap = " + ccapi::toString(nameValueMap) + "]";
89+
std::string output = isFix ? "Element [tagValueList = " + ccapi::toString(tagValueList) + ", nameValueMap = " + ccapi::toString(nameValueMap) + "]"
90+
: "Element [nameValueMap = " + ccapi::toString(nameValueMap) + "]";
9191
return output;
9292
}
9393

9494
std::string toPrettyString(const int space = 2, const int leftToIndent = 0, const bool indentFirstLine = true) const {
9595
std::string sl(leftToIndent, ' ');
9696
std::string ss(leftToIndent + space, ' ');
9797
std::string output = isFix ? (indentFirstLine ? sl : "") + "Element [\n" + ss +
98-
"tagValueList = " + ccapi::toPrettyString(tagValueList, space, space + leftToIndent, false) + "\n" + sl + "]"
98+
"tagValueList = " + ccapi::toPrettyString(tagValueList, space, space + leftToIndent, false) + ",\n" + ss +
99+
"nameValueMap = " + ccapi::toPrettyString(nameValueMap, space, space + leftToIndent, false) + "\n" + sl + "]"
99100
: (indentFirstLine ? sl : "") + "Element [\n" + ss +
100101
"nameValueMap = " + ccapi::toPrettyString(nameValueMap, space, space + leftToIndent, false) + "\n" + sl + "]";
101102
return output;

0 commit comments

Comments
 (0)