Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be9c61f435 | ||
|
|
1f7bacdf3b |
No files matched your search
@@ -6,7 +6,7 @@
|
|||||||
"memory": "4gb",
|
"memory": "4gb",
|
||||||
"storage": "6gb"
|
"storage": "6gb"
|
||||||
},
|
},
|
||||||
"postCreateCommand": "/home/bts/spark/docker/sparkd/dev/devcontainer_post_create.sh",
|
// "postCreateCommand": "/home/bts/spark/docker/sparkd/dev/devcontainer_post_create.sh",
|
||||||
"containerUser": "bts",
|
"containerUser": "bts",
|
||||||
"workspaceMount": "source=${localWorkspaceFolder},target=/home/bts/spark,type=bind",
|
"workspaceMount": "source=${localWorkspaceFolder},target=/home/bts/spark,type=bind",
|
||||||
"workspaceFolder": "/home/bts/spark",
|
"workspaceFolder": "/home/bts/spark",
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
*.cmd eol=crlf
|
*.cmd eol=crlf
|
||||||
*.cs eol=crlf
|
|
||||||
*.sh eol=lf
|
*.sh eol=lf
|
||||||
Vendored
+13
@@ -1,6 +1,19 @@
|
|||||||
{
|
{
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "(gdb) Launch",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceFolder}/build/sparkd-debug-gcc/server/sparkd",
|
||||||
|
"args": ["run"],
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"cwd": "${workspaceFolder}/build/sparkd-debug-gcc/server",
|
||||||
|
"environment": [],
|
||||||
|
"externalConsole": false,
|
||||||
|
"MIMode": "gdb",
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "DataStreamPublisher",
|
"name": "DataStreamPublisher",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
|
|||||||
Vendored
+19
@@ -189,6 +189,25 @@
|
|||||||
"color": "terminal.ansiCyan"
|
"color": "terminal.ansiCyan"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"label": "Build Sparkd -j8",
|
||||||
|
"group": "build",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "",
|
||||||
|
"linux": {
|
||||||
|
"command": "tools/build_sparkd.sh",
|
||||||
|
"args": [
|
||||||
|
"--preset",
|
||||||
|
"${input:sparkdCmakePreset}",
|
||||||
|
"-j",
|
||||||
|
"8"
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"icon": {
|
||||||
|
"id": "terminal",
|
||||||
|
"color": "terminal.ansiCyan"
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"label": "Build Sparkd (Debug)",
|
"label": "Build Sparkd (Debug)",
|
||||||
"group": "build",
|
"group": "build",
|
||||||
|
|||||||
+1
-1
Submodule externals updated: cae5fd20da...d5ef431791.
Generated
+1
-13016
File diff suppressed because it is too large.
Load diff
@@ -161,6 +161,14 @@ AdminServiceUtils::resolve_connection(
|
|||||||
if (rv == nullptr &&
|
if (rv == nullptr &&
|
||||||
(deployment_type == "dev" || deployment_type == "demo"))
|
(deployment_type == "dev" || deployment_type == "demo"))
|
||||||
rv = resolve_sim_connection(data, account, sec);
|
rv = resolve_sim_connection(data, account, sec);
|
||||||
|
if (account.has_connections())
|
||||||
|
for (const std::string &conn_name :
|
||||||
|
account.connections().exchange_connection_names()) {
|
||||||
|
const bts::api::admin::ExchangeConnection *conn =
|
||||||
|
find_connection(data, conn_name);
|
||||||
|
if (conn != nullptr && conn->has_general_connection())
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case api::Venue::VENUE_ICE: {
|
case api::Venue::VENUE_ICE: {
|
||||||
@@ -226,13 +234,15 @@ void AdminServiceUtils::fill_connections_from_config(
|
|||||||
|
|
||||||
switch (c.venue()) {
|
switch (c.venue()) {
|
||||||
case bts::api::VENUE_GLBX:
|
case bts::api::VENUE_GLBX:
|
||||||
if (c.cme_market_segment_id() == 0)
|
connection.mutable_general_connection()->set_exchange(c.venue());
|
||||||
connection.mutable_cme_connection()->mutable_cgw_connection();
|
|
||||||
else
|
|
||||||
connection.mutable_cme_connection()
|
|
||||||
->mutable_msgw_connection()
|
|
||||||
->set_market_segment_id(c.cme_market_segment_id());
|
|
||||||
add_connection(admin_data, connection);
|
add_connection(admin_data, connection);
|
||||||
|
// if (c.cme_market_segment_id() == 0)
|
||||||
|
// connection.mutable_cme_connection()->mutable_cgw_connection();
|
||||||
|
// else
|
||||||
|
// connection.mutable_cme_connection()
|
||||||
|
// ->mutable_msgw_connection()
|
||||||
|
// ->set_market_segment_id(c.cme_market_segment_id());
|
||||||
|
// add_connection(admin_data, connection);
|
||||||
break;
|
break;
|
||||||
case bts::api::VENUE_CBOE:
|
case bts::api::VENUE_CBOE:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -409,6 +409,7 @@ message RoutingRecord {
|
|||||||
|
|
||||||
message NativeOrderState {
|
message NativeOrderState {
|
||||||
string exchange_order_id = 1;
|
string exchange_order_id = 1;
|
||||||
|
string external_order_id = 11; //"string : orderkey"
|
||||||
uint64 last_msg_seq_num = 4;
|
uint64 last_msg_seq_num = 4;
|
||||||
enum SubError {
|
enum SubError {
|
||||||
SUB_ERROR_NONE = 0;
|
SUB_ERROR_NONE = 0;
|
||||||
@@ -752,6 +753,7 @@ message RetrievedExchangeOpenOrder{
|
|||||||
string exchange_sec_desc = 10;
|
string exchange_sec_desc = 10;
|
||||||
string exchange_account = 20;
|
string exchange_account = 20;
|
||||||
string exchange_order_id = 30;
|
string exchange_order_id = 30;
|
||||||
|
string external_order_id = 11; //"string : orderkey"
|
||||||
uint32 security_key = 40;
|
uint32 security_key = 40;
|
||||||
bool security_resolved = 50;
|
bool security_resolved = 50;
|
||||||
string account_name = 60;
|
string account_name = 60;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ function(get_link_libraries dest)
|
|||||||
Pcap++
|
Pcap++
|
||||||
Packet++
|
Packet++
|
||||||
Common++
|
Common++
|
||||||
|
onixs-fix-engine
|
||||||
ssh2
|
ssh2
|
||||||
-lrt
|
-lrt
|
||||||
-ldl
|
-ldl
|
||||||
|
|||||||
@@ -4019,14 +4019,27 @@ JetFIX {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#If no canned cert specified we fallback to just sim
|
# If no canned cert specified we fallback to just sim
|
||||||
CannedCertSession { value { name: "" }}
|
# CannedCertSession { value { name: "" }}
|
||||||
|
# JetFIX {
|
||||||
|
# value {
|
||||||
|
# connection: @JetFIXSimConnection.sim
|
||||||
|
# connection {
|
||||||
|
# name: "deribit_1"
|
||||||
|
# venue: VENUE_DERIBIT
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# CannedCertSession { value { name: "" }}
|
||||||
JetFIX {
|
JetFIX {
|
||||||
value {
|
value {
|
||||||
connection: @JetFIXSimConnection.sim
|
|
||||||
connection {
|
connection {
|
||||||
name: "deribit_1"
|
name: "deribit_1"
|
||||||
venue: VENUE_DERIBIT
|
venue: VENUE_DERIBIT
|
||||||
}
|
}
|
||||||
|
connection {
|
||||||
|
name: "onixs_sim"
|
||||||
|
venue: VENUE_GLBX
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
OnixFixCfg {
|
||||||
|
value{
|
||||||
|
msg_type: "Order_Single",
|
||||||
|
protocol_version: "FIX_42",
|
||||||
|
handl_inst: 2,
|
||||||
|
sender_sub_id: "BTS",
|
||||||
|
target_sub_id: "TRFXMRX",
|
||||||
|
client_id: "BTS",
|
||||||
|
rule80a: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package config;
|
||||||
|
|
||||||
|
message OnixFixCfg {
|
||||||
|
enum HandlInst {
|
||||||
|
UNDEFINED = 0;
|
||||||
|
DMA = 1;
|
||||||
|
ALGO = 2;
|
||||||
|
CARE = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Rule80A {
|
||||||
|
UNUSED = 0;
|
||||||
|
AGENCY = 1;
|
||||||
|
PRINCIPAL = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
string msg_type = 1;
|
||||||
|
string protocol_version = 2;
|
||||||
|
HandlInst handl_inst = 3;
|
||||||
|
string sender_sub_id = 4;
|
||||||
|
string target_sub_id = 5;
|
||||||
|
string client_id = 6;
|
||||||
|
Rule80A rule80a = 7;
|
||||||
|
}
|
||||||
@@ -220,7 +220,7 @@ void ServiceBridge::on(mercury::Update<OrderOpResultEvent> const &update) {
|
|||||||
|
|
||||||
void ServiceBridge::create_order(uint32_t rid, api::orderman::Create const &c) {
|
void ServiceBridge::create_order(uint32_t rid, api::orderman::Create const &c) {
|
||||||
|
|
||||||
LOG(OrderMan, Info, "Received new order from client: {}",
|
LOG(OrderMan, Info, "ServiceBridge::create_order Received new order from client: {}",
|
||||||
utils::pb::to_string(c));
|
utils::pb::to_string(c));
|
||||||
|
|
||||||
me->service_call_marshaller.schedule_action([this, c, rid]() {
|
me->service_call_marshaller.schedule_action([this, c, rid]() {
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class OrderStateUpdateEvent : public mercury::Event<OrderStateUpdateEvent> {
|
|||||||
} else {
|
} else {
|
||||||
auto native_state = get_native_state(state);
|
auto native_state = get_native_state(state);
|
||||||
if (native_state) {
|
if (native_state) {
|
||||||
exchange_order_id = native_state->exchange_order_id();
|
exchange_order_id = native_state->exchange_order_id(); //use this
|
||||||
exchange_order_id_u64 = native_state->exchange_order_id_u64();
|
exchange_order_id_u64 = native_state->exchange_order_id_u64();
|
||||||
last_msg_seq_num = native_state->last_msg_seq_num();
|
last_msg_seq_num = native_state->last_msg_seq_num();
|
||||||
sub_error_code = native_state->sub_error_code();
|
sub_error_code = native_state->sub_error_code();
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
#include "ExecutionGateway.h"
|
||||||
|
#include "lib/logging/logging.h"
|
||||||
|
#include "lib/orderman/CreateOrderMsg.h"
|
||||||
|
#include "lib/orderman/OrderMsg.h"
|
||||||
|
#include "lib/orderman/gateways/IExecutionGateway.h"
|
||||||
|
#include "lib/orderman/gateways/OnixFIXAdapter.h"
|
||||||
|
#include "lib/orderman/gateways/IFIXGenericAdapter.h"
|
||||||
|
#include "lib/orderman/orderman_utils/CancelReject.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace bts::orderman {
|
||||||
|
struct ExecutionGateway::PImpl {
|
||||||
|
PImpl(){
|
||||||
|
_adapter = std::make_unique<OnixFIXAdapter>();
|
||||||
|
}
|
||||||
|
std::unique_ptr<IFIXGenericAdapter> _adapter;
|
||||||
|
OnExeReport on_exe_report;
|
||||||
|
OnGwStatusChange on_gw_status_change;
|
||||||
|
OnCancelReject on_cancel_reject;
|
||||||
|
OnExchangePositionState on_exchange_position_state;
|
||||||
|
OnExchangeOpenOrdersState on_exchange_open_orders;
|
||||||
|
|
||||||
|
};
|
||||||
|
OnGwStatusChange &ExecutionGateway::on_gw_status_change() {
|
||||||
|
return me->on_gw_status_change;
|
||||||
|
}
|
||||||
|
ExecutionGateway::ExecutionGateway():IExecutionGateway(), me(new PImpl()){
|
||||||
|
LOG(OrderMan,Info,"ExecutionGateway::ExecutionGateway constructor" );
|
||||||
|
}
|
||||||
|
ExecutionGateway::~ExecutionGateway() {}
|
||||||
|
void ExecutionGateway::start() {
|
||||||
|
me->on_gw_status_change(true);
|
||||||
|
me->_adapter->start();
|
||||||
|
me->_adapter->register_callback(me->on_exe_report);
|
||||||
|
|
||||||
|
LOG(OrderMan,Info,"ExecutionGateway::start started" );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExecutionGateway::send_msgs(
|
||||||
|
std::vector<OrderMsg> const &msgs, trace::CorID) {
|
||||||
|
LOG(OrderMan,Info,"ExecutionGateway::send_msgs" );
|
||||||
|
for (const auto &msg : msgs) {
|
||||||
|
std::visit(
|
||||||
|
[this](auto &&order) {
|
||||||
|
using T = std::decay_t<decltype(order)>;
|
||||||
|
if constexpr (std::is_same_v<T, CreateOrderMsg>) {
|
||||||
|
LOG(OrderMan,Warn,"ExecutionGateway::CreateOrderMsg" );
|
||||||
|
me->_adapter->launch_new_order(order);
|
||||||
|
|
||||||
|
} else if constexpr (std::is_same_v<T, CancelOrderMsg>) {
|
||||||
|
LOG(OrderMan,Warn,"ExecutionGateway::CancelOrderMsg" );
|
||||||
|
me->_adapter->cancel_order(order);
|
||||||
|
} else if constexpr (std::is_same_v<T, CancelReplaceOrderMsg>) {
|
||||||
|
LOG(OrderMan,Warn,"ExecutionGateway::CancelReplaceOrderMsg" );
|
||||||
|
me->_adapter->modify_order(order);
|
||||||
|
} else if constexpr (std::is_same_v<T, RFQMsg>) {
|
||||||
|
// Handle RFQMsg if necessary
|
||||||
|
// adapter->handle_rfq(order); // Example placeholder
|
||||||
|
}
|
||||||
|
},
|
||||||
|
msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExecutionGateway::dispatch_incoming_fix_messages() {}
|
||||||
|
void ExecutionGateway::on_securities(
|
||||||
|
const mercury::Update<NewSecuritiesEvent> &) {}
|
||||||
|
void ExecutionGateway::on_admin_data(
|
||||||
|
const mercury::Update<NewAdminDataEvent> &) {}
|
||||||
|
void ExecutionGateway::send_fix(const jetfix::OutFIXPtr &, trace::CorID) {}
|
||||||
|
|
||||||
|
OnExeReport &ExecutionGateway::on_exe_report() { return me->on_exe_report; }
|
||||||
|
|
||||||
|
|
||||||
|
OnCancelReject &ExecutionGateway::on_cancel_reject() {
|
||||||
|
static OnCancelReject default_cancel_reject;
|
||||||
|
return default_cancel_reject;
|
||||||
|
}
|
||||||
|
|
||||||
|
OnExchangePositionState &ExecutionGateway::on_exchange_position_state() {
|
||||||
|
static OnExchangePositionState default_exchange_position_state;
|
||||||
|
return default_exchange_position_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
OnExchangeOpenOrdersState &ExecutionGateway::on_exchange_open_orders() {
|
||||||
|
static OnExchangeOpenOrdersState default_exchange_open_orders;
|
||||||
|
return default_exchange_open_orders;
|
||||||
|
}
|
||||||
|
|
||||||
|
} //namespace bts::orderman
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "lib/orderman/gateways/IExecutionGateway.h"
|
||||||
|
namespace bts {
|
||||||
|
namespace orderman {
|
||||||
|
|
||||||
|
class ExecutionGateway : public IExecutionGateway {
|
||||||
|
public:
|
||||||
|
ExecutionGateway();
|
||||||
|
virtual ~ExecutionGateway();
|
||||||
|
void start() override;
|
||||||
|
void send_msgs(std::vector<OrderMsg> const & msgs, trace::CorID) override;
|
||||||
|
void dispatch_incoming_fix_messages() override;
|
||||||
|
void on_securities(const mercury::Update<NewSecuritiesEvent> &) override;
|
||||||
|
void on_admin_data(const mercury::Update<NewAdminDataEvent> &) override;
|
||||||
|
void send_fix(const jetfix::OutFIXPtr &, trace::CorID) override;
|
||||||
|
OnExeReport &on_exe_report() override;
|
||||||
|
OnGwStatusChange &on_gw_status_change() override;
|
||||||
|
OnCancelReject &on_cancel_reject() override;
|
||||||
|
OnExchangePositionState &on_exchange_position_state() override;
|
||||||
|
OnExchangeOpenOrdersState &on_exchange_open_orders() override;
|
||||||
|
private:
|
||||||
|
struct PImpl;
|
||||||
|
std::unique_ptr<PImpl> me;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} //namespace bts
|
||||||
|
} //namespace orderman
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "lib/md/SecurityOracle.h"
|
#include "lib/md/SecurityOracle.h"
|
||||||
#include "lib/orderman/gateways/CCAPIExecutionGateway.h"
|
#include "lib/orderman/gateways/CCAPIExecutionGateway.h"
|
||||||
// #include "lib/orderman/gateways/EMExecutionGateway.h"
|
// #include "lib/orderman/gateways/EMExecutionGateway.h"
|
||||||
|
#include "lib/orderman/gateways/ExecutionGateway.h"
|
||||||
#include "lib/orderman/gateways/FakeExecutionGateway.h"
|
#include "lib/orderman/gateways/FakeExecutionGateway.h"
|
||||||
#include "lib/orderman/gateways/GLBXExecutionGateway.h"
|
#include "lib/orderman/gateways/GLBXExecutionGateway.h"
|
||||||
#include "lib/orderman/gateways/GLBXiLink3ExecutionGateway.h"
|
#include "lib/orderman/gateways/GLBXiLink3ExecutionGateway.h"
|
||||||
@@ -12,6 +13,7 @@
|
|||||||
#include "lib/tracing/PerfLog.h"
|
#include "lib/tracing/PerfLog.h"
|
||||||
#include "lib/utils/PBUtils.h"
|
#include "lib/utils/PBUtils.h"
|
||||||
#include "lib/utils/ValueWrapper.h"
|
#include "lib/utils/ValueWrapper.h"
|
||||||
|
#include "lib/utils/bts_assert.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
@@ -21,19 +23,17 @@ std::unique_ptr<IExecutionGateway> ExecutionGatewayFactory::create_gateway(
|
|||||||
const config::JetFIX::Connection &conn,
|
const config::JetFIX::Connection &conn,
|
||||||
trace::PerfLog &pl,
|
trace::PerfLog &pl,
|
||||||
md::SecurityOracle o) {
|
md::SecurityOracle o) {
|
||||||
|
LOG(OrderMan, Info, "ExecutionGatewayFactory::create_gateway conn: {}",
|
||||||
|
utils::pb::to_string(conn));
|
||||||
|
|
||||||
if (SimExecutionGatewayFactory::is_sim_execution_on(conn.venue())) {
|
if (SimExecutionGatewayFactory::is_sim_execution_on(conn.venue())) {
|
||||||
return std::make_unique<SimExecutionGatewayUniqueWrapper>(conn.venue());
|
return std::make_unique<SimExecutionGatewayUniqueWrapper>(conn.venue());
|
||||||
}
|
}
|
||||||
LOG(OrderMan, Info, "ExecutionGatewayFactory::create_gateway conn: {}",
|
|
||||||
utils::pb::to_string(conn));
|
|
||||||
if (conn.venue() == bts::api::VENUE_ICE ||
|
if (conn.venue() == bts::api::VENUE_ICE ||
|
||||||
conn.venue() == bts::api::VENUE_SIMICE)
|
conn.venue() == bts::api::VENUE_SIMICE)
|
||||||
return std::make_unique<ICEExecutionGateway>(conn, pl, o);
|
return std::make_unique<ICEExecutionGateway>(conn, pl, o);
|
||||||
else if (conn.venue() == bts::api::VENUE_GLBX) {
|
else if (conn.venue() == bts::api::VENUE_GLBX) {
|
||||||
if (conn.use_ilink3())
|
return std::make_unique<ExecutionGateway>();
|
||||||
return std::make_unique<ilink3::GLBXiLink3ExecutionGateway>(
|
|
||||||
conn, pl, o);
|
|
||||||
return std::make_unique<GLBXExecutionGateway>(conn, pl, o);
|
|
||||||
} else if (conn.venue() == bts::api::VENUE_DERIBIT)
|
} else if (conn.venue() == bts::api::VENUE_DERIBIT)
|
||||||
// return std::make_unique<EMExecutionGateway>(o);
|
// return std::make_unique<EMExecutionGateway>(o);
|
||||||
return std::make_unique<CCAPIExecutionGateway>(conn.venue(), o);
|
return std::make_unique<CCAPIExecutionGateway>(conn.venue(), o);
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
#include "IFIXGenericAdapter.h"
|
#include "IFIXGenericAdapter.h"
|
||||||
|
|
||||||
namespace bts::orderman {}
|
namespace bts::orderman {
|
||||||
|
|
||||||
|
IFIXGenericAdapter::~IFIXGenericAdapter(){}
|
||||||
|
}
|
||||||
@@ -15,8 +15,8 @@
|
|||||||
#include "lib/utils/bts_no_copy.h"
|
#include "lib/utils/bts_no_copy.h"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
|
||||||
#include <variant>
|
|
||||||
|
|
||||||
namespace bts::orderman {
|
namespace bts::orderman {
|
||||||
|
|
||||||
@@ -29,33 +29,33 @@ class NewAdminDataEvent;
|
|||||||
class ExecutionReport;
|
class ExecutionReport;
|
||||||
class CancelReject;
|
class CancelReject;
|
||||||
|
|
||||||
struct OrderStateWithFills {
|
// struct OrderStateWithFills {
|
||||||
api::orderman::OrderState ordr_state;
|
// api::orderman::OrderState ordr_state;
|
||||||
std::vector<api::orderman::Fill> fills = {};
|
// std::vector<api::orderman::Fill> fills = {};
|
||||||
};
|
// };
|
||||||
|
|
||||||
using OnOrderUpdate = std::function<void(OrderStateWithFills const &)>;
|
using OnExecutionReport = std::function<void(ExecutionReport const &, const trace::CorID &)>;
|
||||||
|
|
||||||
// fix execution gateway for a single FIX session
|
// fix execution gateway for a single FIX session
|
||||||
class IFIXGenericAdapter {
|
class IFIXGenericAdapter {
|
||||||
public:
|
public:
|
||||||
IFIXGenericAdapter() = default;
|
IFIXGenericAdapter() = default;
|
||||||
virtual ~IFIXGenericAdapter() {}
|
virtual ~IFIXGenericAdapter();
|
||||||
|
|
||||||
virtual void start() = 0;
|
virtual void start() = 0;
|
||||||
// this callback should be added in a list, and on receving an update from the other side, it should be passed here
|
// // this callback should be added in a list, and on receving an update from the other side, it should be passed here
|
||||||
virtual void register_callback(const OnOrderUpdate &);
|
virtual void register_callback(const OnExecutionReport &) =0 ;
|
||||||
virtual void launch_new_order(const CreateOrderMsg &);
|
virtual void launch_new_order(const CreateOrderMsg &) =0;
|
||||||
virtual void modify_order(const CancelReplaceOrderMsg &);
|
virtual void modify_order(const CancelReplaceOrderMsg &) = 0;
|
||||||
virtual void cancel_order(const CancelOrderMsg &);
|
virtual void cancel_order(const CancelOrderMsg &) =0;
|
||||||
// as new securities are added
|
// as new securities are added
|
||||||
virtual void update_securities(
|
// virtual void update_securities(
|
||||||
const mercury::Update<NewSecuritiesEvent> &) = 0;
|
// const mercury::Update<NewSecuritiesEvent> &) = 0;
|
||||||
virtual void update_admin_data(
|
// virtual void update_admin_data(
|
||||||
const mercury::Update<NewAdminDataEvent> &) = 0;
|
// const mercury::Update<NewAdminDataEvent> &) = 0;
|
||||||
|
|
||||||
private:
|
// private:
|
||||||
BTS_NO_COPY(IFIXGenericAdapter);
|
// BTS_NO_COPY(IFIXGenericAdapter);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace bts::orderman
|
} // namespace bts::orderman
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
#include "MarexFIXHandler.h"
|
||||||
|
#include "lib/domain_model/Security.pb.h"
|
||||||
|
#include "lib/orderman/CreateOrderMsg.h"
|
||||||
|
#include "lib/orderman/order_factory/IOrderFactory.h"
|
||||||
|
#include "lib/orderman/orderman_utils/orderman_common.h"
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace bts::orderman {
|
||||||
|
|
||||||
|
// the orderkey is a unique id
|
||||||
|
struct MarexFIXHandler::OrderInfo {
|
||||||
|
OrderInfo(const CreateOrderMsg &msg) : update_count(0), security(msg.security), routing_record(msg.routing_record) {}
|
||||||
|
|
||||||
|
uint update_count;
|
||||||
|
const api::Security* security;
|
||||||
|
const api::orderman::RoutingRecord* routing_record;
|
||||||
|
|
||||||
|
std::string update_id(bts::orderman::OrderKey key) {
|
||||||
|
return std::to_string(update_count++) + ":" + std::to_string(key.value());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MarexFIXHandler::PImpl {
|
||||||
|
PImpl() = default;
|
||||||
|
|
||||||
|
std::unordered_map<bts::orderman::OrderKey, OrderInfo> orders;
|
||||||
|
};
|
||||||
|
|
||||||
|
void MarexFIXHandler::launch_order(const CreateOrderMsg &msg) {
|
||||||
|
me->orders.emplace(msg.key, OrderInfo(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
bts::orderman::OrderKey MarexFIXHandler::modify_order(const std::string& key) {
|
||||||
|
auto order_key = get_order_key(key);
|
||||||
|
auto it = me->orders.find(order_key);
|
||||||
|
if (it != me->orders.end()) {
|
||||||
|
// Modify the order here
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bts::orderman::OrderKey MarexFIXHandler::get_order_key(const std::string& id) {
|
||||||
|
std::size_t pos = id.find(':');
|
||||||
|
if (pos == std::string::npos) {
|
||||||
|
return null_order_key();
|
||||||
|
}
|
||||||
|
int key_value = std::stoi(id.substr(pos + 1));
|
||||||
|
return bts::orderman::OrderKey(key_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IFIXGenericAdapter.h"
|
||||||
|
#include "lib/orderman/gateways/OnixFIXListener.h"
|
||||||
|
#include "lib/orderman/orderman_utils/orderman_common.h"
|
||||||
|
|
||||||
|
namespace bts::orderman {
|
||||||
|
|
||||||
|
|
||||||
|
class MarexFIXHandler {
|
||||||
|
public:
|
||||||
|
MarexFIXHandler();
|
||||||
|
~MarexFIXHandler() ;
|
||||||
|
OnExeReport cb;
|
||||||
|
bts::orderman::OrderKey launch_order(const CreateOrderMsg &msg);
|
||||||
|
bts::orderman::OrderKey modify_order(const std::string &key);
|
||||||
|
bts::orderman::OrderKey cancel_order(const std::string &key);
|
||||||
|
std::string get_marex_id(const bts::orderman::OrderKey& key);
|
||||||
|
|
||||||
|
static bts::orderman::OrderKey get_order_key(const std::string& id);
|
||||||
|
private:
|
||||||
|
struct OrderInfo;
|
||||||
|
struct PImpl;
|
||||||
|
std::unique_ptr<PImpl> me;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace bts::orderman
|
||||||
@@ -0,0 +1,393 @@
|
|||||||
|
#include "OnixFIXAdapter.h"
|
||||||
|
#include "OnixS/FIXEngine/FIX/Engine.h"
|
||||||
|
#include "lib/config/config.h"
|
||||||
|
#include "lib/config/protos/system_config.pb.h"
|
||||||
|
#include "lib/logging/logging.h"
|
||||||
|
#include "lib/orderman/CancelReplaceOrderMsg.h"
|
||||||
|
#include "lib/orderman/gateways/OnixFIXListener.h"
|
||||||
|
#include "lib/utils/bts_assert.h"
|
||||||
|
#include <OnixS/FIXEngine/FIX/Exception.h>
|
||||||
|
#include <OnixS/FIXEngine/FIX/FIX42.h>
|
||||||
|
#include <OnixS/FIXEngine/FIX/Message.h>
|
||||||
|
#include <OnixS/FIXEngine/FIX/ProtocolVersion.h>
|
||||||
|
#include <cassert>
|
||||||
|
#include <quickfix/FixFields.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace bts::orderman {
|
||||||
|
OnixFIXAdapter::OnixFIXAdapter()
|
||||||
|
: listener(), // Initialize listener
|
||||||
|
session(nullptr) // Initialize session pointer to nullptr
|
||||||
|
{
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Initialization phase.
|
||||||
|
LOG(OrderMan, Warn, "OnixFIXAdapter::OnixFIXAdapter constructor");
|
||||||
|
OnixS::FIX::Engine::init();
|
||||||
|
session = std::make_unique<Session>(
|
||||||
|
"BTS", "TRFXMRX", OnixS::FIX::ProtocolVersion::FIX_42, &listener);
|
||||||
|
// Session-related logic goes here.
|
||||||
|
|
||||||
|
} catch (const OnixS::FIX::Exception &ex) {
|
||||||
|
std::string errorMessage = ex.what();
|
||||||
|
LOG(OrderMan, Error, "Exception: {}", errorMessage);
|
||||||
|
Engine::shutdown();
|
||||||
|
bts_assert_msg(false, "OnixFIXAdapter constructor failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OnixFIXAdapter::~OnixFIXAdapter() {
|
||||||
|
try {
|
||||||
|
session->logout();
|
||||||
|
Engine::instance()->unregisterListener();
|
||||||
|
Engine::shutdown();
|
||||||
|
LOG(OrderMan, Warn, "Object removed");
|
||||||
|
} catch (const OnixS::FIX::Exception &ex) {
|
||||||
|
std::string s = ex.what();
|
||||||
|
LOG(OrderMan, Error, "Exception {}", s);
|
||||||
|
bts_assert_msg(false, "OnixFIXAdapter deconstructor failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void OnixFIXAdapter::start() {
|
||||||
|
try {
|
||||||
|
LOG(OrderMan, Warn, "OnixFIXAdapter::start logging on");
|
||||||
|
const std::string counterpartyHost = "74.217.55.230";
|
||||||
|
const int heartBtInt = 30;
|
||||||
|
const int counterpartyPort = 22754;
|
||||||
|
session->logonAsInitiator(counterpartyHost, counterpartyPort, heartBtInt);
|
||||||
|
LOG(OrderMan, Warn, "OnixFIXAdapter::start logging on done");
|
||||||
|
|
||||||
|
} catch (const OnixS::FIX::Exception &ex) {
|
||||||
|
std::string errorMessage = ex.what();
|
||||||
|
LOG(OrderMan, Error, "OnixFIXAdapter::start Exception: {}", errorMessage);
|
||||||
|
session->logout();
|
||||||
|
Engine::shutdown();
|
||||||
|
bts_assert_msg(false, "OnixFIXAdapter session failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
uint translateEnum(T enum_value, const std::map<int, int> &translationMap) {
|
||||||
|
auto it = translationMap.find(enum_value);
|
||||||
|
assert(it != translationMap.end()); // Using assert instead of bts_assert
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint translateTimeInForce(api::orderman::TimeInForce time_in_force) {
|
||||||
|
//0 = Day 1 = GTC 2 = At the Open 3 = IOC 4 = FOK 5 = GTX
|
||||||
|
static const std::map<int, int> tifMap = {
|
||||||
|
{api::orderman::TimeInForce::TIME_IN_FORCE_DAY, 0},
|
||||||
|
{api::orderman::TimeInForce::TIME_IN_FORCE_GTC, 1},
|
||||||
|
{api::orderman::TimeInForce::TIME_IN_FORCE_IOC, 3}};
|
||||||
|
|
||||||
|
return translateEnum(time_in_force, tifMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint translateOrderType(api::orderman::NativeOrderType order_type) {
|
||||||
|
//1 = Market 2 = Limit 3 = Stop 4 = Stop Limit 5 = Market on close A = On Close B = Limit on Close
|
||||||
|
static const std::map<int, int> orderTypeMap = {
|
||||||
|
{api::orderman::NativeOrderType::NATIVE_ORDER_TYPE_MARKET, 1},
|
||||||
|
{api::orderman::NativeOrderType::NATIVE_ORDER_TYPE_LIMIT, 2},
|
||||||
|
{api::orderman::NativeOrderType::NATIVE_ORDER_TYPE_STOP, 3},
|
||||||
|
{api::orderman::NativeOrderType::NATIVE_ORDER_TYPE_STOP_LIMIT, 4}};
|
||||||
|
|
||||||
|
return translateEnum(order_type, orderTypeMap);
|
||||||
|
}
|
||||||
|
uint translateSide(api::Side side) {
|
||||||
|
//1 = Buy 2 = Sell 5 = Sell short 6 = Sell short Exempt
|
||||||
|
static const std::map<int, int> sideMap = {
|
||||||
|
{api::Side::SIDE_BUY, 1}, {api::Side::SIDE_SELL, 2}};
|
||||||
|
|
||||||
|
return translateEnum(side, sideMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void waitUntilEnterKey(const std::string &waitText = std::string()) {
|
||||||
|
OnixS::Threading::ThisThread::sleep(1000);
|
||||||
|
|
||||||
|
if (!waitText.empty())
|
||||||
|
std::clog << std::endl << waitText << std::endl;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
_getch();
|
||||||
|
#else
|
||||||
|
getchar();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
static std::string get_value_from_file(const std::string &fallback, const std::string &name) {
|
||||||
|
std::string filename =
|
||||||
|
config::get<config::SystemConfig>().data_path() + name;
|
||||||
|
std::ifstream infile(filename);
|
||||||
|
if (infile.is_open()) {
|
||||||
|
std::string file_value;
|
||||||
|
infile >> file_value;
|
||||||
|
infile.close();
|
||||||
|
return file_value;
|
||||||
|
} else {
|
||||||
|
std::ofstream outfile(filename);
|
||||||
|
if (!outfile) {
|
||||||
|
throw std::runtime_error("Could not create the file.");
|
||||||
|
}
|
||||||
|
outfile << fallback;
|
||||||
|
outfile.close();
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static std::string get_symbol_from_file(const std::string &symbol) {
|
||||||
|
return get_value_from_file(symbol, "symbol.txt");
|
||||||
|
}
|
||||||
|
static std::string get_exp_day_from_file(const std::string &exp_day) {
|
||||||
|
return get_value_from_file(exp_day, "exp_day.txt");
|
||||||
|
}
|
||||||
|
static std::string get_exp_month_from_file(const std::string &exp_month) {
|
||||||
|
return get_value_from_file(exp_month, "exp_month.txt");
|
||||||
|
}
|
||||||
|
static std::string get_exp_year_from_file(const std::string &exp_year) {
|
||||||
|
return get_value_from_file(exp_year, "exp_year.txt");
|
||||||
|
}
|
||||||
|
static std::string get_put_from_file(const std::string &put) {
|
||||||
|
return get_value_from_file(put, "put.txt");
|
||||||
|
}
|
||||||
|
static std::string get_strike_from_file(const std::string &strike) {
|
||||||
|
return get_value_from_file(strike, "strike.txt");
|
||||||
|
}
|
||||||
|
// std::string pad_string(const std::string& str, size_t length, char padding = ' ') {
|
||||||
|
// if (str.size() > length) {
|
||||||
|
// return str.substr(0, length);
|
||||||
|
// }
|
||||||
|
// return str + std::string(length - str.size(), padding);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Function to create the OSI Symbol
|
||||||
|
// static std::string create_osi_symbol(const std::string &symbol, const uint32_t &year, const uint32_t &month,const uint32_t &day,const char &call_put_indicator,const double &strike_price) {
|
||||||
|
// if (symbol.size() > 6) {
|
||||||
|
// throw std::invalid_argument("Symbol length cannot exceed 6 characters.");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// std::ostringstream osi_stream;
|
||||||
|
|
||||||
|
// // Symbol: 6 bytes, padded with spaces
|
||||||
|
// osi_stream << pad_string(symbol, 6);
|
||||||
|
|
||||||
|
// // Year: last 2 digits of the year
|
||||||
|
// osi_stream << std::setw(2) << std::setfill('0') << (year % 100);
|
||||||
|
|
||||||
|
// // Month: 2 digits
|
||||||
|
// osi_stream << std::setw(2) << std::setfill('0') << month;
|
||||||
|
|
||||||
|
// // Day: 2 digits
|
||||||
|
// osi_stream << std::setw(2) << std::setfill('0') << day;
|
||||||
|
|
||||||
|
// // Call/Put Indicator: 1 byte
|
||||||
|
// osi_stream << call_put_indicator;
|
||||||
|
|
||||||
|
// // Strike Price: 5 bytes for dollars, 3 bytes for decimal part
|
||||||
|
// int strike_dollars = static_cast<int>(strike_price);
|
||||||
|
// int strike_decimals = static_cast<int>((strike_price - strike_dollars) * 1000);
|
||||||
|
// osi_stream << std::setw(5) << std::setfill('0') << strike_dollars;
|
||||||
|
// osi_stream << std::setw(3) << std::setfill('0') << strike_decimals;
|
||||||
|
|
||||||
|
// return osi_stream.str();
|
||||||
|
// }
|
||||||
|
void parse_option(Message &order, const api::Security &sec) {
|
||||||
|
std::string put_call = get_put_from_file(sec.option().call_put() == bts::api::PutOrCall::PUTORCALL_CALL ? "1" : "0");
|
||||||
|
std::string exp_day = get_exp_day_from_file(std::to_string(sec.option().expiration_day()));
|
||||||
|
std::string exp_month = get_exp_month_from_file(std::to_string(sec.option().expiration_month()));
|
||||||
|
std::string exp_year = get_exp_year_from_file(std::to_string(sec.option().expiration_year()));
|
||||||
|
std::string maturity_month_year = exp_year + exp_month;
|
||||||
|
std::string strike_price = get_strike_from_file(std::to_string(sec.option().strike()));
|
||||||
|
// auto osi = create_osi_symbol(sec.symbol(),sec.option().expiration_year(),sec.option().expiration_month(), sec.option().expiration_day(), sec.option().call_put()== bts::api::PutOrCall::PUTORCALL_CALL?'c':'p', sec.option().strike());
|
||||||
|
// std::string osi_symbol = get_value_from_file(osi, "osi_symbol.txt");
|
||||||
|
|
||||||
|
order
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::PutOrCall, put_call)
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::StrikePrice, strike_price)
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::MaturityMonthYear, maturity_month_year)
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::MaturityDay, exp_day)
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::SecurityType,"OPT")
|
||||||
|
// .set(OnixS::FIX::FIX42::Tags::Symbol, osi_symbol)
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::SecurityExchange, "SMART"); // Example value, adjust accordingly
|
||||||
|
}
|
||||||
|
void OnixFIXAdapter::modify_order(const CancelReplaceOrderMsg &msg) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
//use this file:///C:/Users/arham/Downloads/OnixS.FixEngineCpp-Ubuntu2204-gcc1210-c++17-x64-4.10.1/OnixS.FixEngineCpp-Ubuntu2204-gcc1210-c++17-x64-4.10.1/doc/html/group__double-decimal-conversion.html
|
||||||
|
|
||||||
|
LOG(OrderMan, Warn, "OnixFIXAdapter::modify_order modifying order");
|
||||||
|
// auto order_cfg = config::get<config::OnixFixCfg>();
|
||||||
|
//message logic
|
||||||
|
//create message
|
||||||
|
|
||||||
|
// Get the symbol from the file or write it if the file doesn't exist
|
||||||
|
std::string symbol =
|
||||||
|
get_symbol_from_file(msg.create_fields.security->symbol());
|
||||||
|
Message order(
|
||||||
|
OnixS::FIX::FIX42::Values::MsgType::Order_Cancel_Replace_Request,
|
||||||
|
OnixS::FIX::ProtocolVersion::FIX_42);
|
||||||
|
order
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::HandlInst, 2) // 1: DMA 2: ALGO 3:CARE
|
||||||
|
.set(
|
||||||
|
OnixS::FIX::FIX42::Tags::OrigClOrdID,
|
||||||
|
std::to_string(msg.create_fields.key.value()))
|
||||||
|
.set(
|
||||||
|
OnixS::FIX::FIX42::Tags::ClOrdID,
|
||||||
|
"upd:"+std::to_string(msg.create_fields.key.value())) // ID for order
|
||||||
|
.set(
|
||||||
|
OnixS::FIX::FIX42::Tags::Account,
|
||||||
|
msg.create_fields.routing_record->account())
|
||||||
|
.set(
|
||||||
|
OnixS::FIX::FIX42::Tags::TimeInForce,
|
||||||
|
translateTimeInForce(msg.create_fields.time_in_force))
|
||||||
|
.set(
|
||||||
|
OnixS::FIX::FIX42::Tags::OrdType,
|
||||||
|
translateOrderType(msg.create_fields.order_type))
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::Price, msg.create_fields.price.value())
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::Rule80A, "A") //A = AGENCY P = PRINCIPAL
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::SenderSubID, "BTC")
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::TargetSubID, "TRFXMRX")
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::ClientID, "BTC")
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::SecurityType,"OPT")
|
||||||
|
// .set(
|
||||||
|
// OnixS::FIX::FIX42::Tags::Symbol,
|
||||||
|
// msg.create_fields.security->symbol())
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::CustomerOrFirm,0)
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::OpenClose,"O")
|
||||||
|
.set(
|
||||||
|
OnixS::FIX::FIX42::Tags::Side,
|
||||||
|
translateSide(msg.create_fields.side))
|
||||||
|
.set(
|
||||||
|
OnixS::FIX::FIX42::Tags::OrderQty,
|
||||||
|
msg.create_fields.quantity.value())
|
||||||
|
.set(
|
||||||
|
OnixS::FIX::FIX42::Tags::TransactTime,
|
||||||
|
OnixS::FIX::Timestamp::utc(),
|
||||||
|
OnixS::FIX::TimestampFormat::YYYYMMDDHHMMSSMsec);
|
||||||
|
|
||||||
|
if (msg.create_fields.security->has_option()) {
|
||||||
|
parse_option(order, *msg.create_fields.security);}
|
||||||
|
// else{
|
||||||
|
order.set(OnixS::FIX::FIX42::Tags::Symbol, symbol);
|
||||||
|
// }
|
||||||
|
order.validate();
|
||||||
|
LOG(OrderMan, Warn, "order Validated");
|
||||||
|
order.set(847, "SMART");
|
||||||
|
std::string order_string = order.toString('|');
|
||||||
|
updated = true;
|
||||||
|
session->send(&order);
|
||||||
|
LOG(OrderMan, Warn, "Order update sent :{}", order_string);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
// Shut down all reactors if they exist.
|
||||||
|
catch (const OnixS::FIX::Exception &ex) {
|
||||||
|
std::cout << "Exception: " << ex.what() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnixFIXAdapter::launch_new_order(const CreateOrderMsg &msg) {
|
||||||
|
LOG(OrderMan, Warn, "launch order {}", msg);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Listener listener2;
|
||||||
|
|
||||||
|
LOG(OrderMan, Warn, "OnixFIXAdapter::launch_new_order creating order");
|
||||||
|
// auto order_cfg = config::get<config::OnixFixCfg>()
|
||||||
|
//message logic
|
||||||
|
//create message
|
||||||
|
// LOG(OrderMan,Info,"creating order");
|
||||||
|
|
||||||
|
// Get the symbol from the file or write it if the file doesn't exist
|
||||||
|
std::string symbol =
|
||||||
|
get_symbol_from_file(msg.security->symbol());
|
||||||
|
Message order(
|
||||||
|
OnixS::FIX::FIX42::Values::MsgType::Order_Single,
|
||||||
|
OnixS::FIX::ProtocolVersion::FIX_42);
|
||||||
|
order
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::HandlInst, 2) // 1: DMA 2: ALGO 3:CARE
|
||||||
|
.set(
|
||||||
|
OnixS::FIX::FIX42::Tags::ClOrdID,
|
||||||
|
std::to_string(msg.key.value())) // ID for order
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::Account, msg.routing_record->account())
|
||||||
|
.set(
|
||||||
|
OnixS::FIX::FIX42::Tags::TimeInForce,
|
||||||
|
translateTimeInForce(msg.time_in_force))
|
||||||
|
.set(
|
||||||
|
OnixS::FIX::FIX42::Tags::OrdType,
|
||||||
|
translateOrderType(msg.order_type))
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::Price, msg.price.value())
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::Rule80A, "A") //A = AGENCY P = PRINCIPAL
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::SenderSubID, "BTC")
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::TargetSubID, "TRFXMRX")
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::ClientID, "BTC")
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::CustomerOrFirm,0)
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::OpenClose,"O")
|
||||||
|
// .set(
|
||||||
|
// OnixS::FIX::FIX42::Tags::Symbol,
|
||||||
|
// msg.security->symbol())
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::Side, translateSide(msg.side))
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::OrderQty, msg.quantity.value())
|
||||||
|
.set(
|
||||||
|
OnixS::FIX::FIX42::Tags::TransactTime,
|
||||||
|
OnixS::FIX::Timestamp::utc(),
|
||||||
|
OnixS::FIX::TimestampFormat::YYYYMMDDHHMMSSMsec);
|
||||||
|
if (msg.security->has_option()) {
|
||||||
|
parse_option(order, *msg.security);}
|
||||||
|
// else{
|
||||||
|
order.set(OnixS::FIX::FIX42::Tags::Symbol, symbol);
|
||||||
|
// }
|
||||||
|
std::string order_string = order.toString('|');
|
||||||
|
order.validate();
|
||||||
|
LOG(OrderMan, Warn, "order Validated");
|
||||||
|
order.set(847, "SMART");
|
||||||
|
session->send(&order);
|
||||||
|
LOG(OrderMan, Warn, "Order sent :{}", order_string);
|
||||||
|
updated =false;
|
||||||
|
}
|
||||||
|
// Shut down all reactors if they exist.
|
||||||
|
catch (const OnixS::FIX::Exception &ex) {
|
||||||
|
std::cout << "Exception: " << ex.what() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void OnixFIXAdapter::register_callback(const OnExecutionReport &cb) {
|
||||||
|
LOG(OrderMan, Warn, "OnixFIXAdapter::register_callback callback registered");
|
||||||
|
listener.setCallback(cb);
|
||||||
|
}
|
||||||
|
void OnixFIXAdapter::cancel_order(const CancelOrderMsg &msg) {
|
||||||
|
LOG(OrderMan, Warn, "cancel order {}", msg.key);
|
||||||
|
std::string symbol =
|
||||||
|
get_symbol_from_file(msg.security->symbol());
|
||||||
|
try {
|
||||||
|
|
||||||
|
Message order_cancel(
|
||||||
|
OnixS::FIX::FIX42::Values::MsgType::Order_Cancel_Request,
|
||||||
|
OnixS::FIX::ProtocolVersion::FIX_42);
|
||||||
|
order_cancel.set(OnixS::FIX::FIX42::Tags::HandlInst, 2);
|
||||||
|
order_cancel.set(
|
||||||
|
OnixS::FIX::FIX42::Tags::ClOrdID, "cancel:"+std::to_string(msg.key.value()));
|
||||||
|
// .set(OnixS::FIX::FIX42::Tags::OrderQty, msg.manual_order_indicator)
|
||||||
|
std::string prefix = updated?"upd:":"";
|
||||||
|
order_cancel
|
||||||
|
.set(
|
||||||
|
OnixS::FIX::FIX42::Tags::OrigClOrdID,
|
||||||
|
prefix+std::to_string(msg.key.value()))
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::Side, translateSide(msg.side))
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::Symbol, symbol)
|
||||||
|
.set(OnixS::FIX::FIX42::Tags::SecurityType,"OPT")
|
||||||
|
.set(
|
||||||
|
OnixS::FIX::FIX42::Tags::TransactTime,
|
||||||
|
OnixS::FIX::Timestamp::utc(),
|
||||||
|
OnixS::FIX::TimestampFormat::YYYYMMDDHHMMSSMsec);
|
||||||
|
std::string order_str = order_cancel.toString('|');
|
||||||
|
LOG(OrderMan, Warn, "order_cancel Created: {}", order_str);
|
||||||
|
// order_cancel.validate(); fails becasuse of HandlInst
|
||||||
|
LOG(OrderMan, Warn, "order Validated");
|
||||||
|
order_cancel.set(847, "SMART");
|
||||||
|
updated = false;
|
||||||
|
session->send(&order_cancel);
|
||||||
|
LOG(OrderMan, Warn, "order cancel sent");
|
||||||
|
|
||||||
|
}
|
||||||
|
// Shut down all reactors if they exist.
|
||||||
|
catch (const OnixS::FIX::Exception &ex) {
|
||||||
|
std::cout << "Exception: " << ex.what() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace bts::orderman
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IFIXGenericAdapter.h"
|
||||||
|
#include "lib/orderman/gateways/OnixFIXListener.h"
|
||||||
|
|
||||||
|
namespace bts::orderman {
|
||||||
|
|
||||||
|
class OnixFIXAdapter : public IFIXGenericAdapter {
|
||||||
|
public:
|
||||||
|
OnixFIXAdapter();
|
||||||
|
~OnixFIXAdapter() override;
|
||||||
|
void register_callback(const OnExecutionReport &report) override;
|
||||||
|
void launch_new_order(const CreateOrderMsg &msg) override;
|
||||||
|
void cancel_order(const CancelOrderMsg &msg) override;
|
||||||
|
void modify_order(const CancelReplaceOrderMsg &) override;
|
||||||
|
void start() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
OnixFixListener listener;
|
||||||
|
std::unique_ptr<Session> session;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace bts::orderman
|
||||||
@@ -0,0 +1,168 @@
|
|||||||
|
#include "OnixFIXListener.h"
|
||||||
|
|
||||||
|
#include "lib/api/services/OrderService.pb.h"
|
||||||
|
#include "lib/domain_model/Security.pb.h"
|
||||||
|
#include "lib/logging/logging.h"
|
||||||
|
#include "lib/orderman/gateways/IFIXGenericAdapter.h"
|
||||||
|
#include "lib/orderman/orderman_utils/ExecutionReport.h"
|
||||||
|
#include "lib/orderman/orderman_utils/orderman_common.h"
|
||||||
|
#include <OnixS/FIXEngine/FIX/FIX42.h>
|
||||||
|
#include <OnixS/FIXEngine/FIX/Tag.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace bts::orderman {
|
||||||
|
std::unique_ptr<ExecutionReport> OnixFixListener::get_dummy_report(CreateOrderMsg msg) {
|
||||||
|
auto er = std::make_unique<ExecutionReport>();
|
||||||
|
std::string account_name = "BTSIM";
|
||||||
|
std::array<char, 12> an_array = {};
|
||||||
|
size_t i = 0;
|
||||||
|
for (const char c : account_name) {
|
||||||
|
an_array[i++] = c;
|
||||||
|
}
|
||||||
|
er->account_name = AccountName(an_array);
|
||||||
|
to_array(msg.routing_record->account(), &er->account_name.value());
|
||||||
|
to_array(
|
||||||
|
msg.routing_record->operator_id(), &er->operator_id.value());
|
||||||
|
er->order_key = msg.key;
|
||||||
|
er->msg_seq_num = 0;
|
||||||
|
er->security = msg.security;
|
||||||
|
er->leg_security = nullptr;
|
||||||
|
er->side = msg.side;
|
||||||
|
er->time_in_force = msg.time_in_force;
|
||||||
|
er->order_type = msg.order_type;
|
||||||
|
er->exec_type = api::orderman::EXEC_TYPE_NEW;
|
||||||
|
er->order_status = api::orderman::NATIVE_ORDER_STATUS_NEW;
|
||||||
|
er->manual_order_indicator = api::orderman::MANUAL_ORDER_INDICATOR_NO;
|
||||||
|
ExchangeOrderID64 eoid = ExchangeOrderID64(exchange_oid++);
|
||||||
|
ExchangeOrderIDVar oid = eoid;
|
||||||
|
er->exchange_order_id = oid;
|
||||||
|
er->price = msg.price;
|
||||||
|
er->quantity = msg.quantity;
|
||||||
|
er->filled_quantity = Quantity(0);
|
||||||
|
er->last_shares = Quantity(0);
|
||||||
|
er->msg = "Message Placed";
|
||||||
|
er->exchange = api::VENUE_GLBX;
|
||||||
|
// Set transaction time
|
||||||
|
ExchangeTimeStamp64 now = ExchangeTimeStamp64(datetime::unix_nano_now());
|
||||||
|
er->transact_time = now;
|
||||||
|
|
||||||
|
return er;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ExecutionReport> OnixFixListener::get_exe_report(Message msg) {
|
||||||
|
auto er = std::make_unique<ExecutionReport>();
|
||||||
|
std::string account_name = "BTSIM";
|
||||||
|
std::array<char, 12> an_array = {};
|
||||||
|
size_t i = 0;
|
||||||
|
for (const char c : account_name) {
|
||||||
|
an_array[i++] = c;
|
||||||
|
}
|
||||||
|
er->account_name = AccountName(an_array);
|
||||||
|
to_array(
|
||||||
|
"op_id_bts", &er->operator_id.value());
|
||||||
|
auto extractUInt = [](const std::string& input) -> uint {
|
||||||
|
std::string numericPart;
|
||||||
|
std::copy_if(input.begin(), input.end(), std::back_inserter(numericPart), [](char c) {
|
||||||
|
return std::isdigit(c);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (numericPart.empty()) {
|
||||||
|
throw std::invalid_argument("Invalid format: no numeric characters found");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint number = std::stoul(numericPart);
|
||||||
|
return number;
|
||||||
|
};
|
||||||
|
er->order_key = OrderKey(extractUInt(msg.get(OnixS::FIX::FIX42::Tags::OrderID).toString()));
|
||||||
|
er->msg_seq_num = 0;
|
||||||
|
er->security = nullptr ;
|
||||||
|
er->leg_security = nullptr;
|
||||||
|
er->side = msg.get(OnixS::FIX::FIX42::Tags::Side).toString()=="1"?api::Side::SIDE_BUY:api::Side::SIDE_SELL;
|
||||||
|
er->time_in_force = api::orderman::TIME_IN_FORCE_DAY;
|
||||||
|
er->order_type = api::orderman::NATIVE_ORDER_TYPE_LIMIT;
|
||||||
|
er->exec_type = msg.get(OnixS::FIX::FIX42::Tags::ExecType);
|
||||||
|
er->order_status = api::orderman::NATIVE_ORDER_STATUS_NEW;
|
||||||
|
er->manual_order_indicator = api::orderman::MANUAL_ORDER_INDICATOR_NO;
|
||||||
|
ExchangeOrderID64 eoid = ExchangeOrderID64(exchange_oid++);
|
||||||
|
ExchangeOrderIDVar oid = eoid;
|
||||||
|
er->exchange_order_id = oid;
|
||||||
|
er->price = msg.price;
|
||||||
|
er->quantity = msg.quantity;
|
||||||
|
er->filled_quantity = Quantity(0);
|
||||||
|
er->last_shares = Quantity(0);
|
||||||
|
er->msg = "Message Placed";
|
||||||
|
er->exchange = api::VENUE_GLBX;
|
||||||
|
// Set transaction time
|
||||||
|
ExchangeTimeStamp64 now = ExchangeTimeStamp64(datetime::unix_nano_now());
|
||||||
|
er->transact_time = now;
|
||||||
|
|
||||||
|
return er;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnixFixListener::onInboundApplicationMsg(Message &msg, Session * /*sn*/) {
|
||||||
|
std::string msg_str = msg.toString();
|
||||||
|
std::string msg_json = msg.toJson();
|
||||||
|
|
||||||
|
LOG(OrderMan, Warn,
|
||||||
|
"Incoming application-level message: {} As json {}",
|
||||||
|
msg_str, msg_json);
|
||||||
|
FieldValueRef t = msg.type();
|
||||||
|
char message_type;
|
||||||
|
if(!t.toChar(message_type)){
|
||||||
|
LOG(OrderMan, Warn,
|
||||||
|
"no message type message: {} As json {}",
|
||||||
|
msg_str, msg_json);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (message_type) {
|
||||||
|
case 'D':
|
||||||
|
{
|
||||||
|
//exection report
|
||||||
|
auto er = get_dummy_report(msg);
|
||||||
|
cb(*er,{});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LOG(OrderMan, Warn,
|
||||||
|
// "onInboundApplicationMsg::inbound firing er: {}",
|
||||||
|
// er->to_string());
|
||||||
|
|
||||||
|
// cb(*er, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OnixFixListener::onInboundSessionMsg(Message & msg, Session * /*sn*/)
|
||||||
|
{
|
||||||
|
std::string msg_str = msg.toString();
|
||||||
|
std::string msg_json = msg.toJson();
|
||||||
|
LOG( OrderMan, Warn,
|
||||||
|
"Incoming session-level message:\n {} As json {}",
|
||||||
|
msg_str,
|
||||||
|
msg_json);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnixFixListener::onStateChange(SessionState::Enum newState, SessionState::Enum prevState,
|
||||||
|
Session * /*sn*/)
|
||||||
|
{
|
||||||
|
std::string prevst = SessionState::toString(prevState);
|
||||||
|
std::string newst = SessionState::toString(newState);
|
||||||
|
LOG(OrderMan, Warn,
|
||||||
|
"Session's state is changed, prevState = {} , newState= {}",
|
||||||
|
prevst,
|
||||||
|
newst);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnixFixListener::onError(ErrorReason::Enum /*reason*/, const std::string & description, Session * /*sn*/)
|
||||||
|
{
|
||||||
|
LOG( OrderMan, Error, "Session-level error: {}", description);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnixFixListener::onWarning(WarningReason::Enum /*reason*/, const std::string & description,
|
||||||
|
Session * /*sn*/)
|
||||||
|
{
|
||||||
|
LOG( OrderMan, Error, "Session-level warning: {}", description);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace bts::orderman
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "lib/orderman/CreateOrderMsg.h"
|
||||||
|
#include "lib/orderman/gateways/IExecutionGateway.h"
|
||||||
|
#include "lib/orderman/orderman_utils/ExecutionReport.h"
|
||||||
|
#include <OnixS/FIXEngine.h>
|
||||||
|
#include <OnixS/FIXEngine/FIX/Message.h>
|
||||||
|
|
||||||
|
namespace bts::orderman {
|
||||||
|
|
||||||
|
using namespace OnixS::FIX;
|
||||||
|
class OnixFixListener : public OnixS::FIX::ISessionListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OnixFixListener(): cb(dummy){
|
||||||
|
LOG(OrderMan,Info,"OnixFixListener::cb set callback registered");
|
||||||
|
}
|
||||||
|
unsigned long exchange_oid = 0;
|
||||||
|
/// Is called when the application-level message is received from the counterparty.
|
||||||
|
void onInboundApplicationMsg(Message & msg, Session * sn) ONIXS_FIXENGINE_FINAL;
|
||||||
|
// Set the real callback function
|
||||||
|
void setCallback(const OnExeReport &callback) {
|
||||||
|
LOG(OrderMan,Info,"OnixFixListener::setCallback callback registered");
|
||||||
|
cb = callback;
|
||||||
|
}
|
||||||
|
/// Is called when the session-level message is received from the counterparty.
|
||||||
|
void onInboundSessionMsg(Message & msg, Session * sn) ONIXS_FIXENGINE_FINAL;
|
||||||
|
void onStateChange(SessionState::Enum newState, SessionState::Enum prevState, Session * sn) ONIXS_FIXENGINE_FINAL;
|
||||||
|
OnExeReport cb;
|
||||||
|
std::unique_ptr<ExecutionReport> get_dummy_report(CreateOrderMsg msg);
|
||||||
|
std::unique_ptr<ExecutionReport> get_exe_report(Message msg);
|
||||||
|
static void dummy(const ExecutionReport &, const trace::CorID &) {
|
||||||
|
LOG(OrderMan, Info,"OnixFixListener::Dummy fired");
|
||||||
|
}
|
||||||
|
void onError(ErrorReason::Enum reason, const std::string & description, Session * sn) ONIXS_FIXENGINE_FINAL;
|
||||||
|
void onWarning(WarningReason::Enum reason, const std::string & description, Session * sn) ONIXS_FIXENGINE_FINAL;
|
||||||
|
// boost::object_pool<ExecutionReport> exe_report_pool;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}// namespace bts::orderman
|
||||||
@@ -62,7 +62,7 @@ SimExecutionGatewayFactory *SimExecutionGatewayFactory::get() {
|
|||||||
|
|
||||||
bool SimExecutionGatewayFactory::is_sim_execution_on(api::Venue venue) {
|
bool SimExecutionGatewayFactory::is_sim_execution_on(api::Venue venue) {
|
||||||
// TODO: Arham, fix this !
|
// TODO: Arham, fix this !
|
||||||
return true;
|
return false;
|
||||||
const auto &sim_exec = config::get<bts::config::SimExecution>();
|
const auto &sim_exec = config::get<bts::config::SimExecution>();
|
||||||
for (const auto &e : sim_exec.entries()) {
|
for (const auto &e : sim_exec.entries()) {
|
||||||
if (e.venue() == venue) {
|
if (e.venue() == venue) {
|
||||||
|
|||||||
@@ -478,11 +478,11 @@ OrderOpResult GLBXNativeOrder::on_activate(
|
|||||||
now.to_uint64(), (now - corid.app_arrival).nanoseconds());
|
now.to_uint64(), (now - corid.app_arrival).nanoseconds());
|
||||||
// in sim mode, we dont need this,
|
// in sim mode, we dont need this,
|
||||||
me->encoder->send_create(*me->services, *me->session_services);
|
me->encoder->send_create(*me->services, *me->session_services);
|
||||||
if (me->in_sim_mode) {
|
// if (me->in_sim_mode) {
|
||||||
CreateOrderMsg c_msg = {};
|
CreateOrderMsg c_msg = {};
|
||||||
_create_create_msg(c_msg);
|
_create_create_msg(c_msg);
|
||||||
me->services->queue_order_msg(*me->session_services, c_msg);
|
me->services->queue_order_msg(*me->session_services, c_msg);
|
||||||
}
|
// }
|
||||||
me->services->governor(*me->session_services).record_sent();
|
me->services->governor(*me->session_services).record_sent();
|
||||||
me->state.set_status(ORDER_STATUS_PENDING_WORKING);
|
me->state.set_status(ORDER_STATUS_PENDING_WORKING);
|
||||||
|
|
||||||
@@ -579,7 +579,6 @@ OrderOpResult GLBXNativeOrder::on_update(api::orderman::Update const &update) {
|
|||||||
auto p = Price(update.price());
|
auto p = Price(update.price());
|
||||||
auto q = Quantity(update.quantity());
|
auto q = Quantity(update.quantity());
|
||||||
auto send_update_in_sim_mode = [&]() {
|
auto send_update_in_sim_mode = [&]() {
|
||||||
if (me->in_sim_mode) {
|
|
||||||
CancelReplaceOrderMsg cxl_repl_msg = {};
|
CancelReplaceOrderMsg cxl_repl_msg = {};
|
||||||
_create_create_msg(cxl_repl_msg.create_fields);
|
_create_create_msg(cxl_repl_msg.create_fields);
|
||||||
Price new_p = Price(update.price());
|
Price new_p = Price(update.price());
|
||||||
@@ -587,7 +586,6 @@ OrderOpResult GLBXNativeOrder::on_update(api::orderman::Update const &update) {
|
|||||||
cxl_repl_msg.create_fields.price = new_p;
|
cxl_repl_msg.create_fields.price = new_p;
|
||||||
cxl_repl_msg.create_fields.quantity = new_q;
|
cxl_repl_msg.create_fields.quantity = new_q;
|
||||||
me->services->queue_order_msg(*me->session_services, cxl_repl_msg);
|
me->services->queue_order_msg(*me->session_services, cxl_repl_msg);
|
||||||
}
|
|
||||||
};
|
};
|
||||||
LOG(OrderMan, Info, "GLBXNativeOrder::on_update update: {}",
|
LOG(OrderMan, Info, "GLBXNativeOrder::on_update update: {}",
|
||||||
utils::pb::to_string(update));
|
utils::pb::to_string(update));
|
||||||
@@ -799,12 +797,13 @@ OrderOpResult GLBXNativeOrder::on_cancel() {
|
|||||||
me->encoder->update_cancel_encoding(*me->services);
|
me->encoder->update_cancel_encoding(*me->services);
|
||||||
me->encoder->send_cancel(*me->services, *me->session_services);
|
me->encoder->send_cancel(*me->services, *me->session_services);
|
||||||
// TODO: check for sim mode here
|
// TODO: check for sim mode here
|
||||||
if (me->in_sim_mode) {
|
|
||||||
CancelOrderMsg cxl_msg = {};
|
CancelOrderMsg cxl_msg = {};
|
||||||
cxl_msg.key = key();
|
cxl_msg.key = key();
|
||||||
LOG(OrderMan, Info, "GLBXNativeOrder queue_order_msg for cxl");
|
cxl_msg.security = me->sec;
|
||||||
me->services->queue_order_msg(*me->session_services, cxl_msg);
|
cxl_msg.side = me->definition.side();
|
||||||
}
|
LOG(OrderMan, Info, "GLBXNativeOrder queue_order_msg for cxl");
|
||||||
|
me->services->queue_order_msg(*me->session_services, cxl_msg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1383,7 +1382,6 @@ void GLBXNativeOrder::_create_create_msg(CreateOrderMsg &c) {
|
|||||||
c.side = me->definition.side();
|
c.side = me->definition.side();
|
||||||
c.order_type = get_glbx_native_ord_type(me->definition);
|
c.order_type = get_glbx_native_ord_type(me->definition);
|
||||||
c.time_in_force = me->definition.time_in_force();
|
c.time_in_force = me->definition.time_in_force();
|
||||||
c.order_type = api::orderman::NATIVE_ORDER_TYPE_LIMIT;
|
|
||||||
c.manual_order_indicator = me->definition.manual_order_indicator();
|
c.manual_order_indicator = me->definition.manual_order_indicator();
|
||||||
c.routing_record = &me->routing_record;
|
c.routing_record = &me->routing_record;
|
||||||
LOG(OrderMan, Info, "GLBXNativeOrder::_create_create_msg c.qty: {}",
|
LOG(OrderMan, Info, "GLBXNativeOrder::_create_create_msg c.qty: {}",
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "lib/jetfix/codec/FieldDefinitions.h"
|
#include "lib/jetfix/codec/FieldDefinitions.h"
|
||||||
#include "lib/orderman/OrderServices.h"
|
#include "lib/orderman/OrderServices.h"
|
||||||
#include "lib/orderman/orderman_utils/fix_order_codec.h"
|
#include "lib/orderman/orderman_utils/fix_order_codec.h"
|
||||||
|
#include "lib/utils/helper_macros.h"
|
||||||
|
|
||||||
namespace bts {
|
namespace bts {
|
||||||
namespace orderman {
|
namespace orderman {
|
||||||
@@ -274,9 +275,10 @@ void iLink2OrderEncoder::init(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void iLink2OrderEncoder::update_exchange_order_id(ExchangeOrderIDVar const &v) {
|
void iLink2OrderEncoder::update_exchange_order_id(ExchangeOrderIDVar const &v) {
|
||||||
auto oid = to_trim_str(std::get<ExchangeOrderID>(v));
|
UNUSED(v);
|
||||||
me->update_encoding.add<jetfix::fix::OrderID>(oid);
|
// auto oid = to_trim_str(std::get<ExchangeOrderID>(v));
|
||||||
me->cancel_encoding.add<jetfix::fix::OrderID>(oid);
|
// me->update_encoding.add<jetfix::fix::OrderID>(oid);
|
||||||
|
// me->cancel_encoding.add<jetfix::fix::OrderID>(oid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iLink2OrderEncoder::update_create_order_encoding(
|
void iLink2OrderEncoder::update_create_order_encoding(
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
#include "Run.h"
|
#include "Run.h"
|
||||||
#include "lib/api/public/ServiceContext.h"
|
#include "lib/api/public/ServiceContext.h"
|
||||||
|
#include "lib/api/services/OrderService.pb.h"
|
||||||
#include "lib/config/config.h"
|
#include "lib/config/config.h"
|
||||||
#include "lib/config/protos/ports.pb.h"
|
#include "lib/config/protos/ports.pb.h"
|
||||||
#include "lib/config/protos/quickbus_cfg.pb.h"
|
#include "lib/config/protos/quickbus_cfg.pb.h"
|
||||||
#include "lib/config/protos/toggles.pb.h"
|
#include "lib/config/protos/toggles.pb.h"
|
||||||
|
#include "lib/domain_model/Security.pb.h"
|
||||||
|
#include "lib/domain_model/common.h"
|
||||||
#include "lib/logging/logging.h"
|
#include "lib/logging/logging.h"
|
||||||
#include "lib/md/MBOProcessor.h"
|
#include "lib/md/MBOProcessor.h"
|
||||||
#include "lib/md/MBOServiceServer.h"
|
#include "lib/md/MBOServiceServer.h"
|
||||||
@@ -13,9 +16,14 @@
|
|||||||
#include "lib/md/service/MarketDataServiceServer.h"
|
#include "lib/md/service/MarketDataServiceServer.h"
|
||||||
#include "lib/metrics/metrics.h"
|
#include "lib/metrics/metrics.h"
|
||||||
#include "lib/metrics/system_metrics.h"
|
#include "lib/metrics/system_metrics.h"
|
||||||
|
#include "lib/orderman/CancelOrderMsg.h"
|
||||||
|
#include "lib/orderman/CancelReplaceOrderMsg.h"
|
||||||
#include "lib/orderman/OrderServiceServer.h"
|
#include "lib/orderman/OrderServiceServer.h"
|
||||||
|
#include "lib/orderman/gateways/OnixFIXAdapter.h"
|
||||||
#include "lib/orderman/gateways/sim/SimExecutionGatewayFactory.h"
|
#include "lib/orderman/gateways/sim/SimExecutionGatewayFactory.h"
|
||||||
#include "lib/orderman/order_factory/DynamicOrderRegistry.h"
|
#include "lib/orderman/order_factory/DynamicOrderRegistry.h"
|
||||||
|
#include "lib/orderman/order_factory/IOrderFactory.h"
|
||||||
|
#include "lib/orderman/orderman_utils/orderman_common.h"
|
||||||
#include "lib/orderman/orders/algo/algo_orders/ProRataAlgo.h"
|
#include "lib/orderman/orders/algo/algo_orders/ProRataAlgo.h"
|
||||||
#include "lib/orderman/orders/algo/algo_orders/ScratchAlgo.h"
|
#include "lib/orderman/orders/algo/algo_orders/ScratchAlgo.h"
|
||||||
#include "lib/os/os.h"
|
#include "lib/os/os.h"
|
||||||
@@ -26,6 +34,7 @@
|
|||||||
#include "lib/tracing/PerfLog.h"
|
#include "lib/tracing/PerfLog.h"
|
||||||
#include "lib/utils/Dispatcher.h"
|
#include "lib/utils/Dispatcher.h"
|
||||||
#include "lib/utils/thread_manager.h"
|
#include "lib/utils/thread_manager.h"
|
||||||
|
#include "lib/orderman/gateways/ExecutionGateway.h"
|
||||||
#include "md/cmds/Run.h"
|
#include "md/cmds/Run.h"
|
||||||
#include "server/sparkd/algo/AlgoDefinitionServiceServer.h"
|
#include "server/sparkd/algo/AlgoDefinitionServiceServer.h"
|
||||||
#include "server/sparkd/analytics/AnalyticsServiceServer.h"
|
#include "server/sparkd/analytics/AnalyticsServiceServer.h"
|
||||||
@@ -43,6 +52,7 @@
|
|||||||
#include "server/sparkd/user/AdminServiceServer.h"
|
#include "server/sparkd/user/AdminServiceServer.h"
|
||||||
#include "server/sparkd/user/AuthServiceServer.h"
|
#include "server/sparkd/user/AuthServiceServer.h"
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
namespace bts::cmds {
|
namespace bts::cmds {
|
||||||
@@ -52,6 +62,39 @@ static void execute() {
|
|||||||
LOG(Gen, Warn,
|
LOG(Gen, Warn,
|
||||||
"------------------------------------ Sparkd launched "
|
"------------------------------------ Sparkd launched "
|
||||||
"--------------------------------");
|
"--------------------------------");
|
||||||
|
// orderman::CreateOrderMsg cm;
|
||||||
|
// cm.price = Price(165);
|
||||||
|
// cm.key = orderman::OrderKey(47);
|
||||||
|
// api::orderman::RoutingRecord rr;
|
||||||
|
// rr.set_account("BTSIM");
|
||||||
|
// api::Security sec;
|
||||||
|
// sec.set_symbol("BTS");
|
||||||
|
// cm.security = &sec;
|
||||||
|
// cm.routing_record = &rr;
|
||||||
|
// cm.side = api::SIDE_BUY;
|
||||||
|
// cm.quantity = 2;
|
||||||
|
// cm.time_in_force = api::orderman::TimeInForce::TIME_IN_FORCE_DAY;
|
||||||
|
// cm.order_type = api::orderman::NativeOrderType::NATIVE_ORDER_TYPE_LIMIT;
|
||||||
|
|
||||||
|
// orderman::CancelReplaceOrderMsg cnm;
|
||||||
|
// cnm.exchange_order_id = orderman::ExchangeOrderID64(47);
|
||||||
|
// cnm.create_fields.price = Price(164);
|
||||||
|
// cnm.create_fields.key = orderman::OrderKey(47);
|
||||||
|
// cnm.create_fields.security = &sec;
|
||||||
|
// cnm.create_fields.routing_record = &rr;
|
||||||
|
// cnm.create_fields.side = api::SIDE_BUY;
|
||||||
|
// cnm.create_fields.quantity = 3;
|
||||||
|
// cnm.create_fields.time_in_force = api::orderman::TimeInForce::TIME_IN_FORCE_DAY;
|
||||||
|
// cnm.create_fields.order_type = api::orderman::NativeOrderType::NATIVE_ORDER_TYPE_LIMIT;
|
||||||
|
// cnm.create_fields.side = api::SIDE_BUY;
|
||||||
|
// cnm.create_fields.security = &sec;
|
||||||
|
// std::vector<orderman::OrderMsg> msgs = {cm,cnm};
|
||||||
|
// orderman::ExecutionGateway gateway;
|
||||||
|
// gateway.start();
|
||||||
|
// trace::CorID t;
|
||||||
|
// gateway.send_msgs(msgs, t);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
auto qb_cfg = config::get<config::QuickbusCfg>().node();
|
auto qb_cfg = config::get<config::QuickbusCfg>().node();
|
||||||
auto &ports = config::get<config::Ports>();
|
auto &ports = config::get<config::Ports>();
|
||||||
|
|||||||
Reference in new issue
Block a user