Compare commits
58
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8fcd19034 | ||
|
|
993fe6697f | ||
|
|
fa18dcc6d4 | ||
|
|
5786f8eba1 | ||
|
|
f5ae6559ee | ||
|
|
917c3ee909 | ||
|
|
25866533ea | ||
|
|
4306ac0737 | ||
|
|
874f655b55 | ||
|
|
17c7a631f9 | ||
|
|
0a98fd7fed | ||
|
|
d82855aec2 | ||
|
|
516c9c0d84 | ||
|
|
1bfdeeded4 | ||
|
|
929c19f4b2 | ||
|
|
70e58edacb | ||
|
|
26702a1a7e | ||
|
|
71db591365 | ||
|
|
a8d013d054 | ||
|
|
3179f2647f | ||
|
|
91020c2ccc | ||
|
|
404104e12b | ||
|
|
a4145e6bd5 | ||
|
|
425cd6e6a0 | ||
|
|
c21735ad92 | ||
|
|
2f4708eaf5 | ||
|
|
062e28bf5d | ||
|
|
a2754bc2f5 | ||
|
|
6638a89abe | ||
|
|
a11979f1a2 | ||
|
|
7a04547b8d | ||
|
|
d4ebfcb5a2 | ||
|
|
4ac3b77030 | ||
|
|
5e9bd1729b | ||
|
|
14f6e7646a | ||
|
|
e8281dc5a0 | ||
|
|
d3efd1215f | ||
|
|
a5ac746a9d | ||
|
|
578d8678d0 | ||
|
|
7e7b96be22 | ||
|
|
26dd802e6a | ||
|
|
129a0fe3ca | ||
|
|
2c95cb6905 | ||
|
|
61f0851c3f | ||
|
|
5e6dea91f3 | ||
|
|
0c91672317 | ||
|
|
e62fe88f1a | ||
|
|
14993973ff | ||
|
|
7e84e688b7 | ||
|
|
98dd396687 | ||
|
|
eea3bc1d8b | ||
|
|
9e2f72b26e | ||
|
|
1137b0daf8 | ||
|
|
d60720208d | ||
|
|
780633e639 | ||
|
|
7168a4b54c | ||
|
|
b5e85ac873 | ||
|
|
a5a5d56228 |
No files matched your search
@@ -34,3 +34,5 @@ trace_data/
|
||||
/doc/user/public/*
|
||||
.ionide/*
|
||||
/.ignore
|
||||
/build
|
||||
/analysis_data
|
||||
+1
-1
@@ -40,7 +40,7 @@ else ()
|
||||
-fPIC -Wall -pedantic -Wextra -Werror \
|
||||
-Wno-missing-braces -Wno-ignored-qualifiers \
|
||||
--std=c++17 -fdiagnostics-color")
|
||||
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -DNDEBUG -O3")
|
||||
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_DEBUG} -DNDEBUG -O3")
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wno-undef")
|
||||
add_subdirectory(src/server/sparkd)
|
||||
add_subdirectory(src/lib)
|
||||
|
||||
+1
-1
Submodule docker/linux updated: e13bb5d8df...c40e6eba4b.
+1
-1
Submodule externals updated: b5ca264286...6d8f64ca5c.
@@ -36,6 +36,7 @@ namespace bts {
|
||||
Plugin,
|
||||
ClientSdk,
|
||||
Http,
|
||||
OrderMan2,
|
||||
// Please keep this list in sync with logging.h/logging.cpp
|
||||
}
|
||||
|
||||
@@ -105,6 +106,7 @@ namespace bts {
|
||||
internal static Logger DataFlow => new Logger(Subsystem.DataFlow);
|
||||
public static Logger ClientSdk => new Logger(Subsystem.ClientSdk);
|
||||
public static Logger Http => new Logger(Subsystem.Http);
|
||||
public static Logger OrderMan2 => new Logger(Subsystem.OrderMan2);
|
||||
|
||||
internal static void log_at(this Logger logger, Level level, string message) {
|
||||
switch (level) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
Session ID Access ID Secret Key Creation Date Expiration Date Environment
|
||||
Session ID Access ID Secret Key Creation Date Expiration Date Environment
|
||||
|
||||
M4D lLtjH74y1Kh5XUJTLyH2 f1K_tROQp2lTIplVp34WxKa7xDUgfFnIteolfik061o 2019-09-03 2020-09-03 CERT
|
||||
M4D lLtjH74y1Kh5XUJTLyH2 f1K_tROQp2lTIplVp34WxKa7xDUgfFnIteolfik061o 2019-09-03 2020-09-03 CERT
|
||||
|
||||
MC1 VEMlkDuLz74OVHSuacQB IuHyYT3b-9KUo3WsuXykt-fXsjzp7L-JOrdCSQZLNl0 2019-09-03 2020-09-03 CERT
|
||||
MC1 VEMlkDuLz74OVHSuacQB IuHyYT3b-9KUo3WsuXykt-fXsjzp7L-JOrdCSQZLNl0 2019-09-03 2020-09-03 CERT
|
||||
|
||||
MC5 77lzSUwPLlM9obaXh2mK z6aA9qfASDKfZkYTVKFqJd-78i0HZ2Q9ec3CKCYIqHg 2019-09-03 2020-09-03 CERT
|
||||
MC5 77lzSUwPLlM9obaXh2mK z6aA9qfASDKfZkYTVKFqJd-78i0HZ2Q9ec3CKCYIqHg 2019-09-03 2020-09-03 CERT
|
||||
|
||||
MC7 RphzI3rn71oGUEiYnX9e y6OvvPPyoyj2S8YAnE1gFduXT8v29HIMjO5EngYxSNg 2019-09-03 2020-09-03 CERT
|
||||
MC7 RphzI3rn71oGUEiYnX9e y6OvvPPyoyj2S8YAnE1gFduXT8v29HIMjO5EngYxSNg 2019-09-03 2020-09-03 CERT
|
||||
|
||||
MC8 PYBIm2TI9gFPIxmHbuYl 6o-ZolGH2DdeQOlGtJ5Zqoh_kg7VdbxkmjeOHmigKwU 2019-09-03 2020-09-03 CERT
|
||||
MC8 PYBIm2TI9gFPIxmHbuYl 6o-ZolGH2DdeQOlGtJ5Zqoh_kg7VdbxkmjeOHmigKwU 2019-09-03 2020-09-03 CERT
|
||||
|
||||
NGG 1OXPqNxPhbqbzm0kF92e qlUrwY1KG1Pyq-TcbJgMqYXmBTQoAi-wEEBERRDRZPE 2019-12-20 2020-12-20 NEWRELEASE
|
||||
@@ -1 +1 @@
|
||||
set(sources api/apicore.proto;api/apigateway.proto;api/apioptions.proto;api/core/ApiClientInterop.cpp;api/core/ApiServerInterop.cpp;api/public/ApiServer.cpp;api/public/ClientChannel.cpp;api/public/QuickbusClientChannel.cpp;api/public/ServerChannel.cpp;api/public/ServiceContext.cpp;api/service_helpers/AdminServiceUtils.cpp;api/service_helpers/AlgoServiceUtils.cpp;api/service_helpers/PositionUtilities.cpp;api/services/AdminService.proto;api/services/AlgoDefinitionService.proto;api/services/AlgoService.proto;api/services/ApiUnitTestService.proto;api/services/AuthService.proto;api/services/BasePositionService.proto;api/services/ErrorReportService.proto;api/services/HelloService.proto;api/services/MBOService.proto;api/services/MarginService.proto;api/services/MarketDataAuxiliaryService.proto;api/services/MarketDataRelay.proto;api/services/MoneyFileService.proto;api/services/OrderService.proto;api/services/OutOfProcessURLListener.proto;api/services/PersistenceService.proto;api/services/PositionService.proto;api/services/ShellDiagnosticService.proto;api/services/ShellLatencyService.proto;api/services/SyntheticSecurityService.proto;api/test/ApiTests.cpp;api/test/HelloServiceServer.cpp;config/ConfigCheck.cpp;config/ConfigDownloader.cpp;config/ConfigErrorCollector.cpp;config/ConfigLog.cpp;config/ConfigPropertyEvaluator.cpp;config/ConfigValueQueue.cpp;config/ConfigurationException.cpp;config/ConfigurationState.cpp;config/PreprocessInputStream.cpp;config/config.cpp;config/defaults/MarketData.conf;config/defaults/Ports.conf;config/defaults/Symbols.conf;config/defaults/cme_reference_data.conf;config/defaults/edge.conf;config/defaults/jetfix.conf;config/defaults/keycode.conf;config/defaults/logging.conf;config/defaults/orderman_cfg.conf;config/defaults/orders_fills_cleanup.conf;config/defaults/position_cfg.conf;config/defaults/span.conf;config/defaults/spreader.conf;config/defaults/testkeys.conf;config/defaults/threads.conf;config/defaults/toggles.conf;config/extensions/extensions.proto;config/invalid/invalid.proto;config/protos/ExchangeSimCfg.proto;config/protos/MarketData.proto;config/protos/Ports.proto;config/protos/Symbols.proto;config/protos/UI.proto;config/protos/cme_reference_data.proto;config/protos/jetfix.proto;config/protos/keycode.proto;config/protos/logging.proto;config/protos/mercury_cfg.proto;config/protos/orderman_cfg.proto;config/protos/orders_fills_cleanup.proto;config/protos/perflog_cfg.proto;config/protos/position_cfg.proto;config/protos/quickbus_cfg.proto;config/protos/span.proto;config/protos/spreader.proto;config/protos/system.proto;config/protos/testkeys.proto;config/protos/threads.proto;config/protos/toggles.proto;config/tests/HTTPServer.cpp;config/tests/config_ref_tests.cpp;config/tests/config_tests.cpp;config/text_format/text_format.cpp;domain_model/Security.cpp;domain_model/Security.proto;domain_model/SecurityTests.cpp;domain_model/sod.cpp;domain_model/tests/domain_tests.cpp;expression/BooleanGrammar.cpp;expression/ExpressionEvaluator.cpp;expression/ParserExceptions.cpp;expression/Value.cpp;expression/tests/expression_parser_tests.cpp;jetfix/codec/FIXArray.cpp;jetfix/common/OutFIX.cpp;jetfix/connection/AsyncReader.cpp;jetfix/connection/IConnection.cpp;jetfix/connection/SocketConnection.cpp;jetfix/gateway/CoreGateway.cpp;jetfix/gateway/JetFIXGateway.cpp;jetfix/gateway/Session.cpp;jetfix/store/FIXFileStore.cpp;jetfix/store/session_name.cpp;jetfix/tests/async_reader_tests.cpp;jetfix/tests/decoding_tests.cpp;jetfix/tests/fix_encoding_stream_tests.cpp;jetfix/tests/fix_fragment_tests.cpp;jetfix/tests/jetfix_performance_tests.cpp;jetfix/tests/sample_fix.cpp;jetfix/tests/store_tests.cpp;logging/LoggerHub.cpp;logging/Sink.cpp;logging/logging.cpp;logging/tests/logging_tests.cpp;md/Diag/MDPeriodicDumper.cpp;md/Diag/ShmDumper.cpp;md/MBOProcessor.cpp;md/MBOServiceServer.cpp;md/MDClient.cpp;md/MDConsumer.cpp;md/MDConsumerHandle.cpp;md/MDConsumerInterop.cpp;md/MDProducer.cpp;md/MDProducerHandle.cpp;md/MemorySegmentUtils.cpp;md/PlatformLoader.cpp;md/PriceSize.cpp;md/SecurityCache.cpp;md/SecurityDB.cpp;md/SecurityIDRecorder.cpp;md/SecurityMapper.cpp;md/SecurityOracle.cpp;md/SettlementRecorder.cpp;md/Shm/FixedSecurity.cpp;md/SyntheticSecurityService.cpp;md/cme/MDP3Utils.cpp;md/common.cpp;md/ice/ICEUtils.cpp;md/protos/co2.proto;md/relay/QueryServer.cpp;md/relay/RelayClient.cpp;md/relay/RelayRecorder.cpp;md/test/Co2ManagedTestHelper.cpp;md/test/Co2TestInstrument.cpp;md/test/mbo_tests.cpp;md/test/md2_tests.cpp;md/test/md_test_utils.cpp;md/test/synthetic_book_merge_tests.cpp;md/vendor/OnixsUtils.cpp;mercury/actors/IPollableActor.cpp;mercury/broker/Broker.cpp;mercury/broker/BrokerProxy.cpp;mercury/broker/ILocalBroker.cpp;mercury/broker/IRemoteBroker.cpp;mercury/common/mercury_common.cpp;mercury/events/TimerEvent.cpp;mercury/executor/Executor.cpp;mercury/topics/Topic.cpp;metrics/metrics.cpp;metrics/system_metrics.cpp;orderman/actors/AsyncFactory.cpp;orderman/actors/ExecutionGateway.cpp;orderman/actors/FillStore.cpp;orLine truncated
|
||||
set(sources api/apicore.proto;api/apigateway.proto;api/apioptions.proto;api/core/ApiClientInterop.cpp;api/core/ApiServerInterop.cpp;api/public/ApiServer.cpp;api/public/ClientChannel.cpp;api/public/QuickbusClientChannel.cpp;api/public/ServerChannel.cpp;api/public/ServiceContext.cpp;api/service_helpers/AdminServiceUtils.cpp;api/service_helpers/AlgoServiceUtils.cpp;api/service_helpers/PositionUtilities.cpp;api/services/AdminService.proto;api/services/AlgoDefinitionService.proto;api/services/AlgoService.proto;api/services/ApiUnitTestService.proto;api/services/AuthService.proto;api/services/BasePositionService.proto;api/services/ErrorReportService.proto;api/services/HelloService.proto;api/services/MBOService.proto;api/services/MarginService.proto;api/services/MarketDataAuxiliaryService.proto;api/services/MarketDataRelay.proto;api/services/MoneyFileService.proto;api/services/OrderService.proto;api/services/OutOfProcessURLListener.proto;api/services/PersistenceService.proto;api/services/PositionService.proto;api/services/ShellDiagnosticService.proto;api/services/ShellLatencyService.proto;api/services/SyntheticSecurityService.proto;api/test/ApiTests.cpp;api/test/HelloServiceServer.cpp;config/ConfigCheck.cpp;config/ConfigDownloader.cpp;config/ConfigErrorCollector.cpp;config/ConfigLog.cpp;config/ConfigPropertyEvaluator.cpp;config/ConfigValueQueue.cpp;config/ConfigurationException.cpp;config/ConfigurationState.cpp;config/PreprocessInputStream.cpp;config/config.cpp;config/defaults/MarketData.conf;config/defaults/Ports.conf;config/defaults/Symbols.conf;config/defaults/cme_reference_data.conf;config/defaults/edge.conf;config/defaults/jetfix.conf;config/defaults/keycode.conf;config/defaults/logging.conf;config/defaults/orderman_cfg.conf;config/defaults/orders_fills_cleanup.conf;config/defaults/position_cfg.conf;config/defaults/span.conf;config/defaults/spreader.conf;config/defaults/testkeys.conf;config/defaults/threads.conf;config/defaults/toggles.conf;config/extensions/extensions.proto;config/invalid/invalid.proto;config/protos/ExchangeSimCfg.proto;config/protos/MarketData.proto;config/protos/Ports.proto;config/protos/Symbols.proto;config/protos/UI.proto;config/protos/cme_reference_data.proto;config/protos/jetfix.proto;config/protos/keycode.proto;config/protos/logging.proto;config/protos/mercury_cfg.proto;config/protos/orderman_cfg.proto;config/protos/orders_fills_cleanup.proto;config/protos/perflog_cfg.proto;config/protos/position_cfg.proto;config/protos/quickbus_cfg.proto;config/protos/span.proto;config/protos/spreader.proto;config/protos/system.proto;config/protos/testkeys.proto;config/protos/threads.proto;config/protos/toggles.proto;config/tests/HTTPServer.cpp;config/tests/config_ref_tests.cpp;config/tests/config_tests.cpp;config/text_format/text_format.cpp;domain_model/Security.cpp;domain_model/Security.proto;domain_model/SecurityTests.cpp;domain_model/sod.cpp;domain_model/tests/domain_tests.cpp;expression/BooleanGrammar.cpp;expression/ExpressionEvaluator.cpp;expression/ParserExceptions.cpp;expression/Value.cpp;expression/tests/expression_parser_tests.cpp;jetfix/codec/FIXArray.cpp;jetfix/common/OutFIX.cpp;jetfix/connection/AsyncReader.cpp;jetfix/connection/IConnection.cpp;jetfix/connection/SocketConnection.cpp;jetfix/gateway/CoreGateway.cpp;jetfix/gateway/JetFIXGateway.cpp;jetfix/gateway/Session.cpp;jetfix/store/FIXFileStore.cpp;jetfix/store/session_name.cpp;jetfix/tests/async_reader_tests.cpp;jetfix/tests/decoding_tests.cpp;jetfix/tests/fix_encoding_stream_tests.cpp;jetfix/tests/fix_fragment_tests.cpp;jetfix/tests/jetfix_performance_tests.cpp;jetfix/tests/sample_fix.cpp;jetfix/tests/store_tests.cpp;logging/LoggerHub.cpp;logging/Sink.cpp;logging/logging.cpp;logging/tests/logging_tests.cpp;md/Diag/MDPeriodicDumper.cpp;md/Diag/ShmDumper.cpp;md/MBOProcessor.cpp;md/MBOServiceServer.cpp;md/MDClient.cpp;md/MDConsumer.cpp;md/MDConsumerHandle.cpp;md/MDConsumerInterop.cpp;md/MDProducer.cpp;md/MDProducerHandle.cpp;md/MemorySegmentUtils.cpp;md/PlatformLoader.cpp;md/PriceSize.cpp;md/SecurityCache.cpp;md/SecurityDB.cpp;md/SecurityIDRecorder.cpp;md/SecurityMapper.cpp;md/SecurityOracle.cpp;md/SettlementRecorder.cpp;md/Shm/FixedSecurity.cpp;md/SyntheticSecurityService.cpp;md/cme/MDP3Utils.cpp;md/common.cpp;md/ice/ICEUtils.cpp;md/protos/co2.proto;md/relay/QueryServer.cpp;md/relay/RelayClient.cpp;md/relay/RelayRecorder.cpp;md/test/Co2ManagedTestHelper.cpp;md/test/Co2TestInstrument.cpp;md/test/mbo_tests.cpp;md/test/md2_tests.cpp;md/test/md_test_utils.cpp;md/test/synthetic_book_merge_tests.cpp;md/vendor/OnixsUtils.cpp;mercury/actors/IPollableActor.cpp;mercury/broker/Broker.cpp;mercury/broker/BrokerProxy.cpp;mercury/broker/ILocalBroker.cpp;mercury/broker/IRemoteBroker.cpp;mercury/common/mercury_common.cpp;mercury/events/TimerEvent.cpp;mercury/executor/Executor.cpp;mercury/topics/Topic.cpp;metrics/metrics.cpp;metrics/system_metrics.cpp;orderman/actors/AsyncFactory.cpp;orderman/actors/FillStore.cpp;orderman/actors/GLBXExecutionGateway.cpLine truncated
|
||||
@@ -31,4 +31,33 @@ OrdermanCfg {
|
||||
hosted_actor: "*"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OrderManThreadingCfg {
|
||||
value {
|
||||
thread {
|
||||
name: "om_1"
|
||||
poll: true
|
||||
actor: { name: "order_manager" }
|
||||
}
|
||||
|
||||
thread {
|
||||
name: "om_2"
|
||||
poll: true
|
||||
actor: { name: "order_manager" }
|
||||
}
|
||||
|
||||
thread {
|
||||
name: "gw_1"
|
||||
poll: true
|
||||
actor: { name: "gateway" arg: "sim" }
|
||||
actor: { name: "gateway" arg: "cme_mc5_99" }
|
||||
}
|
||||
|
||||
thread {
|
||||
name: "om_slow"
|
||||
actor: {name: "storage"}
|
||||
actor: {name: "service_bridge"}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,11 +7,11 @@ message JetFIX {
|
||||
required string name = 10;
|
||||
|
||||
enum JetFIXPlatform {
|
||||
GLBX = 1;
|
||||
CBOE = 6;
|
||||
GLBX = 1;
|
||||
SIM = 2;
|
||||
ICE = 3;
|
||||
SIMICE = 4;
|
||||
CBOE = 6;
|
||||
}
|
||||
optional JetFIXPlatform platform = 15 [default = GLBX];
|
||||
|
||||
|
||||
@@ -10,3 +10,19 @@ message OrdermanCfg {
|
||||
repeated Executor executor = 1;
|
||||
optional uint32 default_iceberg_pause_secs = 2 [default = 0];
|
||||
}
|
||||
|
||||
message OrderManThreadingCfg {
|
||||
|
||||
message Actor {
|
||||
required string name = 1;
|
||||
repeated string arg = 2;
|
||||
}
|
||||
|
||||
message Thread {
|
||||
required string name = 1;
|
||||
optional bool poll = 2 [default = false];
|
||||
optional uint32 slow_worker_period = 3 [default = 100000];
|
||||
repeated Actor actor = 4;
|
||||
}
|
||||
repeated Thread thread= 1;
|
||||
}
|
||||
@@ -11,7 +11,7 @@ inline int d_toa(double n, char *buffer, size_t buffer_size, int decimal_digits=
|
||||
static double_conversion::DoubleToStringConverter const &c =
|
||||
double_conversion::DoubleToStringConverter::EcmaScriptConverter();
|
||||
|
||||
bts_assert(buffer_size);
|
||||
bts_assert_d(buffer_size);
|
||||
|
||||
if (pad == -1) {
|
||||
// no padding, return the smallest number that contains all the
|
||||
@@ -34,8 +34,8 @@ inline int d_toa(double n, char *buffer, size_t buffer_size, int decimal_digits=
|
||||
// padding, return something with a fixed size
|
||||
|
||||
std::array<char, 128> pre_buffer;
|
||||
bts_assert((int)buffer_size > pad);
|
||||
bts_assert((int)pre_buffer.size() >= pad);
|
||||
bts_assert_d((int)buffer_size > pad);
|
||||
bts_assert_d((int)pre_buffer.size() >= pad);
|
||||
|
||||
double_conversion::StringBuilder builder(&pre_buffer[0], pre_buffer.size());
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ size_t extract(char *start, char *end,
|
||||
std::vector<InMsgBuffer> *msgs) {
|
||||
auto first_unprocessed_byte = 0;
|
||||
auto current = start;
|
||||
|
||||
|
||||
for (;;) {
|
||||
// consume prefix
|
||||
auto this_msg_begin = current;
|
||||
@@ -143,20 +143,20 @@ void AsyncReader::dispatch() {
|
||||
// see what we can parse with the just read bytes
|
||||
framed_msgs.clear();
|
||||
|
||||
// extract as many messages as we can from the last unprocess
|
||||
// byte to the current write cursor, return offset of first
|
||||
// byte in the buffer that we could not process (possibly the
|
||||
// first byte of an incomplete msg)
|
||||
auto first_unprocessed_offset = extract(
|
||||
&((*me->working_buffer)[me->first_pending_msg]),
|
||||
&((*me->working_buffer)[me->write_cursor]), me->working_buffer,
|
||||
&framed_msgs);
|
||||
// extract as many messages as we can from the last
|
||||
// unprocessed byte to the current write cursor, return
|
||||
// offset of first byte in the buffer that we could not
|
||||
// process (possibly the first byte of an incomplete msg)
|
||||
auto first_unprocessed_offset =
|
||||
extract(&((*me->working_buffer)[me->first_pending_msg]),
|
||||
&((*me->working_buffer)[me->write_cursor]),
|
||||
me->working_buffer, &framed_msgs);
|
||||
me->first_pending_msg += first_unprocessed_offset;
|
||||
|
||||
for (auto &msg : framed_msgs) {
|
||||
trace.sn = msg.get_seq_num();
|
||||
socket_read_time.shift_ns(1);
|
||||
me->perf_log.log(trace, socket_read_time,"fix_msg_r");
|
||||
me->perf_log.log(trace, socket_read_time, "fix_msg_r");
|
||||
msg.set_trace(trace);
|
||||
me->sink.in_msg_raw(msg);
|
||||
}
|
||||
|
||||
@@ -27,12 +27,12 @@ namespace jetfix {
|
||||
|
||||
enum class CoreGateway::State {
|
||||
OFF,
|
||||
PAUSED,
|
||||
CONNECTING,
|
||||
READY,
|
||||
WREADER_DISCONNECT,
|
||||
WSESSION_TERMINATE
|
||||
};
|
||||
PAUSED,
|
||||
CONNECTING,
|
||||
READY,
|
||||
WREADER_DISCONNECT,
|
||||
WSESSION_TERMINATE
|
||||
};
|
||||
|
||||
struct CoreGateway::SessionInfo {
|
||||
SessionInfo() : connection(), store(), reader(), session() {}
|
||||
@@ -47,21 +47,21 @@ struct CoreGateway::EventData {
|
||||
typedef void (CoreGateway::*Handler)(EventData const &ev);
|
||||
|
||||
EventData(const EventData &src)
|
||||
: handler(src.handler), out_msgs(src.out_msgs), in_msg(src.in_msg),
|
||||
trace(src.trace), ts(src.ts) {}
|
||||
: handler(src.handler), out_msgs(src.out_msgs), in_msg(src.in_msg),
|
||||
trace(src.trace), ts(src.ts) {}
|
||||
|
||||
EventData() : handler(), out_msgs(), in_msg(), trace(), ts() {}
|
||||
EventData(Handler handler)
|
||||
: handler(handler), out_msgs(), in_msg(), trace(), ts() {}
|
||||
: handler(handler), out_msgs(), in_msg(), trace(), ts() {}
|
||||
EventData(Handler handler, trace::CorID const &trace,
|
||||
OutFIXPtr const &out_msgs)
|
||||
: handler(handler), out_msgs(out_msgs), in_msg(), trace(trace), ts() {}
|
||||
: handler(handler), out_msgs(out_msgs), in_msg(), trace(trace), ts() {}
|
||||
|
||||
EventData(Handler handler, InMsgBuffer const &in_msg)
|
||||
: handler(handler), out_msgs(), in_msg(in_msg), trace(), ts() {}
|
||||
: handler(handler), out_msgs(), in_msg(in_msg), trace(), ts() {}
|
||||
|
||||
EventData(Handler handler, std::shared_ptr<std::string> const &ts)
|
||||
: handler(handler), out_msgs(), in_msg(), trace(), ts(ts) {}
|
||||
: handler(handler), out_msgs(), in_msg(), trace(), ts(ts) {}
|
||||
|
||||
EventData &operator=(EventData &src) {
|
||||
handler = src.handler;
|
||||
@@ -91,11 +91,11 @@ struct CoreGateway::PImpl {
|
||||
PImpl(config::JetFIX::Connection const &cfg, ICoreGatewayObserver &observer,
|
||||
ConnectionFactory const &conn_factory,
|
||||
StoreFactory const &store_factory, trace::PerfLog &l)
|
||||
: cfg(cfg), observer(observer), make_connection(conn_factory),
|
||||
make_store(store_factory), state(State::OFF), start_of_pause(),
|
||||
session_info(), event_queue(), timer_thread(), destroy(false),
|
||||
is_on(false), has_replayed(false), send_batch(), recv_batch(),
|
||||
connection_attempts(0), perf_log(l) {
|
||||
: cfg(cfg), observer(observer), make_connection(conn_factory),
|
||||
make_store(store_factory), state(State::OFF), start_of_pause(),
|
||||
session_info(), event_queue(), timer_thread(), destroy(false),
|
||||
is_on(false), has_replayed(false), send_batch(), recv_batch(),
|
||||
connection_attempts(0), perf_log(l) {
|
||||
send_batch.reserve(1024);
|
||||
recv_batch.reserve(1024);
|
||||
}
|
||||
@@ -130,7 +130,7 @@ CoreGateway::CoreGateway(config::JetFIX::Connection const &cfg,
|
||||
ConnectionFactory const &conn_factory,
|
||||
StoreFactory const &store_factory,
|
||||
trace::PerfLog &perf_trace)
|
||||
: me(new PImpl(cfg, observer, conn_factory, store_factory, perf_trace)) {
|
||||
: me(new PImpl(cfg, observer, conn_factory, store_factory, perf_trace)) {
|
||||
me->timer_thread = make_timer_thread();
|
||||
}
|
||||
|
||||
@@ -148,14 +148,6 @@ void CoreGateway::send(OutFIXPtr const &fix, trace::CorID trace) {
|
||||
me->event_queue.push(EventData(&CoreGateway::sync_send, trace, fix));
|
||||
}
|
||||
|
||||
void CoreGateway::send_hb() {
|
||||
me->event_queue.push(EventData(&CoreGateway::sync_send_hb));
|
||||
}
|
||||
|
||||
void CoreGateway::send_test_request() {
|
||||
me->event_queue.push(EventData(&CoreGateway::sync_send_test_request));
|
||||
}
|
||||
|
||||
void CoreGateway::start() {
|
||||
me->event_queue.push(EventData(&CoreGateway::sync_start));
|
||||
}
|
||||
@@ -198,7 +190,7 @@ void CoreGateway::dispatch_events() {
|
||||
if (me->send_batch.size() || me->recv_batch.size()) {
|
||||
for (auto &ev : me->send_batch)
|
||||
(this->*ev.handler)(ev);
|
||||
for (auto &ev : me->recv_batch)
|
||||
for (auto &ev : me->recv_batch)
|
||||
(this->*ev.handler)(ev);
|
||||
me->send_batch.clear();
|
||||
me->recv_batch.clear();
|
||||
@@ -209,7 +201,7 @@ void CoreGateway::call_time() {
|
||||
while (!me->destroy) {
|
||||
std::this_thread::sleep_for(10ms);
|
||||
auto ts = std::make_shared<std::string>(
|
||||
datetime::FIX_timestamp(datetime::now()));
|
||||
datetime::FIX_timestamp(datetime::now()));
|
||||
me->event_queue.push(EventData(&CoreGateway::sync_time, ts)); // NOLINT
|
||||
}
|
||||
}
|
||||
@@ -276,42 +268,6 @@ void CoreGateway::sync_send(EventData const &ev) {
|
||||
}
|
||||
}
|
||||
|
||||
void CoreGateway::sync_send_hb(EventData const &) {
|
||||
switch (me->state) {
|
||||
case State::OFF:
|
||||
bts_assert(false);
|
||||
break;
|
||||
case State::PAUSED:
|
||||
case State::CONNECTING:
|
||||
case State::WREADER_DISCONNECT:
|
||||
case State::WSESSION_TERMINATE:
|
||||
break;
|
||||
case State::READY:
|
||||
me->session_info->session->send_hb();
|
||||
break;
|
||||
default:
|
||||
bts_assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
void CoreGateway::sync_send_test_request(EventData const &) {
|
||||
switch (me->state) {
|
||||
case State::OFF:
|
||||
bts_assert(false);
|
||||
break;
|
||||
case State::PAUSED:
|
||||
case State::CONNECTING:
|
||||
case State::WREADER_DISCONNECT:
|
||||
case State::WSESSION_TERMINATE:
|
||||
break;
|
||||
case State::READY:
|
||||
me->session_info->session->send_test_request();
|
||||
break;
|
||||
default:
|
||||
bts_assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
void CoreGateway::sync_session_ready(EventData const &) {
|
||||
switch (me->state) {
|
||||
case State::OFF:
|
||||
@@ -443,7 +399,8 @@ void CoreGateway::sync_time(EventData const &ev) {
|
||||
|
||||
if (!me->has_replayed) {
|
||||
auto msgs_to_replay = me->session_info->store->replay();
|
||||
LOG(Jetfix, Warn, "Replaying {} FIX msgs", msgs_to_replay.size());
|
||||
LOG(Jetfix, Warn, "Replaying {} FIX msgs",
|
||||
msgs_to_replay.size());
|
||||
me->observer.replay(msgs_to_replay);
|
||||
me->has_replayed = true;
|
||||
}
|
||||
@@ -468,13 +425,13 @@ void CoreGateway::sync_time(EventData const &ev) {
|
||||
me->cfg.name());
|
||||
|
||||
me->session_info->session.reset(new Session(
|
||||
me->cfg, *me->session_info->connection,
|
||||
*me->session_info->store, *this,
|
||||
[]() { return utils::TimeStamp::now(); }, me->perf_log));
|
||||
me->cfg, *me->session_info->connection,
|
||||
*me->session_info->store, *this,
|
||||
[]() { return utils::TimeStamp::now(); }, me->perf_log));
|
||||
me->session_info->reader.reset(new AsyncReader(
|
||||
*me->session_info->connection, me->cfg.name(), *this,
|
||||
me->perf_log, me->cfg.msg_buffer_sz(),
|
||||
me->cfg.msg_high_water_mark()));
|
||||
*me->session_info->connection, me->cfg.name(), *this,
|
||||
me->perf_log, me->cfg.msg_buffer_sz(),
|
||||
me->cfg.msg_high_water_mark()));
|
||||
me->session_info->reader->start();
|
||||
me->session_info->session->start();
|
||||
transition(State::CONNECTING);
|
||||
|
||||
@@ -35,10 +35,6 @@ public:
|
||||
void send (OutFIXPtr const &msgs, trace::CorID trace);
|
||||
void dispatch_events ();
|
||||
|
||||
// for certification use only
|
||||
void send_hb ();
|
||||
void send_test_request ();
|
||||
|
||||
private:
|
||||
enum class State;
|
||||
struct SessionInfo;
|
||||
@@ -56,8 +52,6 @@ private:
|
||||
void sync_start (EventData const &);
|
||||
void sync_stop (EventData const &);
|
||||
void sync_send (EventData const &);
|
||||
void sync_send_hb (EventData const&);
|
||||
void sync_send_test_request (EventData const&);
|
||||
void sync_session_ready (EventData const&) ;
|
||||
void sync_session_terminated (EventData const&);
|
||||
void sync_reader_disconnected (EventData const&) ;
|
||||
|
||||
@@ -67,10 +67,6 @@ public:
|
||||
DispatcherTuple>::value> (_dispatchers).handler;
|
||||
}
|
||||
|
||||
// for CERT purposes
|
||||
void send_hb () {_core.send_hb ();}
|
||||
void send_test_request () {_core.send_test_request ();}
|
||||
|
||||
private:
|
||||
struct IDispatcher
|
||||
{
|
||||
|
||||
@@ -830,8 +830,8 @@ OutFIXPtr make_logon(uint32_t seq_num, uint32_t last_seq_num_processed,
|
||||
buffer.add<EncodedTextLen>(ld.access_key.size());
|
||||
buffer.add<EncodedText>(ld.access_key);
|
||||
buffer.add<EncryptedPasswordMethod>("CME-1-SHA-256");
|
||||
buffer.add<EncryptedPasswordLen>(ld.signature.size());
|
||||
buffer.add<EncryptedPassword>(ld.signature);
|
||||
buffer.add<EncryptedPasswordLen>(ld.signature_base64.size());
|
||||
buffer.add<EncryptedPassword>(ld.signature_base64);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
namespace bts {
|
||||
namespace jetfix {
|
||||
|
||||
class InMsgBuffer;
|
||||
|
||||
class IFIXStore
|
||||
|
||||
@@ -5,136 +5,204 @@
|
||||
namespace bts {
|
||||
namespace jetfix {
|
||||
|
||||
boost::gregorian::greg_weekday parse_weekday (std::string weekday_str)
|
||||
{
|
||||
boost::to_lower (weekday_str);
|
||||
boost::gregorian::greg_weekday parse_weekday(std::string weekday_str) {
|
||||
boost::to_lower(weekday_str);
|
||||
for (int i = 0; i < 7; i++) {
|
||||
auto gw_day = boost::gregorian::greg_weekday (i);
|
||||
auto prefix = std::string (gw_day.as_short_string ());
|
||||
boost::to_lower (prefix);
|
||||
if (weekday_str.find (prefix) == 0)
|
||||
auto gw_day = boost::gregorian::greg_weekday(i);
|
||||
auto prefix = std::string(gw_day.as_short_string());
|
||||
boost::to_lower(prefix);
|
||||
if (weekday_str.find(prefix) == 0)
|
||||
return gw_day;
|
||||
}
|
||||
bts_assert (false);
|
||||
return boost::gregorian::greg_weekday (0);
|
||||
bts_assert(false);
|
||||
return boost::gregorian::greg_weekday(0);
|
||||
}
|
||||
|
||||
boost::posix_time::time_duration parse_time (std::string const &time_str)
|
||||
{
|
||||
boost::posix_time::time_duration parse_time(std::string const &time_str) {
|
||||
try {
|
||||
return boost::posix_time::duration_from_string (time_str);
|
||||
}
|
||||
catch (boost::bad_lexical_cast &)
|
||||
{
|
||||
bts_assert (false);
|
||||
return boost::posix_time::time_duration ();
|
||||
return boost::posix_time::duration_from_string(time_str);
|
||||
} catch (boost::bad_lexical_cast &) {
|
||||
bts_assert(false);
|
||||
return boost::posix_time::time_duration();
|
||||
}
|
||||
}
|
||||
|
||||
datetime::PTime closest_before (datetime::PTime const &ref_date,
|
||||
boost::gregorian::greg_weekday weekday,
|
||||
boost::posix_time::time_duration time_of_day)
|
||||
{
|
||||
if (ref_date.date ().day_of_week () == weekday) {
|
||||
if (time_of_day < ref_date.time_of_day ())
|
||||
return datetime::PTime (ref_date.date (),time_of_day);
|
||||
datetime::PTime closest_before(datetime::PTime const &ref_date,
|
||||
boost::gregorian::greg_weekday weekday,
|
||||
boost::posix_time::time_duration time_of_day) {
|
||||
if (ref_date.date().day_of_week() == weekday) {
|
||||
if (time_of_day < ref_date.time_of_day())
|
||||
return datetime::PTime(ref_date.date(), time_of_day);
|
||||
else {
|
||||
return datetime::PTime (ref_date.date () - boost::gregorian::date_duration (7),
|
||||
time_of_day);
|
||||
return datetime::PTime(
|
||||
ref_date.date() - boost::gregorian::date_duration(7), time_of_day);
|
||||
}
|
||||
} else {
|
||||
auto distance =
|
||||
ref_date.date ().day_of_week ().as_number () -
|
||||
weekday.as_number ();
|
||||
ref_date.date().day_of_week().as_number() - weekday.as_number();
|
||||
if (distance < 0)
|
||||
distance += 7;
|
||||
return datetime::PTime (ref_date.date () - boost::gregorian::date_duration (distance),
|
||||
time_of_day);
|
||||
return datetime::PTime(ref_date.date() -
|
||||
boost::gregorian::date_duration(distance),
|
||||
time_of_day);
|
||||
}
|
||||
}
|
||||
|
||||
bool in_session (datetime::PTime const &ref_date,
|
||||
boost::posix_time::time_duration time_of_day_start,
|
||||
boost::posix_time::time_duration time_of_day_end)
|
||||
{
|
||||
auto t = ref_date.time_of_day ();
|
||||
bool in_session(datetime::PTime const &ref_date,
|
||||
boost::posix_time::time_duration time_of_day_start,
|
||||
boost::posix_time::time_duration time_of_day_end) {
|
||||
auto t = ref_date.time_of_day();
|
||||
if (time_of_day_start < time_of_day_end)
|
||||
return t >= time_of_day_start && t <= time_of_day_end;
|
||||
else
|
||||
return t >= time_of_day_start || t <= time_of_day_end;
|
||||
}
|
||||
|
||||
bool in_session (datetime::PTime const &ref_date,
|
||||
boost::gregorian::greg_weekday weekday_start,
|
||||
boost::posix_time::time_duration time_of_day_start,
|
||||
boost::gregorian::greg_weekday weekday_end,
|
||||
boost::posix_time::time_duration time_of_day_end)
|
||||
{
|
||||
auto closest_earlier_start = closest_before (ref_date,weekday_start,time_of_day_start);
|
||||
auto closest_earlier_end = closest_before (ref_date,weekday_end,time_of_day_end);
|
||||
return closest_earlier_end<closest_earlier_start;
|
||||
bool in_session(datetime::PTime const &ref_date,
|
||||
boost::gregorian::greg_weekday weekday_start,
|
||||
boost::posix_time::time_duration time_of_day_start,
|
||||
boost::gregorian::greg_weekday weekday_end,
|
||||
boost::posix_time::time_duration time_of_day_end) {
|
||||
auto closest_earlier_start =
|
||||
closest_before(ref_date, weekday_start, time_of_day_start);
|
||||
auto closest_earlier_end =
|
||||
closest_before(ref_date, weekday_end, time_of_day_end);
|
||||
return closest_earlier_end < closest_earlier_start;
|
||||
}
|
||||
|
||||
std::string session_name_from_ptime (datetime::PTime t,
|
||||
boost::posix_time::time_duration time_of_day_start,
|
||||
boost::posix_time::time_duration time_of_day_end)
|
||||
{
|
||||
std::string result (10,' ');
|
||||
SessionName
|
||||
session_name_from_ptime(datetime::PTime t,
|
||||
boost::posix_time::time_duration time_of_day_start,
|
||||
boost::posix_time::time_duration time_of_day_end) {
|
||||
std::string result(10, ' ');
|
||||
auto start_of_session = t;
|
||||
|
||||
if (time_of_day_start > time_of_day_end &&
|
||||
start_of_session.time_of_day () <= time_of_day_end)
|
||||
start_of_session -= boost::gregorian::date_duration (1);
|
||||
|
||||
sprintf (&result[0], "%04d-%02d-%02d",
|
||||
(unsigned short) start_of_session.date ().year (),
|
||||
start_of_session.date ().month ().as_number (),
|
||||
start_of_session.date ().day ().as_number ());
|
||||
return result;
|
||||
|
||||
if (time_of_day_start > time_of_day_end &&
|
||||
start_of_session.time_of_day() <= time_of_day_end)
|
||||
start_of_session -= boost::gregorian::date_duration(1);
|
||||
|
||||
sprintf(&result[0], "%04d-%02d-%02d",
|
||||
(unsigned short)start_of_session.date().year(),
|
||||
start_of_session.date().month().as_number(),
|
||||
start_of_session.date().day().as_number());
|
||||
return {result,t};
|
||||
}
|
||||
|
||||
std::string session_name (datetime::PTime const &ref_date,
|
||||
boost::gregorian::greg_weekday weekday_start,
|
||||
boost::posix_time::time_duration time_of_day_start,
|
||||
boost::gregorian::greg_weekday weekday_end,
|
||||
boost::posix_time::time_duration time_of_day_end)
|
||||
{
|
||||
if (in_session (ref_date,weekday_start,time_of_day_start,weekday_end,time_of_day_end))
|
||||
return session_name_from_ptime (closest_before (ref_date,weekday_start,time_of_day_start),
|
||||
boost::posix_time::time_duration(0, 0, 0),
|
||||
boost::posix_time::time_duration(0, 0, 1));
|
||||
std::optional<SessionName> session_name(datetime::PTime const &ref_date,
|
||||
boost::gregorian::greg_weekday weekday_start,
|
||||
boost::posix_time::time_duration time_of_day_start,
|
||||
boost::gregorian::greg_weekday weekday_end,
|
||||
boost::posix_time::time_duration time_of_day_end) {
|
||||
if (in_session(ref_date, weekday_start, time_of_day_start, weekday_end,
|
||||
time_of_day_end))
|
||||
return session_name_from_ptime(
|
||||
closest_before(ref_date, weekday_start, time_of_day_start),
|
||||
boost::posix_time::time_duration(0, 0, 0),
|
||||
boost::posix_time::time_duration(0, 0, 1));
|
||||
else
|
||||
return std::string ();
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::string session_name (datetime::PTime const &ref_date,
|
||||
boost::posix_time::time_duration time_of_day_start,
|
||||
boost::posix_time::time_duration time_of_day_end)
|
||||
{
|
||||
if (in_session (ref_date,time_of_day_start,time_of_day_end))
|
||||
return session_name_from_ptime (ref_date, time_of_day_start, time_of_day_end);
|
||||
std::optional<SessionName> session_name(datetime::PTime const &ref_date,
|
||||
boost::posix_time::time_duration time_of_day_start,
|
||||
boost::posix_time::time_duration time_of_day_end) {
|
||||
if (in_session(ref_date, time_of_day_start, time_of_day_end))
|
||||
return session_name_from_ptime(ref_date, time_of_day_start,
|
||||
time_of_day_end);
|
||||
else
|
||||
return "";
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::string session_name (config::JetFIX::Connection const &session_cfg)
|
||||
{
|
||||
auto now = datetime::local_now ();
|
||||
std::optional<SessionName> session_name(config::JetFIX::Connection const &session_cfg) {
|
||||
auto now = datetime::local_now();
|
||||
|
||||
if (session_cfg.has_start_day()) {
|
||||
bts_assert(session_cfg.has_end_day());
|
||||
return session_name(now, parse_weekday(session_cfg.start_day()),
|
||||
parse_time(session_cfg.start_time()),
|
||||
parse_weekday(session_cfg.end_day()),
|
||||
parse_time(session_cfg.end_time()));
|
||||
} else
|
||||
return session_name(now, parse_time(session_cfg.start_time()),
|
||||
parse_time(session_cfg.end_time()));
|
||||
}
|
||||
|
||||
SessionSpan session_span(datetime::PTime const &ref_date,
|
||||
boost::gregorian::greg_weekday weekday_start,
|
||||
boost::posix_time::time_duration time_of_day_start,
|
||||
boost::gregorian::greg_weekday weekday_end,
|
||||
boost::posix_time::time_duration time_of_day_end) {
|
||||
auto one_week = boost::gregorian::date_duration(7);
|
||||
auto closest_earlier_start =
|
||||
closest_before(ref_date, weekday_start, time_of_day_start);
|
||||
auto closest_earlier_end =
|
||||
closest_before(ref_date, weekday_end, time_of_day_end);
|
||||
if (closest_earlier_end < closest_earlier_start)
|
||||
// we are in the session
|
||||
return {closest_earlier_start, closest_earlier_end + one_week };
|
||||
else
|
||||
// need to wait for the next session
|
||||
return {closest_earlier_start+one_week, closest_earlier_end + one_week };
|
||||
}
|
||||
|
||||
SessionSpan session_span(datetime::PTime const &ref_date,
|
||||
boost::posix_time::time_duration time_of_day_start,
|
||||
boost::posix_time::time_duration time_of_day_end) {
|
||||
auto t = ref_date.time_of_day();
|
||||
auto today = ref_date.date() ;
|
||||
auto tomorrow = today + boost::gregorian::date_duration(1) ;
|
||||
auto yesterday = today - boost::gregorian::date_duration(1) ;
|
||||
|
||||
if (session_cfg.has_start_day ()) {
|
||||
bts_assert (session_cfg.has_end_day ());
|
||||
return session_name (now,
|
||||
parse_weekday (session_cfg.start_day ()),
|
||||
parse_time (session_cfg.start_time ()),
|
||||
parse_weekday (session_cfg.end_day ()),
|
||||
parse_time (session_cfg.end_time ()));
|
||||
} else
|
||||
return session_name (now,
|
||||
parse_time (session_cfg.start_time ()),
|
||||
parse_time (session_cfg.end_time ()));
|
||||
if (time_of_day_start < time_of_day_end) {
|
||||
// scheduled start/scheduled end do not span midnight
|
||||
|
||||
if (t <= time_of_day_end) {
|
||||
// we are inside the schedule
|
||||
return {
|
||||
datetime::PTime(today,time_of_day_start),
|
||||
datetime::PTime(today,time_of_day_end)
|
||||
};
|
||||
}
|
||||
else {
|
||||
// too late for today, tomorrow is the time for the session
|
||||
return {
|
||||
datetime::PTime(tomorrow,time_of_day_start),
|
||||
datetime::PTime(tomorrow,time_of_day_end)
|
||||
};
|
||||
}
|
||||
} else {
|
||||
// the start/stop span over midnight
|
||||
|
||||
if (t <= time_of_day_end) {
|
||||
// we are inside the the schedule
|
||||
return {
|
||||
datetime::PTime(yesterday,time_of_day_start),
|
||||
datetime::PTime(today,time_of_day_end)
|
||||
};
|
||||
}
|
||||
else {
|
||||
// too late, skip to next session
|
||||
return {
|
||||
datetime::PTime(today,time_of_day_start),
|
||||
datetime::PTime(tomorrow,time_of_day_end)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SessionSpan session_span(config::JetFIX::Connection const &session_cfg) {
|
||||
auto now = datetime::local_now();
|
||||
|
||||
}}
|
||||
|
||||
if (session_cfg.has_start_day()) {
|
||||
bts_assert(session_cfg.has_end_day());
|
||||
return session_span(now, parse_weekday(session_cfg.start_day()),
|
||||
parse_time(session_cfg.start_time()),
|
||||
parse_weekday(session_cfg.end_day()),
|
||||
parse_time(session_cfg.end_time()));
|
||||
} else
|
||||
return session_span(now, parse_time(session_cfg.start_time()),
|
||||
parse_time(session_cfg.end_time()));
|
||||
}
|
||||
|
||||
} // namespace jetfix
|
||||
} // namespace bts
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <string>
|
||||
#include "lib/utils/datetime.h"
|
||||
#include "lib/config/protos/jetfix.pb.h"
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <optional>
|
||||
|
||||
namespace boost {
|
||||
namespace gregorian {
|
||||
@@ -17,6 +19,11 @@ class time_duration;
|
||||
namespace bts {
|
||||
namespace jetfix {
|
||||
|
||||
struct SessionName {
|
||||
std::string name;
|
||||
datetime::PTime time;
|
||||
};
|
||||
|
||||
boost::gregorian::greg_weekday parse_weekday (std::string weekday_str);
|
||||
bool parse_time (std::string const &time_str,boost::posix_time::time_duration *out);
|
||||
|
||||
@@ -34,16 +41,22 @@ bool in_session (datetime::PTime const &ref_date,
|
||||
boost::posix_time::time_duration time_of_day_start,
|
||||
boost::posix_time::time_duration time_of_day_end);
|
||||
|
||||
std::string session_name (datetime::PTime const &ref_date,
|
||||
std::optional<SessionName> session_name (datetime::PTime const &ref_date,
|
||||
boost::gregorian::greg_weekday weekday_start,
|
||||
boost::posix_time::time_duration time_of_day_start,
|
||||
boost::gregorian::greg_weekday weekday_end,
|
||||
boost::posix_time::time_duration time_of_day_end);
|
||||
|
||||
std::string session_name (datetime::PTime const &ref_date,
|
||||
std::optional<SessionName> session_name (datetime::PTime const &ref_date,
|
||||
boost::posix_time::time_duration time_of_day_start,
|
||||
boost::posix_time::time_duration time_of_day_end);
|
||||
|
||||
std::string session_name (config::JetFIX::Connection const &session_cfg);
|
||||
std::optional<SessionName> session_name (config::JetFIX::Connection const &session_cfg);
|
||||
|
||||
struct SessionSpan {
|
||||
datetime::PTime start;
|
||||
datetime::PTime stop;
|
||||
};
|
||||
SessionSpan session_span(config::JetFIX::Connection const&session_cfg);
|
||||
|
||||
}}
|
||||
@@ -120,6 +120,7 @@ void configure_logging(bts::config::Logging const&cfg, bts::config::ThreadGroupC
|
||||
{log::Plugin,"Plugin"},
|
||||
{log::ClientSdk,"ClientSdk"},
|
||||
{log::Http,"Http"},
|
||||
{log::OrderMan2,"OrderMan2"},
|
||||
};
|
||||
|
||||
real_cfg.sinks["console"] =
|
||||
|
||||
@@ -24,7 +24,8 @@ constexpr log::Level Sys {log::Level::Max-1};
|
||||
|
||||
namespace log {
|
||||
|
||||
// Please keep this list in sync with Log.cs
|
||||
// Please keep this list in sync with Log.cs and make sure
|
||||
// to replicate the change in logging.cpp
|
||||
constexpr log::Subsystem Gen {0 };
|
||||
constexpr log::Subsystem Cfg {Gen.ordinal+1 };
|
||||
constexpr log::Subsystem QBus {Cfg.ordinal+1 };
|
||||
@@ -46,6 +47,7 @@ constexpr log::Subsystem DataFlow {Latency.ordinal+1 };
|
||||
constexpr log::Subsystem Plugin {DataFlow.ordinal+1 };
|
||||
constexpr log::Subsystem ClientSdk {Plugin.ordinal+1 };
|
||||
constexpr log::Subsystem Http {ClientSdk.ordinal+1 };
|
||||
constexpr log::Subsystem OrderMan2 {Http.ordinal+1 };
|
||||
|
||||
struct LoggerHandle {
|
||||
LoggerHandle(LoggerHandle const&) = delete;
|
||||
|
||||
@@ -80,9 +80,9 @@ class BrokerProxy : public ILocalBroker {
|
||||
send(m);
|
||||
}
|
||||
|
||||
void do_work(trace::PerfLog& log) {
|
||||
void do_work(trace::PerfLog& ) {
|
||||
_cycles++;
|
||||
_outgoing.consume_all([this,&log](BrokerMsg *m) {
|
||||
_outgoing.consume_all([this](BrokerMsg *m) {
|
||||
switch (m->msg_type) {
|
||||
case BrokerMsgType::ADD_NEIGHBOUR:
|
||||
_real_broker.add_neighbour(*m->neighbour);
|
||||
@@ -102,13 +102,9 @@ class BrokerProxy : public ILocalBroker {
|
||||
case BrokerMsgType::UNSUBSCRIBE:
|
||||
_real_broker.unsubscribe(m->broker_id, m->sub_id, m->stream_id);
|
||||
break;
|
||||
case BrokerMsgType::NOTIFY: {
|
||||
LOG(Latency, Diag, "Notify broker {}. Cycles: {}", _id.value(),
|
||||
_cycles);
|
||||
auto scoped_do_work = trace::log_scope(log, {}, "BrokerProxy::notify");
|
||||
case BrokerMsgType::NOTIFY:
|
||||
_real_broker.notify(m->broker_id, m->stream_id, m->sub_id,
|
||||
m->notification);
|
||||
}
|
||||
break;
|
||||
case BrokerMsgType::LOCAL_SUBSCRIBE:
|
||||
_real_broker.local_subscribe(m->local_sub_id, m->filter,
|
||||
|
||||
@@ -1,45 +1,38 @@
|
||||
#include "lib/mercury/executor/Executor.h"
|
||||
#include "lib/mercury/broker/Broker.h"
|
||||
#include "lib/mercury/broker/BrokerProxy.h"
|
||||
#include "lib/mercury/actors/Actor.h"
|
||||
#include "lib/mercury/actors/IPollableActor.h"
|
||||
#include "lib/mercury/broker/Broker.h"
|
||||
#include "lib/mercury/broker/BrokerProxy.h"
|
||||
|
||||
namespace bts {
|
||||
namespace mercury {
|
||||
|
||||
Executor::Executor() :
|
||||
_broker(),
|
||||
_incoming_proxies(),
|
||||
_my_proxy(make_proxy()),
|
||||
_actor_broker(_my_proxy),
|
||||
_actors() {}
|
||||
Executor::Executor()
|
||||
: _broker(), _incoming_proxies(), _my_proxy(make_proxy()),
|
||||
_actor_broker(_my_proxy), _actors() {}
|
||||
|
||||
Executor::~Executor() {
|
||||
for (auto &a : _actors)
|
||||
a->deactivate();
|
||||
}
|
||||
|
||||
void Executor::init_neighbours(std::vector<Executor*> const&neighbours)
|
||||
{
|
||||
|
||||
void Executor::init_neighbours(std::vector<Executor *> const &neighbours) {
|
||||
for (auto e : neighbours)
|
||||
if (e != this)
|
||||
if (e != this)
|
||||
_outgoing_proxies.push_back(&e->make_proxy());
|
||||
for (auto n : _outgoing_proxies)
|
||||
_broker.add_neighbour(*n);
|
||||
}
|
||||
|
||||
|
||||
void Executor::activate(Actor *actor)
|
||||
{
|
||||
_actors.push_back(std::unique_ptr<Actor> (actor));
|
||||
auto pollable = dynamic_cast<IPollableActor*> (actor);
|
||||
void Executor::activate(Actor *actor) {
|
||||
_actors.push_back(std::unique_ptr<Actor>(actor));
|
||||
auto pollable = dynamic_cast<IPollableActor *>(actor);
|
||||
if (pollable)
|
||||
_pollable_actors.push_back(pollable);
|
||||
actor->activate(_actor_broker);}
|
||||
|
||||
actor->activate(_actor_broker);
|
||||
}
|
||||
|
||||
BrokerProxy& Executor::make_proxy()
|
||||
{
|
||||
BrokerProxy &Executor::make_proxy() {
|
||||
_incoming_proxies.push_back(std::make_unique<BrokerProxy>(_broker));
|
||||
return *_incoming_proxies.back();
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "lib/md/cme/MDP3Utils.h"
|
||||
#include "lib/mercury/actors/Actor.h"
|
||||
#include "lib/mercury/actors/IPollableActor.h"
|
||||
#include "lib/mercury/events/TimerEvent.h"
|
||||
#include "lib/orderman/events/BookUpdateEvent.h"
|
||||
#include "lib/orderman/events/MDRequestEvent.h"
|
||||
#include "lib/orderman/events/TickerUpdateEvent.h"
|
||||
@@ -25,7 +24,8 @@ namespace orderman {
|
||||
// polls a md consumer and publishes BookUpdate events when new MD is
|
||||
// available. To avoid the overhead of maintaing synopsis as well as
|
||||
// polling only relevant MD, observes a MDRequestEvent and limits
|
||||
// updates to requested securities.
|
||||
// updates to requested securities. Also provides trade and security
|
||||
// status events in a similar on demand fashion.
|
||||
|
||||
class MDSource : public mercury::Actor, public mercury::IPollableActor {
|
||||
public:
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include "lib/api/services/OrderService.pb.h"
|
||||
#include "lib/mercury/actors/Actor.h"
|
||||
#include "lib/orderman/events/StoredFillEvent.h"
|
||||
#include "lib/md/SecurityOracle.h"
|
||||
|
||||
using namespace bts::api::orderman;
|
||||
|
||||
@@ -42,7 +42,7 @@ class DynamicOrderRegistry;
|
||||
} // namespace bts
|
||||
// end fwds
|
||||
|
||||
// Provides a threading bridge between the quickbux/service world and
|
||||
// Provides a threading bridge between the quickbus/service world and
|
||||
// the mercury event broker.
|
||||
namespace bts {
|
||||
namespace orderman {
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
#include "lib/orderman/actors/order_manager/OrderServices.h"
|
||||
#include "lib/orderman/actors/order_manager/OrderServicesData.h"
|
||||
#include "lib/orderman/events/AccountPnLUpdateEvent.h"
|
||||
#include "lib/orderman/events/FilledPositionEvent.h"
|
||||
#include "lib/orderman/events/ExcessLiquidityUpdateEvent.h"
|
||||
#include "lib/orderman/events/FilledPositionEvent.h"
|
||||
#include "lib/orderman/events/NewAdminDataEvent.h"
|
||||
#include "lib/orderman/events/NewSecuritiesEvent.h"
|
||||
#include "lib/orderman/events/OrderManagerReadyEvent.h"
|
||||
@@ -111,7 +111,8 @@ void OrderManager::on_excess_liquidity_update(
|
||||
const mercury::Update<ExcessLiquidityUpdateEvent> &u) {
|
||||
if (u.events)
|
||||
for (auto ev : *u.events)
|
||||
me->services_data.limiter.set_excess_liquidity(ev.account_id, ev.excess_liquidity);
|
||||
me->services_data.limiter.set_excess_liquidity(ev.account_id,
|
||||
ev.excess_liquidity);
|
||||
}
|
||||
|
||||
void OrderManager::on_securities(
|
||||
@@ -541,7 +542,7 @@ void OrderManager::init_order_services() {
|
||||
std::make_unique<ContentSubscription<TickerUpdateEvent>>(
|
||||
*this, on_ticker_sub, log);
|
||||
me->services_data.status_subs =
|
||||
std::make_unique<ContentSubscription<StatusUpdateEvent>>(
|
||||
std::make_unique<ContentSubscription<StatusUpdateEvent>>(
|
||||
*this, on_status_sub, log);
|
||||
me->services_data.settlement_subs =
|
||||
std::make_unique<ContentSubscription<SettlementUpdateEvent>>(
|
||||
@@ -581,10 +582,7 @@ void OrderManager::reload_fix_buffer(SessionServicesData &osd) {
|
||||
}
|
||||
}
|
||||
|
||||
void OrderManager::on_poll(trace::PerfLog &log) {
|
||||
auto scoped_do_work =
|
||||
trace::log_scope(log, {}, "OrderManager::dispatch_incoming_fix_messages",
|
||||
utils::TimeStamp::Interval::from_microseconds(2));
|
||||
void OrderManager::on_poll(trace::PerfLog &) {
|
||||
for (auto &osd : me->services_data.sessions)
|
||||
osd->gw->dispatch_incoming_fix_messages();
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
#include "lib/config/protos/jetfix.pb.h"
|
||||
#include "lib/jetfix/common/OutFIXPtr.h"
|
||||
#include "lib/md/SecurityOracle.h"
|
||||
#include "lib/mercury/actors/Actor.h"
|
||||
#include "lib/mercury/actors/IPollableActor.h"
|
||||
#include "lib/md/SecurityOracle.h"
|
||||
#include "lib/orderman/events/ActivateOrderEvent.h"
|
||||
#include "lib/orderman/events/CancelOrderEvent.h"
|
||||
#include "lib/orderman/events/DetachOrderEvent.h"
|
||||
@@ -64,8 +64,9 @@ namespace orderman {
|
||||
|
||||
class OrderManager : public mercury::Actor, public mercury::IPollableActor {
|
||||
public:
|
||||
OrderManager(DynamicOrderRegistry const &dyn_order_builder, trace::PerfLog &, md::SecurityOracle);
|
||||
|
||||
OrderManager(DynamicOrderRegistry const &, trace::PerfLog &,
|
||||
md::SecurityOracle);
|
||||
|
||||
~OrderManager();
|
||||
void init() override;
|
||||
|
||||
@@ -86,8 +87,9 @@ class OrderManager : public mercury::Actor, public mercury::IPollableActor {
|
||||
void on_timer(const mercury::Update<mercury::TimerEvent> &);
|
||||
void on_admin_data(const mercury::Update<NewAdminDataEvent> &);
|
||||
void on_pnl_update(const mercury::Update<AccountPnLUpdateEvent> &);
|
||||
void on_excess_liquidity_update(const mercury::Update<ExcessLiquidityUpdateEvent> &);
|
||||
void on_poll(trace::PerfLog& log) override;
|
||||
void on_excess_liquidity_update(
|
||||
const mercury::Update<ExcessLiquidityUpdateEvent> &);
|
||||
void on_poll(trace::PerfLog &log) override;
|
||||
// end external events
|
||||
|
||||
void init_order_services();
|
||||
@@ -97,8 +99,8 @@ class OrderManager : public mercury::Actor, public mercury::IPollableActor {
|
||||
void after_event() override;
|
||||
|
||||
void add_child_order(OrderServices &parent, Order &child);
|
||||
Order* lookup_order(OrderKey k);
|
||||
|
||||
Order *lookup_order(OrderKey k);
|
||||
|
||||
void publish_order_def_update(
|
||||
OrderKey k,
|
||||
std::shared_ptr<api::orderman::OrderDefinition const> const &def);
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
** Attach/Detach semantics
|
||||
*** Semantics
|
||||
- An order base definition can include a list of running orders to attach
|
||||
to
|
||||
- Each custom definition can have parameters that allow configuration
|
||||
of the specific order type with respect to the attachment
|
||||
list. Obvious configuration alternatives are:
|
||||
- Attach to each of the listed orders directly or
|
||||
- Forward attachment list to children
|
||||
- Only orders with no parent or parents in a terminal state can be
|
||||
attached to
|
||||
- a detach(order_key) message can be sent to any order, even if that
|
||||
order was not started through attachment to an existing order. the
|
||||
expected semantics is for the order in question to stop managing the
|
||||
child order and transition to completed.
|
||||
|
||||
*** API
|
||||
- IOrderServices:
|
||||
- attach_to_order(ok, std::function<void(Result,ChildOrder)>
|
||||
on_attach_complete);
|
||||
- detach(ChildOrder)
|
||||
- Order
|
||||
- on_detach(order_key)
|
||||
- on_attached();
|
||||
- on_detached();
|
||||
message OrderDefinition {
|
||||
CTICode cti_code = 9;
|
||||
l CUSTOMERORFIRM customer_or_firm = 10;
|
||||
OrderSubType sub_type = 12;
|
||||
+ repeated uint32 attach_to_order = 13;
|
||||
CustomOrderDefinition custom_def = 11;
|
||||
}
|
||||
* Order fields
|
||||
| Field | Group | Muttable | on_attach |
|
||||
|------------------------+--------------+----------+-------------|
|
||||
| security_key | standard def | N | from child |
|
||||
| side | | N | from child |
|
||||
| user | | N | from parent |
|
||||
| user_id | | Y | from parent |
|
||||
| account | | Y | from parent |
|
||||
| account_id | | Y | from parent |
|
||||
| time_in_force | | N | from child |
|
||||
| manual_order_indicator | | Y | from parent |
|
||||
| cti_code | | N | from child |
|
||||
| customer_or_firm | | N | from child |
|
||||
| sub_type | | N | |
|
||||
| attach_order | | N | |
|
||||
|------------------------+--------------+----------+-------------|
|
||||
| custom_def | custom_def | Y | from child |
|
||||
| | | | |
|
||||
|------------------------+--------------+----------+-------------|
|
||||
| key | order_record | N | |
|
||||
| parent_key | | Y | from parent |
|
||||
|------------------------+--------------+----------+-------------|
|
||||
| status | order_state | Y | |
|
||||
| price | | Y | |
|
||||
| quantity | | Y | |
|
||||
| filled_quantity | | Y | |
|
||||
| last_price | | Y | |
|
||||
| avg_price | | Y | |
|
||||
| last_msg | | Y | |
|
||||
| created | | Y | |
|
||||
| last_change | | Y | |
|
||||
| custom_state | custom_state | Y | |
|
||||
|
||||
Binary file not shown.
+42
-75
@@ -5,9 +5,22 @@
|
||||
| completed | O | | | |
|
||||
| canceled | canceled | | | |
|
||||
| error | X | | | |
|
||||
| disconnected | | | | |
|
||||
| disconnected | | | | |
|
||||
| rejected by spark | X | | | |
|
||||
* References
|
||||
** Timmings
|
||||
| thing | cost | note |
|
||||
|-------------------------+------+----------------------|
|
||||
| lock/unlock | 8 | test_and_set |
|
||||
| shared_ptr cpy | 14 | |
|
||||
| binary_search_int64/8 | 7 | |
|
||||
| binary_search_int64/512 | 13 | |
|
||||
| mem_copy/8 | 5 | |
|
||||
| mem_copy/64 | 5 | |
|
||||
| mem_copy/512 | 14 | |
|
||||
| new/delete | 58 | |
|
||||
| boost pool new/delete | 2 | no synchronizatio |
|
||||
| boost pool new/delete | 19 | with synchronization |
|
||||
** To Exchange
|
||||
- [[https://www.cmegroup.com/confluence/display/EPICSANDBOX/New+Order][NewOrderSingle]]
|
||||
- [[https://www.cmegroup.com/confluence/display/EPICSANDBOX/Order%2BCancel-Replace%2BRequest][CancelReplace]]
|
||||
@@ -22,8 +35,8 @@
|
||||
- Trade Correction
|
||||
- [[https://www.cmegroup.com/confluence/display/EPICSANDBOX/Execution+Report+-+Trade+Correction][Msg]]
|
||||
- [[https://www.cmegroup.com/confluence/display/EPICSANDBOX/Execution+Report+-+Trade+Correction][Discussion]]
|
||||
* Order Chain trace
|
||||
** NewOrder
|
||||
** Order Chain trace
|
||||
*** NewOrder
|
||||
=-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-=
|
||||
BeginString = FIX.4.2 8=FIX.4.2
|
||||
BodyLength = 271 9=271
|
||||
@@ -95,7 +108,7 @@ ExpireDate = 20161102 432=20161102
|
||||
5979 = 1478119007620967425 5979=1478119007620967425
|
||||
7928 = 8056218 7928=8056218
|
||||
CheckSum = 038 10=038
|
||||
** Cancel
|
||||
*** Cancel
|
||||
=-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-=
|
||||
BeginString = FIX.4.2 8=FIX.4.2
|
||||
BodyLength = 327 9=327
|
||||
@@ -169,7 +182,7 @@ ExpireDate = 20161102 432=20161102
|
||||
7928 = 8056218 7928=8056218
|
||||
9717 = 2KjMkw-1C22h9-001v8Q 9717=2KjMkw-1C22h9-001v8Q
|
||||
CheckSum = 033 10=033
|
||||
** Cancel/Replace
|
||||
*** Cancel/Replace
|
||||
=-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-=
|
||||
BeginString = FIX.4.2 8=FIX.4.2
|
||||
BodyLength = 344 9=344
|
||||
@@ -247,7 +260,7 @@ ExpireDate = 20161102 432=20161102
|
||||
9717 = 2KjMkw-1C22gp-001v8P 9717=2KjMkw-1C22gp-001v8P
|
||||
CheckSum = 151 10=151
|
||||
|
||||
** Trade Correction
|
||||
*** Trade Correction
|
||||
=-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-=
|
||||
BeginString = FIX.4.2 8=FIX.4.2
|
||||
BodyLength = 000234 9=000234
|
||||
@@ -401,35 +414,7 @@ CheckSum = 207 10=207
|
||||
37711 = MDTradeEntryID
|
||||
ExecRefID
|
||||
|
||||
* Open Issues
|
||||
- Re-Connection is done on the fast thread, slowing everything down
|
||||
- Need to make sure there are no duplicate order state update events
|
||||
- Once we have multiple OM's we will need to guarantee that they can
|
||||
see each others order, which means we need to use some sort of
|
||||
synopsis or other mechanism to ensure that they are synchronized
|
||||
- fill mitigation
|
||||
- should cancel on disconnect be on
|
||||
- handling of reject
|
||||
- garbage collection of orders
|
||||
- garbage collection of fills
|
||||
- consider including restatement reason
|
||||
- see if handling of cancel rejects is any good
|
||||
- impossible to shutdown orderservice at the moment
|
||||
* Timmings
|
||||
- 10.96.25.35
|
||||
| thing | cost | note |
|
||||
|-------------------------+------+----------------------|
|
||||
| lock/unlock | 8 | test_and_set |
|
||||
| shared_ptr cpy | 14 | |
|
||||
| binary_search_int64/8 | 7 | |
|
||||
| binary_search_int64/512 | 13 | |
|
||||
| mem_copy/8 | 5 | |
|
||||
| mem_copy/64 | 5 | |
|
||||
| mem_copy/512 | 14 | |
|
||||
| new/delete | 58 | |
|
||||
| boost pool new/delete | 2 | no synchronizatio |
|
||||
| boost pool new/delete | 19 | with synchronization |
|
||||
* Notes on "A guide to spread trading futures"
|
||||
** Notes on "A guide to spread trading futures"
|
||||
- Correlations are discovered by traders
|
||||
- Spread trading exploits correlations between securities and mean
|
||||
reversion
|
||||
@@ -471,47 +456,28 @@ ExecRefID
|
||||
- Strategies
|
||||
- Mean Reversion
|
||||
|
||||
* Open Issues
|
||||
- Re-Connection is done on the fast thread, slowing everything down
|
||||
- Need to make sure there are no duplicate order state update events
|
||||
- Once we have multiple OM's we will need to guarantee that they can
|
||||
see each others order, which means we need to use some sort of
|
||||
synopsis or other mechanism to ensure that they are synchronized
|
||||
- consider including restatement reason
|
||||
- see if handling of cancel rejects is any good
|
||||
- impossible to shutdown orderservice at the moment
|
||||
* Event Flow
|
||||
#+begin_src dot :file event_flow.pdf :cmdline -Kdot -Tpdf
|
||||
digraph G {
|
||||
bgcolor="transparent";
|
||||
|
||||
subgraph cluster_fast {
|
||||
label="Fast Core";
|
||||
GW
|
||||
OMan
|
||||
MDSrc
|
||||
}
|
||||
|
||||
subgraph cluster_slow {
|
||||
label="Slow Core";
|
||||
FillStore
|
||||
SecSrc
|
||||
UI
|
||||
OrderStore
|
||||
Factory
|
||||
}
|
||||
|
||||
OMan -> Factory [label=req]
|
||||
Factory -> OMan [label=rep]
|
||||
SecSrc -> GW [label=psec]
|
||||
SecSrc -> OrderStore [label=psec]
|
||||
SecSrc -> OMan [label=psec]
|
||||
GW -> FillStore [label=xmsgs]
|
||||
GW -> OMan [label=xmsgs]
|
||||
OMan -> GW [label=fix]
|
||||
OMan -> OrderStore [label=oupdate]
|
||||
OrderStore -> OMan [label=rec_orders]
|
||||
OrderStore -> UI [label=orecs]
|
||||
FillStore-> UI [label=frecs]
|
||||
UI -> OMan [label="crud"]
|
||||
MDSrc -> OMan [label="md"]
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:event_flow.pdf]]
|
||||
|
||||
| | MDSource | OManager | Timer | AsyncF | OrderStore | FillStore | SecSrc | MdSup | Bridge |
|
||||
|------------+----------+----------+-------+--------+------------+-----------+--------+-------+--------|
|
||||
| MSource | | | | | | | | | |
|
||||
| OManager | | | | | | | | | |
|
||||
| Timer | | | | | | | | | |
|
||||
| AsyncF | | | | | | | | | |
|
||||
| OrderStore | | | | | | | | | |
|
||||
| FillStore | | | | | | | | | |
|
||||
| SecSrc | | | | | | | | | |
|
||||
| MdSup | | | | | | | | | |
|
||||
| Bridge | | | | | | | | | |
|
||||
|------------+----------+----------+-------+--------+------------+-----------+--------+-------+--------|
|
||||
* Better event broker:
|
||||
** unbundle events from topics and synopsis.
|
||||
- develop Channels = Channel<Event,Tag,Synopsis>
|
||||
@@ -560,3 +526,4 @@ digraph G {
|
||||
- Recovery from disk
|
||||
- Jetfix gateway threading model is wrong, cannot take one thread for
|
||||
each session
|
||||
* Rewrite <2019-09-23 Mon>
|
||||
@@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "lib/mercury/events/Event.h"
|
||||
#include "lib/orderman/orderman_utils/orderman_common.h"
|
||||
#include "lib/tracing/PerfLog.h"
|
||||
|
||||
namespace bts {
|
||||
namespace orderman {
|
||||
|
||||
class DetachOrderEvent : public mercury::Event<DetachOrderEvent> {
|
||||
public:
|
||||
using SynopsisPolicy = mercury::NoSynopsis;
|
||||
|
||||
DetachOrderEvent(uint32_t req_id, OrderKey k)
|
||||
: req_id(req_id), k(k) {}
|
||||
|
||||
uint32_t req_id;
|
||||
// used by ContentSubscription
|
||||
OrderKey key() const { return k; }
|
||||
OrderKey k;
|
||||
};
|
||||
} // namespace orderman
|
||||
} // namespace bts
|
||||
@@ -1,31 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "lib/utils/bts_chrono.h"
|
||||
#include <memory>
|
||||
|
||||
namespace bts {
|
||||
namespace orderman {
|
||||
|
||||
class Governor
|
||||
{
|
||||
public:
|
||||
Governor(uint32_t max_msgs_window,
|
||||
uint32_t window_duration_msecs,
|
||||
TimeStamp now = Timer::now()) :
|
||||
_max_msgs_window(max_msgs_window),
|
||||
_window_duration_msecs(window_duration_msecs),
|
||||
_start_of_window(now),
|
||||
_msgs_in_window(0)
|
||||
{}
|
||||
|
||||
bool can_send(TimeStamp now = Timer::now()) const
|
||||
{
|
||||
class Governor {
|
||||
public:
|
||||
Governor() {
|
||||
init(std::numeric_limits<uint32_t>::max(),
|
||||
std::numeric_limits<uint32_t>::max(), Timer::now());
|
||||
}
|
||||
|
||||
Governor(uint32_t max_msgs_window, uint32_t window_duration_msecs,
|
||||
TimeStamp now = Timer::now()) {
|
||||
init(max_msgs_window, window_duration_msecs, now);
|
||||
}
|
||||
|
||||
void init(uint32_t max_msgs_window, uint32_t window_duration_msecs,
|
||||
TimeStamp now) {
|
||||
_max_msgs_window = max_msgs_window;
|
||||
_window_duration_msecs = window_duration_msecs;
|
||||
_start_of_window = now;
|
||||
}
|
||||
|
||||
bool can_send(TimeStamp now = Timer::now()) const {
|
||||
if (in_window(now))
|
||||
return _msgs_in_window < _max_msgs_window;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void record_sent(TimeStamp now = Timer::now()) {
|
||||
if (!in_window(now)) {
|
||||
_start_of_window = now;
|
||||
@@ -34,15 +40,16 @@ public:
|
||||
_msgs_in_window++;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
bool in_window(TimeStamp now) const {
|
||||
return ms_diff (now, _start_of_window) <= _window_duration_msecs;
|
||||
return ms_diff(now, _start_of_window) <= _window_duration_msecs;
|
||||
}
|
||||
|
||||
|
||||
uint32_t _max_msgs_window;
|
||||
uint32_t _window_duration_msecs;
|
||||
TimeStamp _start_of_window;
|
||||
uint64_t _msgs_in_window;
|
||||
};
|
||||
|
||||
}}
|
||||
} // namespace orderman
|
||||
} // namespace bts
|
||||
@@ -5,7 +5,9 @@ namespace orderman {
|
||||
|
||||
LimitStore::LimitStore(const bts::api::admin::AdminData &admin_data,
|
||||
const std::map<uint32_t, api::Security const *> &sec_map)
|
||||
: _admin_data(bts::admin::AdminServiceUtils::sort_limits(admin_data)) {
|
||||
: _admin_data(bts::admin::AdminServiceUtils::sort_limits(admin_data)),
|
||||
_margin_enabled(config::get<bts::config::SpanMargin>().enabled())
|
||||
{
|
||||
for (const auto& acct : _admin_data.accounts())
|
||||
_account_data_map.insert(std::pair<uint32_t,AccountData>(
|
||||
acct.id(),AccountData(acct)));
|
||||
@@ -110,4 +112,4 @@ LimitStore::test_only_func_find_product_node(AccountID account_id,
|
||||
return nullptr;
|
||||
}
|
||||
} // namespace orderman
|
||||
} // namespace bts
|
||||
} // namespace bts
|
||||
@@ -72,6 +72,7 @@ private:
|
||||
// this is passed over to the SecurityLimitTree
|
||||
// entried (above)
|
||||
std::vector<ProductLimitTree> _prod_map;
|
||||
bool _margin_enabled;
|
||||
const bts::api::admin::AccountProductPositionLimitUnit _zero_product_limit;
|
||||
public:
|
||||
LimitStore(const bts::api::admin::AdminData& admin_data,
|
||||
@@ -298,7 +299,7 @@ private:
|
||||
if(account_ptr != nullptr){
|
||||
const auto& account_data = *account_ptr;
|
||||
const auto& account = account_data.account;
|
||||
if(config::get<bts::config::SpanMargin>().enabled()) {
|
||||
if(_margin_enabled) {
|
||||
if (account.has_margin_limit() && account.margin_limit().enforce_margin()){
|
||||
double ex_liq = account_data.excess_liquidity;
|
||||
if(os::is_nan(ex_liq)){
|
||||
|
||||
@@ -18,12 +18,6 @@ struct DynamicOrderRegistry::PImpl {
|
||||
DynamicOrderRegistry::DynamicOrderRegistry() : me(new PImpl()) {}
|
||||
DynamicOrderRegistry::~DynamicOrderRegistry() {}
|
||||
|
||||
void DynamicOrderRegistry::register_dynamic_order(
|
||||
api::orderman::DynamicOrderDescriptor const &desc,
|
||||
DynamicOrderBuilder const &b) {
|
||||
me->dyn_orders[desc.dynamic_order_type()] = std::make_pair(b, desc);
|
||||
}
|
||||
|
||||
void DynamicOrderRegistry::register_dynamic_algo_order(
|
||||
api::orderman::DynamicOrderDescriptor const &desc,
|
||||
DynamicAlgoBuilder const &b) {
|
||||
|
||||
@@ -13,11 +13,6 @@ class DynamicOrderRegistry {
|
||||
DynamicOrderRegistry();
|
||||
~DynamicOrderRegistry();
|
||||
|
||||
// deprecated
|
||||
void
|
||||
register_dynamic_order(api::orderman::DynamicOrderDescriptor const &desc,
|
||||
DynamicOrderBuilder const &builder);
|
||||
|
||||
void register_dynamic_algo_order(
|
||||
api::orderman::DynamicOrderDescriptor const &desc,
|
||||
DynamicAlgoBuilder const &builder);
|
||||
|
||||
@@ -72,6 +72,7 @@ OrderOpResult SplitterAlgo::do_before_launch(IBeforeLaunchAlgoServices& ibl) {
|
||||
void SplitterAlgo::do_launch(IAlgoServices& ias) {
|
||||
me->algo = &ias;
|
||||
me->target_qty = ias.quantity().value();
|
||||
ias.set_ladder_visibility(false);
|
||||
// launches initial child orders
|
||||
sync_orders();
|
||||
}
|
||||
|
||||
@@ -15,6 +15,14 @@ namespace orderman {
|
||||
class DynamicOrderRegistry;
|
||||
class OrderOpResultEvent;
|
||||
|
||||
// Inputs:
|
||||
// - order maintenance rpc calls from the shell
|
||||
// - admin data from the admin service
|
||||
// - position data from the position service
|
||||
// - margin data from the margin service
|
||||
// Outputs:
|
||||
// - order state
|
||||
// - fills
|
||||
class OrderServiceServer : public api::orderman::OrderServiceBase {
|
||||
public:
|
||||
OrderServiceServer(bts::api::ServiceContext &context,
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
// #include "lib/orderman_v2/OrderManEngine.h"
|
||||
// #include "lib/config/protos/orderman_cfg.pb.h"
|
||||
// #include "lib/md/MDConsumer.h"
|
||||
// #include "lib/orderman_v2/Thread.h"
|
||||
// #include "lib/orderman_v2/components.h"
|
||||
// #include <fmt/format.h>
|
||||
|
||||
// namespace bts {
|
||||
// namespace orderman_v2 {
|
||||
|
||||
// struct ThreadRec {
|
||||
// ThreadRec(config::OrderManThreadingCfg::Thread const &t_cfg)
|
||||
// : thread(t_cfg.name(), t_cfg.poll()), cfg(t_cfg) {}
|
||||
|
||||
// Thread thread;
|
||||
// config::OrderManThreadingCfg::Thread cfg;
|
||||
// };
|
||||
|
||||
// struct MDSourceOM {
|
||||
// MDSourceOM(md::MDConsumer &md) : md_source(md), manager() {}
|
||||
// MDSource md_source;
|
||||
// OrderManager manager;
|
||||
// };
|
||||
|
||||
|
||||
// struct OrderManEngine::PImpl {
|
||||
// PImpl(md::MDConsumer &md) : md_consumer(md) {}
|
||||
|
||||
// std::map<std::string, std::unique_ptr<ThreadRec>> threads;
|
||||
|
||||
// Component<ServiceBridge> service_bridge;
|
||||
// Component<Storage> storage;
|
||||
// std::vector<Component<MDSourceOM>> order_managers;
|
||||
// std::vector<Component<Gateway>> gateways;
|
||||
|
||||
// md::MDConsumer &md_consumer;
|
||||
// };
|
||||
|
||||
// OrderManEngine::OrderManEngine(md::MDConsumer &md,
|
||||
// config::OrderManThreadingCfg const &cfg)
|
||||
// : me(new PImpl(md)) {
|
||||
// init_threads(cfg);
|
||||
// init_components();
|
||||
// }
|
||||
|
||||
// void OrderManEngine::init_threads(config::OrderManThreadingCfg const &cfg) {
|
||||
// for (auto const &t_cfg : cfg.thread()) {
|
||||
// auto &thread_ptr = me->threads[t_cfg.name()];
|
||||
// bts_assert_msg(
|
||||
// !thread_ptr,
|
||||
// fmt::format("Duplicate thread name {} in OrderManThreading "
|
||||
// "configuration key",
|
||||
// t_cfg.name()));
|
||||
// thread_ptr = std::make_unique<ThreadRec>(t_cfg);
|
||||
// }
|
||||
// bts_assert("No threads in OrderManThreading configuration key");
|
||||
// }
|
||||
|
||||
// void OrderManEngine::init_components() {
|
||||
// for (auto const &p : me->threads) {
|
||||
// auto const &tr = p.second;
|
||||
|
||||
// for (auto const &c : tr->cfg.component()) {
|
||||
|
||||
// if (c.name() == "service_bridge") {
|
||||
// bts_assert_msg(!me->service_bridge.component,
|
||||
// "Duplicate service_bridge component found in "
|
||||
// "OrderManThreading configuration key");
|
||||
|
||||
// me->service_bridge.thread = &tr->thread;
|
||||
// me->service_bridge.component = std::make_unique<ServiceBridge>();
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// if (c.name() == "storage") {
|
||||
// bts_assert_msg(!me->storage.component,
|
||||
// "Duplicate storage component found in "
|
||||
// "OrderManThreading configuration key");
|
||||
|
||||
// me->storage.thread = &tr->thread;
|
||||
// me->storage.component = std::make_unique<Storage>();
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// if (c.name() == "order_manager") {
|
||||
// auto md_om = std::make_unique<MDSourceOM>(me->md_consumer);
|
||||
// Component<MDSourceOM> c{std::move(md_om), &tr->thread};
|
||||
// me->order_managers.emplace_back(std::move (c));
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// if (c.name() == "gateway") {
|
||||
// bts_assert_msg(
|
||||
// c.arg_size() == 1,
|
||||
// "Gateway component should have a single jetfix session "
|
||||
// "name (arg: jf_session_name) in OrderManThreading"
|
||||
// "configuration key");
|
||||
// auto gw = std::make_unique<Gateway>(c.arg(0));
|
||||
// Component<Gateway> c{std::move(gw), &tr->thread};
|
||||
// me->gateways.emplace_back(std::move(c));
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
|
||||
// bts_assert_msg(me->service_bridge.component,
|
||||
// "Missing service_bridge component in OrderManThreading "
|
||||
// "configuration key");
|
||||
// bts_assert_msg(
|
||||
// me->storage.component,
|
||||
// "Missing storage component in OrderManThreading configuration key");
|
||||
// bts_assert_msg(
|
||||
// me->order_managers.size(),
|
||||
// "At least a order_manager component is required in OrderManThreading"
|
||||
// "configuration key");
|
||||
// bts_assert_msg(me->order_managers.size(),
|
||||
// "At least a gateway component is required in "
|
||||
// "OrderManThreading configuration key");
|
||||
// }
|
||||
// }
|
||||
|
||||
// } // namespace orderman_v2
|
||||
// } // namespace bts
|
||||
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace bts {
|
||||
namespace config {class OrderManThreadingCfg;}
|
||||
|
||||
namespace orderman_v2 {
|
||||
class Thread;
|
||||
|
||||
class OrderManEngine {
|
||||
public:
|
||||
OrderManEngine(config::OrderManThreadingCfg const&);
|
||||
~OrderManEngine();
|
||||
void start();
|
||||
void stop ();
|
||||
private:
|
||||
struct PImpl;
|
||||
std::unique_ptr<PImpl> me;
|
||||
|
||||
void init_threads(config::OrderManThreadingCfg const&cfg);
|
||||
void init_components();
|
||||
void link_components();
|
||||
};
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,126 @@
|
||||
// #include "lib/orderman_v2/OrderManScheduler.h"
|
||||
// #include "lib/config/protos/orderman_cfg.pb.h"
|
||||
// #include "lib/md/MDConsumer.h"
|
||||
// #include "lib/orderman_v2/Thread.h"
|
||||
// #include "lib/orderman_v2/components.h"
|
||||
// #include <fmt/format.h>
|
||||
|
||||
// namespace bts {
|
||||
// namespace orderman_v2 {
|
||||
|
||||
// struct ThreadRec {
|
||||
// ThreadRec(config::OrderManThreadingCfg::Thread const &t_cfg)
|
||||
// : thread(t_cfg.name(), t_cfg.poll()), cfg(t_cfg) {}
|
||||
|
||||
// Thread thread;
|
||||
// config::OrderManThreadingCfg::Thread cfg;
|
||||
// };
|
||||
|
||||
// struct MDSourceOM {
|
||||
// MDSourceOM(md::MDConsumer &md) : md_source(md), manager() {}
|
||||
// MDSource md_source;
|
||||
// OrderManager manager;
|
||||
// };
|
||||
|
||||
// template <class C> struct Component {
|
||||
// std::unique_ptr<C> component;
|
||||
// Thread *thread;
|
||||
// };
|
||||
|
||||
// struct OrderManScheduler::PImpl {
|
||||
// PImpl(md::MDConsumer &md) : md_consumer(md) {}
|
||||
|
||||
// std::map<std::string, std::unique_ptr<ThreadRec>> threads;
|
||||
|
||||
// Component<ServiceBridge> service_bridge;
|
||||
// Component<Storage> storage;
|
||||
// std::vector<Component<MDSourceOM>> order_managers;
|
||||
// std::vector<Component<Gateway>> gateways;
|
||||
|
||||
// md::MDConsumer &md_consumer;
|
||||
// };
|
||||
|
||||
// OrderManScheduler::OrderManScheduler(md::MDConsumer &md,
|
||||
// config::OrderManThreadingCfg const &cfg)
|
||||
// : me(new PImpl(md)) {
|
||||
// init_threads(cfg);
|
||||
// init_components();
|
||||
// }
|
||||
|
||||
// void OrderManScheduler::init_threads(config::OrderManThreadingCfg const &cfg) {
|
||||
// for (auto const &t_cfg : cfg.thread()) {
|
||||
// auto &thread_ptr = me->threads[t_cfg.name()];
|
||||
// bts_assert_msg(
|
||||
// !thread_ptr,
|
||||
// fmt::format("Duplicate thread name {} in OrderManThreading "
|
||||
// "configuration key",
|
||||
// t_cfg.name()));
|
||||
// thread_ptr = std::make_unique<ThreadRec>(t_cfg);
|
||||
// }
|
||||
// bts_assert("No threads in OrderManThreading configuration key");
|
||||
// }
|
||||
|
||||
// void OrderManScheduler::init_components() {
|
||||
// for (auto const &p : me->threads) {
|
||||
// auto const &tr = p.second;
|
||||
|
||||
// for (auto const &c : tr->cfg.component()) {
|
||||
|
||||
// if (c.name() == "service_bridge") {
|
||||
// bts_assert_msg(!me->service_bridge.component,
|
||||
// "Duplicate service_bridge component found in "
|
||||
// "OrderManThreading configuration key");
|
||||
|
||||
// me->service_bridge.thread = &tr->thread;
|
||||
// me->service_bridge.component = std::make_unique<ServiceBridge>();
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// if (c.name() == "storage") {
|
||||
// bts_assert_msg(!me->storage.component,
|
||||
// "Duplicate storage component found in "
|
||||
// "OrderManThreading configuration key");
|
||||
|
||||
// me->storage.thread = &tr->thread;
|
||||
// me->storage.component = std::make_unique<Storage>();
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// if (c.name() == "order_manager") {
|
||||
// auto md_om = std::make_unique<MDSourceOM>(me->md_consumer);
|
||||
// Component<MDSourceOM> c{std::move(md_om), &tr->thread};
|
||||
// me->order_managers.emplace_back(std::move (c));
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// if (c.name() == "gateway") {
|
||||
// bts_assert_msg(
|
||||
// c.arg_size() == 1,
|
||||
// "Gateway component should have a single jetfix session "
|
||||
// "name (arg: jf_session_name) in OrderManThreading"
|
||||
// "configuration key");
|
||||
// auto gw = std::make_unique<Gateway>(c.arg(0));
|
||||
// Component<Gateway> c{std::move(gw), &tr->thread};
|
||||
// me->gateways.emplace_back(std::move(c));
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
|
||||
// bts_assert_msg(me->service_bridge.component,
|
||||
// "Missing service_bridge component in OrderManThreading "
|
||||
// "configuration key");
|
||||
// bts_assert_msg(
|
||||
// me->storage.component,
|
||||
// "Missing storage component in OrderManThreading configuration key");
|
||||
// bts_assert_msg(
|
||||
// me->order_managers.size(),
|
||||
// "At least a order_manager component is required in OrderManThreading"
|
||||
// "configuration key");
|
||||
// bts_assert_msg(me->order_managers.size(),
|
||||
// "At least a gateway component is required in "
|
||||
// "OrderManThreading configuration key");
|
||||
// }
|
||||
// }
|
||||
|
||||
// } // namespace orderman_v2
|
||||
// } // namespace bts
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace bts {
|
||||
namespace md {class MDConsumer;}
|
||||
namespace config {class OrderManThreadingCfg;}
|
||||
|
||||
namespace orderman_v2 {
|
||||
class Thread;
|
||||
|
||||
class OrderManScheduler {
|
||||
public:
|
||||
OrderManScheduler(md::MDConsumer &,config::OrderManThreadingCfg const&);
|
||||
~OrderManScheduler();
|
||||
void start();
|
||||
void stop ();
|
||||
private:
|
||||
struct PImpl;
|
||||
std::unique_ptr<PImpl> me;
|
||||
|
||||
void init_threads(config::OrderManThreadingCfg const&cfg);
|
||||
void init_components();
|
||||
void link_components();
|
||||
};
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,14 @@
|
||||
#include "Actor.h"
|
||||
#include "lib/orderman_v2/interconnect/Thread.h"
|
||||
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
Actor::~Actor() {}
|
||||
|
||||
Queue* Actor::get_target_queue(Actor &target_actor) {
|
||||
return target_actor._owner_thread->get_queue(*_owner_thread);
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
class Queue;
|
||||
class Thread;
|
||||
|
||||
class Actor {
|
||||
public:
|
||||
virtual ~Actor() ;
|
||||
virtual void init() {}
|
||||
virtual void finit() {}
|
||||
|
||||
private:
|
||||
friend class Thread;
|
||||
template <class A> friend class Signal;
|
||||
// Returns nullptr is the this actor and the target are on the same thread
|
||||
Queue* get_target_queue(Actor &target_actor);
|
||||
void set_owner_thread(Thread &owner) { _owner_thread = &owner; }
|
||||
Thread *_owner_thread = nullptr;
|
||||
};
|
||||
|
||||
} // namespace orderman_v2
|
||||
} // namespace bts
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "MDSource.h"
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
MDSource::MDSource(md::MDConsumer &)
|
||||
: on_book(this), on_ticker(this), on_sec_status(this) {}
|
||||
|
||||
} // namespace orderman_v2
|
||||
} // namespace bts
|
||||
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include "Actor.h"
|
||||
#include "lib/orderman_v2/events/events.h"
|
||||
#include "lib/orderman_v2/common.h"
|
||||
#include "lib/orderman_v2/interconnect/Signal.h"
|
||||
|
||||
namespace bts {
|
||||
namespace md {class MDConsumer;}
|
||||
namespace orderman_v2 {
|
||||
|
||||
|
||||
|
||||
class MDSource : public Actor {
|
||||
public:
|
||||
MDSource(md::MDConsumer &consumer) ;
|
||||
|
||||
// Inputs
|
||||
void on_md_request(MDRequest const&) {};
|
||||
|
||||
// Signals
|
||||
Signal<BookUpdate> on_book;
|
||||
Signal<TickerUpdate> on_ticker;
|
||||
Signal<SecurityStatusUpdate> on_sec_status;
|
||||
};
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "OrderManager.h"
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
OrderManager::OrderManager()
|
||||
: on_gw_op(this), on_order_update(this), on_om_reply(this),
|
||||
on_md_request(this), on_om_bootstrap_orders(this) {}
|
||||
|
||||
} // namespace orderman_v2
|
||||
} // namespace bts
|
||||
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include "Actor.h"
|
||||
#include "lib/orderman_v2/events/events.h"
|
||||
#include "lib/orderman_v2/common.h"
|
||||
#include "lib/orderman_v2/interconnect/Signal.h"
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
class OrderManager : public Actor {
|
||||
public:
|
||||
OrderManager();
|
||||
|
||||
// Inputs
|
||||
void on_bootstrap_orders(BootstrapOrders) {}
|
||||
void on_native_order_update (GW_OrderReport const&) {}
|
||||
void on_unknown_native_order_update(GW_UnknownOrderExeReport const&) {}
|
||||
void on_create_order (CreateOrderRequest const&) {}
|
||||
void on_update_order (UpdateOrderRequest const&) {}
|
||||
void on_cancel_order (CancelOrderRequest const&) {}
|
||||
void on_detach_order (DetachOrderRequest const&) {}
|
||||
void on_book(BookUpdate const&) {}
|
||||
void on_ticker(TickerUpdate const&) {}
|
||||
void on_sec_status(SecurityStatusUpdate const&) {}
|
||||
void on_admin_data(const AdminDataUpdate &) {}
|
||||
|
||||
// Signals
|
||||
Signal<GW_Op_Batch> on_gw_op;
|
||||
Signal<OM_OrderUpdate> on_order_update;
|
||||
Signal<OM_Reply> on_om_reply;
|
||||
Signal<MDRequest> on_md_request;
|
||||
Signal<OM_BootstrapOrders> on_om_bootstrap_orders;
|
||||
};
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,18 @@
|
||||
#include "ServiceBridge.h"
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
ServiceBridge::ServiceBridge() :
|
||||
on_create_order(this),
|
||||
on_update_order(this),
|
||||
on_cancel_order(this),
|
||||
on_detach_order(this),
|
||||
on_admin_data(this),
|
||||
on_excess_liquidity(this),
|
||||
on_account_pnl(this),
|
||||
on_position(this)
|
||||
{}
|
||||
|
||||
} // namespace orderman_v2
|
||||
} // namespace bts
|
||||
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include "Actor.h"
|
||||
#include "lib/orderman_v2/events/events.h"
|
||||
#include "lib/orderman_v2/common.h"
|
||||
#include "lib/orderman_v2/interconnect/Signal.h"
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
class ServiceBridge : public Actor {
|
||||
public:
|
||||
ServiceBridge();
|
||||
|
||||
// Inputs
|
||||
void on_bootstrap_orders(BootstrapOrders) {}
|
||||
void on_bootstrap_fills(BootstrapFills) {}
|
||||
void on_new_stored_order(api::orderman::OrderRecord const*) {}
|
||||
void on_new_stored_fill(api::orderman::Fill const*) {}
|
||||
void on_gw_status(GW_Status const&) {}
|
||||
void on_gw_error(GW_Error const&) {}
|
||||
void on_om_reply(OM_Reply const&) {}
|
||||
|
||||
// Signals
|
||||
Signal<CreateOrderRequest> on_create_order;
|
||||
Signal<UpdateOrderRequest> on_update_order;
|
||||
Signal<CancelOrderRequest> on_cancel_order;
|
||||
Signal<DetachOrderRequest> on_detach_order;
|
||||
Signal<AdminDataUpdate> on_admin_data;
|
||||
Signal<ExcessLiquidityUpdate> on_excess_liquidity;
|
||||
Signal<AccountPnLUpdate> on_account_pnl;
|
||||
Signal<PositionUpdate> on_position;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#include "Storage.h"
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
Storage::Storage()
|
||||
: on_bootstrap_orders(this), on_venue_checkpoint(this),
|
||||
on_bootstrap_fills(this), on_new_stored_order(this),
|
||||
on_new_stored_fill(this) {}
|
||||
|
||||
} // namespace orderman_v2
|
||||
} // namespace bts
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "Actor.h"
|
||||
#include "lib/orderman_v2/events/events.h"
|
||||
#include "lib/orderman_v2/common.h"
|
||||
#include "lib/orderman_v2/interconnect/Signal.h"
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
class Storage : public Actor {
|
||||
public:
|
||||
Storage();
|
||||
|
||||
// Inputs
|
||||
void on_order_update (OM_OrderUpdate const&) {}
|
||||
|
||||
// Signals
|
||||
Signal<BootstrapOrders> on_bootstrap_orders;
|
||||
Signal<VenueCheckpointNotice> on_venue_checkpoint;
|
||||
Signal<BootstrapFills> on_bootstrap_fills;
|
||||
Signal<api::orderman::OrderRecord const*> on_new_stored_order;
|
||||
Signal<api::orderman::Fill const*> on_new_stored_fill;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include "lib/orderman_v2/common.h"
|
||||
#include "lib/orderman_v2/actors/gateway/fix/VenueCheckpoint.h"
|
||||
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
class IFullExeReportMsg;
|
||||
|
||||
class ExecReport {
|
||||
public:
|
||||
OrderKey order_key;
|
||||
Quantity quantity;
|
||||
Quantity total_fills;
|
||||
Quantity last_fills;
|
||||
Price price;
|
||||
Price avg_price;
|
||||
Price last_price;
|
||||
OrderStatus status;
|
||||
VenueCheckpoint checkpoint;
|
||||
IFullExeReportMsg const *msg;
|
||||
};
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,637 @@
|
||||
#include "Gateway.h"
|
||||
|
||||
#include "lib/logging/logging.h"
|
||||
#include "lib/orderman/limiter/Limiter.h"
|
||||
#include "lib/orderman_v2/actors/gateway/ICancelMsg.h"
|
||||
#include "lib/orderman_v2/actors/gateway/ICancelReplaceMsg.h"
|
||||
#include "lib/orderman_v2/actors/gateway/ILimiter.h"
|
||||
#include "lib/orderman_v2/actors/gateway/INewOrderSingleMsg.h"
|
||||
#include "lib/orderman_v2/actors/gateway/IRouter.h"
|
||||
#include "lib/orderman_v2/actors/gateway/IVenue.h"
|
||||
#include "lib/orderman_v2/actors/gateway/UserAccountVenue.h"
|
||||
#include "lib/orderman_v2/utils/FAFStore.h"
|
||||
#include "lib/utils/bts_chrono.h"
|
||||
|
||||
#include <boost/pool/object_pool.hpp>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
// utilities
|
||||
template <class Req> GW_Op_Ack make_ack(Req const &r) {
|
||||
return GW_Op_Ack{GW_OP_Result::OK, r.req_id, nullptr};
|
||||
}
|
||||
|
||||
struct Gateway::OrderRec {
|
||||
OrderRec() = default;
|
||||
OrderRec(OM_ID om_id, GW_BoundOrder const &order)
|
||||
: order(order), cancel_replace(nullptr), cancel(nullptr),
|
||||
originator(om_id) {}
|
||||
|
||||
GW_BoundOrder order;
|
||||
ICancelReplaceMsg *cancel_replace;
|
||||
ICancelMsg *cancel;
|
||||
OM_ID originator;
|
||||
GW_Op_Ack last_ack;
|
||||
|
||||
void clear_msgs() {
|
||||
cancel_replace = nullptr;
|
||||
cancel = nullptr;
|
||||
}
|
||||
|
||||
bool is_routable() const { return cancel_replace != nullptr; }
|
||||
|
||||
void set_msgs(ICancelReplaceMsg const &cr, ICancelMsg &can) {
|
||||
cancel_replace = &cr.clone();
|
||||
cancel = &can.clone();
|
||||
}
|
||||
};
|
||||
|
||||
class Gateway::OrderMap {
|
||||
public:
|
||||
OrderRec *lookup(OrderKey k) { return _store.lookup(k.value); }
|
||||
|
||||
OrderRec *make_and_store(OM_ID om_id, GW_BoundOrder const &bo) {
|
||||
return _store.make_and_index(bo.key.value, om_id, bo);
|
||||
}
|
||||
void remove(OrderKey k) { _store.remove(k.value); }
|
||||
std::vector<OrderRec *> get_all() { return _store.get_all(); }
|
||||
|
||||
private:
|
||||
FAFStore<OrderRec> _store;
|
||||
};
|
||||
|
||||
enum class Gateway::State {
|
||||
W_BOOTSTRAP,
|
||||
W_SCHEDULE,
|
||||
PAUSED,
|
||||
W_LOGON,
|
||||
READY,
|
||||
};
|
||||
|
||||
struct Gateway::Hot {
|
||||
using MsgTemplatesMap =
|
||||
std::unordered_map<UserAccountVenue, MsgTemplates, UserAccountVenueHash>;
|
||||
|
||||
Hot(IVenue &v, ILimiter &l)
|
||||
: state(State::W_BOOTSTRAP), venue(v), limiter(l), working_orders(),
|
||||
pending_msgs(), msg_templates() {}
|
||||
|
||||
State state;
|
||||
IVenue &venue;
|
||||
ILimiter &limiter;
|
||||
// TODO: Separate ourders that cannot be routed from working orders to avoid
|
||||
// the if is_routable() on order events
|
||||
OrderMap working_orders;
|
||||
boost::container::small_vector<IVenueMsg *, 8> pending_msgs;
|
||||
MsgTemplatesMap msg_templates;
|
||||
};
|
||||
|
||||
struct Gateway::Cold {
|
||||
Cold(IRouter &r, IClock &c, GatewayCfg const &cfg)
|
||||
: router(r), clock(c), admin_data(), cfg(cfg), start_of_pause(),
|
||||
current_exponential_backoff(0), bootstrap_orders(), interned_strings () {}
|
||||
|
||||
IRouter &router;
|
||||
IClock &clock;
|
||||
api::admin::AdminData const *admin_data;
|
||||
GatewayCfg cfg;
|
||||
TimeStamp start_of_pause;
|
||||
size_t current_exponential_backoff;
|
||||
SessionSpan session_span;
|
||||
std::map<OM_ID, std::vector<GW_OrderBind> *> bootstrap_orders;
|
||||
std::set<std::string> interned_strings;
|
||||
};
|
||||
|
||||
struct Gateway::PImpl {
|
||||
PImpl(IVenue &v, ILimiter &l, IRouter &r, IClock &c, GatewayCfg const &cfg)
|
||||
: hot(v, l), cold(r, c, cfg) {}
|
||||
Hot hot;
|
||||
Cold cold;
|
||||
};
|
||||
|
||||
Gateway::Gateway(IVenue &v, ILimiter &l, IRouter &r, IClock &c,
|
||||
GatewayCfg const &cfg)
|
||||
: on_order_report(this), on_unknown_native_order_update(this),
|
||||
on_gw_error(this), me(new PImpl(v, l, r, c, cfg)) {
|
||||
me->hot.venue.set_observer(*this);
|
||||
}
|
||||
|
||||
Gateway::~Gateway() {}
|
||||
|
||||
void Gateway::do_slow_work() {
|
||||
switch (me->hot.state) {
|
||||
case State::W_BOOTSTRAP:
|
||||
if (has_bootstrap_data()) {
|
||||
setup_bootstrap_orders();
|
||||
transition(State::W_SCHEDULE);
|
||||
}
|
||||
break;
|
||||
case State::W_SCHEDULE:
|
||||
me->cold.session_span = me->hot.venue.get_current_session_span();
|
||||
if (in_active_schedule()) {
|
||||
me->cold.start_of_pause = me->cold.clock.now();
|
||||
transition(State::PAUSED);
|
||||
}
|
||||
break;
|
||||
case State::PAUSED: {
|
||||
auto now = me->cold.clock.now();
|
||||
if (sec_diff(now, me->cold.start_of_pause) >
|
||||
(me->cold.cfg.pause_seconds
|
||||
<< me->cold.current_exponential_backoff)) {
|
||||
transition(State::W_LOGON);
|
||||
me->hot.venue.login();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case State::READY: {
|
||||
break;
|
||||
}
|
||||
case State::W_LOGON:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Gateway::on_om_bootstrap_orders(OM_BootstrapOrders const &orders) {
|
||||
bts_assert(me->hot.state == State::W_BOOTSTRAP);
|
||||
auto &bso_map = me->cold.bootstrap_orders;
|
||||
bts_assert(bso_map.size() < me->cold.cfg.om_count);
|
||||
bts_assert(bso_map.count(orders.originator) == 0);
|
||||
bts_assert(orders.target == me->cold.cfg.my_id);
|
||||
bts_assert(orders.originator.value < me->cold.cfg.om_count);
|
||||
bso_map[orders.originator] = orders.orders;
|
||||
}
|
||||
|
||||
void Gateway::on_gw_ops(const GW_Op_Batch &op_batch) {
|
||||
op_batch.visit(*this);
|
||||
send_pending_msgs();
|
||||
}
|
||||
|
||||
void Gateway::on_account_pnl(const AccountPnLUpdate &pnl) {
|
||||
me->hot.limiter.update(pnl);
|
||||
}
|
||||
|
||||
void Gateway::on_position(const PositionUpdate &pos) {
|
||||
me->hot.limiter.update(pos);
|
||||
}
|
||||
|
||||
void Gateway::on_excess_liquidity(const ExcessLiquidityUpdate &l) {
|
||||
me->hot.limiter.update(l);
|
||||
}
|
||||
|
||||
void Gateway::on_admin_data(AdminDataUpdate const &admin) {
|
||||
me->hot.limiter.update(*me->cold.admin_data);
|
||||
me->cold.router.update(*me->cold.admin_data);
|
||||
|
||||
switch (me->hot.state) {
|
||||
case State::W_BOOTSTRAP:
|
||||
me->cold.admin_data = admin.admin_data;
|
||||
break;
|
||||
default:
|
||||
rebuild_msg_templates();
|
||||
}
|
||||
}
|
||||
|
||||
void Gateway::on_venue_checkpoint(const VenueCheckpointNotice ¬ice) {
|
||||
me->hot.venue.set_checkpoint(notice.checkpoint);
|
||||
}
|
||||
|
||||
void Gateway::on_venue_login_success(std::vector<ExecReport> const &recovered) {
|
||||
bts_assert(me->hot.state == State::W_LOGON);
|
||||
me->cold.current_exponential_backoff = 0;
|
||||
transition(State::READY);
|
||||
for (auto const &er : recovered)
|
||||
on_venue_exe_report(er);
|
||||
}
|
||||
|
||||
void Gateway::on_venue_login_failure() {
|
||||
bts_assert(me->hot.state == State::W_LOGON);
|
||||
|
||||
if (in_active_schedule()) {
|
||||
me->cold.current_exponential_backoff ++;
|
||||
transition(State::PAUSED);
|
||||
}
|
||||
else {
|
||||
me->cold.current_exponential_backoff = 0;
|
||||
transition(State::W_SCHEDULE);
|
||||
}
|
||||
}
|
||||
|
||||
void Gateway::on_venue_disconnect() {
|
||||
bts_assert(me->hot.state == State::READY);
|
||||
auto all_working = me->hot.working_orders.get_all();
|
||||
|
||||
for (auto orec : all_working) {
|
||||
GW_Error error;
|
||||
error.gw = me->cold.cfg.my_id;
|
||||
error.error_code = GW_Error::DISCONNECT;
|
||||
error.error_msg = "Venue disconnected";
|
||||
error.order_key = orec->order.key;
|
||||
on_gw_error(error);
|
||||
}
|
||||
}
|
||||
|
||||
void Gateway::on_venue_exe_report(const ExecReport &report) {
|
||||
bts_assert(me->hot.state == State::READY);
|
||||
|
||||
auto r = me->hot.working_orders.lookup(report.order_key);
|
||||
if (r) {
|
||||
// This is an order we have seen before. This is the normal
|
||||
// path.
|
||||
r->order.last_exe_report = report;
|
||||
// If the order is no longer working then we remove it from the
|
||||
// working index.
|
||||
if (report.status != OrderStatus::WORKING)
|
||||
me->hot.working_orders.remove(report.order_key);
|
||||
on_order_report(make_order_report(r));
|
||||
} else if (report.status == OrderStatus::WORKING) {
|
||||
auto sec = me->hot.venue.resolve_security(report);
|
||||
if (sec)
|
||||
on_unknown_native_order_update ( {sec,me->cold.cfg.my_id,report});
|
||||
}
|
||||
}
|
||||
|
||||
void Gateway::on_venue_error(VenueError const &v_error) {
|
||||
GW_Error gw_error;
|
||||
switch (v_error.error_code) {
|
||||
case VenueError::CANCEL_REJECT:
|
||||
gw_error.error_code = GW_Error::CANCEL_REJECT;
|
||||
break;
|
||||
case VenueError::BUSINESS_REJECT:
|
||||
gw_error.error_code = GW_Error::BUSINESS_REJECT;
|
||||
break;
|
||||
case VenueError::SESSION_REJECT:
|
||||
gw_error.error_code = GW_Error::SESSION_REJECT;
|
||||
break;
|
||||
default:
|
||||
gw_error.error_code = GW_Error::OTHER;
|
||||
break;
|
||||
}
|
||||
gw_error.error_msg = intern_string(v_error.error_msg);
|
||||
gw_error.order_key = v_error.order_key;
|
||||
on_gw_error(gw_error);
|
||||
}
|
||||
|
||||
void Gateway::on_gw_op(OM_ID om_id, const GW_OrderCreate &create) {
|
||||
bts_assert_d(me->hot.working_orders.lookup(create.bound_order.key) ==
|
||||
nullptr);
|
||||
|
||||
// Construct new order record
|
||||
auto gw_rec =
|
||||
me->hot.working_orders.make_and_store(om_id, create.bound_order);
|
||||
auto &order = gw_rec->order;
|
||||
auto &ack = gw_rec->last_ack;
|
||||
ack = make_ack(create);
|
||||
|
||||
switch (me->hot.state) {
|
||||
case State::READY: {
|
||||
|
||||
// Validate route
|
||||
auto &msg_templates = me->hot.msg_templates;
|
||||
INewOrderSingleMsg *new_order_single;
|
||||
auto it = msg_templates.find(order.uav);
|
||||
if (it == msg_templates.end()) {
|
||||
ack.result = GW_OP_Result::ERROR_NO_ROUTE;
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: Replace the chained ifs with the accumulate error flags
|
||||
// and check them once.
|
||||
|
||||
// Set msgs in order record
|
||||
new_order_single = &it->second.new_order->clone();
|
||||
gw_rec->set_msgs(*it->second.cancel_replace, *it->second.cancel);
|
||||
|
||||
// Validate risk limit
|
||||
auto lqt = me->hot.limiter.can_send_new_order(
|
||||
order.uav.account, *order.security, order.side, order.quantity);
|
||||
if (lqt.error()) {
|
||||
ack.result = lqt.result;
|
||||
ack.message = lqt.message;
|
||||
break;
|
||||
}
|
||||
|
||||
// Validate messaging limits
|
||||
if (!me->hot.venue.under_messaging_limit()) {
|
||||
ack.result = GW_OP_Result::ERROR_MESSAGING_BREACH;
|
||||
break;
|
||||
}
|
||||
|
||||
// All is good. Copy the order params to the order message and
|
||||
// queue the message for sending.
|
||||
new_order_single->set_order_params(order);
|
||||
me->hot.pending_msgs.push_back(new_order_single);
|
||||
|
||||
// For speed we do not send acks for the operation until we hear
|
||||
// from the exchange.
|
||||
return;
|
||||
}
|
||||
default:
|
||||
ack.result = GW_OP_Result::ERROR_GATEWAY_DISCONNECTED;
|
||||
break;
|
||||
}
|
||||
|
||||
// If we got to this point something went wrong and the creation of
|
||||
// the order failed. Since the order is already indexed we need to
|
||||
// remove it from the store. Additionally, because we will never
|
||||
// hear from the exchange on this order we have to send our ack
|
||||
// now. This is an exceptional path, it should almost never happen.
|
||||
bts_assert_d(ack.result != GW_OP_Result::OK);
|
||||
auto report = make_order_report(gw_rec);
|
||||
me->hot.working_orders.remove(order.key);
|
||||
on_order_report(report);
|
||||
}
|
||||
|
||||
// When an order is recovered from disk or from the exchange (meaning
|
||||
// the exchange sends a report for an order we do not have a record of
|
||||
// creating) we are left in a situation where we have to create the
|
||||
// order record that represents the order but we do not have to
|
||||
// actually send the order to the exchange. This is what the bind
|
||||
// order operation is for.
|
||||
void Gateway::on_gw_op(OM_ID om_id, const GW_OrderBind &bind) {
|
||||
bts_assert_d(me->hot.working_orders.lookup(bind.bound_order.key) == nullptr);
|
||||
|
||||
// Construct new order record
|
||||
auto gw_rec = me->hot.working_orders.make_and_store(om_id, bind.bound_order);
|
||||
auto &order = gw_rec->order;
|
||||
auto &ack = gw_rec->last_ack;
|
||||
ack = make_ack(bind);
|
||||
|
||||
// Find the message templates for this UAV and clone them for this
|
||||
// order
|
||||
auto &msg_templates = me->hot.msg_templates;
|
||||
auto it = msg_templates.find(order.uav);
|
||||
if (it == msg_templates.end())
|
||||
ack.result = GW_OP_Result::ERROR_NO_ROUTE;
|
||||
|
||||
// In this case we have to send a reply to the bind operation
|
||||
// because there is no guarantee that we will be able to piggy back
|
||||
// the reply on the next exchange acknowledgement (which may never
|
||||
// come).
|
||||
on_order_report(make_order_report(gw_rec));
|
||||
}
|
||||
|
||||
// A quick update is an update of just price and quantity. This is the
|
||||
// most common type of order change so we special case it so that we
|
||||
// can re-use the update message fields that will not change (which is
|
||||
// everything but quantity and price)
|
||||
void Gateway::on_gw_op(OM_ID, const GW_OrderQuickUpdate &quick_update) {
|
||||
auto gw_rec = me->hot.working_orders.lookup(quick_update.order_key);
|
||||
auto &ack = gw_rec->last_ack;
|
||||
ack = make_ack(quick_update);
|
||||
|
||||
switch (me->hot.state) {
|
||||
case State::READY: {
|
||||
|
||||
// Do we know about this order?
|
||||
if (!gw_rec) {
|
||||
ack.result = GW_OP_Result::ERROR_ORDER_IS_NOT_ACTIVE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Can we route it?
|
||||
if (!gw_rec->is_routable()) {
|
||||
ack.result = GW_OP_Result::ERROR_NO_ROUTE;
|
||||
break;
|
||||
}
|
||||
|
||||
auto &order = gw_rec->order;
|
||||
// Validate trading limits
|
||||
auto delta_q = quick_update.quantity.value - order.quantity.value;
|
||||
auto lqr = me->hot.limiter.can_update_order(
|
||||
order.uav.account, *order.security, order.side, delta_q);
|
||||
if (lqr.error()) {
|
||||
ack.result = lqr.result;
|
||||
ack.message = lqr.message;
|
||||
break;
|
||||
}
|
||||
|
||||
// Validate messaging limits
|
||||
if (!me->hot.venue.under_messaging_limit()) {
|
||||
ack.result = GW_OP_Result::ERROR_MESSAGING_BREACH;
|
||||
break;
|
||||
}
|
||||
order.price = quick_update.price;
|
||||
order.quantity = quick_update.quantity;
|
||||
gw_rec->cancel_replace->update(order);
|
||||
me->hot.pending_msgs.push_back(gw_rec->cancel_replace);
|
||||
|
||||
// We do not send out a order report for performance
|
||||
// reasons. Instead we delay the report until the exchange
|
||||
// reponds our order update.
|
||||
return;
|
||||
}
|
||||
default:
|
||||
ack.result = GW_OP_Result::ERROR_GATEWAY_DISCONNECTED;
|
||||
break;
|
||||
}
|
||||
|
||||
// If we got here something went wrong and the update failed. This
|
||||
// is the exceptional path and it should almost never happen. In
|
||||
// this case we send out a new order report detailing the reasons
|
||||
// for the failure.
|
||||
bts_assert(ack.result != GW_OP_Result::OK);
|
||||
on_order_report(make_order_report(gw_rec));
|
||||
}
|
||||
|
||||
// The difference between a full update and a quick update is that in
|
||||
// a full update we allow for the account / user to change. In this
|
||||
// case we have to re-create the messages for cancel and update since
|
||||
// these messages embed in them account and user specific information.
|
||||
void Gateway::on_gw_op(OM_ID om_id, const GW_OrderFullUpdate &full_update) {
|
||||
auto gw_rec = me->hot.working_orders.lookup(full_update.order_key);
|
||||
auto &ack = gw_rec->last_ack;
|
||||
ack = make_ack(full_update);
|
||||
|
||||
switch (me->hot.state) {
|
||||
case State::READY: {
|
||||
|
||||
// Do we know about this order?
|
||||
if (!gw_rec) {
|
||||
ack.result = GW_OP_Result::ERROR_ORDER_IS_NOT_ACTIVE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Can we route it?
|
||||
if (!gw_rec->is_routable()) {
|
||||
ack.result = GW_OP_Result::ERROR_NO_ROUTE;
|
||||
break;
|
||||
}
|
||||
|
||||
auto &order = gw_rec->order;
|
||||
auto &msg_templates = me->hot.msg_templates;
|
||||
auto it = msg_templates.find(order.uav);
|
||||
if (it == msg_templates.end()) {
|
||||
ack.result = GW_OP_Result::ERROR_NO_ROUTE;
|
||||
gw_rec->clear_msgs();
|
||||
break;
|
||||
}
|
||||
|
||||
// Update existing record with the non quick parts of the full
|
||||
// order update. There is a bit of inconsistency here. We are
|
||||
// already setting the message templates, uav, moi and tif
|
||||
// fields below, even though the quick update might later fail
|
||||
// to set the quantity and price. This could leave the order in
|
||||
// a half-updated half not-updated state. This should be rare
|
||||
// and benign enough so we live with it.
|
||||
gw_rec->set_msgs(*it->second.cancel_replace, *it->second.cancel);
|
||||
gw_rec->order.uav = full_update.uav;
|
||||
gw_rec->order.moi = full_update.moi;
|
||||
gw_rec->order.tif = full_update.tif;
|
||||
|
||||
// Fake a quick update, now that we already set the other fields
|
||||
GW_OrderQuickUpdate quick_update;
|
||||
quick_update.order_key = full_update.order_key;
|
||||
quick_update.quantity = full_update.quantity;
|
||||
quick_update.price = full_update.price;
|
||||
quick_update.req_id = full_update.req_id;
|
||||
on_gw_op(om_id, quick_update);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ack.result = GW_OP_Result::ERROR_GATEWAY_DISCONNECTED;
|
||||
break;
|
||||
}
|
||||
|
||||
// If we got to this point something went wrong and the update of
|
||||
// the order failed. This should be very rare. In this case we send
|
||||
// a reply right away.
|
||||
bts_assert(ack.result != GW_OP_Result::OK);
|
||||
on_order_report(make_order_report(gw_rec));
|
||||
}
|
||||
|
||||
void Gateway::on_gw_op(OM_ID, const GW_OrderCancel &cancel) {
|
||||
auto gw_rec = me->hot.working_orders.lookup(cancel.order_key);
|
||||
auto &ack = gw_rec->last_ack;
|
||||
ack = make_ack(cancel);
|
||||
|
||||
switch (me->hot.state) {
|
||||
case State::READY: {
|
||||
|
||||
// Do we know about this order?
|
||||
if (!gw_rec) {
|
||||
ack.result = GW_OP_Result::ERROR_ORDER_IS_NOT_ACTIVE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Can we route it?
|
||||
if (!gw_rec->is_routable()) {
|
||||
ack.result = GW_OP_Result::ERROR_NO_ROUTE;
|
||||
break;
|
||||
}
|
||||
|
||||
auto &order = gw_rec->order;
|
||||
gw_rec->cancel->update(order);
|
||||
me->hot.pending_msgs.push_back(gw_rec->cancel);
|
||||
|
||||
// We do not send out a order report yet for performance
|
||||
// reasons. Instead we delay the report until the exchange
|
||||
// reponds to our cancel
|
||||
return;
|
||||
}
|
||||
default:
|
||||
ack.result = GW_OP_Result::ERROR_GATEWAY_DISCONNECTED;
|
||||
break;
|
||||
}
|
||||
|
||||
// If we got here something went wrong and the cancel failed. This
|
||||
// is the exceptional path and it should almost never happen. In
|
||||
// this case we send out a new order report detailing the reasons
|
||||
// for the failure.
|
||||
bts_assert(ack.result != GW_OP_Result::OK);
|
||||
on_order_report(make_order_report(gw_rec));
|
||||
}
|
||||
|
||||
const char* Gateway::intern_string(std::string const&str) {
|
||||
auto [it,_] = me->cold.interned_strings.insert(str);
|
||||
(void)_;
|
||||
return it->data();
|
||||
}
|
||||
|
||||
void Gateway::send_pending_msgs() {
|
||||
auto &pending = me->hot.pending_msgs;
|
||||
// TODO: Need to make sure that there is no danger of reentrancy
|
||||
// here, in the case that venue calls us back from the send call
|
||||
me->hot.venue.send(pending.data(), (pending.data() + pending.size()));
|
||||
pending.clear();
|
||||
}
|
||||
|
||||
bool Gateway::has_bootstrap_data() const {
|
||||
return me->cold.bootstrap_orders.size() == me->cold.cfg.om_count &&
|
||||
me->cold.admin_data != nullptr;
|
||||
}
|
||||
|
||||
bool Gateway::in_active_schedule() const {
|
||||
auto now = me->cold.clock.ptime_now();
|
||||
return now >= me->cold.session_span.start &&
|
||||
now < me->cold.session_span.stop;
|
||||
}
|
||||
|
||||
void Gateway::transition(State state) {
|
||||
LOG(OrderMan, Info, "Transitioning gateway {} from {} to {}",
|
||||
me->cold.cfg.my_id.value, state_name(me->hot.state), state_name(state));
|
||||
me->hot.state = state;
|
||||
}
|
||||
|
||||
void Gateway::rebuild_msg_templates() {
|
||||
// First just rebuild our template cache
|
||||
me->hot.msg_templates.clear();
|
||||
auto all_uav = me->hot.limiter.get_all_user_account_venue();
|
||||
for (auto const &uav : all_uav) {
|
||||
auto rq = me->cold.router.get_route(uav);
|
||||
if (rq.has_route) {
|
||||
me->hot.msg_templates[uav] =
|
||||
me->hot.venue.get_msg_templates(rq.routing_record);
|
||||
}
|
||||
}
|
||||
|
||||
// Now go through every order and update its messages
|
||||
auto working = me->hot.working_orders.get_all();
|
||||
for (auto &orec : working) {
|
||||
orec->clear_msgs();
|
||||
if (auto it = me->hot.msg_templates.find(orec->order.uav);
|
||||
it != me->hot.msg_templates.end()) {
|
||||
orec->set_msgs(*it->second.cancel_replace, *it->second.cancel);
|
||||
} else {
|
||||
LOG(OrderMan, Error, "Order {} can no longer be routed. {}",
|
||||
orec->order.key, orec->order.uav.to_str());
|
||||
orec->clear_msgs();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Gateway::setup_bootstrap_orders() {
|
||||
bts_assert(me->hot.state == State::W_BOOTSTRAP);
|
||||
for (auto [om_id, order_vec] : me->cold.bootstrap_orders)
|
||||
for (auto &bind_order : *order_vec)
|
||||
on_gw_op(om_id, bind_order);
|
||||
me->cold.bootstrap_orders.clear();
|
||||
}
|
||||
|
||||
GW_OrderReport Gateway::make_order_report(OrderRec *gw_rec) {
|
||||
GW_OrderReport report;
|
||||
report.last_exe_report = gw_rec->order.last_exe_report;
|
||||
report.last_ack = gw_rec->last_ack;
|
||||
report.target = gw_rec->originator;
|
||||
return report;
|
||||
}
|
||||
|
||||
log::CharPtrWrapper Gateway::state_name(State state) {
|
||||
switch (state) {
|
||||
case State::W_BOOTSTRAP:
|
||||
return {"W_BOOTSTRAP"};
|
||||
case State::W_SCHEDULE:
|
||||
return {"W_SCHEDULE"};
|
||||
case State::PAUSED:
|
||||
return {"PAUSED"};
|
||||
case State::W_LOGON:
|
||||
return {"W_LOGON"};
|
||||
case State::READY:
|
||||
return {"READY"};
|
||||
}
|
||||
return {""};
|
||||
}
|
||||
|
||||
} // namespace orderman_v2
|
||||
} // namespace bts
|
||||
@@ -0,0 +1,78 @@
|
||||
#pragma once
|
||||
|
||||
#include "lib/logging/logging.h"
|
||||
#include "lib/orderman_v2/actors/Actor.h"
|
||||
#include "lib/orderman_v2/common.h"
|
||||
#include "lib/orderman_v2/events/events.h"
|
||||
#include "lib/orderman_v2/interconnect/ISlowWorker.h"
|
||||
#include "lib/orderman_v2/interconnect/Signal.h"
|
||||
#include "lib/orderman_v2/actors/gateway/IVenueObserver.h"
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
class IVenue;
|
||||
class ILimiter;
|
||||
class IRouter;
|
||||
class IClock;
|
||||
|
||||
struct GatewayCfg;
|
||||
class Gateway : public Actor, ISlowWorker, IGW_Op_Visitor, IVenueObserver {
|
||||
public:
|
||||
Gateway(IVenue &, ILimiter &, IRouter &, IClock &c, GatewayCfg const &);
|
||||
~Gateway();
|
||||
|
||||
|
||||
// Inputs
|
||||
void on_om_bootstrap_orders(OM_BootstrapOrders const &);
|
||||
void on_gw_ops(const GW_Op_Batch &);
|
||||
void on_account_pnl(const AccountPnLUpdate &);
|
||||
void on_position(const PositionUpdate &);
|
||||
void on_excess_liquidity(const ExcessLiquidityUpdate &);
|
||||
void on_admin_data(const AdminDataUpdate &);
|
||||
void on_venue_checkpoint(const VenueCheckpointNotice &);
|
||||
|
||||
// Signals
|
||||
Signal<GW_OrderReport> on_order_report;
|
||||
Signal<GW_UnknownOrderExeReport> on_unknown_native_order_update;
|
||||
Signal<GW_Error> on_gw_error;
|
||||
|
||||
// ISlowWorker
|
||||
void do_slow_work() override;
|
||||
|
||||
private:
|
||||
enum class State;
|
||||
class OrderMap;
|
||||
struct OrderRec;
|
||||
struct PImpl;
|
||||
struct Hot;
|
||||
struct Cold;
|
||||
std::unique_ptr<PImpl> me;
|
||||
|
||||
// IVenueObserver
|
||||
void on_venue_login_success(std::vector<ExecReport> const&) override;
|
||||
void on_venue_login_failure() override;
|
||||
void on_venue_disconnect() override;
|
||||
void on_venue_exe_report(const ExecReport &) override;
|
||||
void on_venue_error(VenueError const&) override;
|
||||
|
||||
// IGW_Op_visitor
|
||||
void on_gw_op(OM_ID, const GW_OrderCreate &) override;
|
||||
void on_gw_op(OM_ID, const GW_OrderBind &) override;
|
||||
void on_gw_op(OM_ID, const GW_OrderQuickUpdate &) override;
|
||||
void on_gw_op(OM_ID, const GW_OrderCancel &) override;
|
||||
void on_gw_op(OM_ID, const GW_OrderFullUpdate &) override;
|
||||
|
||||
const char* intern_string (std::string const&);
|
||||
void send_pending_msgs();
|
||||
bool has_bootstrap_data() const;
|
||||
bool in_active_schedule() const;
|
||||
void transition(State);
|
||||
void rebuild_msg_templates();
|
||||
void setup_bootstrap_orders();
|
||||
GW_OrderReport make_order_report(OrderRec *);
|
||||
static log::CharPtrWrapper state_name(State);
|
||||
};
|
||||
|
||||
} // namespace orderman_v2
|
||||
} // namespace bts
|
||||
@@ -0,0 +1 @@
|
||||
#include "ICancelMsg.h"
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include "lib/orderman_v2/actors/gateway/IVenueMsg.h"
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
struct GW_BoundOrder;
|
||||
|
||||
class ICancelMsg : public IVenueMsg {
|
||||
public:
|
||||
virtual ~ICancelMsg() {}
|
||||
|
||||
// These are very performance sensitive calls
|
||||
virtual ICancelMsg& clone() const = 0;
|
||||
virtual void update(GW_BoundOrder const&) const = 0;
|
||||
};
|
||||
|
||||
}}
|
||||
@@ -0,0 +1 @@
|
||||
#include "ICancelReplaceMsg.h"
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include "lib/orderman_v2/actors/gateway/IVenueMsg.h"
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
struct GW_BoundOrder;
|
||||
|
||||
class ICancelReplaceMsg : public IVenueMsg {
|
||||
public:
|
||||
virtual ~ICancelReplaceMsg() {}
|
||||
|
||||
// These are very performance sensitive calls
|
||||
virtual void update(GW_BoundOrder const&) = 0;
|
||||
virtual ICancelReplaceMsg& clone() const = 0;
|
||||
};
|
||||
|
||||
}}
|
||||
@@ -0,0 +1 @@
|
||||
#include "ILimiter.h"
|
||||
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "lib/orderman_v2/common.h"
|
||||
|
||||
namespace bts {
|
||||
namespace api {namespace admin { class AdminData; }}
|
||||
|
||||
namespace orderman_v2 {
|
||||
|
||||
struct AccountPnLUpdate;
|
||||
struct PositionUpdate;
|
||||
struct ExcessLiquidityUpdate;
|
||||
struct UserAccountVenue;
|
||||
|
||||
class ILimiter {
|
||||
public:
|
||||
|
||||
struct LimiterQueryResult {
|
||||
GW_OP_Result result;
|
||||
char const*message;
|
||||
bool ok() const { return result == GW_OP_Result::OK; }
|
||||
bool error() const { return !ok(); }
|
||||
};
|
||||
|
||||
virtual LimiterQueryResult can_send_new_order(AccountID account,
|
||||
api::Security const &sec,
|
||||
Side side, Quantity quantity);
|
||||
|
||||
virtual LimiterQueryResult can_update_order(AccountID account,
|
||||
api::Security const &sec,
|
||||
Side side, double delta);
|
||||
|
||||
virtual void update(api::admin::AdminData const &admin);
|
||||
virtual void update(AccountPnLUpdate const &) = 0;
|
||||
virtual void update(PositionUpdate const &) = 0;
|
||||
virtual void update(ExcessLiquidityUpdate const &) = 0;
|
||||
virtual std::vector<UserAccountVenue> get_all_user_account_venue() const = 0;
|
||||
};
|
||||
|
||||
}}
|
||||
@@ -0,0 +1 @@
|
||||
#include "INewOrderSingleMsg.h"
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include "lib/orderman_v2/actors/gateway/IVenueMsg.h"
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
struct GW_BoundOrder;
|
||||
|
||||
class INewOrderSingleMsg : public IVenueMsg {
|
||||
public:
|
||||
virtual ~INewOrderSingleMsg() {}
|
||||
|
||||
// These are very performance sensitive calls
|
||||
virtual INewOrderSingleMsg & clone() const = 0;
|
||||
virtual void set_order_params(GW_BoundOrder const&) =0;
|
||||
};
|
||||
|
||||
}}
|
||||
@@ -0,0 +1 @@
|
||||
#include "IRouter.h"
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "lib/api/services/OrderService.pb.h"
|
||||
|
||||
namespace bts {
|
||||
|
||||
namespace api {namespace admin {class AdminData;}}
|
||||
|
||||
namespace orderman_v2 {
|
||||
struct UserAccountVenue;
|
||||
|
||||
class IRouter {
|
||||
public:
|
||||
virtual void update(api::admin::AdminData const &admin);
|
||||
|
||||
struct RouteQueryResult {
|
||||
bool has_route;
|
||||
std::string error_msg;
|
||||
api::orderman::RoutingRecord routing_record;
|
||||
};
|
||||
virtual RouteQueryResult get_route(UserAccountVenue const &) = 0;
|
||||
};
|
||||
}}
|
||||
@@ -0,0 +1 @@
|
||||
#include "IVenue.h"
|
||||
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
#include "lib/utils/datetime.h"
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
|
||||
namespace bts {
|
||||
namespace api {
|
||||
class Security;
|
||||
namespace orderman { class RoutingRecord;}
|
||||
}
|
||||
|
||||
namespace orderman_v2 {
|
||||
|
||||
class INewOrderSingleMsg;
|
||||
class ICancelReplaceMsg;
|
||||
class ICancelMsg;
|
||||
class IVenueMsg;
|
||||
class IVenueObserver;
|
||||
class ExecReport;
|
||||
class VenueCheckpoint;
|
||||
|
||||
struct MsgTemplates {
|
||||
INewOrderSingleMsg* new_order;
|
||||
ICancelReplaceMsg* cancel_replace;
|
||||
ICancelMsg* cancel;
|
||||
};
|
||||
|
||||
struct SessionSpan {
|
||||
datetime::PTime start;
|
||||
datetime::PTime stop;
|
||||
};
|
||||
|
||||
|
||||
class IVenue {
|
||||
public:
|
||||
// call this before any of the below
|
||||
virtual void set_observer(IVenueObserver &) = 0;
|
||||
|
||||
// Return the current (or next) time interval when this venue is
|
||||
// active
|
||||
virtual SessionSpan get_current_session_span() = 0;
|
||||
|
||||
// Logon to the venue. This can only be called if the caller knows that the
|
||||
// venue is in the idle state.
|
||||
virtual void login() = 0;
|
||||
|
||||
// Build new order, cancel replace and cancel messages appropriate
|
||||
// for this venue and using the information in the passed routing
|
||||
// record
|
||||
virtual MsgTemplates
|
||||
get_msg_templates(api::orderman::RoutingRecord const &) = 0;
|
||||
|
||||
// Check to to see if the venue is currently able to receive new
|
||||
// messages without breaching messaging limits
|
||||
virtual bool under_messaging_limit() = 0;
|
||||
|
||||
// Send the passed messages to the venue. It is only legal to call
|
||||
// this if the venue is idle or ready.
|
||||
virtual void send(IVenueMsg**begin, IVenueMsg**end) = 0;
|
||||
|
||||
// Resolved the security in the execution report. This is only
|
||||
// needed for disaster recovery. Null should be returned in case of
|
||||
// failure.
|
||||
virtual api::Security const * resolve_security (ExecReport const&) = 0;
|
||||
|
||||
// Tell the venue what was the last message which had its effects
|
||||
// commited to disk
|
||||
virtual void set_checkpoint(VenueCheckpoint const&) = 0;
|
||||
};
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,2 @@
|
||||
#include "IVenueMsg.h"
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
class IVenueMsg {
|
||||
public:
|
||||
virtual void dispatch() = 0;
|
||||
virtual ~IVenueMsg() {}
|
||||
};
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,15 @@
|
||||
#include "IVenueObserver.h"
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
struct SilentVenueObserver : public IVenueObserver {
|
||||
void on_venue_login_success(std::vector<ExecReport> const &) override { }
|
||||
void on_venue_login_failure() override { }
|
||||
void on_venue_disconnect() override { }
|
||||
void on_venue_exe_report(const ExecReport &) override { }
|
||||
void on_venue_error(VenueError const &) override { }
|
||||
};
|
||||
IVenueObserver& default_venue_observer() {
|
||||
static SilentVenueObserver svo;
|
||||
return svo;
|
||||
}
|
||||
}}
|
||||
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
#include "lib/orderman_v2/common.h" // OrderKey
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
class ExecReport;
|
||||
|
||||
struct VenueError {
|
||||
enum Code { CANCEL_REJECT, BUSINESS_REJECT, SESSION_REJECT, OTHER };
|
||||
Code error_code;
|
||||
std::string error_msg;
|
||||
// null_order_key() if not applicable
|
||||
OrderKey order_key;
|
||||
};
|
||||
|
||||
class IVenueObserver {
|
||||
public:
|
||||
// We logged on successfully and recovered the execution reports
|
||||
// passed (this should be empty unless fills occurred while we were
|
||||
// logged out)
|
||||
virtual void on_venue_login_success(std::vector<ExecReport> const &) = 0;
|
||||
|
||||
// We failed to login, either because we could not connect to the
|
||||
// venue or because our credentials were invalid
|
||||
virtual void on_venue_login_failure() = 0;
|
||||
|
||||
// We were disconnected from the venue
|
||||
virtual void on_venue_disconnect() = 0;
|
||||
|
||||
// An execution report was received from the venue
|
||||
virtual void on_venue_exe_report(const ExecReport &) = 0;
|
||||
|
||||
// A message indicating some sort of error was received from the
|
||||
// exchange. If the error is order specific a order key will be
|
||||
// included.
|
||||
virtual void on_venue_error(VenueError const &) = 0;
|
||||
};
|
||||
|
||||
IVenueObserver& default_venue_observer();
|
||||
|
||||
} // namespace orderman_v2
|
||||
} // namespace bts
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include <string>
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
struct UserAccountVenue {
|
||||
UserID user;
|
||||
AccountID account;
|
||||
api::Venue venue;
|
||||
bool operator==(UserAccountVenue const &rhs) const {
|
||||
return user == rhs.user && account == rhs.account && venue == rhs.venue;
|
||||
}
|
||||
|
||||
std::string to_str() {
|
||||
return fmt::format (" user_id: {} account_id: {} venue: {}",
|
||||
user.value,
|
||||
account.value,
|
||||
api::Venue_Name(venue));
|
||||
}
|
||||
};
|
||||
|
||||
struct UserAccountVenueHash {
|
||||
std::size_t operator()(UserAccountVenue const &k) const {
|
||||
size_t result = k.user.value;
|
||||
boost::hash_combine(result, k.account.value);
|
||||
boost::hash_combine(result, k.venue);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
@@ -0,0 +1 @@
|
||||
#include "lib/orderman_v2/actors/gateway/fix/FIXVenueCtx.h"
|
||||
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include "lib/config/protos/jetfix.pb.h"
|
||||
#include "lib/jetfix/codec/FIXEncodingStream.h"
|
||||
#include "lib/orderman/governor/Governor.h"
|
||||
|
||||
#include "VenueCheckpoint.h"
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
class IFIXStore {};
|
||||
class IClock;
|
||||
class IConnectionController;
|
||||
class IVenueObserver;
|
||||
|
||||
class FIXVenueCtx {
|
||||
public:
|
||||
FIXVenueCtx(config::JetFIX::Connection const &cfg,
|
||||
VenueCheckpoint const &last_processed_msg, IClock &clock,
|
||||
IFIXStore &store)
|
||||
: controller(), venue_observer(), store(store), clock(clock),
|
||||
out_buffer(cfg, 1), cfg(cfg), last_processed_msg(last_processed_msg) {}
|
||||
|
||||
IConnectionController *controller;
|
||||
IVenueObserver *venue_observer;
|
||||
IFIXStore &store;
|
||||
IClock &clock;
|
||||
jetfix::FIXEncodingStream out_buffer;
|
||||
orderman::Governor governor;
|
||||
config::JetFIX::Connection cfg;
|
||||
VenueCheckpoint last_processed_msg;
|
||||
}; // namespace orderman_v2
|
||||
|
||||
} // namespace orderman_v2
|
||||
} // namespace bts
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
class VenueCheckpoint {
|
||||
public:
|
||||
const char*connection_name;
|
||||
const char*session_uid;
|
||||
uint32_t seq_number;
|
||||
};
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "FIXVenueIdle.h"
|
||||
#include "FIXVenueCtx.h"
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
FIXVenueIdle::PImpl (FIXVenueCtx &,FIXVenueWConnect &) {
|
||||
FIXVenueCtx &ctx;
|
||||
FIX
|
||||
|
||||
};
|
||||
|
||||
FIXVenueIdle::FIXVenueIdle() : me (new PImpl()) {}
|
||||
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,14 @@
|
||||
// #include "FIXVenueIdle.h"
|
||||
// #include "FIXVenueCtx.h"
|
||||
|
||||
// namespace bts {
|
||||
// namespace orderman_v2 {
|
||||
|
||||
// FIXVenueIdle::PImpl (FIXVenueCtx &,FIXVenueWConnect &) {
|
||||
// FIXVenueCtx &ctx;
|
||||
// };
|
||||
|
||||
// FIXVenueIdle::FIXVenueIdle() : me (new PImpl()) {}
|
||||
|
||||
|
||||
// }}
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include "IFIXVenueState.h"
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
class WConnect;
|
||||
class FIXVenueCtx;
|
||||
|
||||
class FIXVenueIdle : public IFIXVenueState {
|
||||
public:
|
||||
void init(FIXVenueCtx &,WConnect&);
|
||||
void send(IVenueMsg **, IVenueMsg**) override {};
|
||||
const char*name() override {return "FIXVenueIdle";}
|
||||
|
||||
void enter() override;
|
||||
void login() override;
|
||||
private:
|
||||
struct PImpl;
|
||||
std::unique_ptr<PImpl> me;
|
||||
};
|
||||
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
#include "lib/utils/bts_assert.h"
|
||||
|
||||
namespace bts {
|
||||
namespace jetfix {class InMsgBuffer;}
|
||||
namespace orderman_v2 {
|
||||
class IVenueMsg;
|
||||
|
||||
class IFIXVenueState {
|
||||
public:
|
||||
virtual void enter() = 0;
|
||||
virtual void login() {bts_assert(false);}
|
||||
virtual void send(IVenueMsg **, IVenueMsg**) {bts_assert(false);}
|
||||
virtual void on_connect_success() {bts_assert(false);}
|
||||
virtual void on_connect_fail() {bts_assert(false);}
|
||||
virtual void on_disconnect() {bts_assert(false);}
|
||||
virtual void on_msg(jetfix::InMsgBuffer const&) {bts_assert(false);}
|
||||
virtual const char* name() = 0;
|
||||
};
|
||||
}}
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
#pragma once
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
const char* translate_business_reject_reason(int reason) {
|
||||
switch(reason) {
|
||||
case 0: return "Other";
|
||||
case 1: return "Unknown ID (unknown PartyDetailsListReqID being referenced in business message)";
|
||||
case 2: return "Unknown Security";
|
||||
case 3: return "Unsupported Message Type (for example using messages specific to cash markets for futures)";
|
||||
case 5: return "Required Field Missing";
|
||||
case 6: return "Not Authorized";
|
||||
case 8: return "Throttle Limit Exceeded (volume controls)";
|
||||
case 100: return "Value is incorrect (out of range) for this tag (for example using a value outside defined range of integer) ";
|
||||
case 101: return "Incorrect data format for value (for example using ASCII character outside 32-126 in string field)";
|
||||
case 102: return "Rejected due to Kill Switch";
|
||||
case 103: return "Rejected due to Risk Management API";
|
||||
case 104: return "Rejected due to Globex Credit Controls";
|
||||
case 105: return "Not Authorized to trade Deliverable Swap Futures";
|
||||
case 106: return "Not Authorized to trade Interest Rate Swap Futures";
|
||||
case 107: return "Rejected due to Inline Credit Controls";
|
||||
case 108: return "Invalid PartyDetailsListReqID (reusing already existing PartyDetailsListReqID while creating Party Details Definition Request)";
|
||||
case 109: return "Incoming message could not be decoded";
|
||||
case 110: return "Same repeating group entry appears more than once";
|
||||
case 111: return "Exceeded maximum number of allowable Party Details Definition Requests";
|
||||
case 112: return "Technical Error in Registering Party Details";
|
||||
case 113: return "Rejected due to Cross Venue Risk";
|
||||
case 114: return "Order Status Not Available";
|
||||
case 115: return "Enum Not Supported";
|
||||
case 116: return "Order Status Not Found";
|
||||
case 117: return "Mass Order Status Cannot be Completed";
|
||||
case 118: return "Exceeded Maximum Number of Allowable RequestingPartyID's in Party Details List Request";
|
||||
case 119: return "Duplicate Order Threshold Exceeded";
|
||||
case 120: return "On-Demand Message Rejected Due to Preceding Party Details Definition Request Being Rejected";
|
||||
case 121: return "Message Rejected Since PartyDetailsListReqID Does Not Match with Immediately Preceding Party Details Definition Request sent to MSGW when using On-demand administrative information";
|
||||
case 122: return "Party Details Definition Request sent to MSGW Being Rejected Due to Corresponding Business Message Being Rejected";
|
||||
case 123: return "Another Message Sent in Between Party Details Definition Request and Business Message when using On-demand administrative information";
|
||||
case 124: return "Cannot Have More Than One In-Flight Mass Order Status Request in Progress";
|
||||
case 125: return "Exceeded Maximum Number of In-Flight Order Status Requests";
|
||||
case 126: return "Cannot Have More Than One In-Flight Party Details List Request in Progress";
|
||||
case 127: return "Party Details List Request is Missing Requesting Party ID and Party ID";
|
||||
case 128: return "Party Details List Request cannot contain both RequestingPartyID and PartyID";
|
||||
case 129: return "Party Details Definition Request Being Rejected Since Another Message was sent in Between On-Demand Message";
|
||||
case 130: return "Buy Side Firm ID Does Not Match Sell Side Firm ID in New Order Cross";
|
||||
case 131: return "Message Type Not Supported on Backup Instance";
|
||||
case 132: return "New Order Cross Does Not Contain Buy Side Followed by Sell Side";
|
||||
}
|
||||
return "Unknown or invalid business reject reason.";
|
||||
}
|
||||
|
||||
const char* translate_negotiation_reject(int reason) {
|
||||
// https://www.cmegroup.com/confluence/display/EPICSANDBOX/Negotiation+Reject
|
||||
// 01/13/2020
|
||||
switch(reason) {
|
||||
case 0: return "HMACNotAuthenticated: failed authentication because identity is not recognized";
|
||||
case 1: return "HMACNotAvailable: HMAC component is not responding (5sec)";
|
||||
case 2: return "InvalidUUID: UUID is not greater than the one last used or value sent by the client is out of acceptable range (MIN, MAX)";
|
||||
case 3: return "InvalidTimestamp: Timestamp is not greater than the one last used or value sent by the client is out of acceptable range (MIN, MAX)";
|
||||
case 4: return "RequiredHMACSignatureMissing: empty bytes in HMACSignature field";
|
||||
case 5: return "RequiredAccessKeyIDMissing: empty bytes in AccessKeyID field";
|
||||
case 6: return "RequiredSessionMissing: empty bytes in Session field";
|
||||
case 7: return "RequiredFirmMissing: empty bytes in Firm field";
|
||||
case 8: return "RequiredUUIDMisssing: null value in UUID field";
|
||||
case 9: return "RequiredRequestTimestampMissing: null value in RequestTimestamp field";
|
||||
case 10: return "SessionBlocked: session and firm are not authorized for this port";
|
||||
case 12: return "InvalidAccessKeyID: contains non-printable ASCII character";
|
||||
case 13: return "InvalidSession: contains non-printable ASCII character";
|
||||
case 14: return "InvalidFirm: contains non-printable ASCII character";
|
||||
case 15: return "Volume Controls - exceeding TPS limit as defined for volume controls (reject action)";
|
||||
case 16: return "SplitMessageRejected - Messages queued due to split message penalty being rejected because of logout or disconnect";
|
||||
case 17: return "SplitMessageQueue - Reached threshold of messages queued due to split message penalty";
|
||||
case 27: return "DesignatedBackup - Using Designated backup before designated primary not allowed";
|
||||
}
|
||||
return "Unknown or invalid Negotiate reject reason.";
|
||||
}
|
||||
|
||||
const char* translate_establish_reject(int reason) {
|
||||
switch(reason) {
|
||||
case 0: return "HMACNotAuthenticated: failed authentication because identity is not recognized";
|
||||
case 1: return "HMACNotAvailable: HMAC component is not responding (5sec)";
|
||||
case 2: return "InvalidUUID: UUID is not greater than the one last used or value sent by the client is out of acceptable range (MIN, MAX)";
|
||||
case 3: return "InvalidTimestamp: Timestamp is not greater than the one last used or value sent by the client is out of acceptable range (MIN, MAX)";
|
||||
case 4: return "RequiredHMACSignatureMissing: empty bytes in HMACSignature field";
|
||||
case 5: return "RequiredAccessKeyIDMissing: empty bytes in AccessKeyID field";
|
||||
case 6: return "RequiredSessionMissing: empty bytes in Session field";
|
||||
case 7: return "RequiredFirmMissing: empty bytes in Firm field";
|
||||
case 8: return "RequiredUUIDMisssing: null value in UUID field";
|
||||
case 9: return "RequiredRequestTimestampMissing: null value in RequestTimestamp field";
|
||||
case 10: return "SessionBlocked: session and firm are not authorized for this port";
|
||||
case 11: return "InvalidKeepAliveInterval: value is out of acceptable range (MIN, MAX)";
|
||||
case 12: return "InvalidAccessKeyID: contains non-printable ASCII character";
|
||||
case 13: return "InvalidSession: contains non-printable ASCII character";
|
||||
case 14: return "InvalidFirm: contains non-printable ASCII character";
|
||||
case 15: return "Volume Controls - exceeding TPS limit as defined for volume controls (reject action)";
|
||||
case 16: return "SplitMessageRejected - Messages queued due to split message penalty being rejected because of logout or disconnect";
|
||||
case 17: return "SplitMessageQueue - Reached threshold of messages queued due to split message penalty";
|
||||
case 18: return "RequiredTradingSystemNameMissing: empty bytes in TradingSystemName";
|
||||
case 19: return "RequiredTradingSystemVersionMissing: empty bytes in TradingSystemVersion";
|
||||
case 20: return "RequiredTradingSystemVendorMissing: empty bytes in TradingSystemVendor";
|
||||
case 21: return "RequiredKeepAliveIntervalMissing: null value in KeepAliveInterval field";
|
||||
case 22: return "RequiredNextSeqNoMissing: empty bytes in NextSeqNo field";
|
||||
case 23: return "InvalidTradingSystemName: contains non-prinatable ASCII character";
|
||||
case 24: return "InvalidTradingSystemVersion: contains non-prinatable ASCII character";
|
||||
case 25: return "InvalidTradingSystemVendor: contains non-prinatable ASCII character";
|
||||
case 26: return "DesignatedBackup - Using Designated backup before designated primary not allowed";
|
||||
case 27: return "DesignatedBackup - Using Designated backup before designated primary not allowed";
|
||||
}
|
||||
return "Unknown or invalid Establish reject reason.";
|
||||
}
|
||||
|
||||
}}//namespace
|
||||
@@ -0,0 +1,294 @@
|
||||
#include "ILink3Venue.h"
|
||||
#include "ILink3Utils.h"
|
||||
#include "lib/utils/bts_assert.h"
|
||||
#include "lib/logging/logging.h"
|
||||
#include "lib/utils/datetime.h"
|
||||
#include "lib/orderman_v2/actors/gateway/IVenueObserver.h"
|
||||
#include "lib/orderman_v2/actors/network/IConnectionController.h"
|
||||
#include "lib/utils/SecureLogon.h"
|
||||
|
||||
#include "generated/MessageHeader.h"
|
||||
#include "generated/Negotiate500.h"
|
||||
#include "generated/NegotiationResponse501.h"
|
||||
#include "generated/NegotiationReject502.h"
|
||||
#include "generated/Establish503.h"
|
||||
#include "generated/NewOrderSingle514.h"
|
||||
#include "generated/BusinessReject521.h"
|
||||
|
||||
// high pri
|
||||
#include "generated/ExecutionReportNew522.h"
|
||||
#include "generated/ExecutionReportModify531.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <variant>
|
||||
#include <tuple>
|
||||
#include <fstream>
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
typedef unsigned char byte;
|
||||
struct FramingHeader {
|
||||
uint16_t message_size;
|
||||
// always 0xCAFE
|
||||
uint16_t encoding_type;
|
||||
};
|
||||
|
||||
|
||||
template <class Msg, size_t Data=0, size_t Sz=4+iLinkBinary::MessageHeader::encodedLength()+Msg::sbeBlockLength()>
|
||||
std::array<char,Sz+Data> mkbuffer() {
|
||||
static_assert(sizeof(FramingHeader) == 4);
|
||||
return std::array<char,Sz+Data> {};
|
||||
}
|
||||
|
||||
template <class Msg, size_t Sz>
|
||||
Msg frame_message(std::array<char,Sz>& buffer) {
|
||||
static_assert(Sz >= 4+iLinkBinary::MessageHeader::encodedLength()+Msg::sbeBlockLength());
|
||||
static_assert(sizeof(FramingHeader) == 4);
|
||||
FramingHeader* fhead = reinterpret_cast<FramingHeader*>(&buffer[0]);
|
||||
fhead->message_size = buffer.size();
|
||||
fhead->encoding_type = 0xCAFE;
|
||||
Msg msg;
|
||||
msg.wrapAndApplyHeader((char*)&buffer, sizeof(FramingHeader), buffer.size());
|
||||
return msg;
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
//
|
||||
// States
|
||||
//
|
||||
|
||||
struct Idle {};
|
||||
struct Connecting {
|
||||
enum class Step {
|
||||
EstablishSocket,
|
||||
Negotiate, // initiates a new session
|
||||
Establish, // binds to an existing session
|
||||
Transfer, // negotate sequence number?
|
||||
};
|
||||
Step step;
|
||||
int failover_count;
|
||||
};
|
||||
struct Connected {};
|
||||
struct Disconnected {};
|
||||
|
||||
using State = std::variant<Idle,Connecting,Connected,Disconnected>;
|
||||
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
struct ILink3Venue::PImpl {
|
||||
PImpl():
|
||||
session(determine_session()),
|
||||
sequence(0),
|
||||
sequence_cme(0),
|
||||
state(Idle{}),
|
||||
observer(default_venue_observer()),
|
||||
connection(nullptr)
|
||||
{ }
|
||||
|
||||
uint64_t session;
|
||||
uint64_t sequence;
|
||||
uint64_t sequence_cme;
|
||||
State state;
|
||||
IVenueObserver& observer;
|
||||
IConnectionController* connection;
|
||||
|
||||
template<class T>
|
||||
void assert_state() {
|
||||
bts_assert(std::holds_alternative<T>(state));
|
||||
}
|
||||
|
||||
uint64_t determine_session() {
|
||||
// this is fairly complex
|
||||
// see session_name.h
|
||||
return utils::TimeStamp::now().to_uint64();
|
||||
}
|
||||
|
||||
|
||||
// CME messages
|
||||
void do_negotiate() {
|
||||
// add 2 bytes for empty 'credentials' (39008) length
|
||||
auto buffer = mkbuffer<iLinkBinary::Negotiate500,2>();
|
||||
auto msg = frame_message<iLinkBinary::Negotiate500>(buffer);
|
||||
|
||||
// msg.customerFlow(); // constant
|
||||
// msg.hMACVersion(); // constant
|
||||
msg.uUID(this->session);
|
||||
msg.requestTimestamp(datetime::unix_nano_now());
|
||||
msg.putSession("NGG");
|
||||
// sets the length of the credential block to ushort 00
|
||||
msg.putCredentials("");
|
||||
// pad with 0 at the front *and* null at the back
|
||||
const std::string_view firm = "004";
|
||||
// this must use the std::string_view overload
|
||||
// the char* overload does not pad correctly
|
||||
msg.putFirm(firm);
|
||||
const auto ld = glbx::calculate_hmac(
|
||||
msg.getSessionAsString(),
|
||||
std::to_string(msg.requestTimestamp()),
|
||||
std::to_string(msg.uUID()),
|
||||
msg.getSessionAsString(),
|
||||
firm.data()
|
||||
);
|
||||
msg.putAccessKeyID(ld.access_key);
|
||||
msg.putHMACSignature(ld.signature);
|
||||
|
||||
connection->send({ buffer.data(), buffer.size() });
|
||||
}
|
||||
|
||||
void do_establish() {
|
||||
// add 2 bytes for empty 'credentials' (39008) length
|
||||
// auto buffer = mkbuffer<iLinkBinary::Establish503,2>();
|
||||
// auto msg = frame_message<iLinkBinary::Establish503>(buffer);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void log(const T& t) {
|
||||
std::stringstream buf;
|
||||
buf << t;
|
||||
LOG(OrderMan, Warn, "{}", buf.str());
|
||||
}
|
||||
template <class T, class D> void log(const T& t, int errcode, D decode) {
|
||||
std::stringstream buf;
|
||||
buf << t;
|
||||
LOG(OrderMan, Warn, "Error: {}\n{}", std::string(decode(errcode)), buf.str());
|
||||
}
|
||||
|
||||
void handle_negotiate_response(const iLinkBinary::NegotiationResponse501& msg) {
|
||||
log(msg);
|
||||
}
|
||||
|
||||
void handle_negotiate_reject(const iLinkBinary::NegotiationReject502& msg) {
|
||||
log(msg, msg.errorCodes(), translate_negotiation_reject);
|
||||
}
|
||||
|
||||
void handle_business_reject(const iLinkBinary::BusinessReject521& msg) {
|
||||
log(msg, msg.businessRejectReason(), translate_business_reject_reason);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// Interface methods
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
ILink3Venue::ILink3Venue() : me(std::make_unique<PImpl>())
|
||||
{
|
||||
}
|
||||
|
||||
ILink3Venue::~ILink3Venue() {}
|
||||
|
||||
//
|
||||
// IConnectionHandler
|
||||
//
|
||||
|
||||
void ILink3Venue::init_handler(IConnectionController& c) {
|
||||
me->connection = &c;
|
||||
}
|
||||
void ILink3Venue::on_connect_success() {
|
||||
auto& state = std::get<Connecting>(me->state);
|
||||
bts_assert(state.step == Connecting::Step::EstablishSocket);
|
||||
state.step = Connecting::Step::Negotiate;
|
||||
me->do_negotiate();
|
||||
}
|
||||
void ILink3Venue::on_connect_fail() {
|
||||
me->assert_state<Connecting>();
|
||||
me->connection->failover();
|
||||
auto& state = std::get<Connecting>(me->state);
|
||||
//todo: config this
|
||||
if (state.failover_count < 16) {
|
||||
state.failover_count += 1;
|
||||
me->connection->connect();
|
||||
}
|
||||
else {
|
||||
LOG(OrderMan,Error, "ilink3 connection exceeded failover count");
|
||||
me->observer.on_venue_login_failure();
|
||||
}
|
||||
}
|
||||
void ILink3Venue::on_disconnect() {
|
||||
LOG(OrderMan, Warn, "Disconnected");
|
||||
me->state = Disconnected {};
|
||||
}
|
||||
void ILink3Venue::on_data(const std::string_view& message) {
|
||||
// decode message and dispatch to handler function
|
||||
auto fh = reinterpret_cast<const FramingHeader*>(message.data());
|
||||
bts_assert_d(fh->encoding_type == 0xCAFE);
|
||||
iLinkBinary::MessageHeader header((char*)message.data()+4, message.size());
|
||||
constexpr size_t offset = sizeof(FramingHeader) + iLinkBinary::MessageHeader::encodedLength();
|
||||
char* buffer = (char*)message.data() + offset;
|
||||
size_t size = message.size() - offset;
|
||||
|
||||
// TODO: Docs seem to say there will only be one SBE message per packet so we're
|
||||
// going with that for now. If we miss a message it should shake out in certification
|
||||
|
||||
// TODO: For the sake of performance we should split the switch in 2 high priority messages are served first
|
||||
switch(header.templateId()) {
|
||||
case iLinkBinary::NegotiationResponse501::sbeTemplateId():
|
||||
me->handle_negotiate_response({ buffer, size });
|
||||
break;
|
||||
|
||||
case iLinkBinary::NegotiationReject502::sbeTemplateId():
|
||||
me->handle_negotiate_reject({ buffer, size });
|
||||
break;
|
||||
|
||||
case iLinkBinary::BusinessReject521::sbeTemplateId():
|
||||
me->handle_business_reject({buffer,size});
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG(OrderMan, Warn,
|
||||
"Unrecognized iLink3 template templateId={} schemaId={} version={}",
|
||||
header.templateId(),
|
||||
header.schemaId(),
|
||||
header.version()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// IVenue
|
||||
//
|
||||
|
||||
void ILink3Venue::set_observer(IVenueObserver& o) {
|
||||
me->observer = o;
|
||||
}
|
||||
|
||||
SessionSpan ILink3Venue::get_current_session_span() {
|
||||
bts_assert(false);
|
||||
return SessionSpan{};
|
||||
}
|
||||
|
||||
void ILink3Venue::login() {
|
||||
if (me->connection == nullptr) {
|
||||
LOG(OrderMan, Error, "Cannot log in ILink3 session without connection");
|
||||
me->observer.on_venue_login_failure();
|
||||
}
|
||||
me->state = Connecting { Connecting::Step::EstablishSocket, 0 };
|
||||
me->connection->connect();
|
||||
}
|
||||
|
||||
MsgTemplates ILink3Venue::get_msg_templates(const api::orderman::RoutingRecord&) {
|
||||
return {};
|
||||
}
|
||||
|
||||
bool ILink3Venue::under_messaging_limit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ILink3Venue::send(IVenueMsg**begin, IVenueMsg**end) {
|
||||
(void)begin;
|
||||
(void)end;
|
||||
}
|
||||
|
||||
const api::Security* ILink3Venue::resolve_security (const ExecReport&) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ILink3Venue::set_checkpoint(const VenueCheckpoint&) {
|
||||
}
|
||||
|
||||
|
||||
}} //namespace
|
||||
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
#include "lib/orderman_v2/actors/gateway/IVenue.h"
|
||||
#include "lib/orderman_v2/actors/network/IConnectionHandler.h"
|
||||
|
||||
namespace bts {
|
||||
namespace orderman_v2 {
|
||||
|
||||
class ILink3Venue :
|
||||
public IVenue,
|
||||
public IConnectionHandler
|
||||
{
|
||||
struct PImpl;
|
||||
std::unique_ptr<PImpl> me;
|
||||
|
||||
public:
|
||||
ILink3Venue();
|
||||
~ILink3Venue();
|
||||
|
||||
// IConnectionHandler
|
||||
|
||||
void init_handler(IConnectionController &) override;
|
||||
void on_connect_success() override;
|
||||
void on_connect_fail() override;
|
||||
void on_disconnect() override;
|
||||
void on_data(const std::string_view& data) override;
|
||||
|
||||
// IVenue
|
||||
|
||||
void set_observer(IVenueObserver &) override;
|
||||
SessionSpan get_current_session_span() override;
|
||||
void login() override;
|
||||
MsgTemplates get_msg_templates(const api::orderman::RoutingRecord &) override;
|
||||
bool under_messaging_limit() override;
|
||||
void send(IVenueMsg**begin, IVenueMsg**end) override;
|
||||
const api::Security* resolve_security (const ExecReport&) override;
|
||||
void set_checkpoint(const VenueCheckpoint&) override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
}} //namespace
|
||||
@@ -0,0 +1,141 @@
|
||||
/* Generated SBE (Simple Binary Encoding) message codec */
|
||||
#ifndef _ILINKBINARY_AVGPXIND_H_
|
||||
#define _ILINKBINARY_AVGPXIND_H_
|
||||
|
||||
#if defined(SBE_HAVE_CMATH)
|
||||
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
|
||||
# include <cmath>
|
||||
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
|
||||
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
|
||||
#else
|
||||
/* math.h needed for NAN */
|
||||
# include <math.h>
|
||||
# define SBE_FLOAT_NAN NAN
|
||||
# define SBE_DOUBLE_NAN NAN
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# include <cstdint>
|
||||
# include <string>
|
||||
# include <cstring>
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# define SBE_CONSTEXPR constexpr
|
||||
# define SBE_NOEXCEPT noexcept
|
||||
#else
|
||||
# define SBE_CONSTEXPR
|
||||
# define SBE_NOEXCEPT
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
# define SBE_NODISCARD [[nodiscard]]
|
||||
#else
|
||||
# define SBE_NODISCARD
|
||||
#endif
|
||||
|
||||
#if !defined(__STDC_LIMIT_MACROS)
|
||||
# define __STDC_LIMIT_MACROS 1
|
||||
#endif
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
|
||||
#else
|
||||
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
|
||||
#endif
|
||||
|
||||
#if defined(SBE_NO_BOUNDS_CHECK)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
|
||||
#elif defined(_MSC_VER)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
|
||||
#else
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
|
||||
#endif
|
||||
|
||||
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
|
||||
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
|
||||
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
|
||||
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
|
||||
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
|
||||
|
||||
|
||||
namespace iLinkBinary {
|
||||
|
||||
class AvgPxInd
|
||||
{
|
||||
public:
|
||||
enum Value
|
||||
{
|
||||
NoAveragePricing = (std::uint8_t)0,
|
||||
TradeispartofanAveragePriceGroupIdentifiedbytheAvgPxGrpID = (std::uint8_t)1,
|
||||
TradeispartofaNotionalValueAveragePriceGroup = (std::uint8_t)3,
|
||||
NULL_VALUE = (std::uint8_t)255
|
||||
};
|
||||
|
||||
static AvgPxInd::Value get(const std::uint8_t value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 0: return NoAveragePricing;
|
||||
case 1: return TradeispartofanAveragePriceGroupIdentifiedbytheAvgPxGrpID;
|
||||
case 3: return TradeispartofaNotionalValueAveragePriceGroup;
|
||||
case 255: return NULL_VALUE;
|
||||
}
|
||||
|
||||
throw std::runtime_error("unknown value for enum AvgPxInd [E103]");
|
||||
}
|
||||
|
||||
static const char* c_str(const AvgPxInd::Value value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case NoAveragePricing: return "NoAveragePricing";
|
||||
case TradeispartofanAveragePriceGroupIdentifiedbytheAvgPxGrpID: return "TradeispartofanAveragePriceGroupIdentifiedbytheAvgPxGrpID";
|
||||
case TradeispartofaNotionalValueAveragePriceGroup: return "TradeispartofaNotionalValueAveragePriceGroup";
|
||||
case NULL_VALUE: return "NULL_VALUE";
|
||||
}
|
||||
|
||||
throw std::runtime_error("unknown value for enum AvgPxInd [E103]:");
|
||||
}
|
||||
|
||||
template<typename CharT, typename Traits>
|
||||
friend std::basic_ostream<CharT, Traits>& operator<<(
|
||||
std::basic_ostream<CharT, Traits>& os, AvgPxInd::Value m)
|
||||
{
|
||||
return os << AvgPxInd::c_str(m);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,138 @@
|
||||
/* Generated SBE (Simple Binary Encoding) message codec */
|
||||
#ifndef _ILINKBINARY_BOOLEANFLAG_H_
|
||||
#define _ILINKBINARY_BOOLEANFLAG_H_
|
||||
|
||||
#if defined(SBE_HAVE_CMATH)
|
||||
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
|
||||
# include <cmath>
|
||||
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
|
||||
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
|
||||
#else
|
||||
/* math.h needed for NAN */
|
||||
# include <math.h>
|
||||
# define SBE_FLOAT_NAN NAN
|
||||
# define SBE_DOUBLE_NAN NAN
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# include <cstdint>
|
||||
# include <string>
|
||||
# include <cstring>
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# define SBE_CONSTEXPR constexpr
|
||||
# define SBE_NOEXCEPT noexcept
|
||||
#else
|
||||
# define SBE_CONSTEXPR
|
||||
# define SBE_NOEXCEPT
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
# define SBE_NODISCARD [[nodiscard]]
|
||||
#else
|
||||
# define SBE_NODISCARD
|
||||
#endif
|
||||
|
||||
#if !defined(__STDC_LIMIT_MACROS)
|
||||
# define __STDC_LIMIT_MACROS 1
|
||||
#endif
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
|
||||
#else
|
||||
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
|
||||
#endif
|
||||
|
||||
#if defined(SBE_NO_BOUNDS_CHECK)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
|
||||
#elif defined(_MSC_VER)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
|
||||
#else
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
|
||||
#endif
|
||||
|
||||
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
|
||||
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
|
||||
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
|
||||
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
|
||||
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
|
||||
|
||||
|
||||
namespace iLinkBinary {
|
||||
|
||||
class BooleanFlag
|
||||
{
|
||||
public:
|
||||
enum Value
|
||||
{
|
||||
False = (std::uint8_t)0,
|
||||
True = (std::uint8_t)1,
|
||||
NULL_VALUE = (std::uint8_t)255
|
||||
};
|
||||
|
||||
static BooleanFlag::Value get(const std::uint8_t value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 0: return False;
|
||||
case 1: return True;
|
||||
case 255: return NULL_VALUE;
|
||||
}
|
||||
|
||||
throw std::runtime_error("unknown value for enum BooleanFlag [E103]");
|
||||
}
|
||||
|
||||
static const char* c_str(const BooleanFlag::Value value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case False: return "False";
|
||||
case True: return "True";
|
||||
case NULL_VALUE: return "NULL_VALUE";
|
||||
}
|
||||
|
||||
throw std::runtime_error("unknown value for enum BooleanFlag [E103]:");
|
||||
}
|
||||
|
||||
template<typename CharT, typename Traits>
|
||||
friend std::basic_ostream<CharT, Traits>& operator<<(
|
||||
std::basic_ostream<CharT, Traits>& os, BooleanFlag::Value m)
|
||||
{
|
||||
return os << BooleanFlag::c_str(m);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,138 @@
|
||||
/* Generated SBE (Simple Binary Encoding) message codec */
|
||||
#ifndef _ILINKBINARY_BOOLEANNULL_H_
|
||||
#define _ILINKBINARY_BOOLEANNULL_H_
|
||||
|
||||
#if defined(SBE_HAVE_CMATH)
|
||||
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
|
||||
# include <cmath>
|
||||
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
|
||||
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
|
||||
#else
|
||||
/* math.h needed for NAN */
|
||||
# include <math.h>
|
||||
# define SBE_FLOAT_NAN NAN
|
||||
# define SBE_DOUBLE_NAN NAN
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# include <cstdint>
|
||||
# include <string>
|
||||
# include <cstring>
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# define SBE_CONSTEXPR constexpr
|
||||
# define SBE_NOEXCEPT noexcept
|
||||
#else
|
||||
# define SBE_CONSTEXPR
|
||||
# define SBE_NOEXCEPT
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
# define SBE_NODISCARD [[nodiscard]]
|
||||
#else
|
||||
# define SBE_NODISCARD
|
||||
#endif
|
||||
|
||||
#if !defined(__STDC_LIMIT_MACROS)
|
||||
# define __STDC_LIMIT_MACROS 1
|
||||
#endif
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
|
||||
#else
|
||||
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
|
||||
#endif
|
||||
|
||||
#if defined(SBE_NO_BOUNDS_CHECK)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
|
||||
#elif defined(_MSC_VER)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
|
||||
#else
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
|
||||
#endif
|
||||
|
||||
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
|
||||
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
|
||||
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
|
||||
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
|
||||
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
|
||||
|
||||
|
||||
namespace iLinkBinary {
|
||||
|
||||
class BooleanNULL
|
||||
{
|
||||
public:
|
||||
enum Value
|
||||
{
|
||||
False = (std::uint8_t)0,
|
||||
True = (std::uint8_t)1,
|
||||
NULL_VALUE = (std::uint8_t)255
|
||||
};
|
||||
|
||||
static BooleanNULL::Value get(const std::uint8_t value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 0: return False;
|
||||
case 1: return True;
|
||||
case 255: return NULL_VALUE;
|
||||
}
|
||||
|
||||
throw std::runtime_error("unknown value for enum BooleanNULL [E103]");
|
||||
}
|
||||
|
||||
static const char* c_str(const BooleanNULL::Value value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case False: return "False";
|
||||
case True: return "True";
|
||||
case NULL_VALUE: return "NULL_VALUE";
|
||||
}
|
||||
|
||||
throw std::runtime_error("unknown value for enum BooleanNULL [E103]:");
|
||||
}
|
||||
|
||||
template<typename CharT, typename Traits>
|
||||
friend std::basic_ostream<CharT, Traits>& operator<<(
|
||||
std::basic_ostream<CharT, Traits>& os, BooleanNULL::Value m)
|
||||
{
|
||||
return os << BooleanNULL::c_str(m);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,138 @@
|
||||
/* Generated SBE (Simple Binary Encoding) message codec */
|
||||
#ifndef _ILINKBINARY_CLEARINGACCTTYPE_H_
|
||||
#define _ILINKBINARY_CLEARINGACCTTYPE_H_
|
||||
|
||||
#if defined(SBE_HAVE_CMATH)
|
||||
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
|
||||
# include <cmath>
|
||||
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
|
||||
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
|
||||
#else
|
||||
/* math.h needed for NAN */
|
||||
# include <math.h>
|
||||
# define SBE_FLOAT_NAN NAN
|
||||
# define SBE_DOUBLE_NAN NAN
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# include <cstdint>
|
||||
# include <string>
|
||||
# include <cstring>
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# define SBE_CONSTEXPR constexpr
|
||||
# define SBE_NOEXCEPT noexcept
|
||||
#else
|
||||
# define SBE_CONSTEXPR
|
||||
# define SBE_NOEXCEPT
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
# define SBE_NODISCARD [[nodiscard]]
|
||||
#else
|
||||
# define SBE_NODISCARD
|
||||
#endif
|
||||
|
||||
#if !defined(__STDC_LIMIT_MACROS)
|
||||
# define __STDC_LIMIT_MACROS 1
|
||||
#endif
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
|
||||
#else
|
||||
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
|
||||
#endif
|
||||
|
||||
#if defined(SBE_NO_BOUNDS_CHECK)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
|
||||
#elif defined(_MSC_VER)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
|
||||
#else
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
|
||||
#endif
|
||||
|
||||
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
|
||||
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
|
||||
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
|
||||
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
|
||||
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
|
||||
|
||||
|
||||
namespace iLinkBinary {
|
||||
|
||||
class ClearingAcctType
|
||||
{
|
||||
public:
|
||||
enum Value
|
||||
{
|
||||
Customer = (std::uint8_t)0,
|
||||
Firm = (std::uint8_t)1,
|
||||
NULL_VALUE = (std::uint8_t)255
|
||||
};
|
||||
|
||||
static ClearingAcctType::Value get(const std::uint8_t value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 0: return Customer;
|
||||
case 1: return Firm;
|
||||
case 255: return NULL_VALUE;
|
||||
}
|
||||
|
||||
throw std::runtime_error("unknown value for enum ClearingAcctType [E103]");
|
||||
}
|
||||
|
||||
static const char* c_str(const ClearingAcctType::Value value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case Customer: return "Customer";
|
||||
case Firm: return "Firm";
|
||||
case NULL_VALUE: return "NULL_VALUE";
|
||||
}
|
||||
|
||||
throw std::runtime_error("unknown value for enum ClearingAcctType [E103]:");
|
||||
}
|
||||
|
||||
template<typename CharT, typename Traits>
|
||||
friend std::basic_ostream<CharT, Traits>& operator<<(
|
||||
std::basic_ostream<CharT, Traits>& os, ClearingAcctType::Value m)
|
||||
{
|
||||
return os << ClearingAcctType::c_str(m);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,138 @@
|
||||
/* Generated SBE (Simple Binary Encoding) message codec */
|
||||
#ifndef _ILINKBINARY_CMTAGIVEUPCD_H_
|
||||
#define _ILINKBINARY_CMTAGIVEUPCD_H_
|
||||
|
||||
#if defined(SBE_HAVE_CMATH)
|
||||
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
|
||||
# include <cmath>
|
||||
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
|
||||
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
|
||||
#else
|
||||
/* math.h needed for NAN */
|
||||
# include <math.h>
|
||||
# define SBE_FLOAT_NAN NAN
|
||||
# define SBE_DOUBLE_NAN NAN
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# include <cstdint>
|
||||
# include <string>
|
||||
# include <cstring>
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# define SBE_CONSTEXPR constexpr
|
||||
# define SBE_NOEXCEPT noexcept
|
||||
#else
|
||||
# define SBE_CONSTEXPR
|
||||
# define SBE_NOEXCEPT
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
# define SBE_NODISCARD [[nodiscard]]
|
||||
#else
|
||||
# define SBE_NODISCARD
|
||||
#endif
|
||||
|
||||
#if !defined(__STDC_LIMIT_MACROS)
|
||||
# define __STDC_LIMIT_MACROS 1
|
||||
#endif
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
|
||||
#else
|
||||
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
|
||||
#endif
|
||||
|
||||
#if defined(SBE_NO_BOUNDS_CHECK)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
|
||||
#elif defined(_MSC_VER)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
|
||||
#else
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
|
||||
#endif
|
||||
|
||||
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
|
||||
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
|
||||
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
|
||||
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
|
||||
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
|
||||
|
||||
|
||||
namespace iLinkBinary {
|
||||
|
||||
class CmtaGiveUpCD
|
||||
{
|
||||
public:
|
||||
enum Value
|
||||
{
|
||||
GiveUp = (char)71,
|
||||
SGXoffset = (char)83,
|
||||
NULL_VALUE = (char)0
|
||||
};
|
||||
|
||||
static CmtaGiveUpCD::Value get(const char value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 71: return GiveUp;
|
||||
case 83: return SGXoffset;
|
||||
case 0: return NULL_VALUE;
|
||||
}
|
||||
|
||||
throw std::runtime_error("unknown value for enum CmtaGiveUpCD [E103]");
|
||||
}
|
||||
|
||||
static const char* c_str(const CmtaGiveUpCD::Value value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case GiveUp: return "GiveUp";
|
||||
case SGXoffset: return "SGXoffset";
|
||||
case NULL_VALUE: return "NULL_VALUE";
|
||||
}
|
||||
|
||||
throw std::runtime_error("unknown value for enum CmtaGiveUpCD [E103]:");
|
||||
}
|
||||
|
||||
template<typename CharT, typename Traits>
|
||||
friend std::basic_ostream<CharT, Traits>& operator<<(
|
||||
std::basic_ostream<CharT, Traits>& os, CmtaGiveUpCD::Value m)
|
||||
{
|
||||
return os << CmtaGiveUpCD::c_str(m);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,150 @@
|
||||
/* Generated SBE (Simple Binary Encoding) message codec */
|
||||
#ifndef _ILINKBINARY_CUSTORDHANDLINST_H_
|
||||
#define _ILINKBINARY_CUSTORDHANDLINST_H_
|
||||
|
||||
#if defined(SBE_HAVE_CMATH)
|
||||
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
|
||||
# include <cmath>
|
||||
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
|
||||
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
|
||||
#else
|
||||
/* math.h needed for NAN */
|
||||
# include <math.h>
|
||||
# define SBE_FLOAT_NAN NAN
|
||||
# define SBE_DOUBLE_NAN NAN
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# include <cstdint>
|
||||
# include <string>
|
||||
# include <cstring>
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# define SBE_CONSTEXPR constexpr
|
||||
# define SBE_NOEXCEPT noexcept
|
||||
#else
|
||||
# define SBE_CONSTEXPR
|
||||
# define SBE_NOEXCEPT
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
# define SBE_NODISCARD [[nodiscard]]
|
||||
#else
|
||||
# define SBE_NODISCARD
|
||||
#endif
|
||||
|
||||
#if !defined(__STDC_LIMIT_MACROS)
|
||||
# define __STDC_LIMIT_MACROS 1
|
||||
#endif
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
|
||||
#else
|
||||
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
|
||||
#endif
|
||||
|
||||
#if defined(SBE_NO_BOUNDS_CHECK)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
|
||||
#elif defined(_MSC_VER)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
|
||||
#else
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
|
||||
#endif
|
||||
|
||||
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
|
||||
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
|
||||
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
|
||||
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
|
||||
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
|
||||
|
||||
|
||||
namespace iLinkBinary {
|
||||
|
||||
class CustOrdHandlInst
|
||||
{
|
||||
public:
|
||||
enum Value
|
||||
{
|
||||
FCMprovidedscreen = (char)67,
|
||||
Otherprovidedscreen = (char)68,
|
||||
FCMAPIorFIX = (char)71,
|
||||
AlgoEngine = (char)72,
|
||||
DeskElectronic = (char)87,
|
||||
ClientElectronic = (char)89,
|
||||
NULL_VALUE = (char)0
|
||||
};
|
||||
|
||||
static CustOrdHandlInst::Value get(const char value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 67: return FCMprovidedscreen;
|
||||
case 68: return Otherprovidedscreen;
|
||||
case 71: return FCMAPIorFIX;
|
||||
case 72: return AlgoEngine;
|
||||
case 87: return DeskElectronic;
|
||||
case 89: return ClientElectronic;
|
||||
case 0: return NULL_VALUE;
|
||||
}
|
||||
|
||||
throw std::runtime_error("unknown value for enum CustOrdHandlInst [E103]");
|
||||
}
|
||||
|
||||
static const char* c_str(const CustOrdHandlInst::Value value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case FCMprovidedscreen: return "FCMprovidedscreen";
|
||||
case Otherprovidedscreen: return "Otherprovidedscreen";
|
||||
case FCMAPIorFIX: return "FCMAPIorFIX";
|
||||
case AlgoEngine: return "AlgoEngine";
|
||||
case DeskElectronic: return "DeskElectronic";
|
||||
case ClientElectronic: return "ClientElectronic";
|
||||
case NULL_VALUE: return "NULL_VALUE";
|
||||
}
|
||||
|
||||
throw std::runtime_error("unknown value for enum CustOrdHandlInst [E103]:");
|
||||
}
|
||||
|
||||
template<typename CharT, typename Traits>
|
||||
friend std::basic_ostream<CharT, Traits>& operator<<(
|
||||
std::basic_ostream<CharT, Traits>& os, CustOrdHandlInst::Value m)
|
||||
{
|
||||
return os << CustOrdHandlInst::c_str(m);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,144 @@
|
||||
/* Generated SBE (Simple Binary Encoding) message codec */
|
||||
#ifndef _ILINKBINARY_CUSTORDERCAPACITY_H_
|
||||
#define _ILINKBINARY_CUSTORDERCAPACITY_H_
|
||||
|
||||
#if defined(SBE_HAVE_CMATH)
|
||||
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
|
||||
# include <cmath>
|
||||
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
|
||||
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
|
||||
#else
|
||||
/* math.h needed for NAN */
|
||||
# include <math.h>
|
||||
# define SBE_FLOAT_NAN NAN
|
||||
# define SBE_DOUBLE_NAN NAN
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# include <cstdint>
|
||||
# include <string>
|
||||
# include <cstring>
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# define SBE_CONSTEXPR constexpr
|
||||
# define SBE_NOEXCEPT noexcept
|
||||
#else
|
||||
# define SBE_CONSTEXPR
|
||||
# define SBE_NOEXCEPT
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
# define SBE_NODISCARD [[nodiscard]]
|
||||
#else
|
||||
# define SBE_NODISCARD
|
||||
#endif
|
||||
|
||||
#if !defined(__STDC_LIMIT_MACROS)
|
||||
# define __STDC_LIMIT_MACROS 1
|
||||
#endif
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
|
||||
#else
|
||||
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
|
||||
#endif
|
||||
|
||||
#if defined(SBE_NO_BOUNDS_CHECK)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
|
||||
#elif defined(_MSC_VER)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
|
||||
#else
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
|
||||
#endif
|
||||
|
||||
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
|
||||
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
|
||||
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
|
||||
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
|
||||
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
|
||||
|
||||
|
||||
namespace iLinkBinary {
|
||||
|
||||
class CustOrderCapacity
|
||||
{
|
||||
public:
|
||||
enum Value
|
||||
{
|
||||
Membertradingfortheirownaccount = (std::uint8_t)1,
|
||||
Clearingfirmtradingforitsproprietaryaccount = (std::uint8_t)2,
|
||||
Membertradingforanothermember = (std::uint8_t)3,
|
||||
Allother = (std::uint8_t)4,
|
||||
NULL_VALUE = (std::uint8_t)255
|
||||
};
|
||||
|
||||
static CustOrderCapacity::Value get(const std::uint8_t value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 1: return Membertradingfortheirownaccount;
|
||||
case 2: return Clearingfirmtradingforitsproprietaryaccount;
|
||||
case 3: return Membertradingforanothermember;
|
||||
case 4: return Allother;
|
||||
case 255: return NULL_VALUE;
|
||||
}
|
||||
|
||||
throw std::runtime_error("unknown value for enum CustOrderCapacity [E103]");
|
||||
}
|
||||
|
||||
static const char* c_str(const CustOrderCapacity::Value value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case Membertradingfortheirownaccount: return "Membertradingfortheirownaccount";
|
||||
case Clearingfirmtradingforitsproprietaryaccount: return "Clearingfirmtradingforitsproprietaryaccount";
|
||||
case Membertradingforanothermember: return "Membertradingforanothermember";
|
||||
case Allother: return "Allother";
|
||||
case NULL_VALUE: return "NULL_VALUE";
|
||||
}
|
||||
|
||||
throw std::runtime_error("unknown value for enum CustOrderCapacity [E103]:");
|
||||
}
|
||||
|
||||
template<typename CharT, typename Traits>
|
||||
friend std::basic_ostream<CharT, Traits>& operator<<(
|
||||
std::basic_ostream<CharT, Traits>& os, CustOrderCapacity::Value m)
|
||||
{
|
||||
return os << CustOrderCapacity::c_str(m);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,343 @@
|
||||
/* Generated SBE (Simple Binary Encoding) message codec */
|
||||
#ifndef _ILINKBINARY_DATA_H_
|
||||
#define _ILINKBINARY_DATA_H_
|
||||
|
||||
#if defined(SBE_HAVE_CMATH)
|
||||
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
|
||||
# include <cmath>
|
||||
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
|
||||
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
|
||||
#else
|
||||
/* math.h needed for NAN */
|
||||
# include <math.h>
|
||||
# define SBE_FLOAT_NAN NAN
|
||||
# define SBE_DOUBLE_NAN NAN
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# include <cstdint>
|
||||
# include <string>
|
||||
# include <cstring>
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# define SBE_CONSTEXPR constexpr
|
||||
# define SBE_NOEXCEPT noexcept
|
||||
#else
|
||||
# define SBE_CONSTEXPR
|
||||
# define SBE_NOEXCEPT
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
# define SBE_NODISCARD [[nodiscard]]
|
||||
#else
|
||||
# define SBE_NODISCARD
|
||||
#endif
|
||||
|
||||
#if !defined(__STDC_LIMIT_MACROS)
|
||||
# define __STDC_LIMIT_MACROS 1
|
||||
#endif
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
|
||||
#else
|
||||
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
|
||||
#endif
|
||||
|
||||
#if defined(SBE_NO_BOUNDS_CHECK)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
|
||||
#elif defined(_MSC_VER)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
|
||||
#else
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
|
||||
#endif
|
||||
|
||||
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
|
||||
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
|
||||
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
|
||||
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
|
||||
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
|
||||
|
||||
|
||||
namespace iLinkBinary {
|
||||
|
||||
class DATA
|
||||
{
|
||||
private:
|
||||
char *m_buffer = nullptr;
|
||||
std::uint64_t m_bufferLength = 0;
|
||||
std::uint64_t m_offset = 0;
|
||||
std::uint64_t m_actingVersion = 0;
|
||||
|
||||
public:
|
||||
enum MetaAttribute
|
||||
{
|
||||
EPOCH, TIME_UNIT, SEMANTIC_TYPE, PRESENCE
|
||||
};
|
||||
|
||||
union sbe_float_as_uint_u
|
||||
{
|
||||
float fp_value;
|
||||
std::uint32_t uint_value;
|
||||
};
|
||||
|
||||
union sbe_double_as_uint_u
|
||||
{
|
||||
double fp_value;
|
||||
std::uint64_t uint_value;
|
||||
};
|
||||
|
||||
DATA() = default;
|
||||
|
||||
DATA(
|
||||
char *buffer,
|
||||
const std::uint64_t offset,
|
||||
const std::uint64_t bufferLength,
|
||||
const std::uint64_t actingVersion) :
|
||||
m_buffer(buffer),
|
||||
m_bufferLength(bufferLength),
|
||||
m_offset(offset),
|
||||
m_actingVersion(actingVersion)
|
||||
{
|
||||
if (SBE_BOUNDS_CHECK_EXPECT(((m_offset + -1) > m_bufferLength), false))
|
||||
{
|
||||
throw std::runtime_error("buffer too short for flyweight [E107]");
|
||||
}
|
||||
}
|
||||
|
||||
DATA(
|
||||
char *buffer,
|
||||
const std::uint64_t bufferLength,
|
||||
const std::uint64_t actingVersion) :
|
||||
DATA(buffer, 0, bufferLength, actingVersion)
|
||||
{
|
||||
}
|
||||
|
||||
DATA(
|
||||
char *buffer,
|
||||
const std::uint64_t bufferLength) :
|
||||
DATA(buffer, 0, bufferLength, sbeSchemaVersion())
|
||||
{
|
||||
}
|
||||
|
||||
DATA &wrap(
|
||||
char *buffer,
|
||||
const std::uint64_t offset,
|
||||
const std::uint64_t actingVersion,
|
||||
const std::uint64_t bufferLength)
|
||||
{
|
||||
return *this = DATA(buffer, offset, bufferLength, actingVersion);
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t encodedLength() SBE_NOEXCEPT
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint64_t offset() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
SBE_NODISCARD const char * buffer() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
SBE_NODISCARD char * buffer() SBE_NOEXCEPT
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint64_t bufferLength() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_bufferLength;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint64_t actingVersion() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_actingVersion;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaId() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::uint16_t)8;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::uint16_t)2;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static const char * lengthMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
|
||||
{
|
||||
switch (metaAttribute)
|
||||
{
|
||||
case MetaAttribute::EPOCH: return "";
|
||||
case MetaAttribute::TIME_UNIT: return "";
|
||||
case MetaAttribute::SEMANTIC_TYPE: return "";
|
||||
case MetaAttribute::PRESENCE: return "required";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t lengthSinceVersion() SBE_NOEXCEPT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool lengthInActingVersion() SBE_NOEXCEPT
|
||||
{
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wtautological-compare"
|
||||
#endif
|
||||
return m_actingVersion >= lengthSinceVersion();
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::size_t lengthEncodingOffset() SBE_NOEXCEPT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint16_t lengthNullValue() SBE_NOEXCEPT
|
||||
{
|
||||
return SBE_NULLVALUE_UINT16;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint16_t lengthMinValue() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::uint16_t)0;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint16_t lengthMaxValue() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::uint16_t)65534;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::size_t lengthEncodingLength() SBE_NOEXCEPT
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint16_t length() const SBE_NOEXCEPT
|
||||
{
|
||||
std::uint16_t val;
|
||||
std::memcpy(&val, m_buffer + m_offset + 0, sizeof(std::uint16_t));
|
||||
return SBE_LITTLE_ENDIAN_ENCODE_16(val);
|
||||
}
|
||||
|
||||
DATA &length(const std::uint16_t value) SBE_NOEXCEPT
|
||||
{
|
||||
std::uint16_t val = SBE_LITTLE_ENDIAN_ENCODE_16(value);
|
||||
std::memcpy(m_buffer + m_offset + 0, &val, sizeof(std::uint16_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static const char * varDataMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
|
||||
{
|
||||
switch (metaAttribute)
|
||||
{
|
||||
case MetaAttribute::EPOCH: return "";
|
||||
case MetaAttribute::TIME_UNIT: return "";
|
||||
case MetaAttribute::SEMANTIC_TYPE: return "";
|
||||
case MetaAttribute::PRESENCE: return "required";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t varDataSinceVersion() SBE_NOEXCEPT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool varDataInActingVersion() SBE_NOEXCEPT
|
||||
{
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wtautological-compare"
|
||||
#endif
|
||||
return m_actingVersion >= varDataSinceVersion();
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::size_t varDataEncodingOffset() SBE_NOEXCEPT
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR char varDataNullValue() SBE_NOEXCEPT
|
||||
{
|
||||
return (char)0;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR char varDataMinValue() SBE_NOEXCEPT
|
||||
{
|
||||
return (char)32;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR char varDataMaxValue() SBE_NOEXCEPT
|
||||
{
|
||||
return (char)126;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::size_t varDataEncodingLength() SBE_NOEXCEPT
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
template<typename CharT, typename Traits>
|
||||
friend std::basic_ostream<CharT, Traits>& operator<<(
|
||||
std::basic_ostream<CharT, Traits>& builder, DATA writer)
|
||||
{
|
||||
builder << '{';
|
||||
builder << R"("length": )";
|
||||
builder << +writer.length();
|
||||
|
||||
builder << '}';
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,156 @@
|
||||
/* Generated SBE (Simple Binary Encoding) message codec */
|
||||
#ifndef _ILINKBINARY_DKREASON_H_
|
||||
#define _ILINKBINARY_DKREASON_H_
|
||||
|
||||
#if defined(SBE_HAVE_CMATH)
|
||||
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
|
||||
# include <cmath>
|
||||
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
|
||||
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
|
||||
#else
|
||||
/* math.h needed for NAN */
|
||||
# include <math.h>
|
||||
# define SBE_FLOAT_NAN NAN
|
||||
# define SBE_DOUBLE_NAN NAN
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# include <cstdint>
|
||||
# include <string>
|
||||
# include <cstring>
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# define SBE_CONSTEXPR constexpr
|
||||
# define SBE_NOEXCEPT noexcept
|
||||
#else
|
||||
# define SBE_CONSTEXPR
|
||||
# define SBE_NOEXCEPT
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
# define SBE_NODISCARD [[nodiscard]]
|
||||
#else
|
||||
# define SBE_NODISCARD
|
||||
#endif
|
||||
|
||||
#if !defined(__STDC_LIMIT_MACROS)
|
||||
# define __STDC_LIMIT_MACROS 1
|
||||
#endif
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
|
||||
#else
|
||||
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
|
||||
#endif
|
||||
|
||||
#if defined(SBE_NO_BOUNDS_CHECK)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
|
||||
#elif defined(_MSC_VER)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
|
||||
#else
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
|
||||
#endif
|
||||
|
||||
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
|
||||
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
|
||||
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
|
||||
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
|
||||
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
|
||||
|
||||
|
||||
namespace iLinkBinary {
|
||||
|
||||
class DKReason
|
||||
{
|
||||
public:
|
||||
enum Value
|
||||
{
|
||||
UnknownSecurity = (char)65,
|
||||
WrongSide = (char)66,
|
||||
QuantityExceedsOrder = (char)67,
|
||||
NoMatchingOrder = (char)68,
|
||||
PriceExceedsLimit = (char)69,
|
||||
CalculationDifference = (char)70,
|
||||
NoMatchingExecutionReport = (char)71,
|
||||
Other = (char)90,
|
||||
NULL_VALUE = (char)0
|
||||
};
|
||||
|
||||
static DKReason::Value get(const char value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 65: return UnknownSecurity;
|
||||
case 66: return WrongSide;
|
||||
case 67: return QuantityExceedsOrder;
|
||||
case 68: return NoMatchingOrder;
|
||||
case 69: return PriceExceedsLimit;
|
||||
case 70: return CalculationDifference;
|
||||
case 71: return NoMatchingExecutionReport;
|
||||
case 90: return Other;
|
||||
case 0: return NULL_VALUE;
|
||||
}
|
||||
|
||||
throw std::runtime_error("unknown value for enum DKReason [E103]");
|
||||
}
|
||||
|
||||
static const char* c_str(const DKReason::Value value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case UnknownSecurity: return "UnknownSecurity";
|
||||
case WrongSide: return "WrongSide";
|
||||
case QuantityExceedsOrder: return "QuantityExceedsOrder";
|
||||
case NoMatchingOrder: return "NoMatchingOrder";
|
||||
case PriceExceedsLimit: return "PriceExceedsLimit";
|
||||
case CalculationDifference: return "CalculationDifference";
|
||||
case NoMatchingExecutionReport: return "NoMatchingExecutionReport";
|
||||
case Other: return "Other";
|
||||
case NULL_VALUE: return "NULL_VALUE";
|
||||
}
|
||||
|
||||
throw std::runtime_error("unknown value for enum DKReason [E103]:");
|
||||
}
|
||||
|
||||
template<typename CharT, typename Traits>
|
||||
friend std::basic_ostream<CharT, Traits>& operator<<(
|
||||
std::basic_ostream<CharT, Traits>& os, DKReason::Value m)
|
||||
{
|
||||
return os << DKReason::c_str(m);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,361 @@
|
||||
/* Generated SBE (Simple Binary Encoding) message codec */
|
||||
#ifndef _ILINKBINARY_DECIMAL32NULL_H_
|
||||
#define _ILINKBINARY_DECIMAL32NULL_H_
|
||||
|
||||
#if defined(SBE_HAVE_CMATH)
|
||||
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
|
||||
# include <cmath>
|
||||
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
|
||||
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
|
||||
#else
|
||||
/* math.h needed for NAN */
|
||||
# include <math.h>
|
||||
# define SBE_FLOAT_NAN NAN
|
||||
# define SBE_DOUBLE_NAN NAN
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# include <cstdint>
|
||||
# include <string>
|
||||
# include <cstring>
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# define SBE_CONSTEXPR constexpr
|
||||
# define SBE_NOEXCEPT noexcept
|
||||
#else
|
||||
# define SBE_CONSTEXPR
|
||||
# define SBE_NOEXCEPT
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
# define SBE_NODISCARD [[nodiscard]]
|
||||
#else
|
||||
# define SBE_NODISCARD
|
||||
#endif
|
||||
|
||||
#if !defined(__STDC_LIMIT_MACROS)
|
||||
# define __STDC_LIMIT_MACROS 1
|
||||
#endif
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
|
||||
#else
|
||||
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
|
||||
#endif
|
||||
|
||||
#if defined(SBE_NO_BOUNDS_CHECK)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
|
||||
#elif defined(_MSC_VER)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
|
||||
#else
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
|
||||
#endif
|
||||
|
||||
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
|
||||
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
|
||||
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
|
||||
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
|
||||
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
|
||||
|
||||
|
||||
namespace iLinkBinary {
|
||||
|
||||
class Decimal32NULL
|
||||
{
|
||||
private:
|
||||
char *m_buffer = nullptr;
|
||||
std::uint64_t m_bufferLength = 0;
|
||||
std::uint64_t m_offset = 0;
|
||||
std::uint64_t m_actingVersion = 0;
|
||||
|
||||
public:
|
||||
enum MetaAttribute
|
||||
{
|
||||
EPOCH, TIME_UNIT, SEMANTIC_TYPE, PRESENCE
|
||||
};
|
||||
|
||||
union sbe_float_as_uint_u
|
||||
{
|
||||
float fp_value;
|
||||
std::uint32_t uint_value;
|
||||
};
|
||||
|
||||
union sbe_double_as_uint_u
|
||||
{
|
||||
double fp_value;
|
||||
std::uint64_t uint_value;
|
||||
};
|
||||
|
||||
Decimal32NULL() = default;
|
||||
|
||||
Decimal32NULL(
|
||||
char *buffer,
|
||||
const std::uint64_t offset,
|
||||
const std::uint64_t bufferLength,
|
||||
const std::uint64_t actingVersion) :
|
||||
m_buffer(buffer),
|
||||
m_bufferLength(bufferLength),
|
||||
m_offset(offset),
|
||||
m_actingVersion(actingVersion)
|
||||
{
|
||||
if (SBE_BOUNDS_CHECK_EXPECT(((m_offset + 5) > m_bufferLength), false))
|
||||
{
|
||||
throw std::runtime_error("buffer too short for flyweight [E107]");
|
||||
}
|
||||
}
|
||||
|
||||
Decimal32NULL(
|
||||
char *buffer,
|
||||
const std::uint64_t bufferLength,
|
||||
const std::uint64_t actingVersion) :
|
||||
Decimal32NULL(buffer, 0, bufferLength, actingVersion)
|
||||
{
|
||||
}
|
||||
|
||||
Decimal32NULL(
|
||||
char *buffer,
|
||||
const std::uint64_t bufferLength) :
|
||||
Decimal32NULL(buffer, 0, bufferLength, sbeSchemaVersion())
|
||||
{
|
||||
}
|
||||
|
||||
Decimal32NULL &wrap(
|
||||
char *buffer,
|
||||
const std::uint64_t offset,
|
||||
const std::uint64_t actingVersion,
|
||||
const std::uint64_t bufferLength)
|
||||
{
|
||||
return *this = Decimal32NULL(buffer, offset, bufferLength, actingVersion);
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t encodedLength() SBE_NOEXCEPT
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint64_t offset() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
SBE_NODISCARD const char * buffer() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
SBE_NODISCARD char * buffer() SBE_NOEXCEPT
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint64_t bufferLength() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_bufferLength;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint64_t actingVersion() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_actingVersion;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaId() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::uint16_t)8;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::uint16_t)2;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static const char * mantissaMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
|
||||
{
|
||||
switch (metaAttribute)
|
||||
{
|
||||
case MetaAttribute::EPOCH: return "";
|
||||
case MetaAttribute::TIME_UNIT: return "";
|
||||
case MetaAttribute::SEMANTIC_TYPE: return "";
|
||||
case MetaAttribute::PRESENCE: return "optional";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t mantissaSinceVersion() SBE_NOEXCEPT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool mantissaInActingVersion() SBE_NOEXCEPT
|
||||
{
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wtautological-compare"
|
||||
#endif
|
||||
return m_actingVersion >= mantissaSinceVersion();
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::size_t mantissaEncodingOffset() SBE_NOEXCEPT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::int32_t mantissaNullValue() SBE_NOEXCEPT
|
||||
{
|
||||
return 2147483647;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::int32_t mantissaMinValue() SBE_NOEXCEPT
|
||||
{
|
||||
return -2147483647;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::int32_t mantissaMaxValue() SBE_NOEXCEPT
|
||||
{
|
||||
return 2147483647;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::size_t mantissaEncodingLength() SBE_NOEXCEPT
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::int32_t mantissa() const SBE_NOEXCEPT
|
||||
{
|
||||
std::int32_t val;
|
||||
std::memcpy(&val, m_buffer + m_offset + 0, sizeof(std::int32_t));
|
||||
return SBE_LITTLE_ENDIAN_ENCODE_32(val);
|
||||
}
|
||||
|
||||
Decimal32NULL &mantissa(const std::int32_t value) SBE_NOEXCEPT
|
||||
{
|
||||
std::int32_t val = SBE_LITTLE_ENDIAN_ENCODE_32(value);
|
||||
std::memcpy(m_buffer + m_offset + 0, &val, sizeof(std::int32_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static const char * exponentMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
|
||||
{
|
||||
switch (metaAttribute)
|
||||
{
|
||||
case MetaAttribute::EPOCH: return "";
|
||||
case MetaAttribute::TIME_UNIT: return "";
|
||||
case MetaAttribute::SEMANTIC_TYPE: return "";
|
||||
case MetaAttribute::PRESENCE: return "optional";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t exponentSinceVersion() SBE_NOEXCEPT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool exponentInActingVersion() SBE_NOEXCEPT
|
||||
{
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wtautological-compare"
|
||||
#endif
|
||||
return m_actingVersion >= exponentSinceVersion();
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::size_t exponentEncodingOffset() SBE_NOEXCEPT
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::int8_t exponentNullValue() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::int8_t)127;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::int8_t exponentMinValue() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::int8_t)-127;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::int8_t exponentMaxValue() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::int8_t)127;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::size_t exponentEncodingLength() SBE_NOEXCEPT
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::int8_t exponent() const SBE_NOEXCEPT
|
||||
{
|
||||
std::int8_t val;
|
||||
std::memcpy(&val, m_buffer + m_offset + 4, sizeof(std::int8_t));
|
||||
return (val);
|
||||
}
|
||||
|
||||
Decimal32NULL &exponent(const std::int8_t value) SBE_NOEXCEPT
|
||||
{
|
||||
std::int8_t val = (value);
|
||||
std::memcpy(m_buffer + m_offset + 4, &val, sizeof(std::int8_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename CharT, typename Traits>
|
||||
friend std::basic_ostream<CharT, Traits>& operator<<(
|
||||
std::basic_ostream<CharT, Traits>& builder, Decimal32NULL writer)
|
||||
{
|
||||
builder << '{';
|
||||
builder << R"("mantissa": )";
|
||||
builder << +writer.mantissa();
|
||||
|
||||
builder << ", ";
|
||||
builder << R"("exponent": )";
|
||||
builder << +writer.exponent();
|
||||
|
||||
builder << '}';
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,361 @@
|
||||
/* Generated SBE (Simple Binary Encoding) message codec */
|
||||
#ifndef _ILINKBINARY_DECIMAL64NULL_H_
|
||||
#define _ILINKBINARY_DECIMAL64NULL_H_
|
||||
|
||||
#if defined(SBE_HAVE_CMATH)
|
||||
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
|
||||
# include <cmath>
|
||||
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
|
||||
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
|
||||
#else
|
||||
/* math.h needed for NAN */
|
||||
# include <math.h>
|
||||
# define SBE_FLOAT_NAN NAN
|
||||
# define SBE_DOUBLE_NAN NAN
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# include <cstdint>
|
||||
# include <string>
|
||||
# include <cstring>
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# define SBE_CONSTEXPR constexpr
|
||||
# define SBE_NOEXCEPT noexcept
|
||||
#else
|
||||
# define SBE_CONSTEXPR
|
||||
# define SBE_NOEXCEPT
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
# define SBE_NODISCARD [[nodiscard]]
|
||||
#else
|
||||
# define SBE_NODISCARD
|
||||
#endif
|
||||
|
||||
#if !defined(__STDC_LIMIT_MACROS)
|
||||
# define __STDC_LIMIT_MACROS 1
|
||||
#endif
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
|
||||
#else
|
||||
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
|
||||
#endif
|
||||
|
||||
#if defined(SBE_NO_BOUNDS_CHECK)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
|
||||
#elif defined(_MSC_VER)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
|
||||
#else
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
|
||||
#endif
|
||||
|
||||
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
|
||||
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
|
||||
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
|
||||
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
|
||||
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
|
||||
|
||||
|
||||
namespace iLinkBinary {
|
||||
|
||||
class Decimal64NULL
|
||||
{
|
||||
private:
|
||||
char *m_buffer = nullptr;
|
||||
std::uint64_t m_bufferLength = 0;
|
||||
std::uint64_t m_offset = 0;
|
||||
std::uint64_t m_actingVersion = 0;
|
||||
|
||||
public:
|
||||
enum MetaAttribute
|
||||
{
|
||||
EPOCH, TIME_UNIT, SEMANTIC_TYPE, PRESENCE
|
||||
};
|
||||
|
||||
union sbe_float_as_uint_u
|
||||
{
|
||||
float fp_value;
|
||||
std::uint32_t uint_value;
|
||||
};
|
||||
|
||||
union sbe_double_as_uint_u
|
||||
{
|
||||
double fp_value;
|
||||
std::uint64_t uint_value;
|
||||
};
|
||||
|
||||
Decimal64NULL() = default;
|
||||
|
||||
Decimal64NULL(
|
||||
char *buffer,
|
||||
const std::uint64_t offset,
|
||||
const std::uint64_t bufferLength,
|
||||
const std::uint64_t actingVersion) :
|
||||
m_buffer(buffer),
|
||||
m_bufferLength(bufferLength),
|
||||
m_offset(offset),
|
||||
m_actingVersion(actingVersion)
|
||||
{
|
||||
if (SBE_BOUNDS_CHECK_EXPECT(((m_offset + 9) > m_bufferLength), false))
|
||||
{
|
||||
throw std::runtime_error("buffer too short for flyweight [E107]");
|
||||
}
|
||||
}
|
||||
|
||||
Decimal64NULL(
|
||||
char *buffer,
|
||||
const std::uint64_t bufferLength,
|
||||
const std::uint64_t actingVersion) :
|
||||
Decimal64NULL(buffer, 0, bufferLength, actingVersion)
|
||||
{
|
||||
}
|
||||
|
||||
Decimal64NULL(
|
||||
char *buffer,
|
||||
const std::uint64_t bufferLength) :
|
||||
Decimal64NULL(buffer, 0, bufferLength, sbeSchemaVersion())
|
||||
{
|
||||
}
|
||||
|
||||
Decimal64NULL &wrap(
|
||||
char *buffer,
|
||||
const std::uint64_t offset,
|
||||
const std::uint64_t actingVersion,
|
||||
const std::uint64_t bufferLength)
|
||||
{
|
||||
return *this = Decimal64NULL(buffer, offset, bufferLength, actingVersion);
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t encodedLength() SBE_NOEXCEPT
|
||||
{
|
||||
return 9;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint64_t offset() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
SBE_NODISCARD const char * buffer() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
SBE_NODISCARD char * buffer() SBE_NOEXCEPT
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint64_t bufferLength() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_bufferLength;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint64_t actingVersion() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_actingVersion;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaId() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::uint16_t)8;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::uint16_t)2;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static const char * mantissaMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
|
||||
{
|
||||
switch (metaAttribute)
|
||||
{
|
||||
case MetaAttribute::EPOCH: return "";
|
||||
case MetaAttribute::TIME_UNIT: return "";
|
||||
case MetaAttribute::SEMANTIC_TYPE: return "";
|
||||
case MetaAttribute::PRESENCE: return "optional";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t mantissaSinceVersion() SBE_NOEXCEPT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool mantissaInActingVersion() SBE_NOEXCEPT
|
||||
{
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wtautological-compare"
|
||||
#endif
|
||||
return m_actingVersion >= mantissaSinceVersion();
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::size_t mantissaEncodingOffset() SBE_NOEXCEPT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::int64_t mantissaNullValue() SBE_NOEXCEPT
|
||||
{
|
||||
return 9223372036854775807L;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::int64_t mantissaMinValue() SBE_NOEXCEPT
|
||||
{
|
||||
return -9223372036854775807L;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::int64_t mantissaMaxValue() SBE_NOEXCEPT
|
||||
{
|
||||
return 9223372036854775807L;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::size_t mantissaEncodingLength() SBE_NOEXCEPT
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::int64_t mantissa() const SBE_NOEXCEPT
|
||||
{
|
||||
std::int64_t val;
|
||||
std::memcpy(&val, m_buffer + m_offset + 0, sizeof(std::int64_t));
|
||||
return SBE_LITTLE_ENDIAN_ENCODE_64(val);
|
||||
}
|
||||
|
||||
Decimal64NULL &mantissa(const std::int64_t value) SBE_NOEXCEPT
|
||||
{
|
||||
std::int64_t val = SBE_LITTLE_ENDIAN_ENCODE_64(value);
|
||||
std::memcpy(m_buffer + m_offset + 0, &val, sizeof(std::int64_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static const char * exponentMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
|
||||
{
|
||||
switch (metaAttribute)
|
||||
{
|
||||
case MetaAttribute::EPOCH: return "";
|
||||
case MetaAttribute::TIME_UNIT: return "";
|
||||
case MetaAttribute::SEMANTIC_TYPE: return "";
|
||||
case MetaAttribute::PRESENCE: return "optional";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t exponentSinceVersion() SBE_NOEXCEPT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool exponentInActingVersion() SBE_NOEXCEPT
|
||||
{
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wtautological-compare"
|
||||
#endif
|
||||
return m_actingVersion >= exponentSinceVersion();
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::size_t exponentEncodingOffset() SBE_NOEXCEPT
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::int8_t exponentNullValue() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::int8_t)127;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::int8_t exponentMinValue() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::int8_t)-127;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::int8_t exponentMaxValue() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::int8_t)127;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::size_t exponentEncodingLength() SBE_NOEXCEPT
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::int8_t exponent() const SBE_NOEXCEPT
|
||||
{
|
||||
std::int8_t val;
|
||||
std::memcpy(&val, m_buffer + m_offset + 8, sizeof(std::int8_t));
|
||||
return (val);
|
||||
}
|
||||
|
||||
Decimal64NULL &exponent(const std::int8_t value) SBE_NOEXCEPT
|
||||
{
|
||||
std::int8_t val = (value);
|
||||
std::memcpy(m_buffer + m_offset + 8, &val, sizeof(std::int8_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename CharT, typename Traits>
|
||||
friend std::basic_ostream<CharT, Traits>& operator<<(
|
||||
std::basic_ostream<CharT, Traits>& builder, Decimal64NULL writer)
|
||||
{
|
||||
builder << '{';
|
||||
builder << R"("mantissa": )";
|
||||
builder << +writer.mantissa();
|
||||
|
||||
builder << ", ";
|
||||
builder << R"("exponent": )";
|
||||
builder << +writer.exponent();
|
||||
|
||||
builder << '}';
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,992 @@
|
||||
/* Generated SBE (Simple Binary Encoding) message codec */
|
||||
#ifndef _ILINKBINARY_ESTABLISHMENTREJECT505_H_
|
||||
#define _ILINKBINARY_ESTABLISHMENTREJECT505_H_
|
||||
|
||||
#if defined(SBE_HAVE_CMATH)
|
||||
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
|
||||
# include <cmath>
|
||||
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
|
||||
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
|
||||
#else
|
||||
/* math.h needed for NAN */
|
||||
# include <math.h>
|
||||
# define SBE_FLOAT_NAN NAN
|
||||
# define SBE_DOUBLE_NAN NAN
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# include <cstdint>
|
||||
# include <string>
|
||||
# include <cstring>
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# define SBE_CONSTEXPR constexpr
|
||||
# define SBE_NOEXCEPT noexcept
|
||||
#else
|
||||
# define SBE_CONSTEXPR
|
||||
# define SBE_NOEXCEPT
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
# define SBE_NODISCARD [[nodiscard]]
|
||||
#else
|
||||
# define SBE_NODISCARD
|
||||
#endif
|
||||
|
||||
#if !defined(__STDC_LIMIT_MACROS)
|
||||
# define __STDC_LIMIT_MACROS 1
|
||||
#endif
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
|
||||
#else
|
||||
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
|
||||
#endif
|
||||
|
||||
#if defined(SBE_NO_BOUNDS_CHECK)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
|
||||
#elif defined(_MSC_VER)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
|
||||
#else
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
|
||||
#endif
|
||||
|
||||
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
|
||||
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
|
||||
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
|
||||
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
|
||||
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
|
||||
|
||||
|
||||
#include "MaturityMonthYear.h"
|
||||
#include "Decimal64NULL.h"
|
||||
#include "OrderTypeReq.h"
|
||||
#include "BooleanNULL.h"
|
||||
#include "AvgPxInd.h"
|
||||
#include "OrderEventType.h"
|
||||
#include "CmtaGiveUpCD.h"
|
||||
#include "PRICENULL9.h"
|
||||
#include "BooleanFlag.h"
|
||||
#include "OrderType.h"
|
||||
#include "QuoteCxlStatus.h"
|
||||
#include "TimeInForce.h"
|
||||
#include "PRICE9.h"
|
||||
#include "MassStatusOrdTyp.h"
|
||||
#include "ExecInst.h"
|
||||
#include "Decimal32NULL.h"
|
||||
#include "SplitMsg.h"
|
||||
#include "SideReq.h"
|
||||
#include "MassActionResponse.h"
|
||||
#include "CustOrderCapacity.h"
|
||||
#include "SideTimeInForce.h"
|
||||
#include "SLEDS.h"
|
||||
#include "ReqResult.h"
|
||||
#include "ClearingAcctType.h"
|
||||
#include "KeepAliveLapsed.h"
|
||||
#include "ExecAckStatus.h"
|
||||
#include "DATA.h"
|
||||
#include "OFMOverrideReq.h"
|
||||
#include "SideNULL.h"
|
||||
#include "GroupSize.h"
|
||||
#include "ListUpdAct.h"
|
||||
#include "FTI.h"
|
||||
#include "ExecReason.h"
|
||||
#include "MassStatusReqTyp.h"
|
||||
#include "DKReason.h"
|
||||
#include "SecRspTyp.h"
|
||||
#include "MassActionOrdTyp.h"
|
||||
#include "QuoteAckStatus.h"
|
||||
#include "ExpCycle.h"
|
||||
#include "MassCancelTIF.h"
|
||||
#include "OrderStatus.h"
|
||||
#include "ShortSaleType.h"
|
||||
#include "PartyDetailRole.h"
|
||||
#include "MassActionScope.h"
|
||||
#include "RFQSide.h"
|
||||
#include "OrdStatusTrdCxl.h"
|
||||
#include "TradeAddendum.h"
|
||||
#include "MessageHeader.h"
|
||||
#include "ManualOrdInd.h"
|
||||
#include "QuoteCxlTyp.h"
|
||||
#include "MassCxlReqTyp.h"
|
||||
#include "ExecTypTrdCxl.h"
|
||||
#include "ManualOrdIndReq.h"
|
||||
#include "CustOrdHandlInst.h"
|
||||
#include "OrdStatusTrd.h"
|
||||
#include "MassStatusTIF.h"
|
||||
#include "SMPI.h"
|
||||
#include "ExecMode.h"
|
||||
#include "QuoteTyp.h"
|
||||
|
||||
namespace iLinkBinary {
|
||||
|
||||
class EstablishmentReject505
|
||||
{
|
||||
private:
|
||||
char *m_buffer = nullptr;
|
||||
std::uint64_t m_bufferLength = 0;
|
||||
std::uint64_t m_offset = 0;
|
||||
std::uint64_t m_position = 0;
|
||||
std::uint64_t m_actingVersion = 0;
|
||||
|
||||
inline std::uint64_t *sbePositionPtr() SBE_NOEXCEPT
|
||||
{
|
||||
return &m_position;
|
||||
}
|
||||
|
||||
public:
|
||||
enum MetaAttribute
|
||||
{
|
||||
EPOCH, TIME_UNIT, SEMANTIC_TYPE, PRESENCE
|
||||
};
|
||||
|
||||
union sbe_float_as_uint_u
|
||||
{
|
||||
float fp_value;
|
||||
std::uint32_t uint_value;
|
||||
};
|
||||
|
||||
union sbe_double_as_uint_u
|
||||
{
|
||||
double fp_value;
|
||||
std::uint64_t uint_value;
|
||||
};
|
||||
|
||||
EstablishmentReject505() = default;
|
||||
|
||||
EstablishmentReject505(
|
||||
char *buffer,
|
||||
const std::uint64_t offset,
|
||||
const std::uint64_t bufferLength,
|
||||
const std::uint64_t actingBlockLength,
|
||||
const std::uint64_t actingVersion) :
|
||||
m_buffer(buffer),
|
||||
m_bufferLength(bufferLength),
|
||||
m_offset(offset),
|
||||
m_position(sbeCheckPosition(offset + actingBlockLength)),
|
||||
m_actingVersion(actingVersion)
|
||||
{
|
||||
}
|
||||
|
||||
EstablishmentReject505(char *buffer, const std::uint64_t bufferLength) :
|
||||
EstablishmentReject505(buffer, 0, bufferLength, sbeBlockLength(), sbeSchemaVersion())
|
||||
{
|
||||
}
|
||||
|
||||
EstablishmentReject505(
|
||||
char *buffer,
|
||||
const std::uint64_t bufferLength,
|
||||
const std::uint64_t actingBlockLength,
|
||||
const std::uint64_t actingVersion) :
|
||||
EstablishmentReject505(buffer, 0, bufferLength, actingBlockLength, actingVersion)
|
||||
{
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeBlockLength() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::uint16_t)72;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeTemplateId() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::uint16_t)505;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaId() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::uint16_t)8;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::uint16_t)2;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR const char * sbeSemanticType() SBE_NOEXCEPT
|
||||
{
|
||||
return "EstablishmentReject";
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint64_t offset() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
EstablishmentReject505 &wrapForEncode(char *buffer, const std::uint64_t offset, const std::uint64_t bufferLength)
|
||||
{
|
||||
return *this = EstablishmentReject505(buffer, offset, bufferLength, sbeBlockLength(), sbeSchemaVersion());
|
||||
}
|
||||
|
||||
EstablishmentReject505 &wrapAndApplyHeader(char *buffer, const std::uint64_t offset, const std::uint64_t bufferLength)
|
||||
{
|
||||
MessageHeader hdr(buffer, offset, bufferLength, sbeSchemaVersion());
|
||||
|
||||
hdr
|
||||
.blockLength(sbeBlockLength())
|
||||
.templateId(sbeTemplateId())
|
||||
.schemaId(sbeSchemaId())
|
||||
.version(sbeSchemaVersion());
|
||||
|
||||
return *this = EstablishmentReject505(
|
||||
buffer,
|
||||
offset + MessageHeader::encodedLength(),
|
||||
bufferLength,
|
||||
sbeBlockLength(),
|
||||
sbeSchemaVersion());
|
||||
}
|
||||
|
||||
EstablishmentReject505 &wrapForDecode(
|
||||
char *buffer,
|
||||
const std::uint64_t offset,
|
||||
const std::uint64_t actingBlockLength,
|
||||
const std::uint64_t actingVersion,
|
||||
const std::uint64_t bufferLength)
|
||||
{
|
||||
return *this = EstablishmentReject505(buffer, offset, bufferLength, actingBlockLength, actingVersion);
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint64_t sbePosition() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
std::uint64_t sbeCheckPosition(const std::uint64_t position)
|
||||
{
|
||||
if (SBE_BOUNDS_CHECK_EXPECT((position > m_bufferLength), false))
|
||||
{
|
||||
throw std::runtime_error("buffer too short [E100]");
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
void sbePosition(const std::uint64_t position)
|
||||
{
|
||||
m_position = sbeCheckPosition(position);
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint64_t encodedLength() const SBE_NOEXCEPT
|
||||
{
|
||||
return sbePosition() - m_offset;
|
||||
}
|
||||
|
||||
SBE_NODISCARD const char * buffer() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
SBE_NODISCARD char * buffer() SBE_NOEXCEPT
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint64_t bufferLength() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_bufferLength;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint64_t actingVersion() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_actingVersion;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static const char * ReasonMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
|
||||
{
|
||||
switch (metaAttribute)
|
||||
{
|
||||
case MetaAttribute::EPOCH: return "";
|
||||
case MetaAttribute::TIME_UNIT: return "";
|
||||
case MetaAttribute::SEMANTIC_TYPE: return "String";
|
||||
case MetaAttribute::PRESENCE: return "optional";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint16_t reasonId() SBE_NOEXCEPT
|
||||
{
|
||||
return 39011;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t reasonSinceVersion() SBE_NOEXCEPT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool reasonInActingVersion() SBE_NOEXCEPT
|
||||
{
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wtautological-compare"
|
||||
#endif
|
||||
return m_actingVersion >= reasonSinceVersion();
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::size_t reasonEncodingOffset() SBE_NOEXCEPT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR char reasonNullValue() SBE_NOEXCEPT
|
||||
{
|
||||
return (char)0;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR char reasonMinValue() SBE_NOEXCEPT
|
||||
{
|
||||
return (char)32;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR char reasonMaxValue() SBE_NOEXCEPT
|
||||
{
|
||||
return (char)126;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::size_t reasonEncodingLength() SBE_NOEXCEPT
|
||||
{
|
||||
return 48;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint64_t reasonLength() SBE_NOEXCEPT
|
||||
{
|
||||
return 48;
|
||||
}
|
||||
|
||||
SBE_NODISCARD const char *reason() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_buffer + m_offset + 0;
|
||||
}
|
||||
|
||||
SBE_NODISCARD char *reason() SBE_NOEXCEPT
|
||||
{
|
||||
return m_buffer + m_offset + 0;
|
||||
}
|
||||
|
||||
SBE_NODISCARD char reason(const std::uint64_t index) const
|
||||
{
|
||||
if (index >= 48)
|
||||
{
|
||||
throw std::runtime_error("index out of range for reason [E104]");
|
||||
}
|
||||
|
||||
char val;
|
||||
std::memcpy(&val, m_buffer + m_offset + 0 + (index * 1), sizeof(char));
|
||||
return (val);
|
||||
}
|
||||
|
||||
EstablishmentReject505 &reason(const std::uint64_t index, const char value)
|
||||
{
|
||||
if (index >= 48)
|
||||
{
|
||||
throw std::runtime_error("index out of range for reason [E105]");
|
||||
}
|
||||
|
||||
char val = (value);
|
||||
std::memcpy(m_buffer + m_offset + 0 + (index * 1), &val, sizeof(char));
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::uint64_t getReason(char *const dst, const std::uint64_t length) const
|
||||
{
|
||||
if (length > 48)
|
||||
{
|
||||
throw std::runtime_error("length too large for getReason [E106]");
|
||||
}
|
||||
|
||||
std::memcpy(dst, m_buffer + m_offset + 0, sizeof(char) * static_cast<size_t>(length));
|
||||
return length;
|
||||
}
|
||||
|
||||
EstablishmentReject505 &putReason(const char *const src) SBE_NOEXCEPT
|
||||
{
|
||||
std::memcpy(m_buffer + m_offset + 0, src, sizeof(char) * 48);
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string getReasonAsString() const
|
||||
{
|
||||
const char *buffer = m_buffer + m_offset + 0;
|
||||
size_t length = 0;
|
||||
|
||||
for (; length < 48 && *(buffer + length) != '\0'; ++length);
|
||||
std::string result(buffer, length);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string getReasonAsJsonEscapedString()
|
||||
{
|
||||
std::ostringstream oss;
|
||||
std::string s = getReasonAsString();
|
||||
|
||||
for (auto c = s.cbegin(); c != s.cend(); c++)
|
||||
{
|
||||
switch (*c)
|
||||
{
|
||||
case '"': oss << "\\\""; break;
|
||||
case '\\': oss << "\\\\"; break;
|
||||
case '\b': oss << "\\b"; break;
|
||||
case '\f': oss << "\\f"; break;
|
||||
case '\n': oss << "\\n"; break;
|
||||
case '\r': oss << "\\r"; break;
|
||||
case '\t': oss << "\\t"; break;
|
||||
|
||||
default:
|
||||
if ('\x00' <= *c && *c <= '\x1f')
|
||||
{
|
||||
oss << "\\u" << std::hex << std::setw(4)
|
||||
<< std::setfill('0') << (int)(*c);
|
||||
}
|
||||
else
|
||||
{
|
||||
oss << *c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
std::string_view getReasonAsStringView() const SBE_NOEXCEPT
|
||||
{
|
||||
const char *buffer = m_buffer + m_offset + 0;
|
||||
size_t length = 0;
|
||||
|
||||
for (; length < 48 && *(buffer + length) != '\0'; ++length);
|
||||
std::string_view result(buffer, length);
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
EstablishmentReject505 &putReason(const std::string_view str)
|
||||
{
|
||||
const size_t srcLength = str.length();
|
||||
if (srcLength > 48)
|
||||
{
|
||||
throw std::runtime_error("string too large for putReason [E106]");
|
||||
}
|
||||
|
||||
std::memcpy(m_buffer + m_offset + 0, str.data(), srcLength);
|
||||
for (size_t start = srcLength; start < 48; ++start)
|
||||
{
|
||||
m_buffer[m_offset + 0 + start] = 0;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
EstablishmentReject505 &putReason(const std::string& str)
|
||||
{
|
||||
const size_t srcLength = str.length();
|
||||
if (srcLength > 48)
|
||||
{
|
||||
throw std::runtime_error("string too large for putReason [E106]");
|
||||
}
|
||||
|
||||
std::memcpy(m_buffer + m_offset + 0, str.c_str(), srcLength);
|
||||
for (size_t start = srcLength; start < 48; ++start)
|
||||
{
|
||||
m_buffer[m_offset + 0 + start] = 0;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
SBE_NODISCARD static const char * UUIDMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
|
||||
{
|
||||
switch (metaAttribute)
|
||||
{
|
||||
case MetaAttribute::EPOCH: return "";
|
||||
case MetaAttribute::TIME_UNIT: return "";
|
||||
case MetaAttribute::SEMANTIC_TYPE: return "int";
|
||||
case MetaAttribute::PRESENCE: return "required";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint16_t uUIDId() SBE_NOEXCEPT
|
||||
{
|
||||
return 39001;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t uUIDSinceVersion() SBE_NOEXCEPT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool uUIDInActingVersion() SBE_NOEXCEPT
|
||||
{
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wtautological-compare"
|
||||
#endif
|
||||
return m_actingVersion >= uUIDSinceVersion();
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::size_t uUIDEncodingOffset() SBE_NOEXCEPT
|
||||
{
|
||||
return 48;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint64_t uUIDNullValue() SBE_NOEXCEPT
|
||||
{
|
||||
return SBE_NULLVALUE_UINT64;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint64_t uUIDMinValue() SBE_NOEXCEPT
|
||||
{
|
||||
return 0x0L;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint64_t uUIDMaxValue() SBE_NOEXCEPT
|
||||
{
|
||||
return 0xfffffffffffffffeL;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::size_t uUIDEncodingLength() SBE_NOEXCEPT
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint64_t uUID() const SBE_NOEXCEPT
|
||||
{
|
||||
std::uint64_t val;
|
||||
std::memcpy(&val, m_buffer + m_offset + 48, sizeof(std::uint64_t));
|
||||
return SBE_LITTLE_ENDIAN_ENCODE_64(val);
|
||||
}
|
||||
|
||||
EstablishmentReject505 &uUID(const std::uint64_t value) SBE_NOEXCEPT
|
||||
{
|
||||
std::uint64_t val = SBE_LITTLE_ENDIAN_ENCODE_64(value);
|
||||
std::memcpy(m_buffer + m_offset + 48, &val, sizeof(std::uint64_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static const char * RequestTimestampMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
|
||||
{
|
||||
switch (metaAttribute)
|
||||
{
|
||||
case MetaAttribute::EPOCH: return "";
|
||||
case MetaAttribute::TIME_UNIT: return "";
|
||||
case MetaAttribute::SEMANTIC_TYPE: return "int";
|
||||
case MetaAttribute::PRESENCE: return "required";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint16_t requestTimestampId() SBE_NOEXCEPT
|
||||
{
|
||||
return 39002;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t requestTimestampSinceVersion() SBE_NOEXCEPT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool requestTimestampInActingVersion() SBE_NOEXCEPT
|
||||
{
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wtautological-compare"
|
||||
#endif
|
||||
return m_actingVersion >= requestTimestampSinceVersion();
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::size_t requestTimestampEncodingOffset() SBE_NOEXCEPT
|
||||
{
|
||||
return 56;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint64_t requestTimestampNullValue() SBE_NOEXCEPT
|
||||
{
|
||||
return SBE_NULLVALUE_UINT64;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint64_t requestTimestampMinValue() SBE_NOEXCEPT
|
||||
{
|
||||
return 0x0L;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint64_t requestTimestampMaxValue() SBE_NOEXCEPT
|
||||
{
|
||||
return 0xfffffffffffffffeL;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::size_t requestTimestampEncodingLength() SBE_NOEXCEPT
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint64_t requestTimestamp() const SBE_NOEXCEPT
|
||||
{
|
||||
std::uint64_t val;
|
||||
std::memcpy(&val, m_buffer + m_offset + 56, sizeof(std::uint64_t));
|
||||
return SBE_LITTLE_ENDIAN_ENCODE_64(val);
|
||||
}
|
||||
|
||||
EstablishmentReject505 &requestTimestamp(const std::uint64_t value) SBE_NOEXCEPT
|
||||
{
|
||||
std::uint64_t val = SBE_LITTLE_ENDIAN_ENCODE_64(value);
|
||||
std::memcpy(m_buffer + m_offset + 56, &val, sizeof(std::uint64_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static const char * NextSeqNoMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
|
||||
{
|
||||
switch (metaAttribute)
|
||||
{
|
||||
case MetaAttribute::EPOCH: return "";
|
||||
case MetaAttribute::TIME_UNIT: return "";
|
||||
case MetaAttribute::SEMANTIC_TYPE: return "int";
|
||||
case MetaAttribute::PRESENCE: return "required";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint16_t nextSeqNoId() SBE_NOEXCEPT
|
||||
{
|
||||
return 39013;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t nextSeqNoSinceVersion() SBE_NOEXCEPT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool nextSeqNoInActingVersion() SBE_NOEXCEPT
|
||||
{
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wtautological-compare"
|
||||
#endif
|
||||
return m_actingVersion >= nextSeqNoSinceVersion();
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::size_t nextSeqNoEncodingOffset() SBE_NOEXCEPT
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint32_t nextSeqNoNullValue() SBE_NOEXCEPT
|
||||
{
|
||||
return SBE_NULLVALUE_UINT32;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint32_t nextSeqNoMinValue() SBE_NOEXCEPT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint32_t nextSeqNoMaxValue() SBE_NOEXCEPT
|
||||
{
|
||||
return 4294967294;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::size_t nextSeqNoEncodingLength() SBE_NOEXCEPT
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint32_t nextSeqNo() const SBE_NOEXCEPT
|
||||
{
|
||||
std::uint32_t val;
|
||||
std::memcpy(&val, m_buffer + m_offset + 64, sizeof(std::uint32_t));
|
||||
return SBE_LITTLE_ENDIAN_ENCODE_32(val);
|
||||
}
|
||||
|
||||
EstablishmentReject505 &nextSeqNo(const std::uint32_t value) SBE_NOEXCEPT
|
||||
{
|
||||
std::uint32_t val = SBE_LITTLE_ENDIAN_ENCODE_32(value);
|
||||
std::memcpy(m_buffer + m_offset + 64, &val, sizeof(std::uint32_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static const char * ErrorCodesMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
|
||||
{
|
||||
switch (metaAttribute)
|
||||
{
|
||||
case MetaAttribute::EPOCH: return "";
|
||||
case MetaAttribute::TIME_UNIT: return "";
|
||||
case MetaAttribute::SEMANTIC_TYPE: return "int";
|
||||
case MetaAttribute::PRESENCE: return "required";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint16_t errorCodesId() SBE_NOEXCEPT
|
||||
{
|
||||
return 39012;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t errorCodesSinceVersion() SBE_NOEXCEPT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool errorCodesInActingVersion() SBE_NOEXCEPT
|
||||
{
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wtautological-compare"
|
||||
#endif
|
||||
return m_actingVersion >= errorCodesSinceVersion();
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::size_t errorCodesEncodingOffset() SBE_NOEXCEPT
|
||||
{
|
||||
return 68;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint16_t errorCodesNullValue() SBE_NOEXCEPT
|
||||
{
|
||||
return SBE_NULLVALUE_UINT16;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint16_t errorCodesMinValue() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::uint16_t)0;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint16_t errorCodesMaxValue() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::uint16_t)65534;
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::size_t errorCodesEncodingLength() SBE_NOEXCEPT
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint16_t errorCodes() const SBE_NOEXCEPT
|
||||
{
|
||||
std::uint16_t val;
|
||||
std::memcpy(&val, m_buffer + m_offset + 68, sizeof(std::uint16_t));
|
||||
return SBE_LITTLE_ENDIAN_ENCODE_16(val);
|
||||
}
|
||||
|
||||
EstablishmentReject505 &errorCodes(const std::uint16_t value) SBE_NOEXCEPT
|
||||
{
|
||||
std::uint16_t val = SBE_LITTLE_ENDIAN_ENCODE_16(value);
|
||||
std::memcpy(m_buffer + m_offset + 68, &val, sizeof(std::uint16_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static const char * FaultToleranceIndicatorMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
|
||||
{
|
||||
switch (metaAttribute)
|
||||
{
|
||||
case MetaAttribute::EPOCH: return "";
|
||||
case MetaAttribute::TIME_UNIT: return "";
|
||||
case MetaAttribute::SEMANTIC_TYPE: return "int";
|
||||
case MetaAttribute::PRESENCE: return "required";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint16_t faultToleranceIndicatorId() SBE_NOEXCEPT
|
||||
{
|
||||
return 39010;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t faultToleranceIndicatorSinceVersion() SBE_NOEXCEPT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool faultToleranceIndicatorInActingVersion() SBE_NOEXCEPT
|
||||
{
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wtautological-compare"
|
||||
#endif
|
||||
return m_actingVersion >= faultToleranceIndicatorSinceVersion();
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::size_t faultToleranceIndicatorEncodingOffset() SBE_NOEXCEPT
|
||||
{
|
||||
return 70;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::size_t faultToleranceIndicatorEncodingLength() SBE_NOEXCEPT
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
SBE_NODISCARD FTI::Value faultToleranceIndicator() const SBE_NOEXCEPT
|
||||
{
|
||||
std::uint8_t val;
|
||||
std::memcpy(&val, m_buffer + m_offset + 70, sizeof(std::uint8_t));
|
||||
return FTI::get((val));
|
||||
}
|
||||
|
||||
EstablishmentReject505 &faultToleranceIndicator(const FTI::Value value) SBE_NOEXCEPT
|
||||
{
|
||||
std::uint8_t val = (value);
|
||||
std::memcpy(m_buffer + m_offset + 70, &val, sizeof(std::uint8_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static const char * SplitMsgMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
|
||||
{
|
||||
switch (metaAttribute)
|
||||
{
|
||||
case MetaAttribute::EPOCH: return "";
|
||||
case MetaAttribute::TIME_UNIT: return "";
|
||||
case MetaAttribute::SEMANTIC_TYPE: return "int";
|
||||
case MetaAttribute::PRESENCE: return "required";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
static SBE_CONSTEXPR std::uint16_t splitMsgId() SBE_NOEXCEPT
|
||||
{
|
||||
return 9553;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t splitMsgSinceVersion() SBE_NOEXCEPT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool splitMsgInActingVersion() SBE_NOEXCEPT
|
||||
{
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wtautological-compare"
|
||||
#endif
|
||||
return m_actingVersion >= splitMsgSinceVersion();
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::size_t splitMsgEncodingOffset() SBE_NOEXCEPT
|
||||
{
|
||||
return 71;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::size_t splitMsgEncodingLength() SBE_NOEXCEPT
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
SBE_NODISCARD SplitMsg::Value splitMsg() const SBE_NOEXCEPT
|
||||
{
|
||||
std::uint8_t val;
|
||||
std::memcpy(&val, m_buffer + m_offset + 71, sizeof(std::uint8_t));
|
||||
return SplitMsg::get((val));
|
||||
}
|
||||
|
||||
EstablishmentReject505 &splitMsg(const SplitMsg::Value value) SBE_NOEXCEPT
|
||||
{
|
||||
std::uint8_t val = (value);
|
||||
std::memcpy(m_buffer + m_offset + 71, &val, sizeof(std::uint8_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename CharT, typename Traits>
|
||||
friend std::basic_ostream<CharT, Traits>& operator<<(
|
||||
std::basic_ostream<CharT, Traits>& builder, EstablishmentReject505 _writer)
|
||||
{
|
||||
EstablishmentReject505 writer(_writer.m_buffer, _writer.m_offset,
|
||||
_writer.m_bufferLength, _writer.sbeBlockLength(), _writer.m_actingVersion);
|
||||
builder << '{';
|
||||
builder << R"("Name": "EstablishmentReject505", )";
|
||||
builder << R"("sbeTemplateId": )";
|
||||
builder << writer.sbeTemplateId();
|
||||
builder << ", ";
|
||||
|
||||
builder << R"("Reason": )";
|
||||
builder << '"' <<
|
||||
writer.getReasonAsJsonEscapedString().c_str() << '"';
|
||||
|
||||
builder << ", ";
|
||||
builder << R"("UUID": )";
|
||||
builder << +writer.uUID();
|
||||
|
||||
builder << ", ";
|
||||
builder << R"("RequestTimestamp": )";
|
||||
builder << +writer.requestTimestamp();
|
||||
|
||||
builder << ", ";
|
||||
builder << R"("NextSeqNo": )";
|
||||
builder << +writer.nextSeqNo();
|
||||
|
||||
builder << ", ";
|
||||
builder << R"("ErrorCodes": )";
|
||||
builder << +writer.errorCodes();
|
||||
|
||||
builder << ", ";
|
||||
builder << R"("FaultToleranceIndicator": )";
|
||||
builder << '"' << writer.faultToleranceIndicator() << '"';
|
||||
|
||||
builder << ", ";
|
||||
builder << R"("SplitMsg": )";
|
||||
builder << '"' << writer.splitMsg() << '"';
|
||||
|
||||
builder << '}';
|
||||
|
||||
return builder;
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,138 @@
|
||||
/* Generated SBE (Simple Binary Encoding) message codec */
|
||||
#ifndef _ILINKBINARY_EXECACKSTATUS_H_
|
||||
#define _ILINKBINARY_EXECACKSTATUS_H_
|
||||
|
||||
#if defined(SBE_HAVE_CMATH)
|
||||
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
|
||||
# include <cmath>
|
||||
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
|
||||
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
|
||||
#else
|
||||
/* math.h needed for NAN */
|
||||
# include <math.h>
|
||||
# define SBE_FLOAT_NAN NAN
|
||||
# define SBE_DOUBLE_NAN NAN
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# include <cstdint>
|
||||
# include <string>
|
||||
# include <cstring>
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# define SBE_CONSTEXPR constexpr
|
||||
# define SBE_NOEXCEPT noexcept
|
||||
#else
|
||||
# define SBE_CONSTEXPR
|
||||
# define SBE_NOEXCEPT
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
# define SBE_NODISCARD [[nodiscard]]
|
||||
#else
|
||||
# define SBE_NODISCARD
|
||||
#endif
|
||||
|
||||
#if !defined(__STDC_LIMIT_MACROS)
|
||||
# define __STDC_LIMIT_MACROS 1
|
||||
#endif
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
|
||||
#else
|
||||
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
|
||||
#endif
|
||||
|
||||
#if defined(SBE_NO_BOUNDS_CHECK)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
|
||||
#elif defined(_MSC_VER)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
|
||||
#else
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
|
||||
#endif
|
||||
|
||||
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
|
||||
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
|
||||
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
|
||||
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
|
||||
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
|
||||
|
||||
|
||||
namespace iLinkBinary {
|
||||
|
||||
class ExecAckStatus
|
||||
{
|
||||
public:
|
||||
enum Value
|
||||
{
|
||||
Accepted = (std::uint8_t)1,
|
||||
Rejected = (std::uint8_t)2,
|
||||
NULL_VALUE = (std::uint8_t)255
|
||||
};
|
||||
|
||||
static ExecAckStatus::Value get(const std::uint8_t value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 1: return Accepted;
|
||||
case 2: return Rejected;
|
||||
case 255: return NULL_VALUE;
|
||||
}
|
||||
|
||||
throw std::runtime_error("unknown value for enum ExecAckStatus [E103]");
|
||||
}
|
||||
|
||||
static const char* c_str(const ExecAckStatus::Value value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case Accepted: return "Accepted";
|
||||
case Rejected: return "Rejected";
|
||||
case NULL_VALUE: return "NULL_VALUE";
|
||||
}
|
||||
|
||||
throw std::runtime_error("unknown value for enum ExecAckStatus [E103]:");
|
||||
}
|
||||
|
||||
template<typename CharT, typename Traits>
|
||||
friend std::basic_ostream<CharT, Traits>& operator<<(
|
||||
std::basic_ostream<CharT, Traits>& os, ExecAckStatus::Value m)
|
||||
{
|
||||
return os << ExecAckStatus::c_str(m);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,515 @@
|
||||
/* Generated SBE (Simple Binary Encoding) message codec */
|
||||
#ifndef _ILINKBINARY_EXECINST_H_
|
||||
#define _ILINKBINARY_EXECINST_H_
|
||||
|
||||
#if defined(SBE_HAVE_CMATH)
|
||||
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
|
||||
# include <cmath>
|
||||
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
|
||||
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
|
||||
#else
|
||||
/* math.h needed for NAN */
|
||||
# include <math.h>
|
||||
# define SBE_FLOAT_NAN NAN
|
||||
# define SBE_DOUBLE_NAN NAN
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# include <cstdint>
|
||||
# include <string>
|
||||
# include <cstring>
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# define SBE_CONSTEXPR constexpr
|
||||
# define SBE_NOEXCEPT noexcept
|
||||
#else
|
||||
# define SBE_CONSTEXPR
|
||||
# define SBE_NOEXCEPT
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
# define SBE_NODISCARD [[nodiscard]]
|
||||
#else
|
||||
# define SBE_NODISCARD
|
||||
#endif
|
||||
|
||||
#if !defined(__STDC_LIMIT_MACROS)
|
||||
# define __STDC_LIMIT_MACROS 1
|
||||
#endif
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
|
||||
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
|
||||
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
|
||||
#else
|
||||
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
|
||||
#endif
|
||||
|
||||
#if defined(SBE_NO_BOUNDS_CHECK)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
|
||||
#elif defined(_MSC_VER)
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
|
||||
#else
|
||||
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
|
||||
#endif
|
||||
|
||||
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
|
||||
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
|
||||
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
|
||||
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
|
||||
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
|
||||
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
|
||||
|
||||
|
||||
namespace iLinkBinary {
|
||||
|
||||
class ExecInst
|
||||
{
|
||||
private:
|
||||
char *m_buffer = nullptr;
|
||||
std::uint64_t m_bufferLength = 0;
|
||||
std::uint64_t m_offset = 0;
|
||||
std::uint64_t m_actingVersion = 0;
|
||||
|
||||
public:
|
||||
enum MetaAttribute
|
||||
{
|
||||
EPOCH, TIME_UNIT, SEMANTIC_TYPE, PRESENCE
|
||||
};
|
||||
|
||||
union sbe_float_as_uint_u
|
||||
{
|
||||
float fp_value;
|
||||
std::uint32_t uint_value;
|
||||
};
|
||||
|
||||
union sbe_double_as_uint_u
|
||||
{
|
||||
double fp_value;
|
||||
std::uint64_t uint_value;
|
||||
};
|
||||
|
||||
ExecInst() = default;
|
||||
|
||||
ExecInst(
|
||||
char *buffer,
|
||||
const std::uint64_t offset,
|
||||
const std::uint64_t bufferLength,
|
||||
const std::uint64_t actingVersion) :
|
||||
m_buffer(buffer),
|
||||
m_bufferLength(bufferLength),
|
||||
m_offset(offset),
|
||||
m_actingVersion(actingVersion)
|
||||
{
|
||||
if (SBE_BOUNDS_CHECK_EXPECT(((m_offset + 1) > m_bufferLength), false))
|
||||
{
|
||||
throw std::runtime_error("buffer too short for flyweight [E107]");
|
||||
}
|
||||
}
|
||||
|
||||
ExecInst(
|
||||
char *buffer,
|
||||
const std::uint64_t bufferLength,
|
||||
const std::uint64_t actingVersion) :
|
||||
ExecInst(buffer, 0, bufferLength, actingVersion)
|
||||
{
|
||||
}
|
||||
|
||||
ExecInst(
|
||||
char *buffer,
|
||||
const std::uint64_t bufferLength) :
|
||||
ExecInst(buffer, 0, bufferLength, sbeSchemaVersion())
|
||||
{
|
||||
}
|
||||
|
||||
ExecInst &wrap(
|
||||
char *buffer,
|
||||
const std::uint64_t offset,
|
||||
const std::uint64_t actingVersion,
|
||||
const std::uint64_t bufferLength)
|
||||
{
|
||||
return *this = ExecInst(buffer, offset, bufferLength, actingVersion);
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t encodedLength() SBE_NOEXCEPT
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint64_t offset() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
SBE_NODISCARD const char * buffer() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
SBE_NODISCARD char * buffer() SBE_NOEXCEPT
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint64_t bufferLength() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_bufferLength;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint64_t actingVersion() const SBE_NOEXCEPT
|
||||
{
|
||||
return m_actingVersion;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaId() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::uint16_t)8;
|
||||
}
|
||||
|
||||
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
|
||||
{
|
||||
return (std::uint16_t)2;
|
||||
}
|
||||
|
||||
ExecInst &clear()
|
||||
{
|
||||
std::uint8_t zero = 0;
|
||||
std::memcpy(m_buffer + m_offset, &zero, sizeof(std::uint8_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool isEmpty() const
|
||||
{
|
||||
std::uint8_t val;
|
||||
std::memcpy(&val, m_buffer + m_offset, sizeof(std::uint8_t));
|
||||
return 0 == val;
|
||||
}
|
||||
|
||||
SBE_NODISCARD std::uint8_t rawValue() const
|
||||
{
|
||||
std::uint8_t val;
|
||||
std::memcpy(&val, m_buffer + m_offset, sizeof(std::uint8_t));
|
||||
return val;
|
||||
}
|
||||
|
||||
ExecInst &rawValue(std::uint8_t value)
|
||||
{
|
||||
std::memcpy(m_buffer + m_offset, &value, sizeof(std::uint8_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
static bool aON(const std::uint8_t bits)
|
||||
{
|
||||
return (bits & (1u << 0u)) != 0;
|
||||
}
|
||||
|
||||
static std::uint8_t aON(const std::uint8_t bits, const bool value)
|
||||
{
|
||||
return value ? static_cast<std::uint8_t>(bits | (1u << 0u)) : static_cast<std::uint8_t>(bits & ~(1u << 0u));
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool aON() const
|
||||
{
|
||||
std::uint8_t val;
|
||||
std::memcpy(&val, m_buffer + m_offset, sizeof(std::uint8_t));
|
||||
return ((val) & (1u << 0u)) != 0;
|
||||
}
|
||||
|
||||
ExecInst &aON(const bool value)
|
||||
{
|
||||
std::uint8_t bits;
|
||||
std::memcpy(&bits, m_buffer + m_offset, sizeof(std::uint8_t));
|
||||
bits = (value ? static_cast<std::uint8_t>((bits) | (1u << 0u)) : static_cast<std::uint8_t>((bits) & ~(1u << 0u)));
|
||||
std::memcpy(m_buffer + m_offset, &bits, sizeof(std::uint8_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
static bool oB(const std::uint8_t bits)
|
||||
{
|
||||
return (bits & (1u << 1u)) != 0;
|
||||
}
|
||||
|
||||
static std::uint8_t oB(const std::uint8_t bits, const bool value)
|
||||
{
|
||||
return value ? static_cast<std::uint8_t>(bits | (1u << 1u)) : static_cast<std::uint8_t>(bits & ~(1u << 1u));
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool oB() const
|
||||
{
|
||||
std::uint8_t val;
|
||||
std::memcpy(&val, m_buffer + m_offset, sizeof(std::uint8_t));
|
||||
return ((val) & (1u << 1u)) != 0;
|
||||
}
|
||||
|
||||
ExecInst &oB(const bool value)
|
||||
{
|
||||
std::uint8_t bits;
|
||||
std::memcpy(&bits, m_buffer + m_offset, sizeof(std::uint8_t));
|
||||
bits = (value ? static_cast<std::uint8_t>((bits) | (1u << 1u)) : static_cast<std::uint8_t>((bits) & ~(1u << 1u)));
|
||||
std::memcpy(m_buffer + m_offset, &bits, sizeof(std::uint8_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
static bool nH(const std::uint8_t bits)
|
||||
{
|
||||
return (bits & (1u << 2u)) != 0;
|
||||
}
|
||||
|
||||
static std::uint8_t nH(const std::uint8_t bits, const bool value)
|
||||
{
|
||||
return value ? static_cast<std::uint8_t>(bits | (1u << 2u)) : static_cast<std::uint8_t>(bits & ~(1u << 2u));
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool nH() const
|
||||
{
|
||||
std::uint8_t val;
|
||||
std::memcpy(&val, m_buffer + m_offset, sizeof(std::uint8_t));
|
||||
return ((val) & (1u << 2u)) != 0;
|
||||
}
|
||||
|
||||
ExecInst &nH(const bool value)
|
||||
{
|
||||
std::uint8_t bits;
|
||||
std::memcpy(&bits, m_buffer + m_offset, sizeof(std::uint8_t));
|
||||
bits = (value ? static_cast<std::uint8_t>((bits) | (1u << 2u)) : static_cast<std::uint8_t>((bits) & ~(1u << 2u)));
|
||||
std::memcpy(m_buffer + m_offset, &bits, sizeof(std::uint8_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
static bool reserved1(const std::uint8_t bits)
|
||||
{
|
||||
return (bits & (1u << 3u)) != 0;
|
||||
}
|
||||
|
||||
static std::uint8_t reserved1(const std::uint8_t bits, const bool value)
|
||||
{
|
||||
return value ? static_cast<std::uint8_t>(bits | (1u << 3u)) : static_cast<std::uint8_t>(bits & ~(1u << 3u));
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool reserved1() const
|
||||
{
|
||||
std::uint8_t val;
|
||||
std::memcpy(&val, m_buffer + m_offset, sizeof(std::uint8_t));
|
||||
return ((val) & (1u << 3u)) != 0;
|
||||
}
|
||||
|
||||
ExecInst &reserved1(const bool value)
|
||||
{
|
||||
std::uint8_t bits;
|
||||
std::memcpy(&bits, m_buffer + m_offset, sizeof(std::uint8_t));
|
||||
bits = (value ? static_cast<std::uint8_t>((bits) | (1u << 3u)) : static_cast<std::uint8_t>((bits) & ~(1u << 3u)));
|
||||
std::memcpy(m_buffer + m_offset, &bits, sizeof(std::uint8_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
static bool reserved2(const std::uint8_t bits)
|
||||
{
|
||||
return (bits & (1u << 4u)) != 0;
|
||||
}
|
||||
|
||||
static std::uint8_t reserved2(const std::uint8_t bits, const bool value)
|
||||
{
|
||||
return value ? static_cast<std::uint8_t>(bits | (1u << 4u)) : static_cast<std::uint8_t>(bits & ~(1u << 4u));
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool reserved2() const
|
||||
{
|
||||
std::uint8_t val;
|
||||
std::memcpy(&val, m_buffer + m_offset, sizeof(std::uint8_t));
|
||||
return ((val) & (1u << 4u)) != 0;
|
||||
}
|
||||
|
||||
ExecInst &reserved2(const bool value)
|
||||
{
|
||||
std::uint8_t bits;
|
||||
std::memcpy(&bits, m_buffer + m_offset, sizeof(std::uint8_t));
|
||||
bits = (value ? static_cast<std::uint8_t>((bits) | (1u << 4u)) : static_cast<std::uint8_t>((bits) & ~(1u << 4u)));
|
||||
std::memcpy(m_buffer + m_offset, &bits, sizeof(std::uint8_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
static bool reserved3(const std::uint8_t bits)
|
||||
{
|
||||
return (bits & (1u << 5u)) != 0;
|
||||
}
|
||||
|
||||
static std::uint8_t reserved3(const std::uint8_t bits, const bool value)
|
||||
{
|
||||
return value ? static_cast<std::uint8_t>(bits | (1u << 5u)) : static_cast<std::uint8_t>(bits & ~(1u << 5u));
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool reserved3() const
|
||||
{
|
||||
std::uint8_t val;
|
||||
std::memcpy(&val, m_buffer + m_offset, sizeof(std::uint8_t));
|
||||
return ((val) & (1u << 5u)) != 0;
|
||||
}
|
||||
|
||||
ExecInst &reserved3(const bool value)
|
||||
{
|
||||
std::uint8_t bits;
|
||||
std::memcpy(&bits, m_buffer + m_offset, sizeof(std::uint8_t));
|
||||
bits = (value ? static_cast<std::uint8_t>((bits) | (1u << 5u)) : static_cast<std::uint8_t>((bits) & ~(1u << 5u)));
|
||||
std::memcpy(m_buffer + m_offset, &bits, sizeof(std::uint8_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
static bool reserved4(const std::uint8_t bits)
|
||||
{
|
||||
return (bits & (1u << 6u)) != 0;
|
||||
}
|
||||
|
||||
static std::uint8_t reserved4(const std::uint8_t bits, const bool value)
|
||||
{
|
||||
return value ? static_cast<std::uint8_t>(bits | (1u << 6u)) : static_cast<std::uint8_t>(bits & ~(1u << 6u));
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool reserved4() const
|
||||
{
|
||||
std::uint8_t val;
|
||||
std::memcpy(&val, m_buffer + m_offset, sizeof(std::uint8_t));
|
||||
return ((val) & (1u << 6u)) != 0;
|
||||
}
|
||||
|
||||
ExecInst &reserved4(const bool value)
|
||||
{
|
||||
std::uint8_t bits;
|
||||
std::memcpy(&bits, m_buffer + m_offset, sizeof(std::uint8_t));
|
||||
bits = (value ? static_cast<std::uint8_t>((bits) | (1u << 6u)) : static_cast<std::uint8_t>((bits) & ~(1u << 6u)));
|
||||
std::memcpy(m_buffer + m_offset, &bits, sizeof(std::uint8_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
static bool reserved5(const std::uint8_t bits)
|
||||
{
|
||||
return (bits & (1u << 7u)) != 0;
|
||||
}
|
||||
|
||||
static std::uint8_t reserved5(const std::uint8_t bits, const bool value)
|
||||
{
|
||||
return value ? static_cast<std::uint8_t>(bits | (1u << 7u)) : static_cast<std::uint8_t>(bits & ~(1u << 7u));
|
||||
}
|
||||
|
||||
SBE_NODISCARD bool reserved5() const
|
||||
{
|
||||
std::uint8_t val;
|
||||
std::memcpy(&val, m_buffer + m_offset, sizeof(std::uint8_t));
|
||||
return ((val) & (1u << 7u)) != 0;
|
||||
}
|
||||
|
||||
ExecInst &reserved5(const bool value)
|
||||
{
|
||||
std::uint8_t bits;
|
||||
std::memcpy(&bits, m_buffer + m_offset, sizeof(std::uint8_t));
|
||||
bits = (value ? static_cast<std::uint8_t>((bits) | (1u << 7u)) : static_cast<std::uint8_t>((bits) & ~(1u << 7u)));
|
||||
std::memcpy(m_buffer + m_offset, &bits, sizeof(std::uint8_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename CharT, typename Traits>
|
||||
friend std::basic_ostream<CharT, Traits>& operator<<(
|
||||
std::basic_ostream<CharT, Traits>& builder, ExecInst writer)
|
||||
{
|
||||
builder << '[';
|
||||
bool atLeastOne = false;
|
||||
if (writer.aON())
|
||||
{
|
||||
builder << R"("aON")";
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (writer.oB())
|
||||
{
|
||||
if (atLeastOne)
|
||||
{
|
||||
builder << ",";
|
||||
}
|
||||
builder << R"("oB")";
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (writer.nH())
|
||||
{
|
||||
if (atLeastOne)
|
||||
{
|
||||
builder << ",";
|
||||
}
|
||||
builder << R"("nH")";
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (writer.reserved1())
|
||||
{
|
||||
if (atLeastOne)
|
||||
{
|
||||
builder << ",";
|
||||
}
|
||||
builder << R"("reserved1")";
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (writer.reserved2())
|
||||
{
|
||||
if (atLeastOne)
|
||||
{
|
||||
builder << ",";
|
||||
}
|
||||
builder << R"("reserved2")";
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (writer.reserved3())
|
||||
{
|
||||
if (atLeastOne)
|
||||
{
|
||||
builder << ",";
|
||||
}
|
||||
builder << R"("reserved3")";
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (writer.reserved4())
|
||||
{
|
||||
if (atLeastOne)
|
||||
{
|
||||
builder << ",";
|
||||
}
|
||||
builder << R"("reserved4")";
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (writer.reserved5())
|
||||
{
|
||||
if (atLeastOne)
|
||||
{
|
||||
builder << ",";
|
||||
}
|
||||
builder << R"("reserved5")";
|
||||
}
|
||||
builder << ']';
|
||||
return builder;
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
Loaded 100 of 250 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user