Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a89b0c964 |
No files matched your search
@@ -385,6 +385,7 @@ message NativeOrderState {
|
||||
string last_transact_time = 7;
|
||||
uint64 last_transact_time_unix_ns = 9;
|
||||
double stop_px = 8;
|
||||
uint64 exchange_order_id64 = 10;
|
||||
}
|
||||
|
||||
// Custom order states
|
||||
|
||||
@@ -35,12 +35,12 @@ struct CreateOrderMsg {
|
||||
|
||||
struct CancelReplaceOrderMsg {
|
||||
CreateOrderMsg create_fields;
|
||||
ExchangeOrderIDu64 exchange_order_id;
|
||||
ExchangeOrderID64 exchange_order_id;
|
||||
};
|
||||
|
||||
struct CancelOrderMsg {
|
||||
OrderKey key;
|
||||
ExchangeOrderIDu64 exchange_order_id;
|
||||
ExchangeOrderID64 exchange_order_id;
|
||||
api::orderman::ManualOrderIndicator manual_order_indicator;
|
||||
api::Security const *security;
|
||||
api::orderman::RoutingRecord const *routing_record;
|
||||
|
||||
@@ -41,7 +41,7 @@ void IL3ExecutionReportParser::common(const T& msg, ExecutionReport* data) {
|
||||
memcpy(&data->operator_id.value(), msg.senderID(), msg.senderIDLength());
|
||||
auto& price = const_cast<T&>(msg).price();
|
||||
data->exchange = api::VENUE_GLBX;
|
||||
data->exchange_order_id = ExchangeOrderIDu64 { msg.orderID() };
|
||||
data->exchange_order_id = ExchangeOrderID64 { msg.orderID() };
|
||||
data->leg_security = nullptr;
|
||||
data->manual_order_indicator = map_manual_order_indicator(msg.manualOrderIndicator());
|
||||
data->msg_seq_num = msg.seqNum();
|
||||
|
||||
@@ -47,6 +47,7 @@ public:
|
||||
auto native_state = get_native_state(state);
|
||||
if (native_state) {
|
||||
exchange_order_id = native_state->exchange_order_id();
|
||||
exchange_order_id64 = native_state->exchange_order_id64();
|
||||
last_msg_seq_num = native_state->last_msg_seq_num();
|
||||
sub_error_code = native_state->sub_error_code();
|
||||
native_status = native_state->native_status();
|
||||
@@ -79,6 +80,7 @@ public:
|
||||
|
||||
// native order state
|
||||
std::string exchange_order_id;
|
||||
uint64_t exchange_order_id64;
|
||||
uint64_t last_msg_seq_num;
|
||||
api::orderman::NativeOrderState::SubError sub_error_code;
|
||||
api::orderman::NativeOrderStatus native_status;
|
||||
@@ -187,6 +189,7 @@ private:
|
||||
void rebuild_native_state(api::orderman::NativeOrderState *st) const {
|
||||
st->set_stop_px(stop_px);
|
||||
st->set_exchange_order_id(exchange_order_id);
|
||||
st->set_exchange_order_id64(exchange_order_id64);
|
||||
st->set_last_msg_seq_num(last_msg_seq_num);
|
||||
st->set_sub_error_code(sub_error_code);
|
||||
st->set_native_status(native_status);
|
||||
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
Price avg_price;
|
||||
Price stop_price;
|
||||
ExchangeFillID exchange_fill_id;
|
||||
std::variant<orderman::ExchangeTimeStampStr,ExchangeTimeStamp64> transact_time;
|
||||
ExchangeTimeStampVar transact_time;
|
||||
config::JetFIX::Connection const *cfg;
|
||||
std::string cust_order_handling_inst;
|
||||
std::string msg;
|
||||
|
||||
@@ -6,17 +6,19 @@
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
#include "lib/api/services/OrderService.pb.h"
|
||||
#include "lib/domain_model/common.h"
|
||||
#include "lib/utils/ValueWrapper.h"
|
||||
#include "lib/utils/bts_assert.h"
|
||||
#include "lib/utils/bts_chrono.h"
|
||||
#include "lib/api/services/OrderService.pb.h"
|
||||
#include "lib/utils/overloaded.h"
|
||||
|
||||
namespace bts {
|
||||
namespace api {
|
||||
class Security;
|
||||
}
|
||||
namespace orderman {
|
||||
using SecurityPtr = const api::Security *;
|
||||
using AccountID = utils::ValueWrapper<struct AccountIDTag, uint32_t>;
|
||||
using UserID = utils::ValueWrapper<struct UserIDTag, uint32_t>;
|
||||
using OrderKey = utils::ValueWrapper<struct OrderKeyTag, uint32_t>;
|
||||
@@ -27,26 +29,6 @@ using AccountName =
|
||||
using GatewayName = utils::ValueWrapper<struct GatewayNameTag, std::string>;
|
||||
using ExchangeFillID =
|
||||
utils::ValueWrapper<struct ExchangeFillIDTag, std::array<char, 40>>;
|
||||
using ExchangeOrderID =
|
||||
utils::ValueWrapper<struct ExchangeOrderIDTag, std::array<char, 17>>;
|
||||
using ExchangeOrderIDu64 =
|
||||
utils::ValueWrapper<struct ExchangeOrderIDu64Tag, uint64_t>;
|
||||
|
||||
|
||||
using ExchangeTimeStampStr =
|
||||
utils::ValueWrapper<struct ExchangeTimeStampTag,
|
||||
std::array<char, sizeof("20121204-14:44:02.000") - 1>>;
|
||||
using SecurityPtr = const api::Security *;
|
||||
// Nanoseconds since unix epoch
|
||||
using ExchangeTimeStamp64 = utils::ValueWrapper<struct CMETimeStampTag,uint64_t>;
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
using ExchangeOrderIDVar = std::variant<ExchangeOrderID, ExchangeOrderIDu64>;
|
||||
using TimeStampVar = std::variant<ExchangeTimeStampStr, ExchangeTimeStamp64>;
|
||||
#endif
|
||||
//using ExchangeTimeStampVar = std::variant<,ExchangeTimeStamp64>;
|
||||
|
||||
|
||||
const uint16_t NullTickToTradeCorID = 0;
|
||||
const auto fix_buffer_pool_size = 10000;
|
||||
|
||||
@@ -83,17 +65,16 @@ template <class T> inline std::string to_str(T const &t) {
|
||||
template <size_t N>
|
||||
std::pair<const char *, size_t> find_trim_str(std::array<char, N> const &in) {
|
||||
auto i = N;
|
||||
for (; i!= 0; i--)
|
||||
if (in[i-1] != ' ' || in[i-1] == 0)
|
||||
for (; i != 0; i--)
|
||||
if (in[i - 1] != ' ' || in[i - 1] == 0)
|
||||
break;
|
||||
|
||||
return std::make_pair(&in[0], i);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::string to_trim_str(T const&t) {
|
||||
template <class T> std::string to_trim_str(T const &t) {
|
||||
auto ts = find_trim_str(t.value());
|
||||
return std::string(ts.first,ts.second);
|
||||
return std::string(ts.first, ts.second);
|
||||
}
|
||||
|
||||
inline bool in_terminal_state(bts::api::orderman::OrderStatus order_status) {
|
||||
@@ -104,4 +85,70 @@ inline bool in_terminal_state(bts::api::orderman::OrderStatus order_status) {
|
||||
api::orderman::OrderStatus::ORDER_STATUS_REJECTED_BY_SPARK;
|
||||
}
|
||||
|
||||
}} // namespace bts
|
||||
// Exchange order ids
|
||||
using ExchangeOrderID =
|
||||
utils::ValueWrapper<struct ExchangeOrderIDTag, std::array<char, 17>>;
|
||||
using ExchangeOrderID64 =
|
||||
utils::ValueWrapper<struct ExchangeOrderID64Tag, uint64_t>;
|
||||
// Exchange timestamps
|
||||
using ExchangeTimeStampStr =
|
||||
utils::ValueWrapper<struct ExchangeTimeStampTag,
|
||||
std::array<char, sizeof("20121204-14:44:02.000") - 1>>;
|
||||
using ExchangeTimeStamp64 =
|
||||
utils::ValueWrapper<struct CMETimeStampTag, uint64_t>;
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
using ExchangeTimeStampVar =
|
||||
std::variant<ExchangeTimeStampStr, ExchangeTimeStamp64>;
|
||||
using ExchangeOrderIDVar = std::variant<ExchangeOrderID, ExchangeOrderID64>;
|
||||
|
||||
inline ExchangeOrderIDVar
|
||||
get_exchange_order_id(api::orderman::NativeOrderState const &st) {
|
||||
if (st.exchange_order_id().size()) {
|
||||
ExchangeOrderID result;
|
||||
str_to<ExchangeOrderID>(st.exchange_order_id(), &result);
|
||||
return result;
|
||||
} else {
|
||||
return ExchangeOrderID64{st.exchange_order_id64()};
|
||||
}
|
||||
}
|
||||
inline void set_exchange_order_id(ExchangeOrderIDVar const &v,
|
||||
api::orderman::NativeOrderState *out) {
|
||||
std::visit(overloaded{[out](ExchangeOrderID const &str) {
|
||||
out->set_exchange_order_id64(0);
|
||||
*(out->mutable_exchange_order_id()) = to_trim_str(str);
|
||||
},
|
||||
[out](ExchangeOrderID64 oid) {
|
||||
out->set_exchange_order_id64(oid.value());
|
||||
out->clear_exchange_order_id();
|
||||
}},
|
||||
v);
|
||||
}
|
||||
|
||||
inline ExchangeTimeStampVar
|
||||
get_last_transact(api::orderman::NativeOrderState const&st) {
|
||||
if (st.last_transact_time().size()) {
|
||||
ExchangeTimeStampStr result;
|
||||
str_to<ExchangeTimeStampStr>(st.last_transact_time(),&result);
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return ExchangeTimeStamp64 {st.last_transact_time_unix_ns()};
|
||||
}
|
||||
}
|
||||
inline void set_last_transact_time(ExchangeTimeStampVar const&v,
|
||||
api::orderman::NativeOrderState *out) {
|
||||
std::visit(overloaded{[out](ExchangeTimeStampStr const &str) {
|
||||
out->set_last_transact_time_unix_ns(0);
|
||||
*(out->mutable_last_transact_time()) = to_trim_str(str);
|
||||
},
|
||||
[out](ExchangeTimeStamp64 ts) {
|
||||
out->set_last_transact_time_unix_ns(ts.value());
|
||||
out->clear_last_transact_time();
|
||||
}},
|
||||
v);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace orderman
|
||||
} // namespace bts
|
||||
@@ -45,7 +45,6 @@ struct NativeOrder::PImpl {
|
||||
: services(nullptr), session_services(), sec(nullptr),
|
||||
previous_working_position(0), definition(), state(),
|
||||
price_encoding_precision(7), exchange_order_id() {
|
||||
exchange_order_id.reserve(100);
|
||||
}
|
||||
|
||||
OrderServices *services;
|
||||
@@ -59,7 +58,7 @@ struct NativeOrder::PImpl {
|
||||
OrderDefinition definition;
|
||||
OrderState state;
|
||||
int price_encoding_precision;
|
||||
std::string exchange_order_id;
|
||||
std::optional<ExchangeOrderIDVar> exchange_order_id;
|
||||
|
||||
OrderServices::ExeReportSubID exe_report_sid;
|
||||
OrderServices::CancelRejectSubID cancel_reject_sid;
|
||||
@@ -195,8 +194,8 @@ void NativeOrder::on_init_recovered(OrderRecord const &rec,
|
||||
|
||||
init_encodings();
|
||||
if (me->state.status() != ORDER_STATUS_PENDING_WORKING) {
|
||||
me->exchange_order_id = native_state.exchange_order_id();
|
||||
me->encoder->update_exchange_order_id(me->exchange_order_id);
|
||||
me->exchange_order_id = get_exchange_order_id(native_state);
|
||||
me->encoder->update_exchange_order_id(me->exchange_order_id.value());
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -710,7 +709,7 @@ void NativeOrder::on_attached(
|
||||
*native_state.mutable_routing_record() = rq.routing_record;
|
||||
init_encodings();
|
||||
if (has_exchange_order_id())
|
||||
me->encoder->update_exchange_order_id(me->exchange_order_id);
|
||||
me->encoder->update_exchange_order_id(me->exchange_order_id.value());
|
||||
|
||||
// Update user, account and manual order indicator based on new parent
|
||||
me->definition.set_manual_order_indicator(
|
||||
@@ -846,13 +845,7 @@ void NativeOrder::on_exe_report(const NewExecutionReportEvent &er) {
|
||||
}
|
||||
|
||||
native_state.set_last_msg_seq_num(er.data->msg_seq_num);
|
||||
|
||||
orderman::ExchangeTimeStampStr ts_str;
|
||||
ExchangeTimeStamp64 ts_64;
|
||||
er.data->get_ts(&ts_str,&ts_64);
|
||||
|
||||
native_state.set_last_transact_time_unix_ns(ts_64.value());
|
||||
native_state.set_last_transact_time(to_str(ts_str));
|
||||
set_last_transact_time(er.data->transact_time,&native_state);
|
||||
auto external_status = map_external_status(er.data->order_status);
|
||||
|
||||
// filled quantity is reset back to 0 when the order is canceled
|
||||
@@ -894,10 +887,9 @@ void NativeOrder::on_exe_report(const NewExecutionReportEvent &er) {
|
||||
|
||||
bool got_first_exchange_order_id = !has_exchange_order_id();
|
||||
if (got_first_exchange_order_id) {
|
||||
me->exchange_order_id =
|
||||
to_trim_str(std::get<ExchangeOrderID>(er.data->exchange_order_id));
|
||||
native_state.set_exchange_order_id(me->exchange_order_id);
|
||||
me->encoder->update_exchange_order_id(me->exchange_order_id);
|
||||
me->exchange_order_id = er.data->exchange_order_id;
|
||||
set_exchange_order_id(me->exchange_order_id.value(),&native_state);
|
||||
me->encoder->update_exchange_order_id(me->exchange_order_id.value());
|
||||
}
|
||||
|
||||
if (!terminal_state(me->state.status())) {
|
||||
@@ -1138,7 +1130,7 @@ OrderStatus map_external_status(NativeOrderStatus status) {
|
||||
}
|
||||
|
||||
bool NativeOrder::has_exchange_order_id() {
|
||||
return me->exchange_order_id.size();
|
||||
return me->exchange_order_id.has_value();
|
||||
}
|
||||
|
||||
void NativeOrder::transition(api::orderman::OrderStatus new_status,
|
||||
|
||||
@@ -27,7 +27,7 @@ class IGLBXOrderEncoder {
|
||||
int price_encoding_precision,
|
||||
bool stop_order_has_been_triggered) = 0;
|
||||
|
||||
virtual void update_exchange_order_id(std::string const &) = 0;
|
||||
virtual void update_exchange_order_id(ExchangeOrderIDVar const&) = 0;
|
||||
|
||||
virtual void update_create_order_encoding(Price p, int price_precision,
|
||||
Quantity q, OrderServices &) = 0;
|
||||
|
||||
@@ -271,7 +271,8 @@ void iLink2OrderEncoder::init(OrderKey key,
|
||||
}
|
||||
}
|
||||
|
||||
void iLink2OrderEncoder::update_exchange_order_id(std::string const &oid) {
|
||||
void iLink2OrderEncoder::update_exchange_order_id(ExchangeOrderIDVar const&v) {
|
||||
auto oid = to_trim_str(std::get<ExchangeOrderID>(v));
|
||||
me->update_encoding.add<jetfix::fix::OrderID>(oid);
|
||||
me->cancel_encoding.add<jetfix::fix::OrderID>(oid);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ class iLink2OrderEncoder : public IGLBXOrderEncoder {
|
||||
api::orderman::OrderDefinition const &def,
|
||||
int price_encoding_precision,
|
||||
bool stop_order_has_been_triggered) override;
|
||||
void update_exchange_order_id(std::string const &) override;
|
||||
void update_exchange_order_id(ExchangeOrderIDVar const&) override;
|
||||
void update_create_order_encoding(Price p, int price_precision, Quantity q,
|
||||
OrderServices &services) override;
|
||||
void update_cancel_replace_stop_px(Price stop_px,
|
||||
|
||||
@@ -99,10 +99,10 @@ void iLink3OrderEncoder::init(OrderKey key,
|
||||
|
||||
// Cancel Replace template
|
||||
me->cancel_replace.create_fields = me->create;
|
||||
me->cancel_replace.exchange_order_id = ExchangeOrderIDu64(0);
|
||||
me->cancel_replace.exchange_order_id = ExchangeOrderID64(0);
|
||||
|
||||
// Cancel template
|
||||
me->cancel.exchange_order_id = ExchangeOrderIDu64(0);
|
||||
me->cancel.exchange_order_id = ExchangeOrderID64(0);
|
||||
me->cancel.manual_order_indicator = me->create.manual_order_indicator;
|
||||
me->cancel.key = key;
|
||||
me->cancel.security = me->create.security;
|
||||
@@ -110,8 +110,8 @@ void iLink3OrderEncoder::init(OrderKey key,
|
||||
me->cancel.routing_record = &rr;
|
||||
}
|
||||
|
||||
void iLink3OrderEncoder::update_exchange_order_id(std::string const &oid) {
|
||||
me->cancel_replace.exchange_order_id = ExchangeOrderIDu64{std::stoull(oid)};
|
||||
void iLink3OrderEncoder::update_exchange_order_id(ExchangeOrderIDVar const&v) {
|
||||
me->cancel_replace.exchange_order_id = std::get<ExchangeOrderID64> (v);
|
||||
me->cancel.exchange_order_id = me->cancel_replace.exchange_order_id;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ class iLink3OrderEncoder : public IGLBXOrderEncoder {
|
||||
api::orderman::OrderDefinition const &def,
|
||||
int price_encoding_precision,
|
||||
bool stop_order_has_been_triggered) override;
|
||||
void update_exchange_order_id(std::string const &) override;
|
||||
void update_exchange_order_id(ExchangeOrderIDVar const&) override;
|
||||
void update_create_order_encoding(Price p, int price_precision, Quantity q,
|
||||
OrderServices &services) override;
|
||||
void update_cancel_replace_stop_px(Price stop_px,
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
#include <variant>
|
||||
// Helper to visit std::variant
|
||||
namespace bts {
|
||||
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
|
||||
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>; // not needed as of C++20
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -184,7 +184,7 @@ struct TestRunner {
|
||||
void send_modify(CreateOrderMsg &create, const ExecutionReport *report) {
|
||||
bts_assert(gw.state() == State::READY);
|
||||
CancelReplaceOrderMsg msg{
|
||||
create, std::get<ExchangeOrderIDu64>(report->exchange_order_id)};
|
||||
create, std::get<ExchangeOrderID64>(report->exchange_order_id)};
|
||||
gw.send_cancel_replace(msg);
|
||||
gw.flush();
|
||||
}
|
||||
@@ -194,7 +194,7 @@ struct TestRunner {
|
||||
auto rr = get_rr();
|
||||
gw.send_cancel(CancelOrderMsg{
|
||||
last_report->order_key,
|
||||
std::get<ExchangeOrderIDu64>(last_report->exchange_order_id),
|
||||
std::get<ExchangeOrderID64>(last_report->exchange_order_id),
|
||||
api::orderman::ManualOrderIndicator::MANUAL_ORDER_INDICATOR_NO,
|
||||
last_report->security, &rr, last_report->side});
|
||||
}
|
||||
@@ -534,7 +534,7 @@ struct TestRunner {
|
||||
auto last_report = reports.back();
|
||||
gw.send_cancel(CancelOrderMsg{
|
||||
last_report->order_key,
|
||||
std::get<ExchangeOrderIDu64>(last_report->exchange_order_id),
|
||||
std::get<ExchangeOrderID64>(last_report->exchange_order_id),
|
||||
api::orderman::ManualOrderIndicator::MANUAL_ORDER_INDICATOR_NO,
|
||||
last_report->security, &rr, last_report->side});
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user